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