diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:42:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:42:46 -0500 |
commit | 03054de1e0b90b33e9974107d84dabd2509f5898 (patch) | |
tree | a85e92d5387d94ef9e3d10bf11467136c681ad04 /include | |
parent | b5eb9513f7c1bee862ada22bf1489f53752686bd (diff) | |
parent | 0e53c2be0495afa97c6b0d06397adcbff9c65347 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
Enhanced partition statistics: documentation update
Enhanced partition statistics: remove old partition statistics
Enhanced partition statistics: procfs
Enhanced partition statistics: sysfs
Enhanced partition statistics: aoe fix
Enhanced partition statistics: update partition statitics
Enhanced partition statistics: core statistics
block: fixup rq_init() a bit
Manually fixed conflict in drivers/block/aoe/aoecmd.c due to statistics
support.
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/blkdev.h | 4 | ||||
-rw-r--r-- | include/linux/genhd.h | 153 |
2 files changed, 145 insertions, 12 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 90392a9d7a9c..e1888cc5b8ae 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -137,7 +137,9 @@ enum rq_flag_bits { | |||
137 | #define BLK_MAX_CDB 16 | 137 | #define BLK_MAX_CDB 16 |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * try to put the fields that are referenced together in the same cacheline | 140 | * try to put the fields that are referenced together in the same cacheline. |
141 | * if you modify this structure, be sure to check block/blk-core.c:rq_init() | ||
142 | * as well! | ||
141 | */ | 143 | */ |
142 | struct request { | 144 | struct request { |
143 | struct list_head queuelist; | 145 | struct list_head queuelist; |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 1dbea0ac5693..09a3b18918c7 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -91,16 +91,31 @@ struct partition { | |||
91 | __le32 nr_sects; /* nr of sectors in partition */ | 91 | __le32 nr_sects; /* nr of sectors in partition */ |
92 | } __attribute__((packed)); | 92 | } __attribute__((packed)); |
93 | 93 | ||
94 | struct disk_stats { | ||
95 | unsigned long sectors[2]; /* READs and WRITEs */ | ||
96 | unsigned long ios[2]; | ||
97 | unsigned long merges[2]; | ||
98 | unsigned long ticks[2]; | ||
99 | unsigned long io_ticks; | ||
100 | unsigned long time_in_queue; | ||
101 | }; | ||
102 | |||
94 | struct hd_struct { | 103 | struct hd_struct { |
95 | sector_t start_sect; | 104 | sector_t start_sect; |
96 | sector_t nr_sects; | 105 | sector_t nr_sects; |
97 | struct device dev; | 106 | struct device dev; |
98 | struct kobject *holder_dir; | 107 | struct kobject *holder_dir; |
99 | unsigned ios[2], sectors[2]; /* READs and WRITEs */ | ||
100 | int policy, partno; | 108 | int policy, partno; |
101 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 109 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
102 | int make_it_fail; | 110 | int make_it_fail; |
103 | #endif | 111 | #endif |
112 | unsigned long stamp; | ||
113 | int in_flight; | ||
114 | #ifdef CONFIG_SMP | ||
115 | struct disk_stats *dkstats; | ||
116 | #else | ||
117 | struct disk_stats dkstats; | ||
118 | #endif | ||
104 | }; | 119 | }; |
105 | 120 | ||
106 | #define GENHD_FL_REMOVABLE 1 | 121 | #define GENHD_FL_REMOVABLE 1 |
@@ -111,15 +126,7 @@ struct hd_struct { | |||
111 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 | 126 | #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 |
112 | #define GENHD_FL_FAIL 64 | 127 | #define GENHD_FL_FAIL 64 |
113 | 128 | ||
114 | struct disk_stats { | 129 | |
115 | unsigned long sectors[2]; /* READs and WRITEs */ | ||
116 | unsigned long ios[2]; | ||
117 | unsigned long merges[2]; | ||
118 | unsigned long ticks[2]; | ||
119 | unsigned long io_ticks; | ||
120 | unsigned long time_in_queue; | ||
121 | }; | ||
122 | |||
123 | struct gendisk { | 130 | struct gendisk { |
124 | int major; /* major number of driver */ | 131 | int major; /* major number of driver */ |
125 | int first_minor; | 132 | int first_minor; |
@@ -158,6 +165,20 @@ struct gendisk { | |||
158 | * The __ variants should only be called in critical sections. The full | 165 | * The __ variants should only be called in critical sections. The full |
159 | * variants disable/enable preemption. | 166 | * variants disable/enable preemption. |
160 | */ | 167 | */ |
168 | static inline struct hd_struct *get_part(struct gendisk *gendiskp, | ||
169 | sector_t sector) | ||
170 | { | ||
171 | struct hd_struct *part; | ||
172 | int i; | ||
173 | for (i = 0; i < gendiskp->minors - 1; i++) { | ||
174 | part = gendiskp->part[i]; | ||
175 | if (part && part->start_sect <= sector | ||
176 | && sector < part->start_sect + part->nr_sects) | ||
177 | return part; | ||
178 | } | ||
179 | return NULL; | ||
180 | } | ||
181 | |||
161 | #ifdef CONFIG_SMP | 182 | #ifdef CONFIG_SMP |
162 | #define __disk_stat_add(gendiskp, field, addnd) \ | 183 | #define __disk_stat_add(gendiskp, field, addnd) \ |
163 | (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) | 184 | (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) |
@@ -177,15 +198,62 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | |||
177 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, | 198 | memset(per_cpu_ptr(gendiskp->dkstats, i), value, |
178 | sizeof (struct disk_stats)); | 199 | sizeof (struct disk_stats)); |
179 | } | 200 | } |
201 | |||
202 | #define __part_stat_add(part, field, addnd) \ | ||
203 | (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) | ||
204 | |||
205 | #define __all_stat_add(gendiskp, field, addnd, sector) \ | ||
206 | ({ \ | ||
207 | struct hd_struct *part = get_part(gendiskp, sector); \ | ||
208 | if (part) \ | ||
209 | __part_stat_add(part, field, addnd); \ | ||
210 | __disk_stat_add(gendiskp, field, addnd); \ | ||
211 | }) | ||
212 | |||
213 | #define part_stat_read(part, field) \ | ||
214 | ({ \ | ||
215 | typeof(part->dkstats->field) res = 0; \ | ||
216 | int i; \ | ||
217 | for_each_possible_cpu(i) \ | ||
218 | res += per_cpu_ptr(part->dkstats, i)->field; \ | ||
219 | res; \ | ||
220 | }) | ||
221 | |||
222 | static inline void part_stat_set_all(struct hd_struct *part, int value) { | ||
223 | int i; | ||
224 | for_each_possible_cpu(i) | ||
225 | memset(per_cpu_ptr(part->dkstats, i), value, | ||
226 | sizeof(struct disk_stats)); | ||
227 | } | ||
180 | 228 | ||
181 | #else | 229 | #else |
182 | #define __disk_stat_add(gendiskp, field, addnd) \ | 230 | #define __disk_stat_add(gendiskp, field, addnd) \ |
183 | (gendiskp->dkstats.field += addnd) | 231 | (gendiskp->dkstats.field += addnd) |
184 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) | 232 | #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) |
185 | 233 | ||
186 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | 234 | static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) |
235 | { | ||
187 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); | 236 | memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); |
188 | } | 237 | } |
238 | |||
239 | #define __part_stat_add(part, field, addnd) \ | ||
240 | (part->dkstats.field += addnd) | ||
241 | |||
242 | #define __all_stat_add(gendiskp, field, addnd, sector) \ | ||
243 | ({ \ | ||
244 | struct hd_struct *part = get_part(gendiskp, sector); \ | ||
245 | if (part) \ | ||
246 | part->dkstats.field += addnd; \ | ||
247 | __disk_stat_add(gendiskp, field, addnd); \ | ||
248 | }) | ||
249 | |||
250 | #define part_stat_read(part, field) (part->dkstats.field) | ||
251 | |||
252 | static inline void part_stat_set_all(struct hd_struct *part, int value) | ||
253 | { | ||
254 | memset(&part->dkstats, value, sizeof(struct disk_stats)); | ||
255 | } | ||
256 | |||
189 | #endif | 257 | #endif |
190 | 258 | ||
191 | #define disk_stat_add(gendiskp, field, addnd) \ | 259 | #define disk_stat_add(gendiskp, field, addnd) \ |
@@ -206,6 +274,45 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { | |||
206 | #define disk_stat_sub(gendiskp, field, subnd) \ | 274 | #define disk_stat_sub(gendiskp, field, subnd) \ |
207 | disk_stat_add(gendiskp, field, -subnd) | 275 | disk_stat_add(gendiskp, field, -subnd) |
208 | 276 | ||
277 | #define part_stat_add(gendiskp, field, addnd) \ | ||
278 | do { \ | ||
279 | preempt_disable(); \ | ||
280 | __part_stat_add(gendiskp, field, addnd);\ | ||
281 | preempt_enable(); \ | ||
282 | } while (0) | ||
283 | |||
284 | #define __part_stat_dec(gendiskp, field) __part_stat_add(gendiskp, field, -1) | ||
285 | #define part_stat_dec(gendiskp, field) part_stat_add(gendiskp, field, -1) | ||
286 | |||
287 | #define __part_stat_inc(gendiskp, field) __part_stat_add(gendiskp, field, 1) | ||
288 | #define part_stat_inc(gendiskp, field) part_stat_add(gendiskp, field, 1) | ||
289 | |||
290 | #define __part_stat_sub(gendiskp, field, subnd) \ | ||
291 | __part_stat_add(gendiskp, field, -subnd) | ||
292 | #define part_stat_sub(gendiskp, field, subnd) \ | ||
293 | part_stat_add(gendiskp, field, -subnd) | ||
294 | |||
295 | #define all_stat_add(gendiskp, field, addnd, sector) \ | ||
296 | do { \ | ||
297 | preempt_disable(); \ | ||
298 | __all_stat_add(gendiskp, field, addnd, sector); \ | ||
299 | preempt_enable(); \ | ||
300 | } while (0) | ||
301 | |||
302 | #define __all_stat_dec(gendiskp, field, sector) \ | ||
303 | __all_stat_add(gendiskp, field, -1, sector) | ||
304 | #define all_stat_dec(gendiskp, field, sector) \ | ||
305 | all_stat_add(gendiskp, field, -1, sector) | ||
306 | |||
307 | #define __all_stat_inc(gendiskp, field, sector) \ | ||
308 | __all_stat_add(gendiskp, field, 1, sector) | ||
309 | #define all_stat_inc(gendiskp, field, sector) \ | ||
310 | all_stat_add(gendiskp, field, 1, sector) | ||
311 | |||
312 | #define __all_stat_sub(gendiskp, field, subnd, sector) \ | ||
313 | __all_stat_add(gendiskp, field, -subnd, sector) | ||
314 | #define all_stat_sub(gendiskp, field, subnd, sector) \ | ||
315 | all_stat_add(gendiskp, field, -subnd, sector) | ||
209 | 316 | ||
210 | /* Inlines to alloc and free disk stats in struct gendisk */ | 317 | /* Inlines to alloc and free disk stats in struct gendisk */ |
211 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
@@ -221,6 +328,20 @@ static inline void free_disk_stats(struct gendisk *disk) | |||
221 | { | 328 | { |
222 | free_percpu(disk->dkstats); | 329 | free_percpu(disk->dkstats); |
223 | } | 330 | } |
331 | |||
332 | static inline int init_part_stats(struct hd_struct *part) | ||
333 | { | ||
334 | part->dkstats = alloc_percpu(struct disk_stats); | ||
335 | if (!part->dkstats) | ||
336 | return 0; | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | static inline void free_part_stats(struct hd_struct *part) | ||
341 | { | ||
342 | free_percpu(part->dkstats); | ||
343 | } | ||
344 | |||
224 | #else /* CONFIG_SMP */ | 345 | #else /* CONFIG_SMP */ |
225 | static inline int init_disk_stats(struct gendisk *disk) | 346 | static inline int init_disk_stats(struct gendisk *disk) |
226 | { | 347 | { |
@@ -230,10 +351,20 @@ static inline int init_disk_stats(struct gendisk *disk) | |||
230 | static inline void free_disk_stats(struct gendisk *disk) | 351 | static inline void free_disk_stats(struct gendisk *disk) |
231 | { | 352 | { |
232 | } | 353 | } |
354 | |||
355 | static inline int init_part_stats(struct hd_struct *part) | ||
356 | { | ||
357 | return 1; | ||
358 | } | ||
359 | |||
360 | static inline void free_part_stats(struct hd_struct *part) | ||
361 | { | ||
362 | } | ||
233 | #endif /* CONFIG_SMP */ | 363 | #endif /* CONFIG_SMP */ |
234 | 364 | ||
235 | /* drivers/block/ll_rw_blk.c */ | 365 | /* drivers/block/ll_rw_blk.c */ |
236 | extern void disk_round_stats(struct gendisk *disk); | 366 | extern void disk_round_stats(struct gendisk *disk); |
367 | extern void part_round_stats(struct hd_struct *part); | ||
237 | 368 | ||
238 | /* drivers/block/genhd.c */ | 369 | /* drivers/block/genhd.c */ |
239 | extern int get_blkdev_list(char *, int); | 370 | extern int get_blkdev_list(char *, int); |