diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-18 06:51:05 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-18 06:51:05 -0500 |
commit | 40874491f9e9a4cb08eaf663dbe018bf5671975a (patch) | |
tree | 0c212477aa6cb994a7c6702b5076748f95a1a118 | |
parent | d680fe44775ed17a80035462d9898f5e77bfd7dd (diff) | |
parent | d072c25f531c6513994960401d2c7f059434c0d2 (diff) |
Merge branches 'tracing/ftrace' and 'tracing/hw-branch-tracing' into tracing/core
-rw-r--r-- | arch/x86/kernel/ds.c | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index dc1e7123ea4e..98d271e60e08 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 | } |
@@ -492,6 +484,9 @@ static int bts_read(struct bts_tracer *tracer, const void *at, | |||
492 | out->qualifier = bts_branch; | 484 | out->qualifier = bts_branch; |
493 | out->variant.lbr.from = bts_get(at, bts_from); | 485 | out->variant.lbr.from = bts_get(at, bts_from); |
494 | out->variant.lbr.to = bts_get(at, bts_to); | 486 | out->variant.lbr.to = bts_get(at, bts_to); |
487 | |||
488 | if (!out->variant.lbr.from && !out->variant.lbr.to) | ||
489 | out->qualifier = bts_invalid; | ||
495 | } | 490 | } |
496 | 491 | ||
497 | return ds_cfg.sizeof_rec[ds_bts]; | 492 | return ds_cfg.sizeof_rec[ds_bts]; |