The floppy driver does much of its work in response to soft and hard
interrupts. Part of that work is the finishing up of completed requests,
including calling end_request(). The calls to end_request() happen without
the io_request_lock held, leading to a race condition in
end_that_request_last(). It's obviously a small one, or people would have
noticed, but a race is a race...
This is a straightforward fix against -test7.
jon
Jonathan Corbet
Executive editor, LWN.net
corbet@eklektix.com
--- linux-2.4.0-test7/drivers/block/floppy.c Thu Aug 24 10:25:36 2000
+++ linux-jc/drivers/block/floppy.c Mon Aug 28 16:33:11 2000
@@ -2282,6 +2282,7 @@
static void request_done(int uptodate)
{
int block;
+ unsigned long flags;
probing = 0;
reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
@@ -2300,6 +2301,7 @@
DRS->maxtrack = 1;
/* unlock chained buffers */
+ spin_lock_irqsave(&io_request_lock, flags);
while (current_count_sectors && !QUEUE_EMPTY &&
current_count_sectors >= CURRENT->current_nr_sectors){
current_count_sectors -= CURRENT->current_nr_sectors;
@@ -2307,6 +2309,8 @@
CURRENT->sector += CURRENT->current_nr_sectors;
end_request(1);
}
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
if (current_count_sectors && !QUEUE_EMPTY){
/* "unlock" last subsector */
CURRENT->buffer += current_count_sectors <<9;
@@ -2330,7 +2334,9 @@
DRWE->last_error_sector = CURRENT->sector;
DRWE->last_error_generation = DRS->generation;
}
+ spin_lock_irqsave(&io_request_lock, flags);
end_request(0);
+ spin_unlock_irqrestore(&io_request_lock, flags);
}
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Thu Aug 31 2000 - 21:00:22 EST