diff options
author | David S. Miller <davem@davemloft.net> | 2008-11-20 16:44:00 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-20 16:44:00 -0800 |
commit | 6ab33d51713d6d60c7677c0d020910a8cb37e513 (patch) | |
tree | 546c2ff099b2757e75cf34ddace874f1220f740e /arch/x86/kernel/ds.c | |
parent | 7be6065b39c3f1cfa796667eac1a2170465acc91 (diff) | |
parent | 13d428afc007fcfcd6deeb215618f54cf9c0cae6 (diff) | |
download | lwn-6ab33d51713d6d60c7677c0d020910a8cb37e513.tar.gz lwn-6ab33d51713d6d60c7677c0d020910a8cb37e513.zip |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/ixgbe/ixgbe_main.c
include/net/mac80211.h
net/phonet/af_phonet.c
Diffstat (limited to 'arch/x86/kernel/ds.c')
-rw-r--r-- | arch/x86/kernel/ds.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 2b69994fd3a8..d1a121443bde 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c @@ -236,17 +236,33 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task) struct ds_context *context = *p_context; if (!context) { + spin_unlock(&ds_lock); + context = kzalloc(sizeof(*context), GFP_KERNEL); - if (!context) + if (!context) { + spin_lock(&ds_lock); return NULL; + } context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); if (!context->ds) { kfree(context); + spin_lock(&ds_lock); return NULL; } + spin_lock(&ds_lock); + /* + * Check for race - another CPU could have allocated + * it meanwhile: + */ + if (*p_context) { + kfree(context->ds); + kfree(context); + return *p_context; + } + *p_context = context; context->this = p_context; @@ -384,14 +400,15 @@ static int ds_request(struct task_struct *task, void *base, size_t size, spin_lock(&ds_lock); - if (!check_tracer(task)) - return -EPERM; - error = -ENOMEM; context = ds_alloc_context(task); if (!context) goto out_unlock; + error = -EPERM; + if (!check_tracer(task)) + goto out_unlock; + error = -EALREADY; if (context->owner[qual] == current) goto out_unlock; |