[Patch] statistics infrastructure - update 10

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



lib/statistics.c didn't compile if CONFIG_SMP wasn't defined,
because struct percpu_data was used without precautions.

lib/statistic.c: In function 'statistic_move_ptr':
lib/statistic.c:182: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_free':
lib/statistic.c:197: error: dereferencing pointer to incomplete type
lib/statistic.c:198: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_alloc':
lib/statistic.c:217: error: invalid application of 'sizeof' to
incomplete
type 'struct percpu_data'
lib/statistic.c:222: error: dereferencing pointer to incomplete type
lib/statistic.c:223: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_reset':
lib/statistic.c:297: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_merge':
lib/statistic.c:309: error: dereferencing pointer to incomplete type
lib/statistic.c: In function '_statistic_hotcpu':
lib/statistic.c:443: error: dereferencing pointer to incomplete type
lib/statistic.c:444: error: dereferencing pointer to incomplete type
lib/statistic.c:449: error: dereferencing pointer to incomplete type
lib/statistic.c:450: error: dereferencing pointer to incomplete type
lib/statistic.c:451: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_counter_inc':
lib/statistic.c:854: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_counter_prod':
lib/statistic.c:862: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_util':
lib/statistic.c:923: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_histogram_lin':
lib/statistic.c:1054: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_histogram_log2':
lib/statistic.c:1061: error: dereferencing pointer to incomplete type
lib/statistic.c: In function 'statistic_add_sparse':
lib/statistic.c:1270: error: dereferencing pointer to incomplete type
make[1]: *** [lib/statistic.o] Error 1
make: *** [lib] Error 2

Signed-off-by: Martin Peschke <[email protected]>
---

 include/linux/statistic.h |    2
 lib/statistic.c           |  146 ++++++++++++++++++++++++++++------------------
 2 files changed, 92 insertions(+), 56 deletions(-)

--- a/include/linux/statistic.h	2006-07-12 13:04:47.000000000 +0200
+++ b/include/linux/statistic.h	2006-07-12 13:07:12.000000000 +0200
@@ -83,7 +83,7 @@
 /* private: */
 	enum statistic_state	 state;
 	enum statistic_type	 type;
-	struct percpu_data	*pdata;
+	void			*data;
 	void			(*add)(struct statistic *, s64, u64);
 	u64			 started;
 	u64			 stopped;
--- a/lib/statistic.c	2006-07-12 13:04:48.000000000 +0200
+++ b/lib/statistic.c	2006-07-12 13:07:14.000000000 +0200
@@ -62,6 +62,13 @@
 #include <asm/bug.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_SMP
+#define statistic_ptr(stat, cpu) \
+	((struct percpu_data*)((stat)->data))->ptrs[(cpu)]
+#else
+#define statistic_ptr(stat, cpu) (stat)->data
+#endif
+
 struct statistic_file_private {
 	struct list_head read_seg_lh;
 	struct list_head write_seg_lh;
@@ -179,56 +186,87 @@
 	unsigned long flags;
 	if (src) {
 		local_irq_save(flags);
-		disc->merge(stat, stat->pdata->ptrs[smp_processor_id()], src);
+		disc->merge(stat, statistic_ptr(stat, smp_processor_id()), src);
 		local_irq_restore(flags);
 	}
 }
 
-static int statistic_free(struct statistic *stat, struct statistic_info *info)
+static void statistic_free_1(struct statistic *stat)
+{
+	statistic_free_ptr(stat, stat->data);
+	stat->data = NULL;
+}
+
+#ifdef CONFIG_SMP
+static void statistic_free_n(struct statistic *stat)
 {
 	int cpu;
-	stat->state = STATISTIC_STATE_RELEASED;
-	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR)) {
-		statistic_free_ptr(stat, stat->pdata);
-		stat->pdata = NULL;
-		return 0;
-	}
 	for_each_possible_cpu(cpu) {
-		statistic_free_ptr(stat, stat->pdata->ptrs[cpu]);
-		stat->pdata->ptrs[cpu] = NULL;
+		statistic_free_ptr(stat, statistic_ptr(stat, cpu));
+		statistic_ptr(stat, cpu) = NULL;
 	}
-	kfree(stat->pdata);
-	stat->pdata = NULL;
+	kfree(stat->data);
+	stat->data = NULL;
+}
+#endif
+
+static int statistic_free(struct statistic *stat, struct statistic_info *info)
+{
+#ifdef CONFIG_SMP
+	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR))
+		statistic_free_1(stat);
+	else
+		statistic_free_n(stat);
+#else
+	statistic_free_1(stat);
+#endif
+	stat->state = STATISTIC_STATE_RELEASED;
 	return 0;
 }
 
