lkml.org 
[lkml]   [2011]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [perf] overflow/perf_count_sw_cpu_clock crashes recent kernels
Hello

> With 3.0.0 the PAPI "overflow_allcounters" test reliably locks up my
> Nehalem system.

I finally managed to narrow this down to a small test, which is attached.

Basically measuring overflow on the perf::perf_count_sw_cpu_clock
event will potentially *lock up* your system from user-space.

This seems to be a long standing bug. It will quickly lock solid
my Nehalem test box on 3.0, 2.6.39 and 2.6.38.

On a Core2 2.6.32 box the crash testing program will wedge and become
unkillable, but it doesn't actually kill the machine.

As mentioned before, on the Nehalem machine the following warning happens
before the machine becomes unusable:

[ 392.504845] ------------[ cut here ]------------
[ 392.504962] WARNING: at kernel/smp.c:320 smp_call_function_single+0x6c/0xf2()
[ 392.505074] Hardware name: Precision M4500
[ 392.505181] Modules linked in: acpi_cpufreq cpufreq_conservative mperf cpufreq_powersave cpufreq_userspace cpufreq_stats uinput nouveau snd_hda_codec_hdmi ttm drm_kms_helper mxm_wmi snd_hda_codec_idt iwlagn mac80211 snd_hda_intel snd_hda_codec cfg80211 dell_laptop snd_hwdep video processor ehci_hcd dell_wmi sparse_keymap psmouse sdhci_pci rfkill snd_pcm sdhci thermal_sys pcspkr ac battery wmi serio_raw snd_timer snd_page_alloc evdev i2c_i801 dcdbas button
[ 392.509709] Pid: 2310, comm: overflow_allcou Not tainted 3.0.0 #43
[ 392.509819] Call Trace:
[ 392.509925] <IRQ> [<ffffffff81041bb0>] ? warn_slowpath_common+0x78/0x8c
[ 392.510144] [<ffffffff810a4d19>] ? perf_exclude_event.part.23+0x31/0x31
[ 392.510257] [<ffffffff8106b7c5>] ? smp_call_function_single+0x6c/0xf2
[ 392.510369] [<ffffffff810a38aa>] ? task_function_call+0x42/0x4c
[ 392.510476] [<ffffffff810a50e4>] ? update_cgrp_time_from_event+0x2c/0x2c
[ 392.510589] [<ffffffff810a5a9d>] ? perf_event_disable+0x45/0x8c
[ 392.510700] [<ffffffff810a8e89>] ? __perf_event_overflow+0xf1/0x1a3
[ 392.510812] [<ffffffff8103c7bb>] ? select_task_rq_fair+0x349/0x574
[ 392.510924] [<ffffffff810a7f0a>] ? perf_ctx_adjust_freq+0x42/0xe6
[ 392.511038] [<ffffffff8105f152>] ? sched_clock_cpu+0xb/0xc3
[ 392.511152] [<ffffffff8100ded5>] ? paravirt_read_tsc+0x5/0x8
[ 392.511262] [<ffffffff8100e320>] ? native_sched_clock+0x27/0x2f
[ 392.511366] [<ffffffff810a9500>] ? perf_event_overflow+0x10/0x10
[ 392.511476] [<ffffffff810a959f>] ? perf_swevent_hrtimer+0x9f/0xda
[ 392.511599] [<ffffffff8105ca04>] ? run_posix_cpu_timers+0x23/0x346
[ 392.511721] [<ffffffff8131c2ef>] ? rb_insert_color+0xb1/0xd9
[ 392.511841] [<ffffffff8105d373>] ? __run_hrtimer+0xac/0x135
[ 392.511960] [<ffffffff8105daa3>] ? hrtimer_interrupt+0xdb/0x195
[ 392.512083] [<ffffffff8108d040>] ? check_for_new_grace_period.isra.32+0x99/0xa4
[ 392.512220] [<ffffffff8108d201>] ? __rcu_process_callbacks+0x72/0x2b7
[ 392.512345] [<ffffffff8102437c>] ? hpet_interrupt_handler+0x23/0x2b
[ 392.512469] [<ffffffff81089446>] ? handle_irq_event_percpu+0x50/0x180
[ 392.512592] [<ffffffff81046f76>] ? __do_softirq+0x13e/0x177
[ 392.512713] [<ffffffff810f680c>] ? send_sigio+0x95/0xab
[ 392.512832] [<ffffffff810895aa>] ? handle_irq_event+0x34/0x52
[ 392.512952] [<ffffffff8108b433>] ? handle_edge_irq+0x9f/0xc6
[ 392.513072] [<ffffffff8100a831>] ? handle_irq+0x1d/0x21
[ 392.513192] [<ffffffff8100a561>] ? do_IRQ+0x42/0x98
[ 392.513314] [<ffffffff81593053>] ? common_interrupt+0x13/0x13
[ 392.513438] <EOI>
[ 392.513542] ---[ end trace 12f3f913316a2866 ]---

