From: Douglas Gilbert <dougg@torque.net>
To: linux-scsi@vger.kernel.org
Cc: mikpe@csd.uu.se, wrlk@riede.org
Subject: Fwd: [PATCH] 2.5.54 fix ide-cd/ide-scsi oopses after module unload
Date: Sat, 04 Jan 2003 22:18:44 +1100 [thread overview]
Message-ID: <3E16C314.1060307@torque.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 3180 bytes --]
Mikael Pettersson posted the following to the linux-kernel
mailing list. His patch includes a fix that Willem Riede
spotted as well (no driver_unregister() in ide.c). Willem
also had other changes in ide-scsi.c which are still pending.
See attached file.
Doug Gilbert
Mikael Pettersson wrote on lkml:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
In 2.5 (the bug's been there since 2.5.42), rmmod:ing a
modular IDE subdriver like ide-cd or ide-scsi and then
rebooting causes an oops in device_shutdown(). This is because
the IDE layer doesn't reset the drive->gendev.driver pointer
that it previously set up to point to data structures in the
subdriver module. device_shutdown() sees a non-NULL ->driver,
dereferences it, and oopses.
The patch below for 2.5.54 fixes two generic bugs related to
unloading of modular IDE subdrivers, and one specific to ide-scsi:
1. ata_attach() needs to set drive->gendev.driver = NULL
when no specific driver claims the drive. This prevents a
drive previously owned by a subdriver module from keeping
its ->gendev.driver pointing into that module.
2. ide_unregister_driver() needs to unregister &driver->gen_driver;
this is to balance the corresponding register call in
ide_register_driver(). [This part of the patch is originally
by Patrick Mochel.]
3. ide-scsi.c abuses ide_driver_t's busy field as a counter
while the field in fact is a single-bit boolean. This causes
the busyness of the driver to be incorrect while the driver
is active. (From my recent patch for 2.4.20-ac2/2.4.21-pre2.)
With these three fixes modular ide-cd and ide-scsi work quite
reliably for me in 2.5.54.
/Mikael
diff -ruN linux-2.5.54/drivers/ide/ide.c
linux-2.5.54.ide-fixes/drivers/ide/ide.c
--- linux-2.5.54/drivers/ide/ide.c 2003-01-02 14:27:55.000000000 +0100
+++ linux-2.5.54.ide-fixes/drivers/ide/ide.c 2003-01-04
02:34:02.000000000 +0100
@@ -1346,6 +1346,7 @@
spin_unlock(&drivers_lock);
spin_lock(&drives_lock);
list_add_tail(&drive->list, &ata_unused);
+ drive->gendev.driver = NULL;
spin_unlock(&drives_lock);
return 1;
}
@@ -2308,6 +2309,8 @@
list_del(&driver->drivers);
spin_unlock(&drivers_lock);
+ driver_unregister(&driver->gen_driver);
+
while(!list_empty(&driver->drives)) {
drive = list_entry(driver->drives.next, ide_drive_t, list);
if (driver->cleanup(drive)) {
diff -ruN linux-2.5.54/drivers/scsi/ide-scsi.c
linux-2.5.54.ide-fixes/drivers/scsi/ide-scsi.c
--- linux-2.5.54/drivers/scsi/ide-scsi.c 2002-12-24 13:53:50.000000000 +0100
+++ linux-2.5.54.ide-fixes/drivers/scsi/ide-scsi.c 2003-01-04
02:34:02.000000000 +0100
@@ -590,6 +590,7 @@
set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif /* IDESCSI_DEBUG_LOG */
idescsi_add_settings(drive);
+ DRIVER(drive)->busy--;
}
static int idescsi_cleanup (ide_drive_t *drive)
@@ -995,7 +996,7 @@
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
drive = idescsi_drives[id];
if (drive)
- DRIVER(drive)->busy--;
+ DRIVER(drive)->busy = 0;
}
scsi_unregister (idescsi_host);
device_unregister(&idescsi_primary);
-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[-- Attachment #2: ide-scsi_2553wr2.diff --]
[-- Type: text/plain, Size: 997 bytes --]
--- linux/drivers/scsi/ide-scsi.c 2002-12-24 18:12:54.000000000 +1100
+++ linux/drivers/scsi/ide-scsi.c2553wr2 2002-12-24 09:30:17.000000000 +1100
@@ -289,6 +289,7 @@
pc->timeout = jiffies + WAIT_READY;
/* NOTE! Save the failed packet command in "rq->buffer" */
rq->buffer = (void *) failed_command->special;
+ pc->scsi_cmd = ((idescsi_pc_t *) failed_command->special)->scsi_cmd;
if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
printk ("ide-scsi: %s: queue cmd = ", drive->name);
hexdump(pc->c, 6);
@@ -876,7 +877,8 @@
/* is cmd active?
* need to lock so this stuff doesn't change under us */
spin_lock_irqsave(&ide_lock, flags);
- if (scsi->pc && scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
+ if (scsi->pc && scsi->pc->scsi_cmd &&
+ scsi->pc->scsi_cmd->serial_number == cmd->serial_number) {
/* yep - let's give it some more time -
* we can do that, we're in _our_ error kernel thread */
spin_unlock_irqrestore(&ide_lock, flags);
reply other threads:[~2003-01-04 11:18 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3E16C314.1060307@torque.net \
--to=dougg@torque.net \
--cc=linux-scsi@vger.kernel.org \
--cc=mikpe@csd.uu.se \
--cc=wrlk@riede.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox