Re: regparm issue on RHEL4 kernel with LiS 2.18.3

Kevin K <[email protected]> Tue, 28 Mar 2006 07:12:56 -0600
Newsgroups gmane.linux.kernel.streams
Message-ID <[email protected]>
On Mar 27, 2006, at 8:34 PM, Brian F. G. Bidulock wrote:

> 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
>
>
> On Mon, 27 Mar 2006, Kevin K wrote:
>
>> 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
>> [email protected]
>> 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