summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-mq.c31
-rw-r--r--block/blk-mq.h3
-rw-r--r--block/genhd.c37
-rw-r--r--include/linux/genhd.h35
4 files changed, 77 insertions, 29 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index a5d369dc7622..0dfc7a9984b6 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -83,6 +83,37 @@ static void blk_mq_hctx_clear_pending(struct blk_mq_hw_ctx *hctx,
83 sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw); 83 sbitmap_clear_bit(&hctx->ctx_map, ctx->index_hw);
84} 84}
85 85
86struct mq_inflight {
87 struct hd_struct *part;
88 unsigned int *inflight;
89};
90
91static void blk_mq_check_inflight(struct blk_mq_hw_ctx *hctx,
92 struct request *rq, void *priv,
93 bool reserved)
94{
95 struct mq_inflight *mi = priv;
96
97 if (test_bit(REQ_ATOM_STARTED, &rq->atomic_flags) &&
98 !test_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags)) {
99 /*
100 * Count as inflight if it either matches the partition we
101 * asked for, or if it's the root
102 */
103 if (rq->part == mi->part || mi->part->partno)
104 mi->inflight[0]++;
105 }
106}
107
108void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
109 unsigned int inflight[2])
110{
111 struct mq_inflight mi = { .part = part, .inflight = inflight, };
112
113 inflight[0] = 0;
114 blk_mq_queue_tag_busy_iter(q, blk_mq_check_inflight, &mi);
115}
116
86void blk_freeze_queue_start(struct request_queue *q) 117void blk_freeze_queue_start(struct request_queue *q)
87{ 118{
88 int freeze_depth; 119 int freeze_depth;
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 60b01c0309bc..98252b79b80b 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -133,4 +133,7 @@ static inline bool blk_mq_hw_queue_mapped(struct blk_mq_hw_ctx *hctx)
133 return hctx->nr_ctx && hctx->tags; 133 return hctx->nr_ctx && hctx->tags;
134} 134}
135 135
136void blk_mq_in_flight(struct request_queue *q, struct hd_struct *part,
137 unsigned int inflight[2]);
138
136#endif 139#endif
diff --git a/block/genhd.c b/block/genhd.c
index 822f65f95e2a..3dc4d115480f 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -45,6 +45,43 @@ static void disk_add_events(struct gendisk *disk);
45static void disk_del_events(struct gendisk *disk); 45static void disk_del_events(struct gendisk *disk);
46static void disk_release_events(struct gendisk *disk); 46static void disk_release_events(struct gendisk *disk);
47 47
48void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
49{
50 if (q->mq_ops)
51 return;
52
53 atomic_inc(&part->in_flight[rw]);
54 if (part->partno)
55 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]);
56}
57
58void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
59{
60 if (q->mq_ops)
61 return;
62
63 atomic_dec(&part->in_flight[rw]);
64 if (part->partno)
65 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
66}
67
68void part_in_flight(struct request_queue *q, struct hd_struct *part,
69 unsigned int inflight[2])
70{
71 if (q->mq_ops) {
72 blk_mq_in_flight(q, part, inflight);
73 return;
74 }
75
76 inflight[0] = atomic_read(&part->in_flight[0]) +
77 atomic_read(&part->in_flight[1]);
78 if (part->partno) {
79 part = &part_to_disk(part)->part0;
80 inflight[1] = atomic_read(&part->in_flight[0]) +
81 atomic_read(&part->in_flight[1]);
82 }
83}
84
48/** 85/**
49 * disk_get_part - get partition 86 * disk_get_part - get partition
50 * @disk: disk to look partition from 87 * @disk: disk to look partition from
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index f2a3a26cdda1..ea652bfcd675 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -362,35 +362,12 @@ static inline void free_part_stats(struct hd_struct *part)
362#define part_stat_sub(cpu, gendiskp, field, subnd) \ 362#define part_stat_sub(cpu, gendiskp, field, subnd) \
363 part_stat_add(cpu, gendiskp, field, -subnd) 363 part_stat_add(cpu, gendiskp, field, -subnd)
364 364
365static inline void part_inc_in_flight(struct request_queue *q, 365void part_in_flight(struct request_queue *q, struct hd_struct *part,
366 struct hd_struct *part, int rw) 366 unsigned int inflight[2]);
367{ 367void part_dec_in_flight(struct request_queue *q, struct hd_struct *part,
368 atomic_inc(&part->in_flight[rw]); 368 int rw);
369 if (part->partno) 369void part_inc_in_flight(struct request_queue *q, struct hd_struct *part,
370 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]); 370 int rw);
371}
372
373static inline void part_dec_in_flight(struct request_queue *q,
374 struct hd_struct *part, int rw)
375{
376 atomic_dec(&part->in_flight[rw]);
377 if (part->partno)
378 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]);
379}
380
381static inline void part_in_flight(struct request_queue *q,
382 struct hd_struct *part,
383 unsigned int inflight[2])
384{
385 inflight[0] = atomic_read(&part->in_flight[0]) +
386 atomic_read(&part->in_flight[1]);
387 if (part->partno) {
388 part = &part_to_disk(part)->part0;
389 inflight[1] = atomic_read(&part->in_flight[0]) +
390 atomic_read(&part->in_flight[1]);
391 } else
392 inflight[1] = 0;
393}
394 371
395static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk) 372static inline struct partition_meta_info *alloc_part_info(struct gendisk *disk)
396{ 373{