diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/genhd.h | 139 |
1 files changed, 57 insertions, 82 deletions
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 7fbba19e076b..ac8a901f2002 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -209,16 +209,24 @@ extern void disk_part_iter_exit(struct disk_part_iter *piter); | |||
209 | extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | 209 | extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, |
210 | sector_t sector); | 210 | sector_t sector); |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * Macros to operate on percpu disk statistics: | 213 | * Macros to operate on percpu disk statistics: |
214 | * | 214 | * |
215 | * The __ variants should only be called in critical sections. The full | 215 | * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters |
216 | * variants disable/enable preemption. | 216 | * and should be called between disk_stat_lock() and |
217 | * disk_stat_unlock(). | ||
218 | * | ||
219 | * part_stat_read() can be called at any time. | ||
220 | * | ||
221 | * part_stat_{add|set_all}() and {init|free}_part_stats are for | ||
222 | * internal use only. | ||
217 | */ | 223 | */ |
218 | |||
219 | #ifdef CONFIG_SMP | 224 | #ifdef CONFIG_SMP |
220 | #define __disk_stat_add(gendiskp, field, addnd) \ | 225 | #define disk_stat_lock() ({ rcu_read_lock(); get_cpu(); }) |
221 | (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) | 226 | #define disk_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) |
227 | |||
228 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
229 | (per_cpu_ptr(gendiskp->dkstats, cpu)->field += addnd) | ||
222 | 230 | ||
223 | #define disk_stat_read(gendiskp, field) \ | 231 | #define disk_stat_read(gendiskp, field) \ |
224 | ({ \ | 232 | ({ \ |
@@ -229,7 +237,8 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, | |||
229 | res; \ | 237 | res; \ |
230 | }) | 238 | }) |
231 | 239 | ||
232 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | 240 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) |
241 | { | ||
233 | int i; | 242 | int i; |
234 | 243 | ||
235 | for_each_possible_cpu(i) | 244 | for_each_possible_cpu(i) |
@@ -237,14 +246,14 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | |||
237 | sizeof(struct disk_stats)); | 246 | sizeof(struct disk_stats)); |
238 | } | 247 | } |
239 | 248 | ||
240 | #define __part_stat_add(part, field, addnd) \ | 249 | #define part_stat_add(cpu, part, field, addnd) \ |
241 | (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) | 250 | (per_cpu_ptr(part->dkstats, cpu)->field += addnd) |
242 | 251 | ||
243 | #define __all_stat_add(gendiskp, part, field, addnd, sector) \ | 252 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ |
244 | ({ \ | 253 | ({ \ |
245 | if (part) \ | 254 | if (part) \ |
246 | __part_stat_add(part, field, addnd); \ | 255 | part_stat_add(cpu, part, field, addnd); \ |
247 | __disk_stat_add(gendiskp, field, addnd); \ | 256 | disk_stat_add(cpu, gendiskp, field, addnd); \ |
248 | }) | 257 | }) |
249 | 258 | ||
250 | #define part_stat_read(part, field) \ | 259 | #define part_stat_read(part, field) \ |
@@ -264,10 +273,13 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) | |||
264 | memset(per_cpu_ptr(part->dkstats, i), value, | 273 | memset(per_cpu_ptr(part->dkstats, i), value, |
265 | sizeof(struct disk_stats)); | 274 | sizeof(struct disk_stats)); |
266 | } | 275 | } |
267 | 276 | ||
268 | #else /* !CONFIG_SMP */ | 277 | #else /* !CONFIG_SMP */ |
269 | #define __disk_stat_add(gendiskp, field, addnd) \ | 278 | #define disk_stat_lock() ({ rcu_read_lock(); 0; }) |
270 | (gendiskp->dkstats.field += addnd) | 279 | #define disk_stat_unlock() rcu_read_unlock() |
280 | |||
281 | #define disk_stat_add(cpu, gendiskp, field, addnd) \ | ||
282 | (gendiskp->dkstats.field += addnd) | ||
271 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) | 283 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) |
272 | 284 | ||
273 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | 285 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) |
@@ -275,14 +287,14 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) | |||
275 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); | 287 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); |
276 | } | 288 | } |
277 | 289 | ||
278 | #define __part_stat_add(part, field, addnd) \ | 290 | #define part_stat_add(cpu, part, field, addnd) \ |
279 | (part->dkstats.field += addnd) | 291 | (part->dkstats.field += addnd) |
280 | 292 | ||
281 | #define __all_stat_add(gendiskp, part, field, addnd, sector) \ | 293 | #define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ |
282 | ({ \ | 294 | ({ \ |
283 | if (part) \ | 295 | if (part) \ |
284 | part->dkstats.field += addnd; \ | 296 | part_stat_add(cpu, part, field, addnd); \ |
285 | __disk_stat_add(gendiskp, field, addnd); \ | 297 | disk_stat_add(cpu, gendiskp, field, addnd); \ |
286 | }) | 298 | }) |
287 | 299 | ||
288 | #define part_stat_read(part, field) (part->dkstats.field) | 300 | #define part_stat_read(part, field) (part->dkstats.field) |
@@ -294,63 +306,26 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) | |||
294 | 306 | ||
295 | #endif /* CONFIG_SMP */ | 307 | #endif /* CONFIG_SMP */ |
296 | 308 | ||
297 | #define disk_stat_add(gendiskp, field, addnd) \ | 309 | #define disk_stat_dec(cpu, gendiskp, field) \ |
298 | do { \ | 310 | disk_stat_add(cpu, gendiskp, field, -1) |
299 | preempt_disable(); \ | 311 | #define disk_stat_inc(cpu, gendiskp, field) \ |
300 | __disk_stat_add(gendiskp, field, addnd); \ | 312 | disk_stat_add(cpu, gendiskp, field, 1) |
301 | preempt_enable(); \ | 313 | #define disk_stat_sub(cpu, gendiskp, field, subnd) \ |
302 | } while (0) | 314 | disk_stat_add(cpu, gendiskp, field, -subnd) |
303 | 315 | ||
304 | #define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1) | 316 | #define part_stat_dec(cpu, gendiskp, field) \ |
305 | #define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1) | 317 | part_stat_add(cpu, gendiskp, field, -1) |
306 | 318 | #define part_stat_inc(cpu, gendiskp, field) \ | |
307 | #define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1) | 319 | part_stat_add(cpu, gendiskp, field, 1) |
308 | #define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1) | 320 | #define part_stat_sub(cpu, gendiskp, field, subnd) \ |
309 | 321 | part_stat_add(cpu, gendiskp, field, -subnd) | |
310 | #define __disk_stat_sub(gendiskp, field, subnd) \ | 322 | |
311 | __disk_stat_add(gendiskp, field, -subnd) | 323 | #define all_stat_dec(cpu, gendiskp, field, sector) \ |
312 | #define disk_stat_sub(gendiskp, field, subnd) \ | 324 | all_stat_add(cpu, gendiskp, field, -1, sector) |
313 | disk_stat_add(gendiskp, field, -subnd) | 325 | #define all_stat_inc(cpu, gendiskp, part, field, sector) \ |
314 | 326 | all_stat_add(cpu, gendiskp, part, field, 1, sector) | |
315 | #define part_stat_add(gendiskp, field, addnd) \ | 327 | #define all_stat_sub(cpu, gendiskp, part, field, subnd, sector) \ |
316 | do { \ | 328 | all_stat_add(cpu, gendiskp, part, field, -subnd, sector) |
317 | preempt_disable(); \ | ||
318 | __part_stat_add(gendiskp, field, addnd);\ | ||
319 | preempt_enable(); \ | ||
320 | } while (0) | ||
321 | |||
322 | #define __part_stat_dec(gendiskp, field) __part_stat_add(gendiskp, field, -1) | ||
323 | #define part_stat_dec(gendiskp, field) part_stat_add(gendiskp, field, -1) | ||
324 | |||
325 | #define __part_stat_inc(gendiskp, field) __part_stat_add(gendiskp, field, 1) | ||
326 | #define part_stat_inc(gendiskp, field) part_stat_add(gendiskp, field, 1) | ||
327 | |||
328 | #define __part_stat_sub(gendiskp, field, subnd) \ | ||
329 | __part_stat_add(gendiskp, field, -subnd) | ||
330 | #define part_stat_sub(gendiskp, field, subnd) \ | ||
331 | part_stat_add(gendiskp, field, -subnd) | ||
332 | |||
333 | #define all_stat_add(gendiskp, part, field, addnd, sector) \ | ||
334 | do { \ | ||
335 | preempt_disable(); \ | ||
336 | __all_stat_add(gendiskp, part, field, addnd, sector); \ | ||
337 | preempt_enable(); \ | ||
338 | } while (0) | ||
339 | |||
340 | #define __all_stat_dec(gendiskp, field, sector) \ | ||
341 | __all_stat_add(gendiskp, field, -1, sector) | ||
342 | #define all_stat_dec(gendiskp, field, sector) \ | ||
343 | all_stat_add(gendiskp, field, -1, sector) | ||
344 | |||
345 | #define __all_stat_inc(gendiskp, part, field, sector) \ | ||
346 | __all_stat_add(gendiskp, part, field, 1, sector) | ||
347 | #define all_stat_inc(gendiskp, part, field, sector) \ | ||
348 | all_stat_add(gendiskp, part, field, 1, sector) | ||
349 | |||
350 | #define __all_stat_sub(gendiskp, part, field, subnd, sector) \ | ||
351 | __all_stat_add(gendiskp, part, field, -subnd, sector) | ||
352 | #define all_stat_sub(gendiskp, part, field, subnd, sector) \ | ||
353 | all_stat_add(gendiskp, part, field, -subnd, sector) | ||
354 | 329 | ||
355 | /* Inlines to alloc and free disk stats in struct gendisk */ | 330 | /* Inlines to alloc and free disk stats in struct gendisk */ |
356 | #ifdef CONFIG_SMP | 331 | #ifdef CONFIG_SMP |
@@ -401,8 +376,8 @@ static inline void free_part_stats(struct hd_struct *part) | |||
401 | #endif /* CONFIG_SMP */ | 376 | #endif /* CONFIG_SMP */ |
402 | 377 | ||
403 | /* drivers/block/ll_rw_blk.c */ | 378 | /* drivers/block/ll_rw_blk.c */ |
404 | extern void disk_round_stats(struct gendisk *disk); | 379 | extern void disk_round_stats(int cpu, struct gendisk *disk); |
405 | extern void part_round_stats(struct hd_struct *part); | 380 | extern void part_round_stats(int cpu, struct hd_struct *part); |
406 | 381 | ||
407 | /* drivers/block/genhd.c */ | 382 | /* drivers/block/genhd.c */ |
408 | extern int get_blkdev_list(char *, int); | 383 | extern int get_blkdev_list(char *, int); |