Discussion:
regparm issue on RHEL4 kernel with LiS 2.18.3
Kevin K
2006-03-28 01:44:01 UTC
Permalink
Has anyone else noticed a problem with the Redhat Kernel compiled
with the default register parameters?

I'm looking at porting a legacy set of modules written for LiS 2.12
and the 2.4.18 kernel to the Red Hat 2.6.9-34 kernel.

The initial problem I encountered was that the open routine in the
module was getting garbage in it's parameter. I enabled debug
output, and it showed that, just before it called my routine, it had
the right parameters.

Finally, I ended up recompiling the kernel again with regparms turned
off, and recompiled LiS correctly. I required a modification to the
Makefile, since the configure script didn't retrieve the
configuration options correctly, then it finally started to work.

Note, I haven't tried the most recent version of Fast Streams yet. I
couldn't get the streams module to load successfully in the January
version. Unfortunately, I didn't save any of the error output. I
may give it another try in the not to distant future, if only because
if it works, it will save a considerable amount of memory. It is
hard to believe how much memory the current version of streams is
taking up :)
Brian F. G. Bidulock
2006-03-28 02:34:45 UTC
Permalink
Kevin,

Some gcc compilers (and it looks like you're using an older one), don't
detect regparm attribute mismatches in pointers when regparms is pass
as a option to the compiler, that is:

int (*foo)(int) __attribute__((regparm,0));

int bar(int dummy) {
return (dummy);
}

foo = &bar; /* should generate an error -regparm=3, but doesn't */

therefore, even though qinit is defined in include/sys/LiS/queue.h as:

typedef struct qinit {
#if defined(USE_VOID_PUT_PROC)
void _RP (*qi_putp) (queue_t *, mblk_t *); /* put procedure */
void _RP (*qi_srvp) (queue_t *); /* service procedure */
#else
int _RP (*qi_putp) (queue_t *, mblk_t *); /* put procedure */
int _RP (*qi_srvp) (queue_t *); /* service procedure */
#endif
int _RP (*qi_qopen) (queue_t *, dev_t *, int, int, cred_t *);
int _RP (*qi_qclose) (queue_t *, int, cred_t *); /* close procedure */
int _RP (*qi_qadmin) (void); /* debugging */
struct lis_module_info *qi_minfo; /* module information structure */
struct module_stat *qi_mstat; /* module statistics structure */
} qinit_t;

Where _RP is __attribute__((regparm,0)) on regparm supporting architectures,
you can do this:

int foo_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) {
...
return (0);
}

int foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}

struct qinit foo_rinit = {
...
.qi_qopen = &foo_open,
.qi_qclose = &foo_close,
...
};

and when compiled with -regparms=3, older gcc3 compilers will not warn of the
mismatch.

If you do, however,

int _RP foo_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) {
...
return (0);
}

int _RP foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}

There is no mismatch and no problem. So, try that.

For Linux Fast-STREAMS, the equivalent is 'streamscall', so

int streamscall foo_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) {
...
return (0);
}

int streamscall foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}

Under Linux Fast-STREAMS, streamscall is __attribute__((regparm,3)) on
supporting architectures, so if you forget the streamscall you will only
encounter problems on non-regparms kernels (for architectures support
regparms). The result is of course faster than LiS on ia32 architectures.

Hope that helps.

BTW, the current Linux Fast-STREAMS works *way* better than LiS.

