Commit ae625582 authored by Jens Axboe's avatar Jens Axboe

[PATCH] Consolidate SCSI requeueing and add blk elevator hook

This patch removes the scsi mid layer dependency on __elv_add_request
and introduces a new blk_requeue_request() function so the block
layer specificially knows a requeue is in progress.

It also adds an elevator hook for elevators like AS which need to
hook into the requeue for correct adjustment of internal counters.
parent a75b0e15
......@@ -214,6 +214,18 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
e->elevator_merge_req_fn(q, rq, next);
}
void elv_requeue_request(request_queue_t *q, struct request *rq)
{
/*
* if iosched has an explicit requeue hook, then use that. otherwise
* just put the request at the front of the queue
*/
if (q->elevator.elevator_requeue_req_fn)
q->elevator.elevator_requeue_req_fn(q, rq);
else
__elv_add_request(q, rq, 0, 0);
}
void __elv_add_request(request_queue_t *q, struct request *rq, int at_end,
int plug)
{
......@@ -405,6 +417,7 @@ EXPORT_SYMBOL(elevator_noop);
EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_requeue_request);
EXPORT_SYMBOL(elv_next_request);
EXPORT_SYMBOL(elv_remove_request);
EXPORT_SYMBOL(elv_queue_empty);
......
......@@ -1355,6 +1355,23 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
return rq;
}
/**
* blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted
* @rq: request to be inserted
*
* Description:
* Drivers often keep queueing requests until the hardware cannot accept
* more, when that condition happens we need to put the request back
* on the queue. Must be called with queue lock held.
*/
void blk_requeue_request(request_queue_t *q, struct request *rq)
{
if (blk_rq_tagged(rq))
blk_queue_end_tag(q, rq);
elv_requeue_request(q, rq);
}
/**
* blk_insert_request - insert a special request in to a request queue
......@@ -2339,6 +2356,7 @@ EXPORT_SYMBOL(blk_hw_contig_segment);
EXPORT_SYMBOL(blk_get_request);
EXPORT_SYMBOL(blk_put_request);
EXPORT_SYMBOL(blk_insert_request);
EXPORT_SYMBOL(blk_requeue_request);
EXPORT_SYMBOL(blk_queue_prep_rq);
EXPORT_SYMBOL(blk_queue_merge_bvec);
......
......@@ -444,22 +444,8 @@ static void scsi_run_queue(struct request_queue *q)
*/
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
{
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
cmd->request->special = cmd;
if (blk_rq_tagged(cmd->request))
blk_queue_end_tag(q, cmd->request);
/*
* set REQ_SPECIAL - we have a command
* clear REQ_DONTPREP - we assume the sg table has been
* nuked so we need to set it up again.
*/
cmd->request->flags |= REQ_SPECIAL;
cmd->request->flags &= ~REQ_DONTPREP;
__elv_add_request(q, cmd->request, 0, 0);
spin_unlock_irqrestore(q->queue_lock, flags);
blk_insert_request(q, cmd->request, 1, cmd);
scsi_run_queue(q);
}
......@@ -1213,9 +1199,7 @@ static void scsi_request_fn(struct request_queue *q)
* later time.
*/
spin_lock_irq(q->queue_lock);
if (blk_rq_tagged(req))
blk_queue_end_tag(q, req);
__elv_add_request(q, req, 0, 0);
blk_requeue_request(q, req);
sdev->device_busy--;
if(sdev->device_busy == 0)
blk_plug_device(q);
......
......@@ -405,6 +405,7 @@ extern void __blk_attempt_remerge(request_queue_t *, struct request *);
extern struct request *blk_get_request(request_queue_t *, int, int);
extern void blk_put_request(struct request *);
extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
extern void blk_requeue_request(request_queue_t *, struct request *);
extern void blk_plug_device(request_queue_t *);
extern int blk_remove_plug(request_queue_t *);
extern void blk_recount_segments(request_queue_t *, struct bio *);
......
......@@ -13,6 +13,7 @@ typedef struct request *(elevator_next_req_fn) (request_queue_t *);
typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, int);
......@@ -30,6 +31,7 @@ struct elevator_s
elevator_next_req_fn *elevator_next_req_fn;
elevator_add_req_fn *elevator_add_req_fn;
elevator_remove_req_fn *elevator_remove_req_fn;
elevator_requeue_req_fn *elevator_requeue_req_fn;
elevator_queue_empty_fn *elevator_queue_empty_fn;
......@@ -58,6 +60,7 @@ extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
extern void elv_remove_request(request_queue_t *, struct request *);
extern void elv_requeue_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
extern struct request *elv_next_request(struct request_queue *q);
extern struct request *elv_former_request(request_queue_t *, struct request *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment