diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2008-12-16 09:51:03 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-16 12:27:25 -0500 |
commit | cc1dc6d039ced64c2f8b8457bf1cccf4ecfc5942 (patch) | |
tree | ac0d3ce93bce552911cd0b4300775538daca2a45 /arch/x86/kernel | |
parent | 9dfc3bc7d21864d47797d64b8d531d4dbbc0b618 (diff) |
x86, bts: remove recursion from get_context
Impact: cleanup
Optimistically allocate a DS context. It is extremely unlikely that
one already existed. This simplifies the code a lot.
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/ds.c | 58 |
1 files changed, 25 insertions, 33 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index dc1e7123ea4e..0dc795951d73 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
@@ -232,53 +232,45 @@ static DEFINE_PER_CPU(struct ds_context *, system_context_array); | |||
232 | 232 | ||
233 | #define system_context per_cpu(system_context_array, smp_processor_id()) | 233 | #define system_context per_cpu(system_context_array, smp_processor_id()) |
234 | 234 | ||
235 | static struct ds_context *ds_get_context(struct task_struct *task) | 235 | |
236 | static inline struct ds_context *ds_get_context(struct task_struct *task) | ||
236 | { | 237 | { |
237 | struct ds_context **p_context = | 238 | struct ds_context **p_context = |
238 | (task ? &task->thread.ds_ctx : &system_context); | 239 | (task ? &task->thread.ds_ctx : &system_context); |
239 | struct ds_context *context = *p_context; | 240 | struct ds_context *context = NULL; |
241 | struct ds_context *new_context = NULL; | ||
240 | unsigned long irq; | 242 | unsigned long irq; |
241 | 243 | ||
242 | if (!context) { | 244 | /* Chances are small that we already have a context. */ |
243 | context = kzalloc(sizeof(*context), GFP_KERNEL); | 245 | new_context = kzalloc(sizeof(*new_context), GFP_KERNEL); |
244 | if (!context) | 246 | if (!new_context) |
245 | return NULL; | 247 | return NULL; |
246 | |||
247 | spin_lock_irqsave(&ds_lock, irq); | ||
248 | |||
249 | if (*p_context) { | ||
250 | kfree(context); | ||
251 | 248 | ||
252 | context = *p_context; | 249 | spin_lock_irqsave(&ds_lock, irq); |
253 | } else { | ||
254 | *p_context = context; | ||
255 | 250 | ||
256 | context->this = p_context; | 251 | context = *p_context; |
257 | context->task = task; | 252 | if (!context) { |
253 | context = new_context; | ||
258 | 254 | ||
259 | if (task) | 255 | context->this = p_context; |
260 | set_tsk_thread_flag(task, TIF_DS_AREA_MSR); | 256 | context->task = task; |
257 | context->count = 0; | ||
261 | 258 | ||
262 | if (!task || (task == current)) | 259 | if (task) |
263 | wrmsrl(MSR_IA32_DS_AREA, | 260 | set_tsk_thread_flag(task, TIF_DS_AREA_MSR); |
264 | (unsigned long)context->ds); | ||
265 | } | ||
266 | 261 | ||
267 | context->count++; | 262 | if (!task || (task == current)) |
263 | wrmsrl(MSR_IA32_DS_AREA, (unsigned long)context->ds); | ||
268 | 264 | ||
269 | spin_unlock_irqrestore(&ds_lock, irq); | 265 | *p_context = context; |
270 | } else { | 266 | } |
271 | spin_lock_irqsave(&ds_lock, irq); | ||
272 | 267 | ||
273 | context = *p_context; | 268 | context->count++; |
274 | if (context) | ||
275 | context->count++; | ||
276 | 269 | ||
277 | spin_unlock_irqrestore(&ds_lock, irq); | 270 | spin_unlock_irqrestore(&ds_lock, irq); |
278 | 271 | ||
279 | if (!context) | 272 | if (context != new_context) |
280 | context = ds_get_context(task); | 273 | kfree(new_context); |
281 | } | ||
282 | 274 | ||
283 | return context; | 275 | return context; |
284 | } | 276 | } |