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]; |
