disable READA
PATCH 1/1 disable READA
There's a bug in bread() which can cause it to misinterpret a failed READA request as an IO error on SMP.
If a filesytem block is subject to READA and __make_request() decides that the request would block then __make_request() will (via end_buffer_io_sync) mark the buffer as not uptodate and will unlock it.
But if another CPU attempts to bread() the same buffer at the same time, the following happens:
1: ll_rw_block() sees the buffer is locked and does nothing at all
2: bread() does a wait_on_buffer()
3: the other CPU (the one doing READA) unlocks the non uptodate buffer
4: bread() sees the buffer come unlocked. It's not uptodate, so
bread() bogusly reports an IO error.
I haven't seen it in the wild, because it is rare to get that much read I/O in flight. reiserfs and ext3 (at least) use READA.
An appropriate fix for 2.4 is to disable READA.
ll_rw_blk.c | 2 ++ 1 files changed, 2 insertions
drivers/block/ll_rw_blk.c renamed from drivers/block/ll_rw_blk.c~no-readahead +2 -0
@@ -841,7 +841,9 @@ static int __make_request(request_queue_ rw_ahead =0 ;/* normal case; gets changed below for READA */ switch (rw) {case READA : +#if 0 /* bread() misinterprets failed READA attempts as IO errors on SMP */ rw_ahead =1 ; +#endif rw =READ ;/* drop into READ */ case READ :case WRITE :
.
Who is using READA this days ?
Quoted 50 lines · Andrew Morton
There's a bug in
bread()which can cause it to misinterpret a failed READA request as an IO error on SMP.If a filesytem block is subject to READA and
__make_request()decides that the request would block then__make_request()will (viaend_buffer_io_sync) mark the buffer as not uptodate and will unlock it.But if another CPU attempts to
bread()the same buffer at the same time, the following happens:1:
ll_rw_block()sees the buffer is locked and does nothing at all2:
bread()does await_on_buffer()3: the other CPU (the one doing READA) unlocks the non uptodate buffer
4:
bread()sees the buffer come unlocked. It's not uptodate, so
bread()bogusly reports an IO error.I haven't seen it in the wild, because it is rare to get that much read I/O in flight. reiserfs and ext3 (at least) use READA.
An appropriate fix for 2.4 is to disable READA.
ll_rw_blk.c | 2 ++ 1 files changed, 2 insertionsdrivers/block/ll_rw_blk.c renamed from drivers/block/ll_rw_blk.c~no-readahead +2
-0@@ -841,7 +841,9 @@ static int __make_request(request_queue_ rw_ahead =0 ;/* normal case; gets changed below for READA */ switch (rw) {case READA : +#if 0 /* bread() misinterprets failed READA attempts as IO errors on SMP */ rw_ahead =1 ; +#endif rw =READ ;/* drop into READ */ case READ :case WRITE :.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Ah, haven't read the full message.
Forget about my question. :)
Quoted 48 lines · Marcelo Tosatti
Who is using READA this days ?
Quoted 42 lines · Andrew Morton
There's a bug in
bread()which can cause it to misinterpret a failed READA request as an IO error on SMP.If a filesytem block is subject to READA and
__make_request()decides that the request would block then__make_request()will (viaend_buffer_io_sync) mark the buffer as not uptodate and will unlock it.But if another CPU attempts to
bread()the same buffer at the same time, the following happens:1:
ll_rw_block()sees the buffer is locked and does nothing at all2:
bread()does await_on_buffer()3: the other CPU (the one doing READA) unlocks the non uptodate buffer
4:
bread()sees the buffer come unlocked. It's not uptodate, so
bread()bogusly reports an IO error.I haven't seen it in the wild, because it is rare to get that much read I/O in flight. reiserfs and ext3 (at least) use READA.
An appropriate fix for 2.4 is to disable READA.
ll_rw_blk.c | 2 ++ 1 files changed, 2 insertionsdrivers/block/ll_rw_blk.c renamed from drivers/block/ll_rw_blk.c~no-readahead +2
-0@@ -841,7 +841,9 @@ static int __make_request(request_queue_ rw_ahead =0 ;/* normal case; gets changed below for READA */ switch (rw) {case READA : +#if 0 /* bread() misinterprets failed READA attempts as IO errors on SMP */ rw_ahead =1 ; +#endif rw =READ ;/* drop into READ */ case READ :case WRITE :
drivers/block/ll_rw_blk.c static int __make_request(request_queue_ · line 846
Quoted 13 lines · Andrew Morton
There's a bug in
bread()which can cause it to misinterpret a failed READA request as an IO error on SMP.drivers/block/ll_rw_blk.c renamed from drivers/block/ll_rw_blk.c~no-readahead +2
-0@@ -841,7 +841,9 @@ static int __make_request(request_queue_ rw_ahead =0 ;/* normal case; gets changed below for READA */ switch (rw) {case READA : +#if 0 /* bread() misinterprets failed READA attempts as IO errors on SMP */ rw_ahead =1 ; +#endif
If the problem is only on SMP, then that should be #ifndef CONFIG_SMP...
Jeff