-static int statistic_alloc(struct statistic *stat,
-			   struct statistic_info *info)
+static int statistic_alloc_1(struct statistic *stat)
 {
-	int cpu, node;
+	stat->data = statistic_alloc_ptr(stat, -1);
+	return (likely(stat->data) ? 0 : -ENOMEM);
+}
 
-	stat->age = timestamp_clock();
-	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR)) {
-		stat->pdata = statistic_alloc_ptr(stat, -1);
-		if (unlikely(!stat->pdata))
-			return -ENOMEM;
-		stat->state = STATISTIC_STATE_OFF;
-		return 0;
-	}
-	stat->pdata = kzalloc(sizeof(struct percpu_data), GFP_KERNEL);
-	if (unlikely(!stat->pdata))
+#ifdef CONFIG_SMP
+static int statistic_alloc_n(struct statistic *stat)
+{
+	int cpu, node;
+	stat->data = kzalloc(sizeof(struct percpu_data), GFP_KERNEL);
+	if (unlikely(!stat->data))
 		return -ENOMEM;
 	for_each_online_cpu(cpu) {
 		node = cpu_to_node(cpu);
-		stat->pdata->ptrs[cpu] = statistic_alloc_ptr(stat, node);
-		if (unlikely(!stat->pdata->ptrs[cpu])) {
-			statistic_free(stat, info);
+		statistic_ptr(stat, cpu) = statistic_alloc_ptr(stat, node);
+		if (unlikely(!statistic_ptr(stat, cpu)))
 			return -ENOMEM;
-		}
 	}
-	stat->state = STATISTIC_STATE_OFF;
 	return 0;
 }
+#endif
+
+static int statistic_alloc(struct statistic *stat,
+			   struct statistic_info *info)
+{
+	int retval;
+#ifdef CONFIG_SMP
+	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR))
+		retval = statistic_alloc_1(stat);
+	else
+		retval = statistic_alloc_n(stat);
+#else
+	retval = statistic_alloc_1(stat);
+#endif
+	if (likely(!retval)) {
+		stat->state = STATISTIC_STATE_OFF;
+		stat->age = timestamp_clock();
+	} else
+		statistic_free(stat, info);
+	return retval;
+
+}
 
 static int statistic_start(struct statistic *stat)
 {
@@ -292,10 +330,10 @@
 		return 0;
 	statistic_transition(stat, info, STATISTIC_STATE_OFF);
 	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR))
-		statistic_reset_ptr(stat, stat->pdata);
+		statistic_reset_ptr(stat, stat->data);
 	else
 		for_each_possible_cpu(cpu)
-			statistic_reset_ptr(stat, stat->pdata->ptrs[cpu]);
+			statistic_reset_ptr(stat, statistic_ptr(stat, cpu));
 	stat->age = timestamp_clock();
 	statistic_transition(stat, info, prev_state);
 	return 0;
@@ -307,7 +345,7 @@
 	struct statistic *stat = mpriv->stat;
 	struct statistic_discipline *disc = &statistic_discs[stat->type];
 	spin_lock(&mpriv->lock);
-	disc->merge(stat, mpriv->dst, stat->pdata->ptrs[smp_processor_id()]);
+	disc->merge(stat, mpriv->dst, statistic_ptr(stat, smp_processor_id()));
 	spin_unlock(&mpriv->lock);
 }
 
@@ -414,7 +452,7 @@
 	if (unlikely(stat->state < STATISTIC_STATE_OFF))
 		return 0;
 	if (unlikely(info->flags & STATISTIC_FLAGS_NOINCR))
-		return disc->fdata(stat, info->name, fpriv, stat->pdata);
+		return disc->fdata(stat, info->name, fpriv, stat->data);
 	mpriv.dst = statistic_alloc_ptr(stat, -1);
 	if (unlikely(!mpriv.dst))
 		return -ENOMEM;
@@ -441,15 +479,15 @@
 		return NOTIFY_OK;
 	switch (action) {
 	case CPU_UP_PREPARE:
-		stat->pdata->ptrs[cpu] = statistic_alloc_ptr(stat, node);
-		if (!stat->pdata->ptrs[cpu])
+		statistic_ptr(stat, cpu) = statistic_alloc_ptr(stat, node);
+		if (!statistic_ptr(stat, cpu))
 			return NOTIFY_BAD;
 		break;
 	case CPU_UP_CANCELED:
 	case CPU_DEAD:
-		statistic_move_ptr(stat, stat->pdata->ptrs[cpu]);
-		statistic_free_ptr(stat, stat->pdata->ptrs[cpu]);
-		stat->pdata->ptrs[cpu] = NULL;
+		statistic_move_ptr(stat, statistic_ptr(stat, cpu));
+		statistic_free_ptr(stat, statistic_ptr(stat, cpu));
+		statistic_ptr(stat, cpu) = NULL;
 		break;
 	}
 	return NOTIFY_OK;
