aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/genhd.h139
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);
209extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, 209extern 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
232static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { 240static 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
273static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) 285static 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 */
404extern void disk_round_stats(struct gendisk *disk); 379extern void disk_round_stats(int cpu, struct gendisk *disk);
405extern void part_round_stats(struct hd_struct *part); 380extern void part_round_stats(int cpu, struct hd_struct *part);
406 381
407/* drivers/block/genhd.c */ 382/* drivers/block/genhd.c */
408extern int get_blkdev_list(char *, int); 383extern int get_blkdev_list(char *, int);