Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac17dc8e authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf_counter: provide major/minor page fault software events



Provide separate sw counters for major and minor page faults.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 7dd1fcc2
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
	}
	if (ret & VM_FAULT_MAJOR) {
		current->maj_flt++;
		perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs);
#ifdef CONFIG_PPC_SMLPAR
		if (firmware_has_feature(FW_FEATURE_CMO)) {
			preempt_disable();
@@ -319,8 +320,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
			preempt_enable();
		}
#endif
	} else
	} else {
		current->min_flt++;
		perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs);
	}
	up_read(&mm->mmap_sem);
	return 0;

+5 −2
Original line number Diff line number Diff line
@@ -1140,10 +1140,13 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
		return;
	}

	if (fault & VM_FAULT_MAJOR)
	if (fault & VM_FAULT_MAJOR) {
		tsk->maj_flt++;
	else
		perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs);
	} else {
		tsk->min_flt++;
		perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs);
	}

	check_v8086_mode(regs, address, tsk);

+3 −1
Original line number Diff line number Diff line
@@ -49,8 +49,10 @@ enum hw_event_types {
	PERF_COUNT_PAGE_FAULTS		= -3,
	PERF_COUNT_CONTEXT_SWITCHES	= -4,
	PERF_COUNT_CPU_MIGRATIONS	= -5,
	PERF_COUNT_PAGE_FAULTS_MIN	= -6,
	PERF_COUNT_PAGE_FAULTS_MAJ	= -7,

	PERF_SW_EVENTS_MIN		= -6,
	PERF_SW_EVENTS_MIN		= -8,
};

/*
+9 −13
Original line number Diff line number Diff line
@@ -1503,6 +1503,12 @@ static void perf_swcounter_disable(struct perf_counter *counter)
	perf_swcounter_update(counter);
}

static const struct hw_perf_counter_ops perf_ops_generic = {
	.enable		= perf_swcounter_enable,
	.disable	= perf_swcounter_disable,
	.read		= perf_swcounter_read,
};

/*
 * Software counter: cpu wall time clock
 */
@@ -1603,16 +1609,6 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = {
	.read		= task_clock_perf_counter_read,
};

/*
 * Software counter: page faults
 */

static const struct hw_perf_counter_ops perf_ops_page_faults = {
	.enable		= perf_swcounter_enable,
	.disable	= perf_swcounter_disable,
	.read		= perf_swcounter_read,
};

/*
 * Software counter: context switches
 */
@@ -1753,9 +1749,9 @@ sw_perf_counter_init(struct perf_counter *counter)
			hw_ops = &perf_ops_cpu_clock;
		break;
	case PERF_COUNT_PAGE_FAULTS:
		if (!(counter->hw_event.exclude_user ||
		      counter->hw_event.exclude_kernel))
			hw_ops = &perf_ops_page_faults;
	case PERF_COUNT_PAGE_FAULTS_MIN:
	case PERF_COUNT_PAGE_FAULTS_MAJ:
		hw_ops = &perf_ops_generic;
		break;
	case PERF_COUNT_CONTEXT_SWITCHES:
		if (!counter->hw_event.exclude_kernel)