Skip to content

Commit 57ad0d4

Browse files
Thomas RichterVasily Gorbik
authored andcommitted
s390/cpum_sf: Cap sampling rate to prevent lsctl exception
commit fcc43a7 ("s390/configs: Set HZ=1000") changed the interrupt frequency of the system. On machines with heavy load and many perf event overflows, this might lead to an exception. Dmesg displays these entries: [112.242542] cpum_sf: Loading sampling controls failed: op 1 err -22 One line per CPU online. The root cause is the CPU Measurement sampling facility overflow adjustment. Whenever an overflow (too much samples per tick) occurs, the sampling rate is adjusted and increased. This was done without observing the maximum sampling rate limit. When the current sampling interval is higher than the maximum sampling rate limit, the lsctl instruction raises an exception. The error messages is the result of such an exception. Observe the upper limit when the new sampling rate is recalculated. Cc: stable@vger.kernel.org Fixes: 39d4a50 ("s390/cpum_sf: Adjust sampling interval to avoid hitting sample limits") Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 598bbef commit 57ad0d4

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

arch/s390/kernel/perf_cpum_sf.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,7 @@ static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt,
11681168
static void hw_perf_event_update(struct perf_event *event, int flush_all)
11691169
{
11701170
unsigned long long event_overflow, sampl_overflow, num_sdb;
1171+
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
11711172
struct hw_perf_event *hwc = &event->hw;
11721173
union hws_trailer_header prev, new;
11731174
struct hws_trailer_entry *te;
@@ -1247,8 +1248,11 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
12471248
* are dropped.
12481249
* Slightly increase the interval to avoid hitting this limit.
12491250
*/
1250-
if (event_overflow)
1251+
if (event_overflow) {
12511252
SAMPL_RATE(hwc) += DIV_ROUND_UP(SAMPL_RATE(hwc), 10);
1253+
if (SAMPL_RATE(hwc) > cpuhw->qsi.max_sampl_rate)
1254+
SAMPL_RATE(hwc) = cpuhw->qsi.max_sampl_rate;
1255+
}
12521256
}
12531257

12541258
static inline unsigned long aux_sdb_index(struct aux_buffer *aux,

0 commit comments

Comments
 (0)