History

perf: Allocate context task_ctx_data for child event

Currently we use perf_event_context::task_ctx_data to save and restore the LBR status when the task is scheduled out and in. We don't allocate it for child contexts, which results in shorter task's LBR stack, because we don't save the history from previous run and start over every time we schedule the task in. I made a test to generate samples with LBR call stack and got higher numbers on bigger chain depths: before: after: LBR call chain: nr: 1 60561 498127 LBR call chain: nr: 2 0 0 LBR call chain: nr: 3 107030 2172 LBR call chain: nr: 4 466685 62758 LBR call chain: nr: 5 2307319 878046 LBR call chain: nr: 6 48713 495218 LBR call chain: nr: 7 1040 4551 LBR call chain: nr: 8 481 172 LBR call chain: nr: 9 878 120 LBR call chain: nr: 10 2377 6698 LBR call chain: nr: 11 28830 151487 LBR call chain: nr: 12 29347 339867 LBR call chain: nr: 13 4 22 LBR call chain: nr: 14 3 53

Jiri Olsa committed 8 years ago

Commit 313ccb91 parent db9fc761 file · +14 −0Browse files

Unified · Split

kernel/events/core.c+14−0
@@ -10703,6 +10703,19 @@ inherit_event(struct perf_event *parent_event, · 10702 unmodified lines
10703 if (IS_ERR(child_event))10703 if (IS_ERR(child_event))
10704 return child_event;10704 return child_event;
10705 10705
10706
10707 if ((child_event->attach_state & PERF_ATTACH_TASK_DATA) &&
10708 !child_ctx->task_ctx_data) {
10709 struct pmu *pmu = child_event->pmu;
10710
10711 child_ctx->task_ctx_data = kzalloc(pmu->task_ctx_size,
10712 GFP_KERNEL);
10713 if (!child_ctx->task_ctx_data) {
10714 free_event(child_event);
10715 return NULL;
10716 }
10717 }
10718
10706 /*10719 /*
10707 * is_orphaned_event() and list_add_tail(&parent_event->child_list)10720 * is_orphaned_event() and list_add_tail(&parent_event->child_list)
10708 * must be under the same lock in order to serialize against10721 * must be under the same lock in order to serialize against
@@ -10713,6 +10726,7 @@ inherit_event(struct perf_event *parent_event, · 4 unmodified lines
10713 if (is_orphaned_event(parent_event) ||10726 if (is_orphaned_event(parent_event) ||
10714 !atomic_long_inc_not_zero(&parent_event->refcount)) {10727 !atomic_long_inc_not_zero(&parent_event->refcount)) {
10715 mutex_unlock(&parent_event->child_mutex);10728 mutex_unlock(&parent_event->child_mutex);
10729 /* task_ctx_data is freed with child_ctx */
10716 free_event(child_event);10730 free_event(child_event);
10717 return NULL;10731 return NULL;
10718 }10732 }