lkml.org 
[lkml]   [2006]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[Patch] statistics infrastructure - update 10
    From
    Date
    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 <mp3@de.ibm.com>
    ---

    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 majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-07-12 14:31    [W:0.041 / U:90.240 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site