lkml.org 
[lkml]   [2009]   [May]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 4/5] perf_counter: propagate inheritance failures down the fork() path
    Fail fork() when we fail inheritance for some reason (-ENOMEM most likely).

    LKML-Reference: <new-submission>
    Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
    ---
    kernel/fork.c | 5 ++++-
    kernel/perf_counter.c | 20 ++++++++++++--------
    2 files changed, 16 insertions(+), 9 deletions(-)

    Index: linux-2.6/kernel/fork.c
    ===================================================================
    --- linux-2.6.orig/kernel/fork.c
    +++ linux-2.6/kernel/fork.c
    @@ -983,7 +983,9 @@ static struct task_struct *copy_process(
    goto fork_out;

    rt_mutex_init_task(p);
    - perf_counter_init_task(p);
    + retval = perf_counter_init_task(p);
    + if (retval)
    + goto bad_fork_free;

    #ifdef CONFIG_PROVE_LOCKING
    DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
    @@ -1309,6 +1311,7 @@ bad_fork_cleanup_count:
    put_cred(p->real_cred);
    put_cred(p->cred);
    bad_fork_free:
    + perf_counter_exit_task(p);
    free_task(p);
    fork_out:
    return ERR_PTR(retval);
    Index: linux-2.6/kernel/perf_counter.c
    ===================================================================
    --- linux-2.6.orig/kernel/perf_counter.c
    +++ linux-2.6/kernel/perf_counter.c
    @@ -3434,18 +3434,23 @@ again:
    /*
    * Initialize the perf_counter context in task_struct
    */
    -void perf_counter_init_task(struct task_struct *child)
    +int perf_counter_init_task(struct task_struct *child)
    {
    struct perf_counter_context *child_ctx, *parent_ctx;
    struct perf_counter *counter;
    struct task_struct *parent = current;
    int inherited_all = 1;
    + int ret = 0;

    child->perf_counter_ctxp = NULL;

    mutex_init(&child->perf_counter_mutex);
    INIT_LIST_HEAD(&child->perf_counter_list);

    + parent_ctx = parent->perf_counter_ctxp;
    + if (likely(!parent_ctx || !parent_ctx->nr_counters))
    + return 0;
    +
    /*
    * This is executed from the parent task context, so inherit
    * counters that have been marked for cloning.
    @@ -3454,11 +3459,7 @@ void perf_counter_init_task(struct task_

    child_ctx = kmalloc(sizeof(struct perf_counter_context), GFP_KERNEL);
    if (!child_ctx)
    - return;
    -
    - parent_ctx = parent->perf_counter_ctxp;
    - if (likely(!parent_ctx || !parent_ctx->nr_counters))
    - return;
    + return -ENOMEM;

    __perf_counter_init_context(child_ctx, child);
    child->perf_counter_ctxp = child_ctx;
    @@ -3482,8 +3483,9 @@ void perf_counter_init_task(struct task_
    continue;
    }

    - if (inherit_group(counter, parent,
    - parent_ctx, child, child_ctx)) {
    + ret = inherit_group(counter, parent, parent_ctx,
    + child, child_ctx);
    + if (ret) {
    inherited_all = 0;
    break;
    }
    @@ -3505,6 +3507,8 @@ void perf_counter_init_task(struct task_
    }

    mutex_unlock(&parent_ctx->mutex);
    +
    + return ret;
    }

    static void __cpuinit perf_counter_init_cpu(int cpu)
    --



    \
     
     \ /
      Last update: 2009-05-25 14:51    [W:0.027 / U:29.948 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site