lkml.org 
[lkml]   [1996]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: Oops with 1.3.79 and kerneld
Date
Matthias Sattler <m_sattle@poker.informatik.uni-kl.de> wrote:
> Mar 27 12:00:25 gandalf insmod: Initialization of st failed
> Mar 27 12:00:25 gandalf kernel: Detected scsi tape st0 at scsi0, channel 0, id 3, lun 0
> Mar 27 12:00:25 gandalf kernel: st: Can't allocate new tape buffer (nbr 0).
[...]
>
> Mar 27 12:00:25 gandalf kernel: Can't continue without at least one tape buffer.
> Mar 27 12:01:25 gandalf kernel: Unable to handle kernel paging request at virtual address c1866ce0
>
> It seemed to happen when kerneld tried to unload sr_mod (I don't even have a

Nope, I'm almost certain it happened when init_module in st.o failed.

I looked at the scsi sources and think I have found a suspect...
In linux/drivers/scsi/scsi.c the code looks like this:

static int scsi_register_device_module(struct Scsi_Device_Template * tpnt)
{
Scsi_Device * SDpnt;

if (tpnt->next) return 1;

1===> scsi_register_device(tpnt);
/*
* First scan the devices that we know about, and see if we notice them.
*/

for(SDpnt = scsi_devices; SDpnt; SDpnt = SDpnt->next)
if(tpnt->detect) SDpnt->attached += (*tpnt->detect)(SDpnt);

/*
* If any of the devices would match this driver, then perform the
* init function.
*/
if(tpnt->init && tpnt->dev_noticed)
if ((*tpnt->init)()) return 1;
2==============================^^^^^^^^


So, if the *tpnt->init() call failed (at arrow #2 above), a return will
be made to init_module in the upper level driver (st.o in this case),
and the init_module function will fail.

This means that the module will never become resident in the kernel,
but instead immediately removed by the code in linux/kernel/module.c

Unfortunately the st.o module was registred at arrow #1 above, but
it was never _unregistred_ before the "return 1"...

A first fix (completely untested!!!) could look like this:

--- linux/drivers/scsi/scsi.c.ouch Wed Mar 27 22:18:13 1996
+++ linux/drivers/scsi/scsi.c Wed Mar 27 22:22:11 1996
@@ -88,6 +88,7 @@
Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt,
struct Scsi_Host *shpnt, char * scsi_result);
void scsi_build_commandblocks(Scsi_Device * SDpnt);
+static int scsi_unregister_device(struct Scsi_Device_Template * tpnt);

#ifdef CONFIG_MODULES
extern struct symbol_table scsi_symbol_table;
@@ -2968,7 +2969,12 @@
* init function.
*/
if(tpnt->init && tpnt->dev_noticed)
- if ((*tpnt->init)()) return 1;
+ if ((*tpnt->init)()) {
+ /* ouch... scsi_unregister_device does a MOD_DEC_USE_COUNT */
+ MOD_INC_USE_COUNT;
+ scsi_unregister_device(tpnt);
+ return 1;
+ }

/*
* Now actually connect the devices to the new driver.

A more pleasing arrangement of MOD_INC_USE_COUNT can surely be found...

Bjorn


\
 
 \ /
  Last update: 2005-03-22 13:36    [W:0.033 / U:0.168 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site