drivers/block/as-iosched.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) diff -puN drivers/block/as-iosched.c~as-nr_dispatched-atomic-fix drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-nr_dispatched-atomic-fix 2003-03-07 12:24:24.000000000 -0800 +++ 25-akpm/drivers/block/as-iosched.c 2003-03-07 12:34:15.000000000 -0800 @@ -88,6 +88,9 @@ static unsigned long antic_expire = HZ / /* * This is the per-process anticipatory I/O scheduler state. It is refcounted * and kmalloc'ed. + * + * There is no locking protecting the contents of this structure! Pointers + * to a single as_io_context may appear in multiple queues at once. */ struct as_io_context { @@ -95,7 +98,7 @@ struct as_io_context { pid_t pid; unsigned long state; atomic_t nr_queued; /* queued reads & sync writes */ - unsigned long nr_dispatched; /* number of requests gone to the driver */ + atomic_t nr_dispatched; /* number of requests gone to the drivers */ }; /* Bits in as_io_context.state */ @@ -239,7 +242,7 @@ static struct as_io_context *get_as_io_c ret->pid = tsk->pid; ret->state = 1 << AS_TASK_RUNNING; atomic_set(&ret->nr_queued, 0); - ret->nr_dispatched = 0; + atomic_set(&ret->nr_dispatched, 0); tsk->as_io_context = ret; } } @@ -582,8 +585,8 @@ static void as_remove_dispatched_request BUG_ON(arq->state != AS_RQ_DISPATCHED); BUG_ON(ON_RB(&arq->rb_node)); if (arq->as_io_context) { - BUG_ON(arq->as_io_context->nr_dispatched == 0); - arq->as_io_context->nr_dispatched--; + BUG_ON(!atomic_read(&arq->as_io_context->nr_dispatched)); + atomic_dec(&arq->as_io_context->nr_dispatched); } as_complete_arq(ad, arq); } @@ -751,7 +754,7 @@ static void as_move_to_dispatch(struct a as_remove_queued_request(ad->q, arq->request); list_add_tail(&arq->request->queuelist, ad->dispatch); if (arq->as_io_context) - arq->as_io_context->nr_dispatched++; + atomic_inc(&arq->as_io_context->nr_dispatched); BUG_ON(arq->state != AS_RQ_QUEUED); arq->state = AS_RQ_DISPATCHED; _