diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/Makefile | 1 | ||||
| -rw-r--r-- | kernel/fork.c | 1 | ||||
| -rw-r--r-- | kernel/perf_counter.c | 943 | ||||
| -rw-r--r-- | kernel/sched.c | 24 | ||||
| -rw-r--r-- | kernel/sys_ni.c | 3 |
5 files changed, 972 insertions, 0 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 19fad003b19d..1f184a1dc406 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
| @@ -89,6 +89,7 @@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o | |||
| 89 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ | 89 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ |
| 90 | obj-$(CONFIG_TRACING) += trace/ | 90 | obj-$(CONFIG_TRACING) += trace/ |
| 91 | obj-$(CONFIG_SMP) += sched_cpupri.o | 91 | obj-$(CONFIG_SMP) += sched_cpupri.o |
| 92 | obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o | ||
| 92 | 93 | ||
| 93 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) | 94 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) |
| 94 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is | 95 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is |
diff --git a/kernel/fork.c b/kernel/fork.c index 2a372a0e206f..441fadff1fa4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -975,6 +975,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 975 | goto fork_out; | 975 | goto fork_out; |
| 976 | 976 | ||
| 977 | rt_mutex_init_task(p); | 977 | rt_mutex_init_task(p); |
| 978 | perf_counter_init_task(p); | ||
| 978 | 979 | ||
| 979 | #ifdef CONFIG_PROVE_LOCKING | 980 | #ifdef CONFIG_PROVE_LOCKING |
| 980 | DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); | 981 | DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); |
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c new file mode 100644 index 000000000000..20508f053658 --- /dev/null +++ b/kernel/perf_counter.c | |||
| @@ -0,0 +1,943 @@ | |||
| 1 | /* | ||
| 2 | * Performance counter core code | ||
| 3 | * | ||
| 4 | * Copyright(C) 2008 Thomas Gleixner <tglx@linutronix.de> | ||
| 5 | * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar | ||
| 6 | * | ||
| 7 | * For licencing details see kernel-base/COPYING | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/fs.h> | ||
| 11 | #include <linux/cpu.h> | ||
| 12 | #include <linux/smp.h> | ||
| 13 | #include <linux/poll.h> | ||
| 14 | #include <linux/sysfs.h> | ||
| 15 | #include <linux/ptrace.h> | ||
| 16 | #include <linux/percpu.h> | ||
| 17 | #include <linux/uaccess.h> | ||
| 18 | #include <linux/syscalls.h> | ||
| 19 | #include <linux/anon_inodes.h> | ||
| 20 | #include <linux/perf_counter.h> | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Each CPU has a list of per CPU counters: | ||
| 24 | */ | ||
| 25 | DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); | ||
| 26 | |||
| 27 | int perf_max_counters __read_mostly; | ||
| 28 | static int perf_reserved_percpu __read_mostly; | ||
| 29 | static int perf_overcommit __read_mostly = 1; | ||
| 30 | |||
| 31 | /* | ||
| 32 | * Mutex for (sysadmin-configurable) counter reservations: | ||
| 33 | */ | ||
| 34 | static DEFINE_MUTEX(perf_resource_mutex); | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Architecture provided APIs - weak aliases: | ||
| 38 | */ | ||
| 39 | |||
| 40 | int __weak hw_perf_counter_init(struct perf_counter *counter, u32 hw_event_type) | ||
| 41 | { | ||
| 42 | return -EINVAL; | ||
| 43 | } | ||
| 44 | |||
| 45 | void __weak hw_perf_counter_enable(struct perf_counter *counter) { } | ||
| 46 | void __weak hw_perf_counter_disable(struct perf_counter *counter) { } | ||
| 47 | void __weak hw_perf_counter_read(struct perf_counter *counter) { } | ||
| 48 | void __weak hw_perf_disable_all(void) { } | ||
| 49 | void __weak hw_perf_enable_all(void) { } | ||
| 50 | void __weak hw_perf_counter_setup(void) { } | ||
| 51 | |||
| 52 | #if BITS_PER_LONG == 64 | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Read the cached counter in counter safe against cross CPU / NMI | ||
| 56 | * modifications. 64 bit version - no complications. | ||
| 57 | */ | ||
| 58 | static inline u64 perf_read_counter_safe(struct perf_counter *counter) | ||
| 59 | { | ||
| 60 | return (u64) atomic64_read(&counter->count); | ||
| 61 | } | ||
| 62 | |||
| 63 | #else | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Read the cached counter in counter safe against cross CPU / NMI | ||
| 67 | * modifications. 32 bit version. | ||
| 68 | */ | ||
| 69 | static u64 perf_read_counter_safe(struct perf_counter *counter) | ||
| 70 | { | ||
| 71 | u32 cntl, cnth; | ||
| 72 | |||
| 73 | local_irq_disable(); | ||
| 74 | do { | ||
| 75 | cnth = atomic_read(&counter->count32[1]); | ||
| 76 | cntl = atomic_read(&counter->count32[0]); | ||
| 77 | } while (cnth != atomic_read(&counter->count32[1])); | ||
| 78 | |||
| 79 | local_irq_enable(); | ||
| 80 | |||
| 81 | return cntl | ((u64) cnth) << 32; | ||
| 82 | } | ||
| 83 | |||
| 84 | #endif | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Cross CPU call to remove a performance counter | ||
| 88 | * | ||
| 89 | * We disable the counter on the hardware level first. After that we | ||
| 90 | * remove it from the context list. | ||
| 91 | */ | ||
| 92 | static void __perf_remove_from_context(void *info) | ||
| 93 | { | ||
| 94 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
| 95 | struct perf_counter *counter = info; | ||
| 96 | struct perf_counter_context *ctx = counter->ctx; | ||
| 97 | |||
| 98 | /* | ||
| 99 | * If this is a task context, we need to check whether it is | ||
| 100 | * the current task context of this cpu. If not it has been | ||
| 101 | * scheduled out before the smp call arrived. | ||
| 102 | */ | ||
| 103 | if (ctx->task && cpuctx->task_ctx != ctx) | ||
| 104 | return; | ||
| 105 | |||
| 106 | spin_lock(&ctx->lock); | ||
| 107 | |||
| 108 | if (counter->active) { | ||
| 109 | hw_perf_counter_disable(counter); | ||
| 110 | counter->active = 0; | ||
| 111 | ctx->nr_active--; | ||
| 112 | cpuctx->active_oncpu--; | ||
| 113 | counter->task = NULL; | ||
| 114 | } | ||
| 115 | ctx->nr_counters--; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Protect the list operation against NMI by disabling the | ||
| 119 | * counters on a global level. NOP for non NMI based counters. | ||
| 120 | */ | ||
| 121 | hw_perf_disable_all(); | ||
| 122 | list_del_init(&counter->list); | ||
| 123 | hw_perf_enable_all(); | ||
| 124 | |||
| 125 | if (!ctx->task) { | ||
| 126 | /* | ||
| 127 | * Allow more per task counters with respect to the | ||
| 128 | * reservation: | ||
| 129 | */ | ||
| 130 | cpuctx->max_pertask = | ||
| 131 | min(perf_max_counters - ctx->nr_counters, | ||
| 132 | perf_max_counters - perf_reserved_percpu); | ||
| 133 | } | ||
| 134 | |||
| 135 | spin_unlock(&ctx->lock); | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 139 | /* | ||
| 140 | * Remove the counter from a task's (or a CPU's) list of counters. | ||
| 141 | * | ||
| 142 | * Must be called with counter->mutex held. | ||
| 143 | * | ||
| 144 | * CPU counters are removed with a smp call. For task counters we only | ||
| 145 | * call when the task is on a CPU. | ||
| 146 | */ | ||
| 147 | static void perf_remove_from_context(struct perf_counter *counter) | ||
| 148 | { | ||
| 149 | struct perf_counter_context *ctx = counter->ctx; | ||
| 150 | struct task_struct *task = ctx->task; | ||
| 151 | |||
| 152 | if (!task) { | ||
| 153 | /* | ||
| 154 | * Per cpu counters are removed via an smp call and | ||
| 155 | * the removal is always sucessful. | ||
| 156 | */ | ||
| 157 | smp_call_function_single(counter->cpu, | ||
| 158 | __perf_remove_from_context, | ||
| 159 | counter, 1); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | retry: | ||
| 164 | task_oncpu_function_call(task, __perf_remove_from_context, | ||
| 165 | counter); | ||
| 166 | |||
| 167 | spin_lock_irq(&ctx->lock); | ||
| 168 | /* | ||
| 169 | * If the context is active we need to retry the smp call. | ||
| 170 | */ | ||
| 171 | if (ctx->nr_active && !list_empty(&counter->list)) { | ||
| 172 | spin_unlock_irq(&ctx->lock); | ||
| 173 | goto retry; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* | ||
| 177 | * The lock prevents that this context is scheduled in so we | ||
| 178 | * can remove the counter safely, if it the call above did not | ||
| 179 | * succeed. | ||
| 180 | */ | ||
| 181 | if (!list_empty(&counter->list)) { | ||
| 182 | ctx->nr_counters--; | ||
| 183 | list_del_init(&counter->list); | ||
| 184 | counter->task = NULL; | ||
| 185 | } | ||
| 186 | spin_unlock_irq(&ctx->lock); | ||
| 187 | } | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Cross CPU call to install and enable a preformance counter | ||
| 191 | */ | ||
| 192 | static void __perf_install_in_context(void *info) | ||
| 193 | { | ||
| 194 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
| 195 | struct perf_counter *counter = info; | ||
| 196 | struct perf_counter_context *ctx = counter->ctx; | ||
| 197 | int cpu = smp_processor_id(); | ||
| 198 | |||
| 199 | /* | ||
| 200 | * If this is a task context, we need to check whether it is | ||
| 201 | * the current task context of this cpu. If not it has been | ||
| 202 | * scheduled out before the smp call arrived. | ||
| 203 | */ | ||
| 204 | if (ctx->task && cpuctx->task_ctx != ctx) | ||
| 205 | return; | ||
| 206 | |||
| 207 | spin_lock(&ctx->lock); | ||
| 208 | |||
| 209 | /* | ||
| 210 | * Protect the list operation against NMI by disabling the | ||
| 211 | * counters on a global level. NOP for non NMI based counters. | ||
| 212 | */ | ||
| 213 | hw_perf_disable_all(); | ||
| 214 | list_add_tail(&counter->list, &ctx->counters); | ||
| 215 | hw_perf_enable_all(); | ||
| 216 | |||
| 217 | ctx->nr_counters++; | ||
| 218 | |||
| 219 | if (cpuctx->active_oncpu < perf_max_counters) { | ||
| 220 | hw_perf_counter_enable(counter); | ||
| 221 | counter->active = 1; | ||
| 222 | counter->oncpu = cpu; | ||
| 223 | ctx->nr_active++; | ||
| 224 | cpuctx->active_oncpu++; | ||
| 225 | } | ||
| 226 | |||
| 227 | if (!ctx->task && cpuctx->max_pertask) | ||
| 228 | cpuctx->max_pertask--; | ||
| 229 | |||
| 230 | spin_unlock(&ctx->lock); | ||
| 231 | } | ||
| 232 | |||
| 233 | /* | ||
| 234 | * Attach a performance counter to a context | ||
| 235 | * | ||
| 236 | * First we add the counter to the list with the hardware enable bit | ||
| 237 | * in counter->hw_config cleared. | ||
| 238 | * | ||
| 239 | * If the counter is attached to a task which is on a CPU we use a smp | ||
| 240 | * call to enable it in the task context. The task might have been | ||
| 241 | * scheduled away, but we check this in the smp call again. | ||
| 242 | */ | ||
| 243 | static void | ||
| 244 | perf_install_in_context(struct perf_counter_context *ctx, | ||
| 245 | struct perf_counter *counter, | ||
| 246 | int cpu) | ||
| 247 | { | ||
| 248 | struct task_struct *task = ctx->task; | ||
| 249 | |||
| 250 | counter->ctx = ctx; | ||
| 251 | if (!task) { | ||
| 252 | /* | ||
| 253 | * Per cpu counters are installed via an smp call and | ||
| 254 | * the install is always sucessful. | ||
| 255 | */ | ||
| 256 | smp_call_function_single(cpu, __perf_install_in_context, | ||
| 257 | counter, 1); | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | |||
| 261 | counter->task = task; | ||
| 262 | retry: | ||
| 263 | task_oncpu_function_call(task, __perf_install_in_context, | ||
| 264 | counter); | ||
| 265 | |||
| 266 | spin_lock_irq(&ctx->lock); | ||
| 267 | /* | ||
| 268 | * If the context is active and the counter has not been added | ||
| 269 | * we need to retry the smp call. | ||
| 270 | */ | ||
| 271 | if (ctx->nr_active && list_empty(&counter->list)) { | ||
| 272 | spin_unlock_irq(&ctx->lock); | ||
| 273 | goto retry; | ||
| 274 | } | ||
| 275 | |||
| 276 | /* | ||
| 277 | * The lock prevents that this context is scheduled in so we | ||
| 278 | * can add the counter safely, if it the call above did not | ||
| 279 | * succeed. | ||
| 280 | */ | ||
| 281 | if (list_empty(&counter->list)) { | ||
| 282 | list_add_tail(&counter->list, &ctx->counters); | ||
| 283 | ctx->nr_counters++; | ||
| 284 | } | ||
| 285 | spin_unlock_irq(&ctx->lock); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | ||
| 289 | * Called from scheduler to remove the counters of the current task, | ||
| 290 | * with interrupts disabled. | ||
| 291 | * | ||
| 292 | * We stop each counter and update the counter value in counter->count. | ||
| 293 | * | ||
| 294 | * This does not protect us against NMI, but hw_perf_counter_disable() | ||
| 295 | * sets the disabled bit in the control field of counter _before_ | ||
| 296 | * accessing the counter control register. If a NMI hits, then it will | ||
| 297 | * not restart the counter. | ||
| 298 | */ | ||
| 299 | void perf_counter_task_sched_out(struct task_struct *task, int cpu) | ||
| 300 | { | ||
| 301 | struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
| 302 | struct perf_counter_context *ctx = &task->perf_counter_ctx; | ||
| 303 | struct perf_counter *counter; | ||
| 304 | |||
| 305 | if (likely(!cpuctx->task_ctx)) | ||
| 306 | return; | ||
| 307 | |||
| 308 | spin_lock(&ctx->lock); | ||
| 309 | list_for_each_entry(counter, &ctx->counters, list) { | ||
| 310 | if (!ctx->nr_active) | ||
| 311 | break; | ||
| 312 | if (counter->active) { | ||
| 313 | hw_perf_counter_disable(counter); | ||
| 314 | counter->active = 0; | ||
| 315 | counter->oncpu = -1; | ||
| 316 | ctx->nr_active--; | ||
| 317 | cpuctx->active_oncpu--; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | spin_unlock(&ctx->lock); | ||
| 321 | cpuctx->task_ctx = NULL; | ||
| 322 | } | ||
| 323 | |||
| 324 | /* | ||
| 325 | * Called from scheduler to add the counters of the current task | ||
| 326 | * with interrupts disabled. | ||
| 327 | * | ||
| 328 | * We restore the counter value and then enable it. | ||
| 329 | * | ||
| 330 | * This does not protect us against NMI, but hw_perf_counter_enable() | ||
| 331 | * sets the enabled bit in the control field of counter _before_ | ||
| 332 | * accessing the counter control register. If a NMI hits, then it will | ||
| 333 | * keep the counter running. | ||
| 334 | */ | ||
| 335 | void perf_counter_task_sched_in(struct task_struct *task, int cpu) | ||
| 336 | { | ||
| 337 | struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
| 338 | struct perf_counter_context *ctx = &task->perf_counter_ctx; | ||
| 339 | struct perf_counter *counter; | ||
| 340 | |||
| 341 | if (likely(!ctx->nr_counters)) | ||
| 342 | return; | ||
| 343 | |||
| 344 | spin_lock(&ctx->lock); | ||
| 345 | list_for_each_entry(counter, &ctx->counters, list) { | ||
| 346 | if (ctx->nr_active == cpuctx->max_pertask) | ||
| 347 | break; | ||
| 348 | if (counter->cpu != -1 && counter->cpu != cpu) | ||
| 349 | continue; | ||
| 350 | |||
| 351 | hw_perf_counter_enable(counter); | ||
| 352 | counter->active = 1; | ||
| 353 | counter->oncpu = cpu; | ||
| 354 | ctx->nr_active++; | ||
| 355 | cpuctx->active_oncpu++; | ||
| 356 | } | ||
| 357 | spin_unlock(&ctx->lock); | ||
| 358 | cpuctx->task_ctx = ctx; | ||
| 359 | } | ||
| 360 | |||
| 361 | void perf_counter_task_tick(struct task_struct *curr, int cpu) | ||
| 362 | { | ||
| 363 | struct perf_counter_context *ctx = &curr->perf_counter_ctx; | ||
| 364 | struct perf_counter *counter; | ||
| 365 | |||
| 366 | if (likely(!ctx->nr_counters)) | ||
| 367 | return; | ||
| 368 | |||
| 369 | perf_counter_task_sched_out(curr, cpu); | ||
| 370 | |||
| 371 | spin_lock(&ctx->lock); | ||
| 372 | |||
| 373 | /* | ||
| 374 | * Rotate the first entry last: | ||
| 375 | */ | ||
| 376 | hw_perf_disable_all(); | ||
| 377 | list_for_each_entry(counter, &ctx->counters, list) { | ||
| 378 | list_del(&counter->list); | ||
| 379 | list_add_tail(&counter->list, &ctx->counters); | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | hw_perf_enable_all(); | ||
| 383 | |||
| 384 | spin_unlock(&ctx->lock); | ||
| 385 | |||
| 386 | perf_counter_task_sched_in(curr, cpu); | ||
| 387 | } | ||
| 388 | |||
| 389 | /* | ||
| 390 | * Initialize the perf_counter context in task_struct | ||
| 391 | */ | ||
| 392 | void perf_counter_init_task(struct task_struct *task) | ||
| 393 | { | ||
| 394 | struct perf_counter_context *ctx = &task->perf_counter_ctx; | ||
| 395 | |||
| 396 | spin_lock_init(&ctx->lock); | ||
| 397 | INIT_LIST_HEAD(&ctx->counters); | ||
| 398 | ctx->nr_counters = 0; | ||
| 399 | ctx->task = task; | ||
| 400 | } | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Cross CPU call to read the hardware counter | ||
| 404 | */ | ||
| 405 | static void __hw_perf_counter_read(void *info) | ||
| 406 | { | ||
| 407 | hw_perf_counter_read(info); | ||
| 408 | } | ||
| 409 | |||
| 410 | static u64 perf_read_counter(struct perf_counter *counter) | ||
| 411 | { | ||
| 412 | /* | ||
| 413 | * If counter is enabled and currently active on a CPU, update the | ||
| 414 | * value in the counter structure: | ||
| 415 | */ | ||
| 416 | if (counter->active) { | ||
| 417 | smp_call_function_single(counter->oncpu, | ||
| 418 | __hw_perf_counter_read, counter, 1); | ||
| 419 | } | ||
| 420 | |||
| 421 | return perf_read_counter_safe(counter); | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * Cross CPU call to switch performance data pointers | ||
| 426 | */ | ||
| 427 | static void __perf_switch_irq_data(void *info) | ||
| 428 | { | ||
| 429 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
| 430 | struct perf_counter *counter = info; | ||
| 431 | struct perf_counter_context *ctx = counter->ctx; | ||
| 432 | struct perf_data *oldirqdata = counter->irqdata; | ||
| 433 | |||
| 434 | /* | ||
| 435 | * If this is a task context, we need to check whether it is | ||
| 436 | * the current task context of this cpu. If not it has been | ||
| 437 | * scheduled out before the smp call arrived. | ||
| 438 | */ | ||
| 439 | if (ctx->task) { | ||
| 440 | if (cpuctx->task_ctx != ctx) | ||
| 441 | return; | ||
| 442 | spin_lock(&ctx->lock); | ||
| 443 | } | ||
| 444 | |||
| 445 | /* Change the pointer NMI safe */ | ||
| 446 | atomic_long_set((atomic_long_t *)&counter->irqdata, | ||
| 447 | (unsigned long) counter->usrdata); | ||
| 448 | counter->usrdata = oldirqdata; | ||
| 449 | |||
| 450 | if (ctx->task) | ||
| 451 | spin_unlock(&ctx->lock); | ||
| 452 | } | ||
| 453 | |||
| 454 | static struct perf_data *perf_switch_irq_data(struct perf_counter *counter) | ||
| 455 | { | ||
| 456 | struct perf_counter_context *ctx = counter->ctx; | ||
| 457 | struct perf_data *oldirqdata = counter->irqdata; | ||
| 458 | struct task_struct *task = ctx->task; | ||
| 459 | |||
| 460 | if (!task) { | ||
| 461 | smp_call_function_single(counter->cpu, | ||
| 462 | __perf_switch_irq_data, | ||
| 463 | counter, 1); | ||
| 464 | return counter->usrdata; | ||
| 465 | } | ||
| 466 | |||
| 467 | retry: | ||
| 468 | spin_lock_irq(&ctx->lock); | ||
| 469 | if (!counter->active) { | ||
| 470 | counter->irqdata = counter->usrdata; | ||
| 471 | counter->usrdata = oldirqdata; | ||
| 472 | spin_unlock_irq(&ctx->lock); | ||
| 473 | return oldirqdata; | ||
| 474 | } | ||
| 475 | spin_unlock_irq(&ctx->lock); | ||
| 476 | task_oncpu_function_call(task, __perf_switch_irq_data, counter); | ||
| 477 | /* Might have failed, because task was scheduled out */ | ||
| 478 | if (counter->irqdata == oldirqdata) | ||
| 479 | goto retry; | ||
| 480 | |||
| 481 | return counter->usrdata; | ||
| 482 | } | ||
| 483 | |||
| 484 | static void put_context(struct perf_counter_context *ctx) | ||
| 485 | { | ||
| 486 | if (ctx->task) | ||
| 487 | put_task_struct(ctx->task); | ||
| 488 | } | ||
| 489 | |||
| 490 | static struct perf_counter_context *find_get_context(pid_t pid, int cpu) | ||
| 491 | { | ||
| 492 | struct perf_cpu_context *cpuctx; | ||
| 493 | struct perf_counter_context *ctx; | ||
| 494 | struct task_struct *task; | ||
| 495 | |||
| 496 | /* | ||
| 497 | * If cpu is not a wildcard then this is a percpu counter: | ||
| 498 | */ | ||
| 499 | if (cpu != -1) { | ||
| 500 | /* Must be root to operate on a CPU counter: */ | ||
| 501 | if (!capable(CAP_SYS_ADMIN)) | ||
| 502 | return ERR_PTR(-EACCES); | ||
| 503 | |||
| 504 | if (cpu < 0 || cpu > num_possible_cpus()) | ||
| 505 | return ERR_PTR(-EINVAL); | ||
| 506 | |||
| 507 | /* | ||
| 508 | * We could be clever and allow to attach a counter to an | ||
| 509 | * offline CPU and activate it when the CPU comes up, but | ||
| 510 | * that's for later. | ||
| 511 | */ | ||
| 512 | if (!cpu_isset(cpu, cpu_online_map)) | ||
| 513 | return ERR_PTR(-ENODEV); | ||
| 514 | |||
| 515 | cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
| 516 | ctx = &cpuctx->ctx; | ||
| 517 | |||
| 518 | WARN_ON_ONCE(ctx->task); | ||
| 519 | return ctx; | ||
| 520 | } | ||
| 521 | |||
| 522 | rcu_read_lock(); | ||
| 523 | if (!pid) | ||
| 524 | task = current; | ||
| 525 | else | ||
| 526 | task = find_task_by_vpid(pid); | ||
| 527 | if (task) | ||
| 528 | get_task_struct(task); | ||
| 529 | rcu_read_unlock(); | ||
| 530 | |||
| 531 | if (!task) | ||
| 532 | return ERR_PTR(-ESRCH); | ||
| 533 | |||
| 534 | ctx = &task->perf_counter_ctx; | ||
| 535 | ctx->task = task; | ||
| 536 | |||
| 537 | /* Reuse ptrace permission checks for now. */ | ||
| 538 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) { | ||
| 539 | put_context(ctx); | ||
| 540 | return ERR_PTR(-EACCES); | ||
| 541 | } | ||
| 542 | |||
| 543 | return ctx; | ||
| 544 | } | ||
| 545 | |||
| 546 | /* | ||
| 547 | * Called when the last reference to the file is gone. | ||
| 548 | */ | ||
| 549 | static int perf_release(struct inode *inode, struct file *file) | ||
| 550 | { | ||
| 551 | struct perf_counter *counter = file->private_data; | ||
| 552 | struct perf_counter_context *ctx = counter->ctx; | ||
| 553 | |||
| 554 | file->private_data = NULL; | ||
| 555 | |||
| 556 | mutex_lock(&counter->mutex); | ||
| 557 | |||
| 558 | perf_remove_from_context(counter); | ||
| 559 | put_context(ctx); | ||
| 560 | |||
| 561 | mutex_unlock(&counter->mutex); | ||
| 562 | |||
| 563 | kfree(counter); | ||
| 564 | |||
| 565 | return 0; | ||
| 566 | } | ||
| 567 | |||
| 568 | /* | ||
| 569 | * Read the performance counter - simple non blocking version for now | ||
| 570 | */ | ||
| 571 | static ssize_t | ||
| 572 | perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) | ||
| 573 | { | ||
| 574 | u64 cntval; | ||
| 575 | |||
| 576 | if (count != sizeof(cntval)) | ||
| 577 | return -EINVAL; | ||
| 578 | |||
| 579 | mutex_lock(&counter->mutex); | ||
| 580 | cntval = perf_read_counter(counter); | ||
| 581 | mutex_unlock(&counter->mutex); | ||
| 582 | |||
| 583 | return put_user(cntval, (u64 __user *) buf) ? -EFAULT : sizeof(cntval); | ||
| 584 | } | ||
| 585 | |||
| 586 | static ssize_t | ||
| 587 | perf_copy_usrdata(struct perf_data *usrdata, char __user *buf, size_t count) | ||
| 588 | { | ||
| 589 | if (!usrdata->len) | ||
| 590 | return 0; | ||
| 591 | |||
| 592 | count = min(count, (size_t)usrdata->len); | ||
| 593 | if (copy_to_user(buf, usrdata->data + usrdata->rd_idx, count)) | ||
| 594 | return -EFAULT; | ||
| 595 | |||
| 596 | /* Adjust the counters */ | ||
| 597 | usrdata->len -= count; | ||
| 598 | if (!usrdata->len) | ||
| 599 | usrdata->rd_idx = 0; | ||
| 600 | else | ||
| 601 | usrdata->rd_idx += count; | ||
| 602 | |||
| 603 | return count; | ||
| 604 | } | ||
| 605 | |||
| 606 | static ssize_t | ||
| 607 | perf_read_irq_data(struct perf_counter *counter, | ||
| 608 | char __user *buf, | ||
| 609 | size_t count, | ||
| 610 | int nonblocking) | ||
| 611 | { | ||
| 612 | struct perf_data *irqdata, *usrdata; | ||
| 613 | DECLARE_WAITQUEUE(wait, current); | ||
| 614 | ssize_t res; | ||
| 615 | |||
| 616 | irqdata = counter->irqdata; | ||
| 617 | usrdata = counter->usrdata; | ||
| 618 | |||
| 619 | if (usrdata->len + irqdata->len >= count) | ||
| 620 | goto read_pending; | ||
| 621 | |||
| 622 | if (nonblocking) | ||
| 623 | return -EAGAIN; | ||
| 624 | |||
| 625 | spin_lock_irq(&counter->waitq.lock); | ||
| 626 | __add_wait_queue(&counter->waitq, &wait); | ||
| 627 | for (;;) { | ||
| 628 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 629 | if (usrdata->len + irqdata->len >= count) | ||
| 630 | break; | ||
| 631 | |||
| 632 | if (signal_pending(current)) | ||
| 633 | break; | ||
| 634 | |||
| 635 | spin_unlock_irq(&counter->waitq.lock); | ||
| 636 | schedule(); | ||
| 637 | spin_lock_irq(&counter->waitq.lock); | ||
| 638 | } | ||
| 639 | __remove_wait_queue(&counter->waitq, &wait); | ||
| 640 | __set_current_state(TASK_RUNNING); | ||
| 641 | spin_unlock_irq(&counter->waitq.lock); | ||
| 642 | |||
| 643 | if (usrdata->len + irqdata->len < count) | ||
| 644 | return -ERESTARTSYS; | ||
| 645 | read_pending: | ||
| 646 | mutex_lock(&counter->mutex); | ||
| 647 | |||
| 648 | /* Drain pending data first: */ | ||
| 649 | res = perf_copy_usrdata(usrdata, buf, count); | ||
| 650 | if (res < 0 || res == count) | ||
| 651 | goto out; | ||
| 652 | |||
| 653 | /* Switch irq buffer: */ | ||
| 654 | usrdata = perf_switch_irq_data(counter); | ||
| 655 | if (perf_copy_usrdata(usrdata, buf + res, count - res) < 0) { | ||
| 656 | if (!res) | ||
| 657 | res = -EFAULT; | ||
| 658 | } else { | ||
| 659 | res = count; | ||
| 660 | } | ||
| 661 | out: | ||
| 662 | mutex_unlock(&counter->mutex); | ||
| 663 | |||
| 664 | return res; | ||
| 665 | } | ||
| 666 | |||
| 667 | static ssize_t | ||
| 668 | perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | ||
| 669 | { | ||
| 670 | struct perf_counter *counter = file->private_data; | ||
| 671 | |||
| 672 | switch (counter->record_type) { | ||
| 673 | case PERF_RECORD_SIMPLE: | ||
| 674 | return perf_read_hw(counter, buf, count); | ||
| 675 | |||
| 676 | case PERF_RECORD_IRQ: | ||
| 677 | case PERF_RECORD_GROUP: | ||
| 678 | return perf_read_irq_data(counter, buf, count, | ||
| 679 | file->f_flags & O_NONBLOCK); | ||
| 680 | } | ||
| 681 | return -EINVAL; | ||
| 682 | } | ||
| 683 | |||
| 684 | static unsigned int perf_poll(struct file *file, poll_table *wait) | ||
| 685 | { | ||
| 686 | struct perf_counter *counter = file->private_data; | ||
| 687 | unsigned int events = 0; | ||
| 688 | unsigned long flags; | ||
| 689 | |||
| 690 | poll_wait(file, &counter->waitq, wait); | ||
| 691 | |||
| 692 | spin_lock_irqsave(&counter->waitq.lock, flags); | ||
| 693 | if (counter->usrdata->len || counter->irqdata->len) | ||
| 694 | events |= POLLIN; | ||
| 695 | spin_unlock_irqrestore(&counter->waitq.lock, flags); | ||
| 696 | |||
| 697 | return events; | ||
| 698 | } | ||
| 699 | |||
| 700 | static const struct file_operations perf_fops = { | ||
| 701 | .release = perf_release, | ||
| 702 | .read = perf_read, | ||
| 703 | .poll = perf_poll, | ||
| 704 | }; | ||
| 705 | |||
| 706 | /* | ||
| 707 | * Allocate and initialize a counter structure | ||
| 708 | */ | ||
| 709 | static struct perf_counter * | ||
| 710 | perf_counter_alloc(u32 hw_event_period, int cpu, u32 record_type) | ||
| 711 | { | ||
| 712 | struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); | ||
| 713 | |||
| 714 | if (!counter) | ||
| 715 | return NULL; | ||
| 716 | |||
| 717 | mutex_init(&counter->mutex); | ||
| 718 | INIT_LIST_HEAD(&counter->list); | ||
| 719 | init_waitqueue_head(&counter->waitq); | ||
| 720 | |||
| 721 | counter->irqdata = &counter->data[0]; | ||
| 722 | counter->usrdata = &counter->data[1]; | ||
| 723 | counter->cpu = cpu; | ||
| 724 | counter->record_type = record_type; | ||
| 725 | counter->__irq_period = hw_event_period; | ||
| 726 | counter->wakeup_pending = 0; | ||
| 727 | |||
| 728 | return counter; | ||
| 729 | } | ||
| 730 | |||
| 731 | /** | ||
| 732 | * sys_perf_task_open - open a performance counter associate it to a task | ||
| 733 | * @hw_event_type: event type for monitoring/sampling... | ||
| 734 | * @pid: target pid | ||
| 735 | */ | ||
| 736 | asmlinkage int | ||
| 737 | sys_perf_counter_open(u32 hw_event_type, | ||
| 738 | u32 hw_event_period, | ||
| 739 | u32 record_type, | ||
| 740 | pid_t pid, | ||
| 741 | int cpu) | ||
| 742 | { | ||
| 743 | struct perf_counter_context *ctx; | ||
| 744 | struct perf_counter *counter; | ||
| 745 | int ret; | ||
| 746 | |||
| 747 | ctx = find_get_context(pid, cpu); | ||
| 748 | if (IS_ERR(ctx)) | ||
| 749 | return PTR_ERR(ctx); | ||
| 750 | |||
| 751 | ret = -ENOMEM; | ||
| 752 | counter = perf_counter_alloc(hw_event_period, cpu, record_type); | ||
| 753 | if (!counter) | ||
| 754 | goto err_put_context; | ||
| 755 | |||
| 756 | ret = hw_perf_counter_init(counter, hw_event_type); | ||
| 757 | if (ret) | ||
| 758 | goto err_free_put_context; | ||
| 759 | |||
| 760 | perf_install_in_context(ctx, counter, cpu); | ||
| 761 | |||
| 762 | ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); | ||
| 763 | if (ret < 0) | ||
| 764 | goto err_remove_free_put_context; | ||
| 765 | |||
| 766 | return ret; | ||
| 767 | |||
| 768 | err_remove_free_put_context: | ||
| 769 | mutex_lock(&counter->mutex); | ||
| 770 | perf_remove_from_context(counter); | ||
| 771 | mutex_unlock(&counter->mutex); | ||
| 772 | |||
| 773 | err_free_put_context: | ||
| 774 | kfree(counter); | ||
| 775 | |||
| 776 | err_put_context: | ||
| 777 | put_context(ctx); | ||
| 778 | |||
| 779 | return ret; | ||
| 780 | } | ||
| 781 | |||
| 782 | static void __cpuinit perf_init_cpu(int cpu) | ||
| 783 | { | ||
| 784 | struct perf_cpu_context *ctx; | ||
| 785 | |||
| 786 | ctx = &per_cpu(perf_cpu_context, cpu); | ||
| 787 | spin_lock_init(&ctx->ctx.lock); | ||
| 788 | INIT_LIST_HEAD(&ctx->ctx.counters); | ||
| 789 | |||
| 790 | mutex_lock(&perf_resource_mutex); | ||
| 791 | ctx->max_pertask = perf_max_counters - perf_reserved_percpu; | ||
| 792 | mutex_unlock(&perf_resource_mutex); | ||
| 793 | hw_perf_counter_setup(); | ||
| 794 | } | ||
| 795 | |||
| 796 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 797 | static void __perf_exit_cpu(void *info) | ||
| 798 | { | ||
| 799 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
| 800 | struct perf_counter_context *ctx = &cpuctx->ctx; | ||
| 801 | struct perf_counter *counter, *tmp; | ||
| 802 | |||
| 803 | list_for_each_entry_safe(counter, tmp, &ctx->counters, list) | ||
| 804 | __perf_remove_from_context(counter); | ||
| 805 | |||
| 806 | } | ||
| 807 | static void perf_exit_cpu(int cpu) | ||
| 808 | { | ||
| 809 | smp_call_function_single(cpu, __perf_exit_cpu, NULL, 1); | ||
| 810 | } | ||
| 811 | #else | ||
| 812 | static inline void perf_exit_cpu(int cpu) { } | ||
| 813 | #endif | ||
| 814 | |||
| 815 | static int __cpuinit | ||
| 816 | perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) | ||
| 817 | { | ||
| 818 | unsigned int cpu = (long)hcpu; | ||
| 819 | |||
| 820 | switch (action) { | ||
| 821 | |||
| 822 | case CPU_UP_PREPARE: | ||
| 823 | case CPU_UP_PREPARE_FROZEN: | ||
| 824 | perf_init_cpu(cpu); | ||
| 825 | break; | ||
| 826 | |||
| 827 | case CPU_DOWN_PREPARE: | ||
| 828 | case CPU_DOWN_PREPARE_FROZEN: | ||
| 829 | perf_exit_cpu(cpu); | ||
| 830 | break; | ||
| 831 | |||
| 832 | default: | ||
| 833 | break; | ||
| 834 | } | ||
| 835 | |||
| 836 | return NOTIFY_OK; | ||
| 837 | } | ||
| 838 | |||
| 839 | static struct notifier_block __cpuinitdata perf_cpu_nb = { | ||
| 840 | .notifier_call = perf_cpu_notify, | ||
| 841 | }; | ||
| 842 | |||
| 843 | static int __init perf_counter_init(void) | ||
| 844 | { | ||
| 845 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, | ||
| 846 | (void *)(long)smp_processor_id()); | ||
| 847 | register_cpu_notifier(&perf_cpu_nb); | ||
| 848 | |||
| 849 | return 0; | ||
| 850 | } | ||
| 851 | early_initcall(perf_counter_init); | ||
| 852 | |||
| 853 | static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf) | ||
| 854 | { | ||
| 855 | return sprintf(buf, "%d\n", perf_reserved_percpu); | ||
| 856 | } | ||
| 857 | |||
| 858 | static ssize_t | ||
| 859 | perf_set_reserve_percpu(struct sysdev_class *class, | ||
| 860 | const char *buf, | ||
| 861 | size_t count) | ||
| 862 | { | ||
| 863 | struct perf_cpu_context *cpuctx; | ||
| 864 | unsigned long val; | ||
| 865 | int err, cpu, mpt; | ||
| 866 | |||
| 867 | err = strict_strtoul(buf, 10, &val); | ||
| 868 | if (err) | ||
| 869 | return err; | ||
| 870 | if (val > perf_max_counters) | ||
| 871 | return -EINVAL; | ||
| 872 | |||
| 873 | mutex_lock(&perf_resource_mutex); | ||
| 874 | perf_reserved_percpu = val; | ||
| 875 | for_each_online_cpu(cpu) { | ||
| 876 | cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
| 877 | spin_lock_irq(&cpuctx->ctx.lock); | ||
| 878 | mpt = min(perf_max_counters - cpuctx->ctx.nr_counters, | ||
| 879 | perf_max_counters - perf_reserved_percpu); | ||
| 880 | cpuctx->max_pertask = mpt; | ||
| 881 | spin_unlock_irq(&cpuctx->ctx.lock); | ||
| 882 | } | ||
| 883 | mutex_unlock(&perf_resource_mutex); | ||
| 884 | |||
| 885 | return count; | ||
| 886 | } | ||
| 887 | |||
| 888 | static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf) | ||
| 889 | { | ||
| 890 | return sprintf(buf, "%d\n", perf_overcommit); | ||
| 891 | } | ||
| 892 | |||
| 893 | static ssize_t | ||
| 894 | perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count) | ||
| 895 | { | ||
| 896 | unsigned long val; | ||
| 897 | int err; | ||
| 898 | |||
| 899 | err = strict_strtoul(buf, 10, &val); | ||
| 900 | if (err) | ||
| 901 | return err; | ||
| 902 | if (val > 1) | ||
| 903 | return -EINVAL; | ||
| 904 | |||
| 905 | mutex_lock(&perf_resource_mutex); | ||
| 906 | perf_overcommit = val; | ||
| 907 | mutex_unlock(&perf_resource_mutex); | ||
| 908 | |||
| 909 | return count; | ||
| 910 | } | ||
| 911 | |||
| 912 | static SYSDEV_CLASS_ATTR( | ||
| 913 | reserve_percpu, | ||
| 914 | 0644, | ||
| 915 | perf_show_reserve_percpu, | ||
| 916 | perf_set_reserve_percpu | ||
| 917 | ); | ||
| 918 | |||
| 919 | static SYSDEV_CLASS_ATTR( | ||
| 920 | overcommit, | ||
| 921 | 0644, | ||
| 922 | perf_show_overcommit, | ||
| 923 | perf_set_overcommit | ||
| 924 | ); | ||
| 925 | |||
| 926 | static struct attribute *perfclass_attrs[] = { | ||
| 927 | &attr_reserve_percpu.attr, | ||
| 928 | &attr_overcommit.attr, | ||
| 929 | NULL | ||
| 930 | }; | ||
| 931 | |||
| 932 | static struct attribute_group perfclass_attr_group = { | ||
| 933 | .attrs = perfclass_attrs, | ||
| 934 | .name = "perf_counters", | ||
| 935 | }; | ||
| 936 | |||
| 937 | static int __init perf_counter_sysfs_init(void) | ||
| 938 | { | ||
| 939 | return sysfs_create_group(&cpu_sysdev_class.kset.kobj, | ||
| 940 | &perfclass_attr_group); | ||
| 941 | } | ||
| 942 | device_initcall(perf_counter_sysfs_init); | ||
| 943 | |||
diff --git a/kernel/sched.c b/kernel/sched.c index b7480fb5c3dc..254d56de2548 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -2212,6 +2212,27 @@ static int sched_balance_self(int cpu, int flag) | |||
| 2212 | 2212 | ||
| 2213 | #endif /* CONFIG_SMP */ | 2213 | #endif /* CONFIG_SMP */ |
| 2214 | 2214 | ||
| 2215 | /** | ||
| 2216 | * task_oncpu_function_call - call a function on the cpu on which a task runs | ||
| 2217 | * @p: the task to evaluate | ||
| 2218 | * @func: the function to be called | ||
| 2219 | * @info: the function call argument | ||
| 2220 | * | ||
| 2221 | * Calls the function @func when the task is currently running. This might | ||
| 2222 | * be on the current CPU, which just calls the function directly | ||
| 2223 | */ | ||
| 2224 | void task_oncpu_function_call(struct task_struct *p, | ||
| 2225 | void (*func) (void *info), void *info) | ||
| 2226 | { | ||
| 2227 | int cpu; | ||
| 2228 | |||
| 2229 | preempt_disable(); | ||
| 2230 | cpu = task_cpu(p); | ||
| 2231 | if (task_curr(p)) | ||
| 2232 | smp_call_function_single(cpu, func, info, 1); | ||
| 2233 | preempt_enable(); | ||
| 2234 | } | ||
| 2235 | |||
| 2215 | /*** | 2236 | /*** |
| 2216 | * try_to_wake_up - wake up a thread | 2237 | * try_to_wake_up - wake up a thread |
| 2217 | * @p: the to-be-woken-up thread | 2238 | * @p: the to-be-woken-up thread |
| @@ -2534,6 +2555,7 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, | |||
| 2534 | struct task_struct *next) | 2555 | struct task_struct *next) |
| 2535 | { | 2556 | { |
| 2536 | fire_sched_out_preempt_notifiers(prev, next); | 2557 | fire_sched_out_preempt_notifiers(prev, next); |
| 2558 | perf_counter_task_sched_out(prev, cpu_of(rq)); | ||
| 2537 | prepare_lock_switch(rq, next); | 2559 | prepare_lock_switch(rq, next); |
| 2538 | prepare_arch_switch(next); | 2560 | prepare_arch_switch(next); |
| 2539 | } | 2561 | } |
| @@ -2574,6 +2596,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev) | |||
| 2574 | */ | 2596 | */ |
| 2575 | prev_state = prev->state; | 2597 | prev_state = prev->state; |
| 2576 | finish_arch_switch(prev); | 2598 | finish_arch_switch(prev); |
| 2599 | perf_counter_task_sched_in(current, cpu_of(rq)); | ||
| 2577 | finish_lock_switch(rq, prev); | 2600 | finish_lock_switch(rq, prev); |
| 2578 | #ifdef CONFIG_SMP | 2601 | #ifdef CONFIG_SMP |
| 2579 | if (current->sched_class->post_schedule) | 2602 | if (current->sched_class->post_schedule) |
| @@ -4296,6 +4319,7 @@ void scheduler_tick(void) | |||
| 4296 | rq->idle_at_tick = idle_cpu(cpu); | 4319 | rq->idle_at_tick = idle_cpu(cpu); |
| 4297 | trigger_load_balance(rq, cpu); | 4320 | trigger_load_balance(rq, cpu); |
| 4298 | #endif | 4321 | #endif |
| 4322 | perf_counter_task_tick(curr, cpu); | ||
| 4299 | } | 4323 | } |
| 4300 | 4324 | ||
| 4301 | #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ | 4325 | #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index e14a23281707..4be8bbc7577c 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
| @@ -174,3 +174,6 @@ cond_syscall(compat_sys_timerfd_settime); | |||
| 174 | cond_syscall(compat_sys_timerfd_gettime); | 174 | cond_syscall(compat_sys_timerfd_gettime); |
| 175 | cond_syscall(sys_eventfd); | 175 | cond_syscall(sys_eventfd); |
| 176 | cond_syscall(sys_eventfd2); | 176 | cond_syscall(sys_eventfd2); |
| 177 | |||
| 178 | /* performance counters: */ | ||
| 179 | cond_syscall(sys_perf_counter_open); | ||