@@ -852,7 +890,7 @@
 
 void statistic_add_counter_inc(struct statistic *stat, s64 value, u64 incr)
 {
-	*(u64*)stat->pdata->ptrs[smp_processor_id()] += incr;
+	*(u64*)statistic_ptr(stat, smp_processor_id()) += incr;
 }
 EXPORT_SYMBOL_GPL(statistic_add_counter_inc);
 
@@ -860,14 +898,14 @@
 {
 	if (unlikely(value < 0))
 		value = -value;
-	*(u64*)stat->pdata->ptrs[smp_processor_id()] += value * incr;
+	*(u64*)statistic_ptr(stat, smp_processor_id()) += value * incr;
 }
 EXPORT_SYMBOL_GPL(statistic_add_counter_prod);
 
 static void statistic_set_counter_inc(struct statistic *stat,
 				      s64 value, u64 total)
 {
-	*(u64*)stat->pdata = total;
+	*(u64*)stat->data = total;
 }
 
 static void statistic_set_counter_prod(struct statistic *stat,
@@ -875,7 +913,7 @@
 {
 	if (unlikely(value < 0))
 		value = -value;
-	*(u64*)stat->pdata = value * total;
+	*(u64*)stat->data = value * total;
 }
 
 static void statistic_merge_counter(struct statistic *stat,
@@ -920,8 +958,8 @@
 
 void statistic_add_util(struct statistic *stat, s64 value, u64 incr)
 {
-	int cpu = smp_processor_id();
-	struct statistic_entry_util *util = stat->pdata->ptrs[cpu];
+	struct statistic_entry_util *util;
+	util = statistic_ptr(stat, smp_processor_id());
 	util->num += incr;
 	util->acc += value * incr;
 	util->sqr += value * value * incr;
@@ -934,8 +972,7 @@
 
 static void statistic_set_util(struct statistic *stat, s64 value, u64 total)
 {
-	struct statistic_entry_util *util;
-	util = (struct statistic_entry_util *) stat->pdata;
+	struct statistic_entry_util *util = stat->data;
 	util->num = total;
 	util->acc = value * total;
 	util->sqr = value * value * total;
@@ -1052,14 +1089,14 @@
 void statistic_add_histogram_lin(struct statistic *stat, s64 value, u64 incr)
 {
 	int i = statistic_histogram_calc_index_lin(stat, value);
-	((u64*)stat->pdata->ptrs[smp_processor_id()])[i] += incr;
+	((u64*)statistic_ptr(stat, smp_processor_id()))[i] += incr;
 }
 EXPORT_SYMBOL_GPL(statistic_add_histogram_lin);
 
 void statistic_add_histogram_log2(struct statistic *stat, s64 value, u64 incr)
 {
 	int i = statistic_histogram_calc_index_log2(stat, value);
-	((u64*)stat->pdata->ptrs[smp_processor_id()])[i] += incr;
+	((u64*)statistic_ptr(stat, smp_processor_id()))[i] += incr;
 }
 EXPORT_SYMBOL_GPL(statistic_add_histogram_log2);
 
@@ -1067,14 +1104,14 @@
 					s64 value, u64 total)
 {
 	int i = statistic_histogram_calc_index_lin(stat, value);
-	((u64*)stat->pdata)[i] = total;
+	((u64*)stat->data)[i] = total;
 }
 
 static void statistic_set_histogram_log2(struct statistic *stat,
 					 s64 value, u64 total)
 {
 	int i = statistic_histogram_calc_index_log2(stat, value);
-	((u64*)stat->pdata)[i] = total;
+	((u64*)stat->data)[i] = total;
 }
 
 static void statistic_merge_histogram(struct statistic *stat,
@@ -1267,16 +1304,15 @@
 
 void statistic_add_sparse(struct statistic *stat, s64 value, u64 incr)
 {
-	int cpu = smp_processor_id();
-	struct statistic_sparse_list *slist = stat->pdata->ptrs[cpu];
+	struct statistic_sparse_list *slist;
+	slist = statistic_ptr(stat, smp_processor_id());
 	_statistic_add_sparse(slist, value, incr);
 }
 EXPORT_SYMBOL_GPL(statistic_add_sparse);
 
 static void statistic_set_sparse(struct statistic *stat, s64 value, u64 total)
 {
-	struct statistic_sparse_list *slist = (struct statistic_sparse_list *)
-						stat->pdata;
+	struct statistic_sparse_list *slist = stat->data;
 	struct list_head *head = &slist->entry_lh;
 	struct statistic_entry_sparse *entry;
 



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux