summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2018-12-06 11:41:20 -0500
committerJens Axboe <axboe@kernel.dk>2018-12-10 10:30:37 -0500
commit1226b8dd0e91331cfab500f305b2c264445a0392 (patch)
tree347679d6d2eafea136d7d93529e16cd6fbe87609 /block
parent5b18b5a737600fd20ba2045f320d5926ebbf341a (diff)
block: switch to per-cpu in-flight counters
Now when part_round_stats is gone, we can switch to per-cpu in-flight counters. We use the local-atomic type local_t, so that if part_inc_in_flight or part_dec_in_flight is reentrantly called from an interrupt, the value will be correct. The other counters could be corrupted due to reentrant interrupt, but the corruption only results in slight counter skew - the in_flight counter must be exact, so it needs local_t. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/genhd.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/block/genhd.c b/block/genhd.c
index cdf174d7d329..9827a2c05db7 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -50,9 +50,9 @@ void part_inc_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
50 if (queue_is_mq(q)) 50 if (queue_is_mq(q))
51 return; 51 return;
52 52
53 atomic_inc(&part->in_flight[rw]); 53 part_stat_local_inc(part, in_flight[rw]);
54 if (part->partno) 54 if (part->partno)
55 atomic_inc(&part_to_disk(part)->part0.in_flight[rw]); 55 part_stat_local_inc(&part_to_disk(part)->part0, in_flight[rw]);
56} 56}
57 57
58void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw) 58void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
@@ -60,38 +60,61 @@ void part_dec_in_flight(struct request_queue *q, struct hd_struct *part, int rw)
60 if (queue_is_mq(q)) 60 if (queue_is_mq(q))
61 return; 61 return;
62 62
63 atomic_dec(&part->in_flight[rw]); 63 part_stat_local_dec(part, in_flight[rw]);
64 if (part->partno) 64 if (part->partno)
65 atomic_dec(&part_to_disk(part)->part0.in_flight[rw]); 65 part_stat_local_dec(&part_to_disk(part)->part0, in_flight[rw]);
66} 66}
67 67
68void part_in_flight(struct request_queue *q, struct hd_struct *part, 68void part_in_flight(struct request_queue *q, struct hd_struct *part,
69 unsigned int inflight[2]) 69 unsigned int inflight[2])
70{ 70{
71 int cpu;
72
71 if (queue_is_mq(q)) { 73 if (queue_is_mq(q)) {
72 blk_mq_in_flight(q, part, inflight); 74 blk_mq_in_flight(q, part, inflight);
73 return; 75 return;
74 } 76 }
75 77
76 inflight[0] = atomic_read(&part->in_flight[0]) + 78 inflight[0] = 0;
77 atomic_read(&part->in_flight[1]); 79 for_each_possible_cpu(cpu) {
80 inflight[0] += part_stat_local_read_cpu(part, in_flight[0], cpu) +
81 part_stat_local_read_cpu(part, in_flight[1], cpu);
82 }
83 if ((int)inflight[0] < 0)
84 inflight[0] = 0;
85
78 if (part->partno) { 86 if (part->partno) {
79 part = &part_to_disk(part)->part0; 87 part = &part_to_disk(part)->part0;
80 inflight[1] = atomic_read(&part->in_flight[0]) + 88 inflight[1] = 0;
81 atomic_read(&part->in_flight[1]); 89 for_each_possible_cpu(cpu) {
90 inflight[1] += part_stat_local_read_cpu(part, in_flight[0], cpu) +
91 part_stat_local_read_cpu(part, in_flight[1], cpu);
92 }
93 if ((int)inflight[1] < 0)
94 inflight[1] = 0;
82 } 95 }
83} 96}
84 97
85void part_in_flight_rw(struct request_queue *q, struct hd_struct *part, 98void part_in_flight_rw(struct request_queue *q, struct hd_struct *part,
86 unsigned int inflight[2]) 99 unsigned int inflight[2])
87{ 100{
101 int cpu;
102
88 if (queue_is_mq(q)) { 103 if (queue_is_mq(q)) {
89 blk_mq_in_flight_rw(q, part, inflight); 104 blk_mq_in_flight_rw(q, part, inflight);
90 return; 105 return;
91 } 106 }
92 107
93 inflight[0] = atomic_read(&part->in_flight[0]); 108 inflight[0] = 0;
94 inflight[1] = atomic_read(&part->in_flight[1]); 109 inflight[1] = 0;
110 for_each_possible_cpu(cpu) {
111 inflight[0] += part_stat_local_read_cpu(part, in_flight[0], cpu);
112 inflight[1] += part_stat_local_read_cpu(part, in_flight[1], cpu);
113 }
114 if ((int)inflight[0] < 0)
115 inflight[0] = 0;
116 if ((int)inflight[1] < 0)
117 inflight[1] = 0;
95} 118}
96 119
97struct hd_struct *__disk_get_part(struct gendisk *disk, int partno) 120struct hd_struct *__disk_get_part(struct gendisk *disk, int partno)