summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2002-10-27 17:14:14 -0800
committerJens Axboe <axboe@suse.de>2002-10-27 17:14:14 -0800
commit86b9d08bca816f68dea450e9baf42d474e09112c (patch)
tree946e2c0ba180c4593ebaf1052facdfafe82e2ee0
parent6d94d882f8924da545059f82952707dc6ca9157b (diff)
[PATCH] elv_add_request cleanups
Request insertion in the current tree is a mess. We have all sorts of variants of *elv_add_request*, and it's not at all clear who does what and with what locks (or not). This patch cleans it up to be: o __elv_add_request(queue, request, at_end, plug) Core function, requires queue lock to be held o elv_add_request(queue, request, at_end, plug) Like __elv_add_request(), but grabs queue lock o __elv_add_request_pos(queue, request, position) Insert request at a given location, lock must be held
-rw-r--r--drivers/block/elevator.c27
-rw-r--r--drivers/block/ll_rw_blk.c4
-rw-r--r--drivers/scsi/scsi_lib.c4
-rw-r--r--include/linux/blk.h16
-rw-r--r--include/linux/elevator.h7
5 files changed, 30 insertions, 28 deletions
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 0b1517f93501..ff3825209510 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -272,13 +272,27 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
e->elevator_merge_req_fn(q, rq, next);
}
-/*
- * add_request and next_request are required to be supported, naturally
- */
-void __elv_add_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+void __elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+ int plug)
+{
+ struct list_head *insert = &q->queue_head;
+
+ if (at_end)
+ insert = insert->prev;
+ if (plug)
+ blk_plug_device(q);
+
+ q->elevator.elevator_add_req_fn(q, rq, insert);
+}
+
+void elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+ int plug)
{
- q->elevator.elevator_add_req_fn(q, rq, insert_here);
+ unsigned long flags;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ __elv_add_request(q, rq, at_end, plug);
+ spin_unlock_irqrestore(q->queue_lock, flags);
}
static inline struct request *__elv_next_request(request_queue_t *q)
@@ -357,6 +371,7 @@ module_init(elevator_global_init);
EXPORT_SYMBOL(elevator_noop);
+EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_next_request);
EXPORT_SYMBOL(elv_remove_request);
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index c5697e05a6b8..efc4b61ec7ce 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -639,7 +639,7 @@ void blk_queue_invalidate_tags(request_queue_t *q)
blk_queue_end_tag(q, rq);
rq->flags &= ~REQ_STARTED;
- elv_add_request(q, rq, 0);
+ __elv_add_request(q, rq, 0, 0);
}
}
@@ -1466,7 +1466,7 @@ static inline void add_request(request_queue_t * q, struct request * req,
* elevator indicated where it wants this request to be
* inserted at elevator_merge time
*/
- __elv_add_request(q, req, insert_here);
+ __elv_add_request_pos(q, req, insert_here);
}
/*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index dfa18e0c0eb9..0b6a9c2f7034 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -240,7 +240,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
SCpnt->request->special = (void *) SCpnt;
if(blk_rq_tagged(SCpnt->request))
blk_queue_end_tag(q, SCpnt->request);
- _elv_add_request(q, SCpnt->request, 0, 0);
+ __elv_add_request(q, SCpnt->request, 0, 0);
}
/*
@@ -951,7 +951,7 @@ void scsi_request_fn(request_queue_t * q)
SCpnt->request->flags |= REQ_SPECIAL;
if(blk_rq_tagged(SCpnt->request))
blk_queue_end_tag(q, SCpnt->request);
- _elv_add_request(q, SCpnt->request, 0, 0);
+ __elv_add_request(q, SCpnt->request, 0, 0);
break;
}
diff --git a/include/linux/blk.h b/include/linux/blk.h
index 7fbd3f6acae8..775d021167c1 100644
--- a/include/linux/blk.h
+++ b/include/linux/blk.h
@@ -50,22 +50,6 @@ static inline void blkdev_dequeue_request(struct request *req)
elv_remove_request(req->q, req);
}
-#define _elv_add_request_core(q, rq, where, plug) \
- do { \
- if ((plug)) \
- blk_plug_device((q)); \
- (q)->elevator.elevator_add_req_fn((q), (rq), (where)); \
- } while (0)
-
-#define _elv_add_request(q, rq, back, p) do { \
- if ((back)) \
- _elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \
- else \
- _elv_add_request_core((q), (rq), &(q)->queue_head, (p)); \
-} while (0)
-
-#define elv_add_request(q, rq, back) _elv_add_request((q), (rq), (back), 1)
-
#if defined(MAJOR_NR) || defined(IDE_DRIVER)
#if (MAJOR_NR != SCSI_TAPE_MAJOR) && (MAJOR_NR != OSST_MAJOR)
#if !defined(IDE_DRIVER)
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 8a54a1c5e5af..62092e8ed2ad 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -40,8 +40,8 @@ struct elevator_s
/*
* block elevator interface
*/
-extern void __elv_add_request(request_queue_t *, struct request *,
- struct list_head *);
+extern void elv_add_request(request_queue_t *, struct request *, int, int);
+extern void __elv_add_request(request_queue_t *, struct request *, int, int);
extern int elv_merge(request_queue_t *, struct list_head **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
@@ -50,6 +50,9 @@ extern void elv_remove_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
extern inline struct list_head *elv_get_sort_head(request_queue_t *, struct request *);
+#define __elv_add_request_pos(q, rq, pos) \
+ (q)->elevator.elevator_add_req_fn((q), (rq), (pos))
+
/*
* noop I/O scheduler. always merges, always inserts new request at tail
*/