block: add a rq_list type

Replace the semi-open coded request list helpers with a proper rq_list
type that mirrors the bio_list and has head and tail pointers.  Besides
better type safety this actually allows to insert at the tail of the
list, which will be useful soon.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20241113152050.157179-5-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig
2024-11-13 16:20:44 +01:00
committed by Jens Axboe
parent e8225ab150
commit a3396b9999
11 changed files with 102 additions and 86 deletions

View File

@@ -229,44 +229,60 @@ static inline unsigned short req_get_ioprio(struct request *req)
#define rq_dma_dir(rq) \
(op_is_write(req_op(rq)) ? DMA_TO_DEVICE : DMA_FROM_DEVICE)
#define rq_list_add(listptr, rq) do { \
(rq)->rq_next = *(listptr); \
*(listptr) = rq; \
} while (0)
static inline int rq_list_empty(const struct rq_list *rl)
{
return rl->head == NULL;
}
#define rq_list_add_tail(lastpptr, rq) do { \
(rq)->rq_next = NULL; \
**(lastpptr) = rq; \
*(lastpptr) = &rq->rq_next; \
} while (0)
static inline void rq_list_init(struct rq_list *rl)
{
rl->head = NULL;
rl->tail = NULL;
}
#define rq_list_pop(listptr) \
({ \
struct request *__req = NULL; \
if ((listptr) && *(listptr)) { \
__req = *(listptr); \
*(listptr) = __req->rq_next; \
} \
__req; \
})
static inline void rq_list_add_tail(struct rq_list *rl, struct request *rq)
{
rq->rq_next = NULL;
if (rl->tail)
rl->tail->rq_next = rq;
else
rl->head = rq;
rl->tail = rq;
}
#define rq_list_peek(listptr) \
({ \
struct request *__req = NULL; \
if ((listptr) && *(listptr)) \
__req = *(listptr); \
__req; \
})
static inline void rq_list_add_head(struct rq_list *rl, struct request *rq)
{
rq->rq_next = rl->head;
rl->head = rq;
if (!rl->tail)
rl->tail = rq;
}
#define rq_list_for_each(listptr, pos) \
for (pos = rq_list_peek((listptr)); pos; pos = rq_list_next(pos))
static inline struct request *rq_list_pop(struct rq_list *rl)
{
struct request *rq = rl->head;
#define rq_list_for_each_safe(listptr, pos, nxt) \
for (pos = rq_list_peek((listptr)), nxt = rq_list_next(pos); \
pos; pos = nxt, nxt = pos ? rq_list_next(pos) : NULL)
if (rq) {
rl->head = rl->head->rq_next;
if (!rl->head)
rl->tail = NULL;
rq->rq_next = NULL;
}
#define rq_list_next(rq) (rq)->rq_next
#define rq_list_empty(list) ((list) == (struct request *) NULL)
return rq;
}
static inline struct request *rq_list_peek(struct rq_list *rl)
{
return rl->head;
}
#define rq_list_for_each(rl, pos) \
for (pos = rq_list_peek((rl)); (pos); pos = pos->rq_next)
#define rq_list_for_each_safe(rl, pos, nxt) \
for (pos = rq_list_peek((rl)), nxt = pos->rq_next; \
pos; pos = nxt, nxt = pos ? pos->rq_next : NULL)
/**
* enum blk_eh_timer_return - How the timeout handler should proceed
@@ -559,7 +575,7 @@ struct blk_mq_ops {
* empty the @rqlist completely, then the rest will be queued
* individually by the block layer upon return.
*/
void (*queue_rqs)(struct request **rqlist);
void (*queue_rqs)(struct rq_list *rqlist);
/**
* @get_budget: Reserve budget before queue request, once .queue_rq is
@@ -868,7 +884,7 @@ static inline bool blk_mq_add_to_batch(struct request *req,
else if (iob->complete != complete)
return false;
iob->need_ts |= blk_mq_need_time_stamp(req);
rq_list_add(&iob->req_list, req);
rq_list_add_head(&iob->req_list, req);
return true;
}