Thanks,

Vince
/* Error with overflows and perf::perf_count_sw_cpu_clock */
/* This test will crash Linux 3.0.0 */
/* compile with gcc -O2 -o oflo_sw_cpu_clock_crash oflo_sw_cpu_clock_crash.c */

/* by Vince Weaver <vweaver1 _at_ eecs.utk.edu> */

#define _GNU_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>


#include <linux/perf_event.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/ioctl.h>

#include <sys/mman.h>

#include <signal.h>


#include <sys/prctl.h>

#define MATRIX_SIZE 512
static double a[MATRIX_SIZE][MATRIX_SIZE];
static double b[MATRIX_SIZE][MATRIX_SIZE];
static double c[MATRIX_SIZE][MATRIX_SIZE];

static void naive_matrix_multiply(int quiet) {

double s;
int i,j,k;

for(i=0;i<MATRIX_SIZE;i++) {
for(j=0;j<MATRIX_SIZE;j++) {
a[i][j]=(double)i*(double)j;
b[i][j]=(double)i/(double)(j+5);
}
}

for(j=0;j<MATRIX_SIZE;j++) {
for(i=0;i<MATRIX_SIZE;i++) {
s=0;
for(k=0;k<MATRIX_SIZE;k++) {
s+=a[i][k]*b[k][j];
}
c[i][j] = s;
}
}

s=0.0;
for(i=0;i<MATRIX_SIZE;i++) {
for(j=0;j<MATRIX_SIZE;j++) {
s+=c[i][j];
}
}

if (!quiet) printf("Matrix multiply sum: s=%lf\n",s);

return;
}


static int total=0;

void our_handler(int signum,siginfo_t *oh, void *blah) {

int fd=oh->si_fd;

ioctl(fd , PERF_EVENT_IOC_DISABLE,0);
total++;
ioctl(fd , PERF_EVENT_IOC_REFRESH,1);
}

int perf_event_open(struct perf_event_attr *hw_event_uptr,
pid_t pid, int cpu, int group_fd, unsigned long flags) {

return syscall(__NR_perf_event_open,hw_event_uptr,pid,cpu,group_fd,flags);

}

int main( int argc, char **argv ) {

int fd;
void *blargh;

struct perf_event_attr pe;

struct sigaction sa;

memset(&sa, 0, sizeof(struct sigaction));
sa.sa_sigaction=our_handler;
sa.sa_flags=SA_SIGINFO;

if (sigaction(SIGIO,&sa,NULL)<0) {
fprintf(stderr,"Error setting up signal handler\n");
exit(1);
}

memset(&pe,0,sizeof(struct perf_event_attr));
pe.type=PERF_TYPE_SOFTWARE;
pe.size=sizeof(struct perf_event_attr);
pe.config=PERF_COUNT_SW_CPU_CLOCK;
pe.sample_period=100000;
pe.sample_type=PERF_SAMPLE_IP;
pe.read_format=PERF_FORMAT_GROUP|PERF_FORMAT_ID;
pe.disabled=1;
pe.pinned=1;
pe.exclude_kernel=1;
pe.exclude_hv=1;
pe.wakeup_events=1;

fd=perf_event_open(&pe,0,-1,-1,0);
if (fd<0) {
printf("Error opening\n");
}

blargh=mmap(NULL,(1+2)*4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
fcntl(fd,F_SETFL,O_RDWR|O_NONBLOCK|O_ASYNC);
fcntl(fd,F_SETSIG,SIGIO);
fcntl(fd,F_SETOWN,getpid());

ioctl(fd,PERF_EVENT_IOC_RESET,0);
ioctl(fd,PERF_EVENT_IOC_ENABLE,0);

naive_matrix_multiply(0);

ioctl(fd,PERF_EVENT_IOC_DISABLE,0);
munmap(blargh,(1+2)*4096);
close(fd);

printf("Total overflows: %d\n",total);

return 0;
}
\
 
 \ /
  Last update: 2011-07-27 20:55    [W:0.066 / U:0.792 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site