aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-05-07 04:15:46 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-05-07 04:15:46 -0400
commit28f13702f03e527fcb979747a882cf366c489c50 (patch)
tree08cf04c696bf0facb083bbfbdd867e5949c5fa14 /include/linux
parent6d63c275572d1e6f00d4fa154f16fbb0d8c2d2bf (diff)
block: avoid duplicate calls to get_part() in disk stat code
get_part() is fairly expensive, as it O(N) loops over partitions to find the right one. In lots of normal IO paths we end up looking up the partition twice, to make matters even worse. Change the stat add code to accept a passed in partition instead. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/genhd.h35
1 files changed, 18 insertions, 17 deletions
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index ecd2bf63fc84..e9874e7fcdf9 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -178,17 +178,17 @@ static inline struct hd_struct *get_part(struct gendisk *gendiskp,
178 178
179static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { 179static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) {
180 int i; 180 int i;
181
181 for_each_possible_cpu(i) 182 for_each_possible_cpu(i)
182 memset(per_cpu_ptr(gendiskp->dkstats, i), value, 183 memset(per_cpu_ptr(gendiskp->dkstats, i), value,
183 sizeof (struct disk_stats)); 184 sizeof(struct disk_stats));
184} 185}
185 186
186#define __part_stat_add(part, field, addnd) \ 187#define __part_stat_add(part, field, addnd) \
187 (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) 188 (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd)
188 189
189#define __all_stat_add(gendiskp, field, addnd, sector) \ 190#define __all_stat_add(gendiskp, part, field, addnd, sector) \
190({ \ 191({ \
191 struct hd_struct *part = get_part(gendiskp, sector); \
192 if (part) \ 192 if (part) \
193 __part_stat_add(part, field, addnd); \ 193 __part_stat_add(part, field, addnd); \
194 __disk_stat_add(gendiskp, field, addnd); \ 194 __disk_stat_add(gendiskp, field, addnd); \
@@ -203,11 +203,13 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) {
203 res; \ 203 res; \
204}) 204})
205 205
206static inline void part_stat_set_all(struct hd_struct *part, int value) { 206static inline void part_stat_set_all(struct hd_struct *part, int value)
207{
207 int i; 208 int i;
209
208 for_each_possible_cpu(i) 210 for_each_possible_cpu(i)
209 memset(per_cpu_ptr(part->dkstats, i), value, 211 memset(per_cpu_ptr(part->dkstats, i), value,
210 sizeof(struct disk_stats)); 212 sizeof(struct disk_stats));
211} 213}
212 214
213#else /* !CONFIG_SMP */ 215#else /* !CONFIG_SMP */
@@ -223,9 +225,8 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value)
223#define __part_stat_add(part, field, addnd) \ 225#define __part_stat_add(part, field, addnd) \
224 (part->dkstats.field += addnd) 226 (part->dkstats.field += addnd)
225 227
226#define __all_stat_add(gendiskp, field, addnd, sector) \ 228#define __all_stat_add(gendiskp, part, field, addnd, sector) \
227({ \ 229({ \
228 struct hd_struct *part = get_part(gendiskp, sector); \
229 if (part) \ 230 if (part) \
230 part->dkstats.field += addnd; \ 231 part->dkstats.field += addnd; \
231 __disk_stat_add(gendiskp, field, addnd); \ 232 __disk_stat_add(gendiskp, field, addnd); \
@@ -276,10 +277,10 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
276#define part_stat_sub(gendiskp, field, subnd) \ 277#define part_stat_sub(gendiskp, field, subnd) \
277 part_stat_add(gendiskp, field, -subnd) 278 part_stat_add(gendiskp, field, -subnd)
278 279
279#define all_stat_add(gendiskp, field, addnd, sector) \ 280#define all_stat_add(gendiskp, part, field, addnd, sector) \
280 do { \ 281 do { \
281 preempt_disable(); \ 282 preempt_disable(); \
282 __all_stat_add(gendiskp, field, addnd, sector); \ 283 __all_stat_add(gendiskp, part, field, addnd, sector); \
283 preempt_enable(); \ 284 preempt_enable(); \
284 } while (0) 285 } while (0)
285 286
@@ -288,15 +289,15 @@ static inline void part_stat_set_all(struct hd_struct *part, int value)
288#define all_stat_dec(gendiskp, field, sector) \ 289#define all_stat_dec(gendiskp, field, sector) \
289 all_stat_add(gendiskp, field, -1, sector) 290 all_stat_add(gendiskp, field, -1, sector)
290 291
291#define __all_stat_inc(gendiskp, field, sector) \ 292#define __all_stat_inc(gendiskp, part, field, sector) \
292 __all_stat_add(gendiskp, field, 1, sector) 293 __all_stat_add(gendiskp, part, field, 1, sector)
293#define all_stat_inc(gendiskp, field, sector) \ 294#define all_stat_inc(gendiskp, part, field, sector) \
294 all_stat_add(gendiskp, field, 1, sector) 295 all_stat_add(gendiskp, part, field, 1, sector)
295 296
296#define __all_stat_sub(gendiskp, field, subnd, sector) \ 297#define __all_stat_sub(gendiskp, part, field, subnd, sector) \
297 __all_stat_add(gendiskp, field, -subnd, sector) 298 __all_stat_add(gendiskp, part, field, -subnd, sector)
298#define all_stat_sub(gendiskp, field, subnd, sector) \ 299#define all_stat_sub(gendiskp, part, field, subnd, sector) \
299 all_stat_add(gendiskp, field, -subnd, sector) 300 all_stat_add(gendiskp, part, field, -subnd, sector)
300 301
301/* Inlines to alloc and free disk stats in struct gendisk */ 302/* Inlines to alloc and free disk stats in struct gendisk */
302#ifdef CONFIG_SMP 303#ifdef CONFIG_SMP