@@ -1034,6 +1034,9 @@ get_next_pebs_record_by_bit(void *base, void *top, int bit)
1034
1034
struct pebs_record_nhm * p = at ;
1035
1035
1036
1036
if (test_bit (bit , (unsigned long * )& p -> status )) {
1037
+ /* PEBS v3 has accurate status bits */
1038
+ if (x86_pmu .intel_cap .pebs_format >= 3 )
1039
+ return at ;
1037
1040
1038
1041
if (p -> status == (1 << bit ))
1039
1042
return at ;
@@ -1055,20 +1058,18 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
1055
1058
{
1056
1059
struct perf_sample_data data ;
1057
1060
struct pt_regs regs ;
1058
- int i ;
1059
1061
void * at = get_next_pebs_record_by_bit (base , top , bit );
1060
1062
1061
1063
if (!intel_pmu_save_and_restart (event ) &&
1062
1064
!(event -> hw .flags & PERF_X86_EVENT_AUTO_RELOAD ))
1063
1065
return ;
1064
1066
1065
- if (count > 1 ) {
1066
- for (i = 0 ; i < count - 1 ; i ++ ) {
1067
- setup_pebs_sample_data (event , iregs , at , & data , & regs );
1068
- perf_event_output (event , & data , & regs );
1069
- at += x86_pmu .pebs_record_size ;
1070
- at = get_next_pebs_record_by_bit (at , top , bit );
1071
- }
1067
+ while (count > 1 ) {
1068
+ setup_pebs_sample_data (event , iregs , at , & data , & regs );
1069
+ perf_event_output (event , & data , & regs );
1070
+ at += x86_pmu .pebs_record_size ;
1071
+ at = get_next_pebs_record_by_bit (at , top , bit );
1072
+ count -- ;
1072
1073
}
1073
1074
1074
1075
setup_pebs_sample_data (event , iregs , at , & data , & regs );
@@ -1124,9 +1125,9 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
1124
1125
struct debug_store * ds = cpuc -> ds ;
1125
1126
struct perf_event * event ;
1126
1127
void * base , * at , * top ;
1127
- int bit ;
1128
1128
short counts [MAX_PEBS_EVENTS ] = {};
1129
1129
short error [MAX_PEBS_EVENTS ] = {};
1130
+ int bit , i ;
1130
1131
1131
1132
if (!x86_pmu .pebs_active )
1132
1133
return ;
@@ -1142,6 +1143,15 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
1142
1143
for (at = base ; at < top ; at += x86_pmu .pebs_record_size ) {
1143
1144
struct pebs_record_nhm * p = at ;
1144
1145
1146
+ /* PEBS v3 has accurate status bits */
1147
+ if (x86_pmu .intel_cap .pebs_format >= 3 ) {
1148
+ for_each_set_bit (bit , (unsigned long * )& p -> status ,
1149
+ MAX_PEBS_EVENTS )
1150
+ counts [bit ]++ ;
1151
+
1152
+ continue ;
1153
+ }
1154
+
1145
1155
bit = find_first_bit ((unsigned long * )& p -> status ,
1146
1156
x86_pmu .max_pebs_events );
1147
1157
if (bit >= x86_pmu .max_pebs_events )
@@ -1171,8 +1181,6 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
1171
1181
pebs_status = p -> status & cpuc -> pebs_enabled ;
1172
1182
pebs_status &= (1ULL << MAX_PEBS_EVENTS ) - 1 ;
1173
1183
if (pebs_status != (1 << bit )) {
1174
- u8 i ;
1175
-
1176
1184
for_each_set_bit (i , (unsigned long * )& pebs_status ,
1177
1185
MAX_PEBS_EVENTS )
1178
1186
error [i ]++ ;
0 commit comments