Enhanced partition statistics: core statistics
PATCH 1/8 Enhanced partition statistics: core statistics
This patch contain the core infrastructure of enhanced partition statistics.
It adds to struct hd_struct the same stats data as struct gendisk and define basics function to manipulate them.
--- genhd.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-)
include/linux/genhd.h +128 -1
@@ -91,6 +91,13 @@ struct hd_struct {#ifdef CONFIG_FAIL_MAKE_REQUEST int make_it_fail;#endif +unsigned long stamp; +int in_flight; +#ifdef CONFIG_SMP +struct disk_stats *dkstats; +#else +struct disk_stats dkstats; +#endif };#define GENHD_FL_REMOVABLE 1
@@ -156,6 +163,19 @@ struct disk_attribute {* The __ variants should only be called in critical sections. The full * variants disable/enable preemption. */ +static inline struct hd_struct *get_part (struct gendisk *gendiskp,sector_t sector) +{ +struct hd_struct *part; +int i; +for (i=0 ; i < gendiskp->minors -1 ; i++){ + part = gendiskp->part[i]; +if (part && part->start_sect <= sector + && sector <= part->start_sect + part->nr_sects) +return part; + } +return NULL ; +} +#ifdef CONFIG_SMP #define __disk_stat_add (gendiskp, field, addnd) \ (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd)
@@ -175,15 +195,60 @@ static inline void disk_stat_set_all(strmemset (per_cpu_ptr (gendiskp->dkstats, i), value,sizeof (struct disk_stats )); } + +#define __part_stat_add (part, field, addnd) \ + (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) + +#define __all_stat_add (gendiskp, field, addnd, sector) \ +({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ + if (part) __part_stat_add(part, field, addnd); \ + __disk_stat_add(gendiskp, field, addnd); \ +}) + +#define part_stat_read (part, field) \ +({ \ + typeof(part->dkstats->field) res = 0; \ + int i; \ + for_each_possible_cpu(i) \ + res += per_cpu_ptr(part->dkstats, i)->field; \ + res; \ +}) + +static inline void part_stat_set_all (struct hd_struct *part,int value) { +int i; +for_each_possible_cpu (i) +memset (per_cpu_ptr (part->dkstats, i), value, +sizeof (struct disk_stats )); +}#else #define __disk_stat_add (gendiskp, field, addnd) \ (gendiskp->dkstats.field += addnd)#define disk_stat_read (gendiskp, field) (gendiskp->dkstats.field) -static inline void disk_stat_set_all (struct gendisk *gendiskp,int value) { +static inline void disk_stat_set_all (struct gendisk *gendiskp,int value) +{memset (&gendiskp->dkstats, value,sizeof (struct disk_stats )); } + +#define __part_stat_add (part, field, addnd) \ + (part->dkstats.field += addnd) + +#define __all_stat_add (gendiskp, field, addnd, sector) \ +({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ + if (part) part->dkstats.field += addnd; \ + __disk_stat_add(gendiskp, field, addnd); \ +}) + +#define part_stat_read (part, field) (part->dkstats.field) + +static inline void part_stat_set_all (struct hd_struct *part,int value) +{ +memset (&part->dkstats, value,sizeof (struct disk_stats )); +} +#endif #define disk_stat_add (gendiskp, field, addnd) \
@@ -204,6 +269,45 @@ static inline void disk_stat_set_all(str#define disk_stat_sub (gendiskp, field, subnd) \ disk_stat_add(gendiskp, field, -subnd) +#define part_stat_add (gendiskp, field, addnd) \ + do { \ + preempt_disable(); \ + __part_stat_add(gendiskp, field, addnd);\ + preempt_enable(); \ + } while (0) + +#define __part_stat_dec (gendiskp, field) __part_stat_add(gendiskp, field, -1) +#define part_stat_dec (gendiskp, field) part_stat_add(gendiskp, field, -1) + +#define __part_stat_inc (gendiskp, field) __part_stat_add(gendiskp, field, 1) +#define part_stat_inc (gendiskp, field) part_stat_add(gendiskp, field, 1) + +#define __part_stat_sub (gendiskp, field, subnd) \ + __part_stat_add(gendiskp, field, -subnd) +#define part_stat_sub (gendiskp, field, subnd) \ + part_stat_add(gendiskp, field, -subnd) + +#define all_stat_add (gendiskp, field, addnd, sector) \ + do { \ + preempt_disable(); \ + __all_stat_add(gendiskp, field, addnd, sector); \ + preempt_enable(); \ + } while (0) + +#define __all_stat_dec (gendiskp, field, sector) \ + __all_stat_add(gendiskp, field, -1, sector) +#define all_stat_dec (gendiskp, field, sector) \ + all_stat_add(gendiskp, field, -1, sector) + +#define __all_stat_inc (gendiskp, field, sector) \ + __all_stat_add(gendiskp, field, 1, sector) +#define all_stat_inc (gendiskp, field, sector) \ + all_stat_add(gendiskp, field, 1, sector) + +#define __all_stat_sub (gendiskp, field, subnd, sector) \ + __all_stat_add(gendiskp, field, -subnd, sector) +#define all_stat_sub (gendiskp, field, subnd, sector) \ + all_stat_add(gendiskp, field, -subnd, sector)/* Inlines to alloc and free disk stats in struct gendisk */ #ifdef CONFIG_SMP
@@ -219,6 +323,20 @@ static inline void free_disk_stats(struc {free_percpu (disk->dkstats); } + +static inline int init_part_stats (struct hd_struct *part) +{ + part->dkstats = alloc_percpu(struct disk_stats); +if (!part->dkstats) +return 0 ; +return 1 ; +} + +static inline void free_part_stats (struct hd_struct *part) +{ +free_percpu (part->dkstats); +} +#else /* CONFIG_SMP */ static inline int init_disk_stats (struct gendisk *disk) {
@@ -228,6 +346,15 @@ static inline int init_disk_stats(structstatic inline void free_disk_stats (struct gendisk *disk) { } + +static inline int init_part_stats (struct hd_struct *part) +{ +return 1 ; +} + +static inline void free_part_stats (struct hd_struct *part) +{ +}#endif /* CONFIG_SMP */ /* drivers/block/ll_rw_blk.c */
Quoted 7 lines · On Thu, 13 Dec 2007 17:17:30 +0100 Jerome Marchand wrote:
This patch contain the core infrastructure of enhanced partition statistics.
It adds to structhd_structthe same stats data as struct gendisk and define basics function to manipulate them.Signed-off-by Jerome Marchand <[email protected]>--- genhd.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-)
Please use "diffstat -p1 -w70" (Documentation/SubmittingPatches).
Quoted 18 lines
diff -urNp -X linux-2.6/Documentation/dontdiff
linux-2.6.orig/include/linux/genhd.hlinux-2.6/include/linux/genhd.hinclude/linux/genhd.h +7
-0@@ -91,6 +91,13 @@ struct hd_struct {#ifdef CONFIG_FAIL_MAKE_REQUEST int make_it_fail;#endif +unsigned long stamp; +int in_flight; +#ifdef CONFIG_SMP +struct disk_stats *dkstats; +#else +struct disk_stats dkstats; +#endif };#define GENHD_FL_REMOVABLE 1
include/linux/genhd.h struct disk_attribute { · line 170
Quoted 8 lines
include/linux/genhd.h +5
-0@@ -156,6 +163,19 @@ struct disk_attribute {* The __ variants should only be called in critical sections. The full * variants disable/enable preemption. */ +static inline struct hd_struct *get_part (struct gendisk *gendiskp,sector_t sector) +{ +struct hd_struct *part; +int i; +for (i=0 ; i < gendiskp->minors -1 ; i++){
for (i = 0; i < gendiskp->minors - 1; i++) {include/linux/genhd.h struct disk_attribute { · line 173
Quoted 3 lines
include/linux/genhd.h +3
-0+ part = gendiskp->part[i]; +if (part && part->start_sect <= sector + && sector <= part->start_sect + part->nr_sects)
I expect that the second comparison should just be <, not <=.
Quoted 10 lines
include/linux/genhd.h +5
-0+return part; + } +return NULL ; +} +#ifdef CONFIG_SMP #define __disk_stat_add (gendiskp, field, addnd) \ (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd)@@ -175,15 +195,60 @@ static inline void disk_stat_set_all(str memset(per_cpu_ptr(gendiskp->dkstats, i), value,
include/linux/genhd.h static inline void disk_stat_set_all(str · line 205
Quoted 10 lines
include/linux/genhd.h +8
-0sizeof (struct disk_stats)); } + +#define __part_stat_add (part, field, addnd) \ + (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) + +#define __all_stat_add (gendiskp, field, addnd, sector) \ +({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ + if (part) __part_stat_add(part, field, addnd); \
if (part) \ __part_stat_add(part, field, addnd); \
Quoted 27 lines
include/linux/genhd.h +20
-1+__disk_stat_add (gendiskp, field, addnd); \ +}) + +#define part_stat_read (part, field) \ +({ \ + typeof(part->dkstats->field) res = 0; \ + int i; \ + for_each_possible_cpu(i) \ + res += per_cpu_ptr(part->dkstats, i)->field; \ + res; \ +}) + +static inline void part_stat_set_all (struct hd_struct *part,int value) { +int i; +for_each_possible_cpu (i) +memset (per_cpu_ptr (part->dkstats, i), value, +sizeof (struct disk_stats )); +}#else #define __disk_stat_add (gendiskp, field, addnd) \ (gendiskp->dkstats.field += addnd)#define disk_stat_read (gendiskp, field) (gendiskp->dkstats.field) -static inline void disk_stat_set_all (struct gendisk *gendiskp,int value) { +static inline void disk_stat_set_all (struct gendisk *gendiskp,int value) +{
include/linux/genhd.h static inline void disk_stat_set_all(str · line 241
Quoted 10 lines
include/linux/genhd.h +8
-0memset (&gendiskp->dkstats, value,sizeof (struct disk_stats )); } + +#define __part_stat_add (part, field, addnd) \ + (part->dkstats.field += addnd) + +#define __all_stat_add (gendiskp, field, addnd, sector) \ +({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ + if (part) part->dkstats.field += addnd; \
if-condition + following statement on separate lines, please.
include/linux/genhd.h static inline void disk_stat_set_all(str · line 254
Quoted 13 lines
include/linux/genhd.h +10
-0+__disk_stat_add (gendiskp, field, addnd); \ +}) + +#define part_stat_read (part, field) (part->dkstats.field) + +static inline void part_stat_set_all (struct hd_struct *part,int value) +{ +memset (&part->dkstats, value,sizeof (struct disk_stats )); +} +#endif #define disk_stat_add (gendiskp, field, addnd) \
---
~Randy