--brian
Post by Kevin K
Has anyone else noticed a problem with the Redhat Kernel compiled
with the default register parameters?
I'm looking at porting a legacy set of modules written for LiS 2.12
and the 2.4.18 kernel to the Red Hat 2.6.9-34 kernel.
The initial problem I encountered was that the open routine in the
module was getting garbage in it's parameter. I enabled debug
output, and it showed that, just before it called my routine, it had
the right parameters.
Finally, I ended up recompiling the kernel again with regparms turned
off, and recompiled LiS correctly. I required a modification to the
Makefile, since the configure script didn't retrieve the
configuration options correctly, then it finally started to work.
Note, I haven't tried the most recent version of Fast Streams yet. I
couldn't get the streams module to load successfully in the January
version. Unfortunately, I didn't save any of the error output. I
may give it another try in the not to distant future, if only because
if it works, it will save a considerable amount of memory. It is
hard to believe how much memory the current version of streams is
taking up :)
_______________________________________________
Linux-streams mailing list
http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams
--
Brian F. G. Bidulock ¦ The reasonable man adapts himself to the ¦
***@openss7.org ¦ world; the unreasonable one persists in ¦
http://www.openss7.org/ ¦ trying to adapt the world to himself. ¦
¦ Therefore all progress depends on the ¦
¦ unreasonable man. -- George Bernard Shaw ¦
Kevin K
2006-03-28 13:12:56 UTC
Permalink
Post by Brian F. G. Bidulock
Kevin,
Some gcc compilers (and it looks like you're using an older one), don't
detect regparm attribute mismatches in pointers when regparms is pass
int (*foo)(int) __attribute__((regparm,0));
int bar(int dummy) {
return (dummy);
}
foo = &bar; /* should generate an error -regparm=3, but doesn't */
typedef struct qinit {
#if defined(USE_VOID_PUT_PROC)
void _RP (*qi_putp) (queue_t *, mblk_t *); /* put procedure */
void _RP (*qi_srvp) (queue_t *); /* service procedure */
#else
int _RP (*qi_putp) (queue_t *, mblk_t *); /* put procedure */
int _RP (*qi_srvp) (queue_t *); /* service procedure */
#endif
int _RP (*qi_qopen) (queue_t *, dev_t *, int, int, cred_t *);
int _RP (*qi_qclose) (queue_t *, int, cred_t *); /* close
procedure */
int _RP (*qi_qadmin) (void); /* debugging */
struct lis_module_info *qi_minfo; /* module information
structure */
struct module_stat *qi_mstat; /* module statistics structure */
} qinit_t;
Where _RP is __attribute__((regparm,0)) on regparm supporting
architectures,
int foo_open(queue_t *q, dev_t *devp, int oflag, int sflag,
cred_t *crp) {
...
return (0);
}
int foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}
struct qinit foo_rinit = {
...
.qi_qopen = &foo_open,
.qi_qclose = &foo_close,
...
};
and when compiled with -regparms=3, older gcc3 compilers will not warn of the
mismatch.
If you do, however,
int _RP foo_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) {
...
return (0);
}
int _RP foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}
There is no mismatch and no problem. So, try that.
For Linux Fast-STREAMS, the equivalent is 'streamscall', so
int streamscall foo_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) {
...
return (0);
}
int streamscall foo_close(queue_t *q, int oflag, cred_t *crp) {
...
return (0);
}
Under Linux Fast-STREAMS, streamscall is __attribute__((regparm,3)) on
supporting architectures, so if you forget the streamscall you will only
encounter problems on non-regparms kernels (for architectures support
regparms). The result is of course faster than LiS on ia32
architectures.
Hope that helps.
BTW, the current Linux Fast-STREAMS works *way* better than LiS.
--brian
Post by Kevin K
Has anyone else noticed a problem with the Redhat Kernel compiled
with the default register parameters?
I'm looking at porting a legacy set of modules written for LiS 2.12
and the 2.4.18 kernel to the Red Hat 2.6.9-34 kernel.
The initial problem I encountered was that the open routine in the
module was getting garbage in it's parameter. I enabled debug
output, and it showed that, just before it called my routine, it had
the right parameters.
Finally, I ended up recompiling the kernel again with regparms turned
off, and recompiled LiS correctly. I required a modification to the
Makefile, since the configure script didn't retrieve the
configuration options correctly, then it finally started to work.
Note, I haven't tried the most recent version of Fast Streams yet. I
couldn't get the streams module to load successfully in the January
version. Unfortunately, I didn't save any of the error output. I
may give it another try in the not to distant future, if only because
if it works, it will save a considerable amount of memory. It is
hard to believe how much memory the current version of streams is
taking up :)
_______________________________________________
Linux-streams mailing list
http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams
I'll take a look at that. I didn't think about definition of the
actual open routine, and since it is over 5 years old, it isn't
aware of any of the newer compiler issues. But after 5 years of
using gcc 2.96, 3.4.5 seems new to me :)

Obviously, I'm hopeful that any issues in our code can be cleaned up
enough that it will support both versions. On some of our hardware,
the meg that LiS is using is a significant portion of a 32MB
computer, especially when we already hit the swap file pretty hard on
RHEL 2.1.

Thanks for the pointer.

Kevin

Loading...