@@ -298,8 +298,8 @@ static int event_function(void *info)
298
298
static void event_function_call (struct perf_event * event , event_f func , void * data )
299
299
{
300
300
struct perf_event_context * ctx = event -> ctx ;
301
- struct perf_cpu_context * cpuctx = this_cpu_ptr (& perf_cpu_context );
302
301
struct task_struct * task = READ_ONCE (ctx -> task ); /* verified in event_function */
302
+ struct perf_cpu_context * cpuctx ;
303
303
struct event_function_struct efs = {
304
304
.event = event ,
305
305
.func = func ,
@@ -327,22 +327,25 @@ static void event_function_call(struct perf_event *event, event_f func, void *da
327
327
if (!task_function_call (task , event_function , & efs ))
328
328
return ;
329
329
330
+ local_irq_disable ();
331
+ cpuctx = this_cpu_ptr (& perf_cpu_context );
330
332
perf_ctx_lock (cpuctx , ctx );
331
333
/*
332
334
* Reload the task pointer, it might have been changed by
333
335
* a concurrent perf_event_context_sched_out().
334
336
*/
335
337
task = ctx -> task ;
336
- if (task == TASK_TOMBSTONE ) {
337
- perf_ctx_unlock (cpuctx , ctx );
338
- return ;
339
- }
338
+ if (task == TASK_TOMBSTONE )
339
+ goto unlock ;
340
340
if (ctx -> is_active ) {
341
341
perf_ctx_unlock (cpuctx , ctx );
342
+ local_irq_enable ();
342
343
goto again ;
343
344
}
344
345
func (event , NULL , ctx , data );
346
+ unlock :
345
347
perf_ctx_unlock (cpuctx , ctx );
348
+ local_irq_enable ();
346
349
}
347
350
348
351
/*
0 commit comments