diff options
author | Tejun Heo <tj@kernel.org> | 2008-08-25 06:56:14 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:08 -0400 |
commit | 074a7aca7afa6f230104e8e65eba3420263714a5 (patch) | |
tree | f418313e45bd55be8156c8a3e8f9a216cf63058d /include | |
parent | eddb2e26b5ee3c5da68ba4bf1921ba20e2097bff (diff) |
block: move stats from disk to part0
Move stats related fields - stamp, in_flight, dkstats - from disk to
part0 and unify stat handling such that...
* part_stat_*() now updates part0 together if the specified partition
is not part0. ie. part_stat_*() are now essentially all_stat_*().
* {disk|all}_stat_*() are gone.
* part_round_stats() is updated similary. It handles part0 stats
automatically and disk_round_stats() is killed.
* part_{inc|dec}_in_fligh() is implemented which automatically updates
part0 stats for parts other than part0.
* disk_map_sector_rcu() is updated to return part0 if no part matches.
Combined with the above changes, this makes NULL special case
handling in callers unnecessary.
* Separate stats show code paths for disk are collapsed into part
stats show code paths.
* Rename disk_stat_lock/unlock() to part_stat_lock/unlock()
While at it, reposition stat handling macros a bit and add missing
parentheses around macro parameters.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/genhd.h | 159 |
1 files changed, 45 insertions, 114 deletions
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3d15b42dc352..c90e1b4fbe5a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -145,13 +145,6 @@ struct gendisk { | |||
145 | struct timer_rand_state *random; | 145 | struct timer_rand_state *random; |
146 | 146 | ||
147 | atomic_t sync_io; /* RAID */ | 147 | atomic_t sync_io; /* RAID */ |
148 | unsigned long stamp; | ||
149 | int in_flight; | ||
150 | #ifdef CONFIG_SMP | ||
151 | struct disk_stats *dkstats; | ||
152 | #else | ||
153 | struct disk_stats dkstats; | ||
154 | #endif | ||
155 | struct work_struct async_notify; | 148 | struct work_struct async_notify; |
156 | #ifdef CONFIG_BLK_DEV_INTEGRITY | 149 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
157 | struct blk_integrity *integrity; | 150 | struct blk_integrity *integrity; |
@@ -232,46 +225,18 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | |||
232 | * internal use only. | 225 | * internal use only. |
233 | */ | 226 | */ |
234 | #ifdef CONFIG_SMP | 227 | #ifdef CONFIG_SMP |
235 | #define disk_stat_lock() ({ rcu_read_lock(); get_cpu(); }) | 228 | #define part_stat_lock() ({ rcu_read_lock(); get_cpu(); }) |
236 | #define disk_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) | 229 | #define part_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) |
237 | |||
238 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
239 | (per_cpu_ptr(gendiskp->dkstats, cpu)->field += addnd) | ||
240 | |||
241 | #define disk_stat_read(gendiskp, field) \ | ||
242 | ({ \ | ||
243 | typeof(gendiskp->dkstats->field) res = 0; \ | ||
244 | int i; \ | ||
245 | for_each_possible_cpu(i) \ | ||
246 | res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ | ||
247 | res; \ | ||
248 | }) | ||
249 | |||
250 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | ||
251 | { | ||
252 | int i; | ||
253 | |||
254 | for_each_possible_cpu(i) | ||
255 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, | ||
256 | sizeof(struct disk_stats)); | ||
257 | } | ||
258 | 230 | ||
259 | #define part_stat_add(cpu, part, field, addnd) \ | 231 | #define __part_stat_add(cpu, part, field, addnd) \ |
260 | (per_cpu_ptr(part->dkstats, cpu)->field += addnd) | 232 | (per_cpu_ptr((part)->dkstats, (cpu))->field += (addnd)) |
261 | |||
262 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ | ||
263 | ({ \ | ||
264 | if (part) \ | ||
265 | part_stat_add(cpu, part, field, addnd); \ | ||
266 | disk_stat_add(cpu, gendiskp, field, addnd); \ | ||
267 | }) | ||
268 | 233 | ||
269 | #define part_stat_read(part, field) \ | 234 | #define part_stat_read(part, field) \ |
270 | ({ \ | 235 | ({ \ |
271 | typeof(part->dkstats->field) res = 0; \ | 236 | typeof((part)->dkstats->field) res = 0; \ |
272 | int i; \ | 237 | int i; \ |
273 | for_each_possible_cpu(i) \ | 238 | for_each_possible_cpu(i) \ |
274 | res += per_cpu_ptr(part->dkstats, i)->field; \ | 239 | res += per_cpu_ptr((part)->dkstats, i)->field; \ |
275 | res; \ | 240 | res; \ |
276 | }) | 241 | }) |
277 | 242 | ||
@@ -284,109 +249,73 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) | |||
284 | sizeof(struct disk_stats)); | 249 | sizeof(struct disk_stats)); |
285 | } | 250 | } |
286 | 251 | ||
287 | #else /* !CONFIG_SMP */ | 252 | static inline int init_part_stats(struct hd_struct *part) |
288 | #define disk_stat_lock() ({ rcu_read_lock(); 0; }) | ||
289 | #define disk_stat_unlock() rcu_read_unlock() | ||
290 | |||
291 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
292 | (gendiskp->dkstats.field += addnd) | ||
293 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) | ||
294 | |||
295 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | ||
296 | { | 253 | { |
297 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); | 254 | part->dkstats = alloc_percpu(struct disk_stats); |
255 | if (!part->dkstats) | ||
256 | return 0; | ||
257 | return 1; | ||
298 | } | 258 | } |
299 | 259 | ||
300 | #define part_stat_add(cpu, part, field, addnd) \ | 260 | static inline void free_part_stats(struct hd_struct *part) |
301 | (part->dkstats.field += addnd) | ||
302 | |||
303 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ | ||
304 | ({ \ | ||
305 | if (part) \ | ||
306 | part_stat_add(cpu, part, field, addnd); \ | ||
307 | disk_stat_add(cpu, gendiskp, field, addnd); \ | ||
308 | }) | ||
309 | |||
310 | #define part_stat_read(part, field) (part->dkstats.field) | ||
311 | |||
312 | static inline void part_stat_set_all(struct hd_struct *part, int value) | ||
313 | { | 261 | { |
314 | memset(&part->dkstats, value, sizeof(struct disk_stats)); | 262 | free_percpu(part->dkstats); |
315 | } | 263 | } |
316 | 264 | ||
317 | #endif /* CONFIG_SMP */ | 265 | #else /* !CONFIG_SMP */ |
318 | 266 | #define part_stat_lock() ({ rcu_read_lock(); 0; }) | |
319 | #define disk_stat_dec(cpu, gendiskp, field) \ | 267 | #define part_stat_unlock() rcu_read_unlock() |
320 | disk_stat_add(cpu, gendiskp, field, -1) | ||
321 | #define disk_stat_inc(cpu, gendiskp, field) \ | ||
322 | disk_stat_add(cpu, gendiskp, field, 1) | ||
323 | #define disk_stat_sub(cpu, gendiskp, field, subnd) \ | ||
324 | disk_stat_add(cpu, gendiskp, field, -subnd) | ||
325 | |||
326 | #define part_stat_dec(cpu, gendiskp, field) \ | ||
327 | part_stat_add(cpu, gendiskp, field, -1) | ||
328 | #define part_stat_inc(cpu, gendiskp, field) \ | ||
329 | part_stat_add(cpu, gendiskp, field, 1) | ||
330 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | ||
331 | part_stat_add(cpu, gendiskp, field, -subnd) | ||
332 | 268 | ||
333 | #define all_stat_dec(cpu, gendiskp, field, sector) \ | 269 | #define __part_stat_add(cpu, part, field, addnd) \ |
334 | all_stat_add(cpu, gendiskp, field, -1, sector) | 270 | ((part)->dkstats.field += addnd) |
335 | #define all_stat_inc(cpu, gendiskp, part, field, sector) \ | ||
336 | all_stat_add(cpu, gendiskp, part, field, 1, sector) | ||
337 | #define all_stat_sub(cpu, gendiskp, part, field, subnd, sector) \ | ||
338 | all_stat_add(cpu, gendiskp, part, field, -subnd, sector) | ||
339 | 271 | ||
340 | /* Inlines to alloc and free disk stats in struct gendisk */ | 272 | #define part_stat_read(part, field) ((part)->dkstats.field) |
341 | #ifdef CONFIG_SMP | ||
342 | static inline int init_disk_stats(struct gendisk *disk) | ||
343 | { | ||
344 | disk->dkstats = alloc_percpu(struct disk_stats); | ||
345 | if (!disk->dkstats) | ||
346 | return 0; | ||
347 | return 1; | ||
348 | } | ||
349 | 273 | ||
350 | static inline void free_disk_stats(struct gendisk *disk) | 274 | static inline void part_stat_set_all(struct hd_struct *part, int value) |
351 | { | 275 | { |
352 | free_percpu(disk->dkstats); | 276 | memset(&part->dkstats, value, sizeof(struct disk_stats)); |
353 | } | 277 | } |
354 | 278 | ||
355 | static inline int init_part_stats(struct hd_struct *part) | 279 | static inline int init_part_stats(struct hd_struct *part) |
356 | { | 280 | { |
357 | part->dkstats = alloc_percpu(struct disk_stats); | ||
358 | if (!part->dkstats) | ||
359 | return 0; | ||
360 | return 1; | 281 | return 1; |
361 | } | 282 | } |
362 | 283 | ||
363 | static inline void free_part_stats(struct hd_struct *part) | 284 | static inline void free_part_stats(struct hd_struct *part) |
364 | { | 285 | { |
365 | free_percpu(part->dkstats); | ||
366 | } | 286 | } |
367 | 287 | ||
368 | #else /* CONFIG_SMP */ | 288 | #endif /* CONFIG_SMP */ |
369 | static inline int init_disk_stats(struct gendisk *disk) | ||
370 | { | ||
371 | return 1; | ||
372 | } | ||
373 | 289 | ||
374 | static inline void free_disk_stats(struct gendisk *disk) | 290 | #define part_stat_add(cpu, part, field, addnd) do { \ |
375 | { | 291 | __part_stat_add((cpu), (part), field, addnd); \ |
376 | } | 292 | if ((part)->partno) \ |
293 | __part_stat_add((cpu), &part_to_disk((part))->part0, \ | ||
294 | field, addnd); \ | ||
295 | } while (0) | ||
377 | 296 | ||
378 | static inline int init_part_stats(struct hd_struct *part) | 297 | #define part_stat_dec(cpu, gendiskp, field) \ |
298 | part_stat_add(cpu, gendiskp, field, -1) | ||
299 | #define part_stat_inc(cpu, gendiskp, field) \ | ||
300 | part_stat_add(cpu, gendiskp, field, 1) | ||
301 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ | ||
302 | part_stat_add(cpu, gendiskp, field, -subnd) | ||
303 | |||
304 | static inline void part_inc_in_flight(struct hd_struct *part) | ||
379 | { | 305 | { |
380 | return 1; | 306 | part->in_flight++; |
307 | if (part->partno) | ||
308 | part_to_disk(part)->part0.in_flight++; | ||
381 | } | 309 | } |
382 | 310 | ||
383 | static inline void free_part_stats(struct hd_struct *part) | 311 | static inline void part_dec_in_flight(struct hd_struct *part) |
384 | { | 312 | { |
313 | part->in_flight--; | ||
314 | if (part->partno) | ||
315 | part_to_disk(part)->part0.in_flight--; | ||
385 | } | 316 | } |
386 | #endif /* CONFIG_SMP */ | ||
387 | 317 | ||
388 | /* drivers/block/ll_rw_blk.c */ | 318 | /* drivers/block/ll_rw_blk.c */ |
389 | extern void disk_round_stats(int cpu, struct gendisk *disk); | ||
390 | extern void part_round_stats(int cpu, struct hd_struct *part); | 319 | extern void part_round_stats(int cpu, struct hd_struct *part); |
391 | 320 | ||
392 | /* drivers/block/genhd.c */ | 321 | /* drivers/block/genhd.c */ |
@@ -595,6 +524,8 @@ extern void blk_unregister_region(dev_t devt, unsigned long range); | |||
595 | 524 | ||
596 | extern ssize_t part_size_show(struct device *dev, | 525 | extern ssize_t part_size_show(struct device *dev, |
597 | struct device_attribute *attr, char *buf); | 526 | struct device_attribute *attr, char *buf); |
527 | extern ssize_t part_stat_show(struct device *dev, | ||
528 | struct device_attribute *attr, char *buf); | ||
598 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 529 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
599 | extern ssize_t part_fail_show(struct device *dev, | 530 | extern ssize_t part_fail_show(struct device *dev, |
600 | struct device_attribute *attr, char *buf); | 531 | struct device_attribute *attr, char *buf); |