2003-03-12 01:10:07

by Luben Tuikov

[permalink] [raw]
Subject: [PATCH] fix kernel oops in generic_unplug_device() for md

The following patch fixes a kernel oops when doing
blk_unplug_work() (oopses in generic_unplug_device()) for md.

The oops and the original report are here:
http://MARC.10East.com/?l=linux-kernel&m=104706400705154&w=2

The problem is that the md driver provides its own unplug
function (among other things) and blk_unplug_work() assumes
that the generic one would work, but it doesn't and BOOM,
it oopses and dies.

--
Luben

--- linux-2.5.64bk6/drivers/block/ll_rw_blk.c.orig 2003-03-11 16:23:55.000000000 -0500
+++ linux-2.5.64bk6/drivers/block/ll_rw_blk.c 2003-03-11 18:38:40.000000000 -0500
@@ -29,6 +29,7 @@

static void blk_unplug_work(void *data);
static void blk_unplug_timeout(unsigned long data);
+static int __make_request(request_queue_t *, struct bio *);

/*
* For the allocated request tables
@@ -1040,7 +1041,13 @@

static void blk_unplug_work(void *data)
{
- generic_unplug_device(data);
+ request_queue_t *q = data;
+
+ if (q->make_request_fn && q->make_request_fn != __make_request
+ && q->unplug_fn)
+ q->unplug_fn(data);
+ else
+ generic_unplug_device(data);
}

static void blk_unplug_timeout(unsigned long data)
@@ -1246,8 +1253,6 @@
return 1;
}

-static int __make_request(request_queue_t *, struct bio *);
-
/**
* blk_init_queue - prepare a request queue for use with a block device
* @q: The &request_queue_t to be initialised


2003-03-12 01:22:36

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] fix kernel oops in generic_unplug_device() for md

Luben Tuikov <[email protected]> wrote:
>
> The following patch fixes a kernel oops when doing
> blk_unplug_work() (oopses in generic_unplug_device()) for md.
>
> The oops and the original report are here:
> http://MARC.10East.com/?l=linux-kernel&m=104706400705154&w=2
>

Yup, is a bug. I received the below fix from Neil today which looks
simpler.

diff -puN drivers/block/ll_rw_blk.c~auto-unplugging-fix drivers/block/ll_rw_blk.c
--- 25/drivers/block/ll_rw_blk.c~auto-unplugging-fix Tue Mar 11 15:04:00 2003
+++ 25-akpm/drivers/block/ll_rw_blk.c Tue Mar 11 15:04:00 2003
@@ -1004,7 +1004,8 @@ void generic_unplug_device(void *data)

static void blk_unplug_work(void *data)
{
- generic_unplug_device(data);
+ request_queue_t *q = data;
+ q->unplug_fn(q);
}

static void blk_unplug_timeout(unsigned long data)

_

2003-03-12 07:01:11

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] fix kernel oops in generic_unplug_device() for md

On Tue, Mar 11 2003, Andrew Morton wrote:
> Luben Tuikov <[email protected]> wrote:
> >
> > The following patch fixes a kernel oops when doing
> > blk_unplug_work() (oopses in generic_unplug_device()) for md.
> >
> > The oops and the original report are here:
> > http://MARC.10East.com/?l=linux-kernel&m=104706400705154&w=2
> >
>
> Yup, is a bug. I received the below fix from Neil today which looks
> simpler.
>
> diff -puN drivers/block/ll_rw_blk.c~auto-unplugging-fix drivers/block/ll_rw_blk.c
> --- 25/drivers/block/ll_rw_blk.c~auto-unplugging-fix Tue Mar 11 15:04:00 2003
> +++ 25-akpm/drivers/block/ll_rw_blk.c Tue Mar 11 15:04:00 2003
> @@ -1004,7 +1004,8 @@ void generic_unplug_device(void *data)
>
> static void blk_unplug_work(void *data)
> {
> - generic_unplug_device(data);
> + request_queue_t *q = data;
> + q->unplug_fn(q);
> }

this is the correct fix

--
Jens Axboe