Subject: Re: LKM puzzle
To: Chris Huang <chris@bsdz.org>
From: Bill Studenmund <wrstuden@zembu.com>
List: tech-kern
Date: 08/02/2001 12:20:35
On Thu, 2 Aug 2001, Chris Huang wrote:
> Hi there,
> Recently, I have played around with the LKM stuff on i386 NetBSD1.5, and
> it has been interesting. I did get my pseudo driver to work with LKM.
> Nevertheless, I am kinda lost now on how LKM handle some of the stuff.
>
> When I first started out writing the character device module, I did not know
> that
> LKM will automatically save the old content in the cdevsw[] slots to
> lkm_olddev,
> so by following the examples in /usr/share/lkm/misc, I put the following in
> my code
> in my loading function where I tried to save the old content manually.
This context saving isn't in the examples I find, and is your problem. :-)
> -----cut---------
> /* get the first empty cdev_lkm_dummy slot in cdevsw */
> /* for ( counter = 0; counter < nchrdev ; counter++)
> {
> if ( cdevsw[counter].d_open == (dev_type_open((*)))lkmenodev)
> {
> args->lkm_offset = counter;
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This line is responsable for the behavior you are seeing.
> break;
> }
>
> if ( counter == nchrdev )
> {
> printf("the slots are full !\n");
> return(2);
> }
>
> /* if we make it here, an empty lkm slot has been found */
> /* save the old device driver switch entry */
> bcopy(&cdevsw[args->lkm_offset], &oldDevsw, sizeof(struct cdevsw) );
>
> /* load the new device driver switch entry */
> bcopy(&dateDevsw, &cdevsw[args->lkm_offset], sizeof(struct cdevsw) );
> ----cut------
>
> and In my unload function call , I have
>
> ---cut ----
> bcopy(&oldDevsw, &cdevsw[args->lkm_offset], sizeof(struct cdevsw) );
> -----cut-----
>
> my question is that the lkm code help to save the old content in the
> cdevsw[]
> after the load fucntion is call and restore it after the unload fnction
> call. so what I
> did to cdevsw[] in my load/unload function shouldn't have any side effect on
> cdevsw[]
> since LKM code will restore it.
But you are doing more than play with cdevsw, you are adjusting
args->lkm_offset. That's the variable which the lkm code uses to remember
the slot _it_ stored things in.
> but as I run my code for couple times, the cdevsw[] slot is not restored to
> it original
> condition, everytime the cdevsw[] slot is different and the one previously
> used is never free
> up, thus at the end, it couldnt find any free cdev_lkm_dummmy() slots.
>
> Any suggestions why this is happening ?
Yes. Remove your slot adjusting code. :-)
The problem is that both your code _and_ the lkm code are aloocating a
slot on cdevsw for your driver. That's TWO slots. But both bits of code
clean up the same one, the one at args->lkm_offset. That's why you are
seeing a leak.
Take care,
Bill