diff options
463 files changed, 8360 insertions, 3829 deletions
@@ -3554,12 +3554,12 @@ E: cvance@nai.com | |||
3554 | D: portions of the Linux Security Module (LSM) framework and security modules | 3554 | D: portions of the Linux Security Module (LSM) framework and security modules |
3555 | 3555 | ||
3556 | N: Petr Vandrovec | 3556 | N: Petr Vandrovec |
3557 | E: vandrove@vc.cvut.cz | 3557 | E: petr@vandrovec.name |
3558 | D: Small contributions to ncpfs | 3558 | D: Small contributions to ncpfs |
3559 | D: Matrox framebuffer driver | 3559 | D: Matrox framebuffer driver |
3560 | S: Chudenicka 8 | 3560 | S: 21513 Conradia Ct |
3561 | S: 10200 Prague 10, Hostivar | 3561 | S: Cupertino, CA 95014 |
3562 | S: Czech Republic | 3562 | S: USA |
3563 | 3563 | ||
3564 | N: Thibaut Varene | 3564 | N: Thibaut Varene |
3565 | E: T-Bone@parisc-linux.org | 3565 | E: T-Bone@parisc-linux.org |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 1762b81fcdf2..741fe66d6eca 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt | |||
@@ -542,9 +542,11 @@ Kprobes does not use mutexes or allocate memory except during | |||
542 | registration and unregistration. | 542 | registration and unregistration. |
543 | 543 | ||
544 | Probe handlers are run with preemption disabled. Depending on the | 544 | Probe handlers are run with preemption disabled. Depending on the |
545 | architecture, handlers may also run with interrupts disabled. In any | 545 | architecture and optimization state, handlers may also run with |
546 | case, your handler should not yield the CPU (e.g., by attempting to | 546 | interrupts disabled (e.g., kretprobe handlers and optimized kprobe |
547 | acquire a semaphore). | 547 | handlers run without interrupt disabled on x86/x86-64). In any case, |
548 | your handler should not yield the CPU (e.g., by attempting to acquire | ||
549 | a semaphore). | ||
548 | 550 | ||
549 | Since a return probe is implemented by replacing the return | 551 | Since a return probe is implemented by replacing the return |
550 | address with the trampoline's address, stack backtraces and calls | 552 | address with the trampoline's address, stack backtraces and calls |
diff --git a/MAINTAINERS b/MAINTAINERS index 50b8148448fd..f46d8e66333f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -962,6 +962,13 @@ W: http://www.fluff.org/ben/linux/ | |||
962 | S: Maintained | 962 | S: Maintained |
963 | F: arch/arm/mach-s3c6410/ | 963 | F: arch/arm/mach-s3c6410/ |
964 | 964 | ||
965 | ARM/S5P ARM ARCHITECTURES | ||
966 | M: Kukjin Kim <kgene.kim@samsung.com> | ||
967 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
968 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | ||
969 | S: Maintained | ||
970 | F: arch/arm/mach-s5p*/ | ||
971 | |||
965 | ARM/SHMOBILE ARM ARCHITECTURE | 972 | ARM/SHMOBILE ARM ARCHITECTURE |
966 | M: Paul Mundt <lethal@linux-sh.org> | 973 | M: Paul Mundt <lethal@linux-sh.org> |
967 | M: Magnus Damm <magnus.damm@gmail.com> | 974 | M: Magnus Damm <magnus.damm@gmail.com> |
@@ -1220,7 +1227,7 @@ F: drivers/auxdisplay/ | |||
1220 | F: include/linux/cfag12864b.h | 1227 | F: include/linux/cfag12864b.h |
1221 | 1228 | ||
1222 | AVR32 ARCHITECTURE | 1229 | AVR32 ARCHITECTURE |
1223 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1230 | M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> |
1224 | W: http://www.atmel.com/products/AVR32/ | 1231 | W: http://www.atmel.com/products/AVR32/ |
1225 | W: http://avr32linux.org/ | 1232 | W: http://avr32linux.org/ |
1226 | W: http://avrfreaks.net/ | 1233 | W: http://avrfreaks.net/ |
@@ -1228,7 +1235,7 @@ S: Supported | |||
1228 | F: arch/avr32/ | 1235 | F: arch/avr32/ |
1229 | 1236 | ||
1230 | AVR32/AT32AP MACHINE SUPPORT | 1237 | AVR32/AT32AP MACHINE SUPPORT |
1231 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1238 | M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> |
1232 | S: Supported | 1239 | S: Supported |
1233 | F: arch/avr32/mach-at32ap/ | 1240 | F: arch/avr32/mach-at32ap/ |
1234 | 1241 | ||
@@ -2199,6 +2206,12 @@ W: http://acpi4asus.sf.net | |||
2199 | S: Maintained | 2206 | S: Maintained |
2200 | F: drivers/platform/x86/eeepc-laptop.c | 2207 | F: drivers/platform/x86/eeepc-laptop.c |
2201 | 2208 | ||
2209 | EFIFB FRAMEBUFFER DRIVER | ||
2210 | L: linux-fbdev@vger.kernel.org | ||
2211 | M: Peter Jones <pjones@redhat.com> | ||
2212 | S: Maintained | ||
2213 | F: drivers/video/efifb.c | ||
2214 | |||
2202 | EFS FILESYSTEM | 2215 | EFS FILESYSTEM |
2203 | W: http://aeschi.ch.eu.org/efs/ | 2216 | W: http://aeschi.ch.eu.org/efs/ |
2204 | S: Orphan | 2217 | S: Orphan |
@@ -2662,6 +2675,8 @@ M: Guenter Roeck <guenter.roeck@ericsson.com> | |||
2662 | L: lm-sensors@lm-sensors.org | 2675 | L: lm-sensors@lm-sensors.org |
2663 | W: http://www.lm-sensors.org/ | 2676 | W: http://www.lm-sensors.org/ |
2664 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ | 2677 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ |
2678 | T: quilt kernel.org/pub/linux/kernel/people/groeck/linux-staging/ | ||
2679 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git | ||
2665 | S: Maintained | 2680 | S: Maintained |
2666 | F: Documentation/hwmon/ | 2681 | F: Documentation/hwmon/ |
2667 | F: drivers/hwmon/ | 2682 | F: drivers/hwmon/ |
@@ -3773,9 +3788,8 @@ W: http://www.syskonnect.com | |||
3773 | S: Supported | 3788 | S: Supported |
3774 | 3789 | ||
3775 | MATROX FRAMEBUFFER DRIVER | 3790 | MATROX FRAMEBUFFER DRIVER |
3776 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | ||
3777 | L: linux-fbdev@vger.kernel.org | 3791 | L: linux-fbdev@vger.kernel.org |
3778 | S: Maintained | 3792 | S: Orphan |
3779 | F: drivers/video/matrox/matroxfb_* | 3793 | F: drivers/video/matrox/matroxfb_* |
3780 | F: include/linux/matroxfb.h | 3794 | F: include/linux/matroxfb.h |
3781 | 3795 | ||
@@ -3899,10 +3913,8 @@ F: Documentation/serial/moxa-smartio | |||
3899 | F: drivers/char/mxser.* | 3913 | F: drivers/char/mxser.* |
3900 | 3914 | ||
3901 | MSI LAPTOP SUPPORT | 3915 | MSI LAPTOP SUPPORT |
3902 | M: Lennart Poettering <mzxreary@0pointer.de> | 3916 | M: Lee, Chun-Yi <jlee@novell.com> |
3903 | L: platform-driver-x86@vger.kernel.org | 3917 | L: platform-driver-x86@vger.kernel.org |
3904 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux | ||
3905 | W: http://0pointer.de/lennart/tchibo.html | ||
3906 | S: Maintained | 3918 | S: Maintained |
3907 | F: drivers/platform/x86/msi-laptop.c | 3919 | F: drivers/platform/x86/msi-laptop.c |
3908 | 3920 | ||
@@ -3919,8 +3931,10 @@ S: Supported | |||
3919 | F: drivers/mfd/ | 3931 | F: drivers/mfd/ |
3920 | 3932 | ||
3921 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM | 3933 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM |
3922 | S: Orphan | 3934 | M: Chris Ball <cjb@laptop.org> |
3923 | L: linux-mmc@vger.kernel.org | 3935 | L: linux-mmc@vger.kernel.org |
3936 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git | ||
3937 | S: Maintained | ||
3924 | F: drivers/mmc/ | 3938 | F: drivers/mmc/ |
3925 | F: include/linux/mmc/ | 3939 | F: include/linux/mmc/ |
3926 | 3940 | ||
@@ -3962,8 +3976,8 @@ S: Maintained | |||
3962 | F: drivers/net/natsemi.c | 3976 | F: drivers/net/natsemi.c |
3963 | 3977 | ||
3964 | NCP FILESYSTEM | 3978 | NCP FILESYSTEM |
3965 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3979 | M: Petr Vandrovec <petr@vandrovec.name> |
3966 | S: Maintained | 3980 | S: Odd Fixes |
3967 | F: fs/ncpfs/ | 3981 | F: fs/ncpfs/ |
3968 | 3982 | ||
3969 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) | 3983 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) |
@@ -5091,8 +5105,10 @@ S: Maintained | |||
5091 | F: drivers/mmc/host/sdricoh_cs.c | 5105 | F: drivers/mmc/host/sdricoh_cs.c |
5092 | 5106 | ||
5093 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER | 5107 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER |
5094 | S: Orphan | 5108 | M: Chris Ball <cjb@laptop.org> |
5095 | L: linux-mmc@vger.kernel.org | 5109 | L: linux-mmc@vger.kernel.org |
5110 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git | ||
5111 | S: Maintained | ||
5096 | F: drivers/mmc/host/sdhci.* | 5112 | F: drivers/mmc/host/sdhci.* |
5097 | 5113 | ||
5098 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) | 5114 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 36 | 3 | SUBLEVEL = 36 |
4 | EXTRAVERSION = -rc5 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Sheep on Meth | 5 | NAME = Sheep on Meth |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -568,6 +568,12 @@ endif | |||
568 | 568 | ||
569 | ifdef CONFIG_FUNCTION_TRACER | 569 | ifdef CONFIG_FUNCTION_TRACER |
570 | KBUILD_CFLAGS += -pg | 570 | KBUILD_CFLAGS += -pg |
571 | ifdef CONFIG_DYNAMIC_FTRACE | ||
572 | ifdef CONFIG_HAVE_C_RECORDMCOUNT | ||
573 | BUILD_C_RECORDMCOUNT := y | ||
574 | export BUILD_C_RECORDMCOUNT | ||
575 | endif | ||
576 | endif | ||
571 | endif | 577 | endif |
572 | 578 | ||
573 | # We trigger additional mismatches with less inlining | 579 | # We trigger additional mismatches with less inlining |
@@ -591,6 +597,11 @@ KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) | |||
591 | # conserve stack if available | 597 | # conserve stack if available |
592 | KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) | 598 | KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) |
593 | 599 | ||
600 | # check for 'asm goto' | ||
601 | ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC)), y) | ||
602 | KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO | ||
603 | endif | ||
604 | |||
594 | # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments | 605 | # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments |
595 | # But warn user when we do so | 606 | # But warn user when we do so |
596 | warn-assign = \ | 607 | warn-assign = \ |
diff --git a/arch/Kconfig b/arch/Kconfig index fe48fc7a3eba..53d7f619a1b9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -158,4 +158,7 @@ config HAVE_PERF_EVENTS_NMI | |||
158 | subsystem. Also has support for calculating CPU cycle events | 158 | subsystem. Also has support for calculating CPU cycle events |
159 | to determine how many clock cycles in a given period. | 159 | to determine how many clock cycles in a given period. |
160 | 160 | ||
161 | config HAVE_ARCH_JUMP_LABEL | ||
162 | bool | ||
163 | |||
161 | source "kernel/gcov/Kconfig" | 164 | source "kernel/gcov/Kconfig" |
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index ab1ee0ab082b..6d159cee5f2f 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
@@ -73,8 +73,6 @@ | |||
73 | ldq $20, HAE_REG($19); \ | 73 | ldq $20, HAE_REG($19); \ |
74 | stq $21, HAE_CACHE($19); \ | 74 | stq $21, HAE_CACHE($19); \ |
75 | stq $21, 0($20); \ | 75 | stq $21, 0($20); \ |
76 | ldq $0, 0($sp); \ | ||
77 | ldq $1, 8($sp); \ | ||
78 | 99:; \ | 76 | 99:; \ |
79 | ldq $19, 72($sp); \ | 77 | ldq $19, 72($sp); \ |
80 | ldq $20, 80($sp); \ | 78 | ldq $20, 80($sp); \ |
@@ -316,7 +314,7 @@ ret_from_sys_call: | |||
316 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ | 314 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ |
317 | ldq $0, SP_OFF($sp) | 315 | ldq $0, SP_OFF($sp) |
318 | and $0, 8, $0 | 316 | and $0, 8, $0 |
319 | beq $0, restore_all | 317 | beq $0, ret_to_kernel |
320 | ret_to_user: | 318 | ret_to_user: |
321 | /* Make sure need_resched and sigpending don't change between | 319 | /* Make sure need_resched and sigpending don't change between |
322 | sampling and the rti. */ | 320 | sampling and the rti. */ |
@@ -329,6 +327,11 @@ restore_all: | |||
329 | RESTORE_ALL | 327 | RESTORE_ALL |
330 | call_pal PAL_rti | 328 | call_pal PAL_rti |
331 | 329 | ||
330 | ret_to_kernel: | ||
331 | lda $16, 7 | ||
332 | call_pal PAL_swpipl | ||
333 | br restore_all | ||
334 | |||
332 | .align 3 | 335 | .align 3 |
333 | $syscall_error: | 336 | $syscall_error: |
334 | /* | 337 | /* |
@@ -657,7 +660,7 @@ kernel_thread: | |||
657 | /* We don't actually care for a3 success widgetry in the kernel. | 660 | /* We don't actually care for a3 success widgetry in the kernel. |
658 | Not for positive errno values. */ | 661 | Not for positive errno values. */ |
659 | stq $0, 0($sp) /* $0 */ | 662 | stq $0, 0($sp) /* $0 */ |
660 | br restore_all | 663 | br ret_to_kernel |
661 | .end kernel_thread | 664 | .end kernel_thread |
662 | 665 | ||
663 | /* | 666 | /* |
@@ -912,15 +915,6 @@ sys_execve: | |||
912 | .end sys_execve | 915 | .end sys_execve |
913 | 916 | ||
914 | .align 4 | 917 | .align 4 |
915 | .globl osf_sigprocmask | ||
916 | .ent osf_sigprocmask | ||
917 | osf_sigprocmask: | ||
918 | .prologue 0 | ||
919 | mov $sp, $18 | ||
920 | jmp $31, sys_osf_sigprocmask | ||
921 | .end osf_sigprocmask | ||
922 | |||
923 | .align 4 | ||
924 | .globl alpha_ni_syscall | 918 | .globl alpha_ni_syscall |
925 | .ent alpha_ni_syscall | 919 | .ent alpha_ni_syscall |
926 | alpha_ni_syscall: | 920 | alpha_ni_syscall: |
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 85d8e4f58c83..1cc49683fb69 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c | |||
@@ -307,7 +307,7 @@ again: | |||
307 | new_raw_count) != prev_raw_count) | 307 | new_raw_count) != prev_raw_count) |
308 | goto again; | 308 | goto again; |
309 | 309 | ||
310 | delta = (new_raw_count - (prev_raw_count & alpha_pmu->pmc_count_mask[idx])) + ovf; | 310 | delta = (new_raw_count - (prev_raw_count & alpha_pmu->pmc_count_mask[idx])) + ovf; |
311 | 311 | ||
312 | /* It is possible on very rare occasions that the PMC has overflowed | 312 | /* It is possible on very rare occasions that the PMC has overflowed |
313 | * but the interrupt is yet to come. Detect and fix this situation. | 313 | * but the interrupt is yet to come. Detect and fix this situation. |
@@ -402,14 +402,13 @@ static void maybe_change_configuration(struct cpu_hw_events *cpuc) | |||
402 | struct hw_perf_event *hwc = &pe->hw; | 402 | struct hw_perf_event *hwc = &pe->hw; |
403 | int idx = hwc->idx; | 403 | int idx = hwc->idx; |
404 | 404 | ||
405 | if (cpuc->current_idx[j] != PMC_NO_INDEX) { | 405 | if (cpuc->current_idx[j] == PMC_NO_INDEX) { |
406 | cpuc->idx_mask |= (1<<cpuc->current_idx[j]); | 406 | alpha_perf_event_set_period(pe, hwc, idx); |
407 | continue; | 407 | cpuc->current_idx[j] = idx; |
408 | } | 408 | } |
409 | 409 | ||
410 | alpha_perf_event_set_period(pe, hwc, idx); | 410 | if (!(hwc->state & PERF_HES_STOPPED)) |
411 | cpuc->current_idx[j] = idx; | 411 | cpuc->idx_mask |= (1<<cpuc->current_idx[j]); |
412 | cpuc->idx_mask |= (1<<cpuc->current_idx[j]); | ||
413 | } | 412 | } |
414 | cpuc->config = cpuc->event[0]->hw.config_base; | 413 | cpuc->config = cpuc->event[0]->hw.config_base; |
415 | } | 414 | } |
@@ -420,12 +419,13 @@ static void maybe_change_configuration(struct cpu_hw_events *cpuc) | |||
420 | * - this function is called from outside this module via the pmu struct | 419 | * - this function is called from outside this module via the pmu struct |
421 | * returned from perf event initialisation. | 420 | * returned from perf event initialisation. |
422 | */ | 421 | */ |
423 | static int alpha_pmu_enable(struct perf_event *event) | 422 | static int alpha_pmu_add(struct perf_event *event, int flags) |
424 | { | 423 | { |
425 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 424 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
425 | struct hw_perf_event *hwc = &event->hw; | ||
426 | int n0; | 426 | int n0; |
427 | int ret; | 427 | int ret; |
428 | unsigned long flags; | 428 | unsigned long irq_flags; |
429 | 429 | ||
430 | /* | 430 | /* |
431 | * The Sparc code has the IRQ disable first followed by the perf | 431 | * The Sparc code has the IRQ disable first followed by the perf |
@@ -435,8 +435,8 @@ static int alpha_pmu_enable(struct perf_event *event) | |||
435 | * nevertheless we disable the PMCs first to enable a potential | 435 | * nevertheless we disable the PMCs first to enable a potential |
436 | * final PMI to occur before we disable interrupts. | 436 | * final PMI to occur before we disable interrupts. |
437 | */ | 437 | */ |
438 | perf_disable(); | 438 | perf_pmu_disable(event->pmu); |
439 | local_irq_save(flags); | 439 | local_irq_save(irq_flags); |
440 | 440 | ||
441 | /* Default to error to be returned */ | 441 | /* Default to error to be returned */ |
442 | ret = -EAGAIN; | 442 | ret = -EAGAIN; |
@@ -455,8 +455,12 @@ static int alpha_pmu_enable(struct perf_event *event) | |||
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
458 | local_irq_restore(flags); | 458 | hwc->state = PERF_HES_UPTODATE; |
459 | perf_enable(); | 459 | if (!(flags & PERF_EF_START)) |
460 | hwc->state |= PERF_HES_STOPPED; | ||
461 | |||
462 | local_irq_restore(irq_flags); | ||
463 | perf_pmu_enable(event->pmu); | ||
460 | 464 | ||
461 | return ret; | 465 | return ret; |
462 | } | 466 | } |
@@ -467,15 +471,15 @@ static int alpha_pmu_enable(struct perf_event *event) | |||
467 | * - this function is called from outside this module via the pmu struct | 471 | * - this function is called from outside this module via the pmu struct |
468 | * returned from perf event initialisation. | 472 | * returned from perf event initialisation. |
469 | */ | 473 | */ |
470 | static void alpha_pmu_disable(struct perf_event *event) | 474 | static void alpha_pmu_del(struct perf_event *event, int flags) |
471 | { | 475 | { |
472 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 476 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
473 | struct hw_perf_event *hwc = &event->hw; | 477 | struct hw_perf_event *hwc = &event->hw; |
474 | unsigned long flags; | 478 | unsigned long irq_flags; |
475 | int j; | 479 | int j; |
476 | 480 | ||
477 | perf_disable(); | 481 | perf_pmu_disable(event->pmu); |
478 | local_irq_save(flags); | 482 | local_irq_save(irq_flags); |
479 | 483 | ||
480 | for (j = 0; j < cpuc->n_events; j++) { | 484 | for (j = 0; j < cpuc->n_events; j++) { |
481 | if (event == cpuc->event[j]) { | 485 | if (event == cpuc->event[j]) { |
@@ -501,8 +505,8 @@ static void alpha_pmu_disable(struct perf_event *event) | |||
501 | } | 505 | } |
502 | } | 506 | } |
503 | 507 | ||
504 | local_irq_restore(flags); | 508 | local_irq_restore(irq_flags); |
505 | perf_enable(); | 509 | perf_pmu_enable(event->pmu); |
506 | } | 510 | } |
507 | 511 | ||
508 | 512 | ||
@@ -514,13 +518,44 @@ static void alpha_pmu_read(struct perf_event *event) | |||
514 | } | 518 | } |
515 | 519 | ||
516 | 520 | ||
517 | static void alpha_pmu_unthrottle(struct perf_event *event) | 521 | static void alpha_pmu_stop(struct perf_event *event, int flags) |
522 | { | ||
523 | struct hw_perf_event *hwc = &event->hw; | ||
524 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
525 | |||
526 | if (!(hwc->state & PERF_HES_STOPPED)) { | ||
527 | cpuc->idx_mask &= ~(1UL<<hwc->idx); | ||
528 | hwc->state |= PERF_HES_STOPPED; | ||
529 | } | ||
530 | |||
531 | if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { | ||
532 | alpha_perf_event_update(event, hwc, hwc->idx, 0); | ||
533 | hwc->state |= PERF_HES_UPTODATE; | ||
534 | } | ||
535 | |||
536 | if (cpuc->enabled) | ||
537 | wrperfmon(PERFMON_CMD_DISABLE, (1UL<<hwc->idx)); | ||
538 | } | ||
539 | |||
540 | |||
541 | static void alpha_pmu_start(struct perf_event *event, int flags) | ||
518 | { | 542 | { |
519 | struct hw_perf_event *hwc = &event->hw; | 543 | struct hw_perf_event *hwc = &event->hw; |
520 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 544 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
521 | 545 | ||
546 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) | ||
547 | return; | ||
548 | |||
549 | if (flags & PERF_EF_RELOAD) { | ||
550 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); | ||
551 | alpha_perf_event_set_period(event, hwc, hwc->idx); | ||
552 | } | ||
553 | |||
554 | hwc->state = 0; | ||
555 | |||
522 | cpuc->idx_mask |= 1UL<<hwc->idx; | 556 | cpuc->idx_mask |= 1UL<<hwc->idx; |
523 | wrperfmon(PERFMON_CMD_ENABLE, (1UL<<hwc->idx)); | 557 | if (cpuc->enabled) |
558 | wrperfmon(PERFMON_CMD_ENABLE, (1UL<<hwc->idx)); | ||
524 | } | 559 | } |
525 | 560 | ||
526 | 561 | ||
@@ -642,39 +677,36 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
642 | return 0; | 677 | return 0; |
643 | } | 678 | } |
644 | 679 | ||
645 | static const struct pmu pmu = { | ||
646 | .enable = alpha_pmu_enable, | ||
647 | .disable = alpha_pmu_disable, | ||
648 | .read = alpha_pmu_read, | ||
649 | .unthrottle = alpha_pmu_unthrottle, | ||
650 | }; | ||
651 | |||
652 | |||
653 | /* | 680 | /* |
654 | * Main entry point to initialise a HW performance event. | 681 | * Main entry point to initialise a HW performance event. |
655 | */ | 682 | */ |
656 | const struct pmu *hw_perf_event_init(struct perf_event *event) | 683 | static int alpha_pmu_event_init(struct perf_event *event) |
657 | { | 684 | { |
658 | int err; | 685 | int err; |
659 | 686 | ||
687 | switch (event->attr.type) { | ||
688 | case PERF_TYPE_RAW: | ||
689 | case PERF_TYPE_HARDWARE: | ||
690 | case PERF_TYPE_HW_CACHE: | ||
691 | break; | ||
692 | |||
693 | default: | ||
694 | return -ENOENT; | ||
695 | } | ||
696 | |||
660 | if (!alpha_pmu) | 697 | if (!alpha_pmu) |
661 | return ERR_PTR(-ENODEV); | 698 | return -ENODEV; |
662 | 699 | ||
663 | /* Do the real initialisation work. */ | 700 | /* Do the real initialisation work. */ |
664 | err = __hw_perf_event_init(event); | 701 | err = __hw_perf_event_init(event); |
665 | 702 | ||
666 | if (err) | 703 | return err; |
667 | return ERR_PTR(err); | ||
668 | |||
669 | return &pmu; | ||
670 | } | 704 | } |
671 | 705 | ||
672 | |||
673 | |||
674 | /* | 706 | /* |
675 | * Main entry point - enable HW performance counters. | 707 | * Main entry point - enable HW performance counters. |
676 | */ | 708 | */ |
677 | void hw_perf_enable(void) | 709 | static void alpha_pmu_enable(struct pmu *pmu) |
678 | { | 710 | { |
679 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 711 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
680 | 712 | ||
@@ -700,7 +732,7 @@ void hw_perf_enable(void) | |||
700 | * Main entry point - disable HW performance counters. | 732 | * Main entry point - disable HW performance counters. |
701 | */ | 733 | */ |
702 | 734 | ||
703 | void hw_perf_disable(void) | 735 | static void alpha_pmu_disable(struct pmu *pmu) |
704 | { | 736 | { |
705 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 737 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
706 | 738 | ||
@@ -713,6 +745,17 @@ void hw_perf_disable(void) | |||
713 | wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask); | 745 | wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask); |
714 | } | 746 | } |
715 | 747 | ||
748 | static struct pmu pmu = { | ||
749 | .pmu_enable = alpha_pmu_enable, | ||
750 | .pmu_disable = alpha_pmu_disable, | ||
751 | .event_init = alpha_pmu_event_init, | ||
752 | .add = alpha_pmu_add, | ||
753 | .del = alpha_pmu_del, | ||
754 | .start = alpha_pmu_start, | ||
755 | .stop = alpha_pmu_stop, | ||
756 | .read = alpha_pmu_read, | ||
757 | }; | ||
758 | |||
716 | 759 | ||
717 | /* | 760 | /* |
718 | * Main entry point - don't know when this is called but it | 761 | * Main entry point - don't know when this is called but it |
@@ -766,7 +809,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr, | |||
766 | wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask); | 809 | wrperfmon(PERFMON_CMD_DISABLE, cpuc->idx_mask); |
767 | 810 | ||
768 | /* la_ptr is the counter that overflowed. */ | 811 | /* la_ptr is the counter that overflowed. */ |
769 | if (unlikely(la_ptr >= perf_max_events)) { | 812 | if (unlikely(la_ptr >= alpha_pmu->num_pmcs)) { |
770 | /* This should never occur! */ | 813 | /* This should never occur! */ |
771 | irq_err_count++; | 814 | irq_err_count++; |
772 | pr_warning("PMI: silly index %ld\n", la_ptr); | 815 | pr_warning("PMI: silly index %ld\n", la_ptr); |
@@ -807,7 +850,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr, | |||
807 | /* Interrupts coming too quickly; "throttle" the | 850 | /* Interrupts coming too quickly; "throttle" the |
808 | * counter, i.e., disable it for a little while. | 851 | * counter, i.e., disable it for a little while. |
809 | */ | 852 | */ |
810 | cpuc->idx_mask &= ~(1UL<<idx); | 853 | alpha_pmu_stop(event, 0); |
811 | } | 854 | } |
812 | } | 855 | } |
813 | wrperfmon(PERFMON_CMD_ENABLE, cpuc->idx_mask); | 856 | wrperfmon(PERFMON_CMD_ENABLE, cpuc->idx_mask); |
@@ -837,6 +880,7 @@ void __init init_hw_perf_events(void) | |||
837 | 880 | ||
838 | /* And set up PMU specification */ | 881 | /* And set up PMU specification */ |
839 | alpha_pmu = &ev67_pmu; | 882 | alpha_pmu = &ev67_pmu; |
840 | perf_max_events = alpha_pmu->num_pmcs; | 883 | |
884 | perf_pmu_register(&pmu); | ||
841 | } | 885 | } |
842 | 886 | ||
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 842dba308eab..3ec35066f1dc 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -356,7 +356,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) | |||
356 | dest[27] = pt->r27; | 356 | dest[27] = pt->r27; |
357 | dest[28] = pt->r28; | 357 | dest[28] = pt->r28; |
358 | dest[29] = pt->gp; | 358 | dest[29] = pt->gp; |
359 | dest[30] = rdusp(); | 359 | dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp; |
360 | dest[31] = pt->pc; | 360 | dest[31] = pt->pc; |
361 | 361 | ||
362 | /* Once upon a time this was the PS value. Which is stupid | 362 | /* Once upon a time this was the PS value. Which is stupid |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 0f6b51ae865a..6f7feb5db271 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -41,46 +41,20 @@ static void do_signal(struct pt_regs *, struct switch_stack *, | |||
41 | /* | 41 | /* |
42 | * The OSF/1 sigprocmask calling sequence is different from the | 42 | * The OSF/1 sigprocmask calling sequence is different from the |
43 | * C sigprocmask() sequence.. | 43 | * C sigprocmask() sequence.. |
44 | * | ||
45 | * how: | ||
46 | * 1 - SIG_BLOCK | ||
47 | * 2 - SIG_UNBLOCK | ||
48 | * 3 - SIG_SETMASK | ||
49 | * | ||
50 | * We change the range to -1 .. 1 in order to let gcc easily | ||
51 | * use the conditional move instructions. | ||
52 | * | ||
53 | * Note that we don't need to acquire the kernel lock for SMP | ||
54 | * operation, as all of this is local to this thread. | ||
55 | */ | 44 | */ |
56 | SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask, | 45 | SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask) |
57 | struct pt_regs *, regs) | ||
58 | { | 46 | { |
59 | unsigned long oldmask = -EINVAL; | 47 | sigset_t oldmask; |
60 | 48 | sigset_t mask; | |
61 | if ((unsigned long)how-1 <= 2) { | 49 | unsigned long res; |
62 | long sign = how-2; /* -1 .. 1 */ | 50 | |
63 | unsigned long block, unblock; | 51 | siginitset(&mask, newmask & _BLOCKABLE); |
64 | 52 | res = sigprocmask(how, &mask, &oldmask); | |
65 | newmask &= _BLOCKABLE; | 53 | if (!res) { |
66 | spin_lock_irq(¤t->sighand->siglock); | 54 | force_successful_syscall_return(); |
67 | oldmask = current->blocked.sig[0]; | 55 | res = oldmask.sig[0]; |
68 | |||
69 | unblock = oldmask & ~newmask; | ||
70 | block = oldmask | newmask; | ||
71 | if (!sign) | ||
72 | block = unblock; | ||
73 | if (sign <= 0) | ||
74 | newmask = block; | ||
75 | if (_NSIG_WORDS > 1 && sign > 0) | ||
76 | sigemptyset(¤t->blocked); | ||
77 | current->blocked.sig[0] = newmask; | ||
78 | recalc_sigpending(); | ||
79 | spin_unlock_irq(¤t->sighand->siglock); | ||
80 | |||
81 | regs->r0 = 0; /* special no error return */ | ||
82 | } | 56 | } |
83 | return oldmask; | 57 | return res; |
84 | } | 58 | } |
85 | 59 | ||
86 | SYSCALL_DEFINE3(osf_sigaction, int, sig, | 60 | SYSCALL_DEFINE3(osf_sigaction, int, sig, |
@@ -94,9 +68,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
94 | old_sigset_t mask; | 68 | old_sigset_t mask; |
95 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 69 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
96 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 70 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
97 | __get_user(new_ka.sa.sa_flags, &act->sa_flags)) | 71 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || |
72 | __get_user(mask, &act->sa_mask)) | ||
98 | return -EFAULT; | 73 | return -EFAULT; |
99 | __get_user(mask, &act->sa_mask); | ||
100 | siginitset(&new_ka.sa.sa_mask, mask); | 74 | siginitset(&new_ka.sa.sa_mask, mask); |
101 | new_ka.ka_restorer = NULL; | 75 | new_ka.ka_restorer = NULL; |
102 | } | 76 | } |
@@ -106,9 +80,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
106 | if (!ret && oact) { | 80 | if (!ret && oact) { |
107 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 81 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
108 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 82 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
109 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) | 83 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || |
84 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
110 | return -EFAULT; | 85 | return -EFAULT; |
111 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
112 | } | 86 | } |
113 | 87 | ||
114 | return ret; | 88 | return ret; |
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index ce594ef533cc..a6a1de9db16f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -58,7 +58,7 @@ sys_call_table: | |||
58 | .quad sys_open /* 45 */ | 58 | .quad sys_open /* 45 */ |
59 | .quad alpha_ni_syscall | 59 | .quad alpha_ni_syscall |
60 | .quad sys_getxgid | 60 | .quad sys_getxgid |
61 | .quad osf_sigprocmask | 61 | .quad sys_osf_sigprocmask |
62 | .quad alpha_ni_syscall | 62 | .quad alpha_ni_syscall |
63 | .quad alpha_ni_syscall /* 50 */ | 63 | .quad alpha_ni_syscall /* 50 */ |
64 | .quad sys_acct | 64 | .quad sys_acct |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 553b7cf17bfb..88c97bc7a6f5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -271,7 +271,6 @@ config ARCH_AT91 | |||
271 | bool "Atmel AT91" | 271 | bool "Atmel AT91" |
272 | select ARCH_REQUIRE_GPIOLIB | 272 | select ARCH_REQUIRE_GPIOLIB |
273 | select HAVE_CLK | 273 | select HAVE_CLK |
274 | select ARCH_USES_GETTIMEOFFSET | ||
275 | help | 274 | help |
276 | This enables support for systems based on the Atmel AT91RM9200, | 275 | This enables support for systems based on the Atmel AT91RM9200, |
277 | AT91SAM9 and AT91CAP9 processors. | 276 | AT91SAM9 and AT91CAP9 processors. |
@@ -1051,6 +1050,32 @@ config ARM_ERRATA_460075 | |||
1051 | ACTLR register. Note that setting specific bits in the ACTLR register | 1050 | ACTLR register. Note that setting specific bits in the ACTLR register |
1052 | may not be available in non-secure mode. | 1051 | may not be available in non-secure mode. |
1053 | 1052 | ||
1053 | config ARM_ERRATA_742230 | ||
1054 | bool "ARM errata: DMB operation may be faulty" | ||
1055 | depends on CPU_V7 && SMP | ||
1056 | help | ||
1057 | This option enables the workaround for the 742230 Cortex-A9 | ||
1058 | (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction | ||
1059 | between two write operations may not ensure the correct visibility | ||
1060 | ordering of the two writes. This workaround sets a specific bit in | ||
1061 | the diagnostic register of the Cortex-A9 which causes the DMB | ||
1062 | instruction to behave as a DSB, ensuring the correct behaviour of | ||
1063 | the two writes. | ||
1064 | |||
1065 | config ARM_ERRATA_742231 | ||
1066 | bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption" | ||
1067 | depends on CPU_V7 && SMP | ||
1068 | help | ||
1069 | This option enables the workaround for the 742231 Cortex-A9 | ||
1070 | (r2p0..r2p2) erratum. Under certain conditions, specific to the | ||
1071 | Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode, | ||
1072 | accessing some data located in the same cache line, may get corrupted | ||
1073 | data due to bad handling of the address hazard when the line gets | ||
1074 | replaced from one of the CPUs at the same time as another CPU is | ||
1075 | accessing it. This workaround sets specific bits in the diagnostic | ||
1076 | register of the Cortex-A9 which reduces the linefill issuing | ||
1077 | capabilities of the processor. | ||
1078 | |||
1054 | config PL310_ERRATA_588369 | 1079 | config PL310_ERRATA_588369 |
1055 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" | 1080 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" |
1056 | depends on CACHE_L2X0 && ARCH_OMAP4 | 1081 | depends on CACHE_L2X0 && ARCH_OMAP4 |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index b23f6bc46cfa..65a7c1c588a9 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -116,5 +116,5 @@ CFLAGS_font.o := -Dstatic= | |||
116 | $(obj)/font.c: $(FONTC) | 116 | $(obj)/font.c: $(FONTC) |
117 | $(call cmd,shipped) | 117 | $(call cmd,shipped) |
118 | 118 | ||
119 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config | 119 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) |
120 | @sed "$(SEDFLAGS)" < $< > $@ | 120 | @sed "$(SEDFLAGS)" < $< > $@ |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 7974baacafce..1bec96e85196 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -271,6 +271,14 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | |||
271 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); | 271 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); |
272 | } | 272 | } |
273 | 273 | ||
274 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
275 | { | ||
276 | if (mask >= PHYS_OFFSET + SZ_64M - 1) | ||
277 | return 0; | ||
278 | |||
279 | return -EIO; | ||
280 | } | ||
281 | |||
274 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) | 282 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) |
275 | { | 283 | { |
276 | it8152_io.start = IT8152_IO_BASE + 0x12000; | 284 | it8152_io.start = IT8152_IO_BASE + 0x12000; |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index ab68cf1ef80f..e90b167ea848 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -317,6 +317,10 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | |||
317 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | 317 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE |
318 | #define pgprot_dmacoherent(prot) \ | 318 | #define pgprot_dmacoherent(prot) \ |
319 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) | 319 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) |
320 | #define __HAVE_PHYS_MEM_ACCESS_PROT | ||
321 | struct file; | ||
322 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
323 | unsigned long size, pgprot_t vma_prot); | ||
320 | #else | 324 | #else |
321 | #define pgprot_dmacoherent(prot) \ | 325 | #define pgprot_dmacoherent(prot) \ |
322 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) | 326 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 1b560825e1cf..7885722bdf4e 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -48,6 +48,8 @@ work_pending: | |||
48 | beq no_work_pending | 48 | beq no_work_pending |
49 | mov r0, sp @ 'regs' | 49 | mov r0, sp @ 'regs' |
50 | mov r2, why @ 'syscall' | 50 | mov r2, why @ 'syscall' |
51 | tst r1, #_TIF_SIGPENDING @ delivering a signal? | ||
52 | movne why, #0 @ prevent further restarts | ||
51 | bl do_notify_resume | 53 | bl do_notify_resume |
52 | b ret_slow_syscall @ Check work again | 54 | b ret_slow_syscall @ Check work again |
53 | 55 | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index ef3bc331518f..6cc6521881aa 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -227,46 +227,56 @@ again: | |||
227 | } | 227 | } |
228 | 228 | ||
229 | static void | 229 | static void |
230 | armpmu_disable(struct perf_event *event) | 230 | armpmu_read(struct perf_event *event) |
231 | { | 231 | { |
232 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
233 | struct hw_perf_event *hwc = &event->hw; | 232 | struct hw_perf_event *hwc = &event->hw; |
234 | int idx = hwc->idx; | ||
235 | |||
236 | WARN_ON(idx < 0); | ||
237 | |||
238 | clear_bit(idx, cpuc->active_mask); | ||
239 | armpmu->disable(hwc, idx); | ||
240 | |||
241 | barrier(); | ||
242 | 233 | ||
243 | armpmu_event_update(event, hwc, idx); | 234 | /* Don't read disabled counters! */ |
244 | cpuc->events[idx] = NULL; | 235 | if (hwc->idx < 0) |
245 | clear_bit(idx, cpuc->used_mask); | 236 | return; |
246 | 237 | ||
247 | perf_event_update_userpage(event); | 238 | armpmu_event_update(event, hwc, hwc->idx); |
248 | } | 239 | } |
249 | 240 | ||
250 | static void | 241 | static void |
251 | armpmu_read(struct perf_event *event) | 242 | armpmu_stop(struct perf_event *event, int flags) |
252 | { | 243 | { |
253 | struct hw_perf_event *hwc = &event->hw; | 244 | struct hw_perf_event *hwc = &event->hw; |
254 | 245 | ||
255 | /* Don't read disabled counters! */ | 246 | if (!armpmu) |
256 | if (hwc->idx < 0) | ||
257 | return; | 247 | return; |
258 | 248 | ||
259 | armpmu_event_update(event, hwc, hwc->idx); | 249 | /* |
250 | * ARM pmu always has to update the counter, so ignore | ||
251 | * PERF_EF_UPDATE, see comments in armpmu_start(). | ||
252 | */ | ||
253 | if (!(hwc->state & PERF_HES_STOPPED)) { | ||
254 | armpmu->disable(hwc, hwc->idx); | ||
255 | barrier(); /* why? */ | ||
256 | armpmu_event_update(event, hwc, hwc->idx); | ||
257 | hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
258 | } | ||
260 | } | 259 | } |
261 | 260 | ||
262 | static void | 261 | static void |
263 | armpmu_unthrottle(struct perf_event *event) | 262 | armpmu_start(struct perf_event *event, int flags) |
264 | { | 263 | { |
265 | struct hw_perf_event *hwc = &event->hw; | 264 | struct hw_perf_event *hwc = &event->hw; |
266 | 265 | ||
266 | if (!armpmu) | ||
267 | return; | ||
268 | |||
269 | /* | ||
270 | * ARM pmu always has to reprogram the period, so ignore | ||
271 | * PERF_EF_RELOAD, see the comment below. | ||
272 | */ | ||
273 | if (flags & PERF_EF_RELOAD) | ||
274 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); | ||
275 | |||
276 | hwc->state = 0; | ||
267 | /* | 277 | /* |
268 | * Set the period again. Some counters can't be stopped, so when we | 278 | * Set the period again. Some counters can't be stopped, so when we |
269 | * were throttled we simply disabled the IRQ source and the counter | 279 | * were stopped we simply disabled the IRQ source and the counter |
270 | * may have been left counting. If we don't do this step then we may | 280 | * may have been left counting. If we don't do this step then we may |
271 | * get an interrupt too soon or *way* too late if the overflow has | 281 | * get an interrupt too soon or *way* too late if the overflow has |
272 | * happened since disabling. | 282 | * happened since disabling. |
@@ -275,14 +285,33 @@ armpmu_unthrottle(struct perf_event *event) | |||
275 | armpmu->enable(hwc, hwc->idx); | 285 | armpmu->enable(hwc, hwc->idx); |
276 | } | 286 | } |
277 | 287 | ||
288 | static void | ||
289 | armpmu_del(struct perf_event *event, int flags) | ||
290 | { | ||
291 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
292 | struct hw_perf_event *hwc = &event->hw; | ||
293 | int idx = hwc->idx; | ||
294 | |||
295 | WARN_ON(idx < 0); | ||
296 | |||
297 | clear_bit(idx, cpuc->active_mask); | ||
298 | armpmu_stop(event, PERF_EF_UPDATE); | ||
299 | cpuc->events[idx] = NULL; | ||
300 | clear_bit(idx, cpuc->used_mask); | ||
301 | |||
302 | perf_event_update_userpage(event); | ||
303 | } | ||
304 | |||
278 | static int | 305 | static int |
279 | armpmu_enable(struct perf_event *event) | 306 | armpmu_add(struct perf_event *event, int flags) |
280 | { | 307 | { |
281 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 308 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
282 | struct hw_perf_event *hwc = &event->hw; | 309 | struct hw_perf_event *hwc = &event->hw; |
283 | int idx; | 310 | int idx; |
284 | int err = 0; | 311 | int err = 0; |
285 | 312 | ||
313 | perf_pmu_disable(event->pmu); | ||
314 | |||
286 | /* If we don't have a space for the counter then finish early. */ | 315 | /* If we don't have a space for the counter then finish early. */ |
287 | idx = armpmu->get_event_idx(cpuc, hwc); | 316 | idx = armpmu->get_event_idx(cpuc, hwc); |
288 | if (idx < 0) { | 317 | if (idx < 0) { |
@@ -299,25 +328,19 @@ armpmu_enable(struct perf_event *event) | |||
299 | cpuc->events[idx] = event; | 328 | cpuc->events[idx] = event; |
300 | set_bit(idx, cpuc->active_mask); | 329 | set_bit(idx, cpuc->active_mask); |
301 | 330 | ||
302 | /* Set the period for the event. */ | 331 | hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; |
303 | armpmu_event_set_period(event, hwc, idx); | 332 | if (flags & PERF_EF_START) |
304 | 333 | armpmu_start(event, PERF_EF_RELOAD); | |
305 | /* Enable the event. */ | ||
306 | armpmu->enable(hwc, idx); | ||
307 | 334 | ||
308 | /* Propagate our changes to the userspace mapping. */ | 335 | /* Propagate our changes to the userspace mapping. */ |
309 | perf_event_update_userpage(event); | 336 | perf_event_update_userpage(event); |
310 | 337 | ||
311 | out: | 338 | out: |
339 | perf_pmu_enable(event->pmu); | ||
312 | return err; | 340 | return err; |
313 | } | 341 | } |
314 | 342 | ||
315 | static struct pmu pmu = { | 343 | static struct pmu pmu; |
316 | .enable = armpmu_enable, | ||
317 | .disable = armpmu_disable, | ||
318 | .unthrottle = armpmu_unthrottle, | ||
319 | .read = armpmu_read, | ||
320 | }; | ||
321 | 344 | ||
322 | static int | 345 | static int |
323 | validate_event(struct cpu_hw_events *cpuc, | 346 | validate_event(struct cpu_hw_events *cpuc, |
@@ -497,20 +520,29 @@ __hw_perf_event_init(struct perf_event *event) | |||
497 | return err; | 520 | return err; |
498 | } | 521 | } |
499 | 522 | ||
500 | const struct pmu * | 523 | static int armpmu_event_init(struct perf_event *event) |
501 | hw_perf_event_init(struct perf_event *event) | ||
502 | { | 524 | { |
503 | int err = 0; | 525 | int err = 0; |
504 | 526 | ||
527 | switch (event->attr.type) { | ||
528 | case PERF_TYPE_RAW: | ||
529 | case PERF_TYPE_HARDWARE: | ||
530 | case PERF_TYPE_HW_CACHE: | ||
531 | break; | ||
532 | |||
533 | default: | ||
534 | return -ENOENT; | ||
535 | } | ||
536 | |||
505 | if (!armpmu) | 537 | if (!armpmu) |
506 | return ERR_PTR(-ENODEV); | 538 | return -ENODEV; |
507 | 539 | ||
508 | event->destroy = hw_perf_event_destroy; | 540 | event->destroy = hw_perf_event_destroy; |
509 | 541 | ||
510 | if (!atomic_inc_not_zero(&active_events)) { | 542 | if (!atomic_inc_not_zero(&active_events)) { |
511 | if (atomic_read(&active_events) > perf_max_events) { | 543 | if (atomic_read(&active_events) > armpmu->num_events) { |
512 | atomic_dec(&active_events); | 544 | atomic_dec(&active_events); |
513 | return ERR_PTR(-ENOSPC); | 545 | return -ENOSPC; |
514 | } | 546 | } |
515 | 547 | ||
516 | mutex_lock(&pmu_reserve_mutex); | 548 | mutex_lock(&pmu_reserve_mutex); |
@@ -524,17 +556,16 @@ hw_perf_event_init(struct perf_event *event) | |||
524 | } | 556 | } |
525 | 557 | ||
526 | if (err) | 558 | if (err) |
527 | return ERR_PTR(err); | 559 | return err; |
528 | 560 | ||
529 | err = __hw_perf_event_init(event); | 561 | err = __hw_perf_event_init(event); |
530 | if (err) | 562 | if (err) |
531 | hw_perf_event_destroy(event); | 563 | hw_perf_event_destroy(event); |
532 | 564 | ||
533 | return err ? ERR_PTR(err) : &pmu; | 565 | return err; |
534 | } | 566 | } |
535 | 567 | ||
536 | void | 568 | static void armpmu_enable(struct pmu *pmu) |
537 | hw_perf_enable(void) | ||
538 | { | 569 | { |
539 | /* Enable all of the perf events on hardware. */ | 570 | /* Enable all of the perf events on hardware. */ |
540 | int idx; | 571 | int idx; |
@@ -555,13 +586,23 @@ hw_perf_enable(void) | |||
555 | armpmu->start(); | 586 | armpmu->start(); |
556 | } | 587 | } |
557 | 588 | ||
558 | void | 589 | static void armpmu_disable(struct pmu *pmu) |
559 | hw_perf_disable(void) | ||
560 | { | 590 | { |
561 | if (armpmu) | 591 | if (armpmu) |
562 | armpmu->stop(); | 592 | armpmu->stop(); |
563 | } | 593 | } |
564 | 594 | ||
595 | static struct pmu pmu = { | ||
596 | .pmu_enable = armpmu_enable, | ||
597 | .pmu_disable = armpmu_disable, | ||
598 | .event_init = armpmu_event_init, | ||
599 | .add = armpmu_add, | ||
600 | .del = armpmu_del, | ||
601 | .start = armpmu_start, | ||
602 | .stop = armpmu_stop, | ||
603 | .read = armpmu_read, | ||
604 | }; | ||
605 | |||
565 | /* | 606 | /* |
566 | * ARMv6 Performance counter handling code. | 607 | * ARMv6 Performance counter handling code. |
567 | * | 608 | * |
@@ -2939,14 +2980,12 @@ init_hw_perf_events(void) | |||
2939 | armpmu = &armv6pmu; | 2980 | armpmu = &armv6pmu; |
2940 | memcpy(armpmu_perf_cache_map, armv6_perf_cache_map, | 2981 | memcpy(armpmu_perf_cache_map, armv6_perf_cache_map, |
2941 | sizeof(armv6_perf_cache_map)); | 2982 | sizeof(armv6_perf_cache_map)); |
2942 | perf_max_events = armv6pmu.num_events; | ||
2943 | break; | 2983 | break; |
2944 | case 0xB020: /* ARM11mpcore */ | 2984 | case 0xB020: /* ARM11mpcore */ |
2945 | armpmu = &armv6mpcore_pmu; | 2985 | armpmu = &armv6mpcore_pmu; |
2946 | memcpy(armpmu_perf_cache_map, | 2986 | memcpy(armpmu_perf_cache_map, |
2947 | armv6mpcore_perf_cache_map, | 2987 | armv6mpcore_perf_cache_map, |
2948 | sizeof(armv6mpcore_perf_cache_map)); | 2988 | sizeof(armv6mpcore_perf_cache_map)); |
2949 | perf_max_events = armv6mpcore_pmu.num_events; | ||
2950 | break; | 2989 | break; |
2951 | case 0xC080: /* Cortex-A8 */ | 2990 | case 0xC080: /* Cortex-A8 */ |
2952 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; | 2991 | armv7pmu.id = ARM_PERF_PMU_ID_CA8; |
@@ -2958,7 +2997,6 @@ init_hw_perf_events(void) | |||
2958 | /* Reset PMNC and read the nb of CNTx counters | 2997 | /* Reset PMNC and read the nb of CNTx counters |
2959 | supported */ | 2998 | supported */ |
2960 | armv7pmu.num_events = armv7_reset_read_pmnc(); | 2999 | armv7pmu.num_events = armv7_reset_read_pmnc(); |
2961 | perf_max_events = armv7pmu.num_events; | ||
2962 | break; | 3000 | break; |
2963 | case 0xC090: /* Cortex-A9 */ | 3001 | case 0xC090: /* Cortex-A9 */ |
2964 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; | 3002 | armv7pmu.id = ARM_PERF_PMU_ID_CA9; |
@@ -2970,7 +3008,6 @@ init_hw_perf_events(void) | |||
2970 | /* Reset PMNC and read the nb of CNTx counters | 3008 | /* Reset PMNC and read the nb of CNTx counters |
2971 | supported */ | 3009 | supported */ |
2972 | armv7pmu.num_events = armv7_reset_read_pmnc(); | 3010 | armv7pmu.num_events = armv7_reset_read_pmnc(); |
2973 | perf_max_events = armv7pmu.num_events; | ||
2974 | break; | 3011 | break; |
2975 | } | 3012 | } |
2976 | /* Intel CPUs [xscale]. */ | 3013 | /* Intel CPUs [xscale]. */ |
@@ -2981,13 +3018,11 @@ init_hw_perf_events(void) | |||
2981 | armpmu = &xscale1pmu; | 3018 | armpmu = &xscale1pmu; |
2982 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, | 3019 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, |
2983 | sizeof(xscale_perf_cache_map)); | 3020 | sizeof(xscale_perf_cache_map)); |
2984 | perf_max_events = xscale1pmu.num_events; | ||
2985 | break; | 3021 | break; |
2986 | case 2: | 3022 | case 2: |
2987 | armpmu = &xscale2pmu; | 3023 | armpmu = &xscale2pmu; |
2988 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, | 3024 | memcpy(armpmu_perf_cache_map, xscale_perf_cache_map, |
2989 | sizeof(xscale_perf_cache_map)); | 3025 | sizeof(xscale_perf_cache_map)); |
2990 | perf_max_events = xscale2pmu.num_events; | ||
2991 | break; | 3026 | break; |
2992 | } | 3027 | } |
2993 | } | 3028 | } |
@@ -2997,9 +3032,10 @@ init_hw_perf_events(void) | |||
2997 | arm_pmu_names[armpmu->id], armpmu->num_events); | 3032 | arm_pmu_names[armpmu->id], armpmu->num_events); |
2998 | } else { | 3033 | } else { |
2999 | pr_info("no hardware support available\n"); | 3034 | pr_info("no hardware support available\n"); |
3000 | perf_max_events = -1; | ||
3001 | } | 3035 | } |
3002 | 3036 | ||
3037 | perf_pmu_register(&pmu); | ||
3038 | |||
3003 | return 0; | 3039 | return 0; |
3004 | } | 3040 | } |
3005 | arch_initcall(init_hw_perf_events); | 3041 | arch_initcall(init_hw_perf_events); |
@@ -3007,13 +3043,6 @@ arch_initcall(init_hw_perf_events); | |||
3007 | /* | 3043 | /* |
3008 | * Callchain handling code. | 3044 | * Callchain handling code. |
3009 | */ | 3045 | */ |
3010 | static inline void | ||
3011 | callchain_store(struct perf_callchain_entry *entry, | ||
3012 | u64 ip) | ||
3013 | { | ||
3014 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
3015 | entry->ip[entry->nr++] = ip; | ||
3016 | } | ||
3017 | 3046 | ||
3018 | /* | 3047 | /* |
3019 | * The registers we're interested in are at the end of the variable | 3048 | * The registers we're interested in are at the end of the variable |
@@ -3045,7 +3074,7 @@ user_backtrace(struct frame_tail *tail, | |||
3045 | if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail))) | 3074 | if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail))) |
3046 | return NULL; | 3075 | return NULL; |
3047 | 3076 | ||
3048 | callchain_store(entry, buftail.lr); | 3077 | perf_callchain_store(entry, buftail.lr); |
3049 | 3078 | ||
3050 | /* | 3079 | /* |
3051 | * Frame pointers should strictly progress back up the stack | 3080 | * Frame pointers should strictly progress back up the stack |
@@ -3057,16 +3086,11 @@ user_backtrace(struct frame_tail *tail, | |||
3057 | return buftail.fp - 1; | 3086 | return buftail.fp - 1; |
3058 | } | 3087 | } |
3059 | 3088 | ||
3060 | static void | 3089 | void |
3061 | perf_callchain_user(struct pt_regs *regs, | 3090 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) |
3062 | struct perf_callchain_entry *entry) | ||
3063 | { | 3091 | { |
3064 | struct frame_tail *tail; | 3092 | struct frame_tail *tail; |
3065 | 3093 | ||
3066 | callchain_store(entry, PERF_CONTEXT_USER); | ||
3067 | |||
3068 | if (!user_mode(regs)) | ||
3069 | regs = task_pt_regs(current); | ||
3070 | 3094 | ||
3071 | tail = (struct frame_tail *)regs->ARM_fp - 1; | 3095 | tail = (struct frame_tail *)regs->ARM_fp - 1; |
3072 | 3096 | ||
@@ -3084,56 +3108,18 @@ callchain_trace(struct stackframe *fr, | |||
3084 | void *data) | 3108 | void *data) |
3085 | { | 3109 | { |
3086 | struct perf_callchain_entry *entry = data; | 3110 | struct perf_callchain_entry *entry = data; |
3087 | callchain_store(entry, fr->pc); | 3111 | perf_callchain_store(entry, fr->pc); |
3088 | return 0; | 3112 | return 0; |
3089 | } | 3113 | } |
3090 | 3114 | ||
3091 | static void | 3115 | void |
3092 | perf_callchain_kernel(struct pt_regs *regs, | 3116 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
3093 | struct perf_callchain_entry *entry) | ||
3094 | { | 3117 | { |
3095 | struct stackframe fr; | 3118 | struct stackframe fr; |
3096 | 3119 | ||
3097 | callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
3098 | fr.fp = regs->ARM_fp; | 3120 | fr.fp = regs->ARM_fp; |
3099 | fr.sp = regs->ARM_sp; | 3121 | fr.sp = regs->ARM_sp; |
3100 | fr.lr = regs->ARM_lr; | 3122 | fr.lr = regs->ARM_lr; |
3101 | fr.pc = regs->ARM_pc; | 3123 | fr.pc = regs->ARM_pc; |
3102 | walk_stackframe(&fr, callchain_trace, entry); | 3124 | walk_stackframe(&fr, callchain_trace, entry); |
3103 | } | 3125 | } |
3104 | |||
3105 | static void | ||
3106 | perf_do_callchain(struct pt_regs *regs, | ||
3107 | struct perf_callchain_entry *entry) | ||
3108 | { | ||
3109 | int is_user; | ||
3110 | |||
3111 | if (!regs) | ||
3112 | return; | ||
3113 | |||
3114 | is_user = user_mode(regs); | ||
3115 | |||
3116 | if (!current || !current->pid) | ||
3117 | return; | ||
3118 | |||
3119 | if (is_user && current->state != TASK_RUNNING) | ||
3120 | return; | ||
3121 | |||
3122 | if (!is_user) | ||
3123 | perf_callchain_kernel(regs, entry); | ||
3124 | |||
3125 | if (current->mm) | ||
3126 | perf_callchain_user(regs, entry); | ||
3127 | } | ||
3128 | |||
3129 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); | ||
3130 | |||
3131 | struct perf_callchain_entry * | ||
3132 | perf_callchain(struct pt_regs *regs) | ||
3133 | { | ||
3134 | struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry); | ||
3135 | |||
3136 | entry->nr = 0; | ||
3137 | perf_do_callchain(regs, entry); | ||
3138 | return entry; | ||
3139 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 5e71ccd5e7d3..1276babf84d5 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -426,7 +426,7 @@ static struct i2c_gpio_platform_data pdata_i2c0 = { | |||
426 | .sda_is_open_drain = 1, | 426 | .sda_is_open_drain = 1, |
427 | .scl_pin = AT91_PIN_PA21, | 427 | .scl_pin = AT91_PIN_PA21, |
428 | .scl_is_open_drain = 1, | 428 | .scl_is_open_drain = 1, |
429 | .udelay = 2, /* ~100 kHz */ | 429 | .udelay = 5, /* ~100 kHz */ |
430 | }; | 430 | }; |
431 | 431 | ||
432 | static struct platform_device at91sam9g45_twi0_device = { | 432 | static struct platform_device at91sam9g45_twi0_device = { |
@@ -440,7 +440,7 @@ static struct i2c_gpio_platform_data pdata_i2c1 = { | |||
440 | .sda_is_open_drain = 1, | 440 | .sda_is_open_drain = 1, |
441 | .scl_pin = AT91_PIN_PB11, | 441 | .scl_pin = AT91_PIN_PB11, |
442 | .scl_is_open_drain = 1, | 442 | .scl_is_open_drain = 1, |
443 | .udelay = 2, /* ~100 kHz */ | 443 | .udelay = 5, /* ~100 kHz */ |
444 | }; | 444 | }; |
445 | 445 | ||
446 | static struct platform_device at91sam9g45_twi1_device = { | 446 | static struct platform_device at91sam9g45_twi1_device = { |
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3d996b659ff4..9be261beae7d 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c | |||
@@ -769,8 +769,7 @@ static struct map_desc dm355_io_desc[] = { | |||
769 | .virtual = SRAM_VIRT, | 769 | .virtual = SRAM_VIRT, |
770 | .pfn = __phys_to_pfn(0x00010000), | 770 | .pfn = __phys_to_pfn(0x00010000), |
771 | .length = SZ_32K, | 771 | .length = SZ_32K, |
772 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 772 | .type = MT_MEMORY_NONCACHED, |
773 | .type = MT_DEVICE, | ||
774 | }, | 773 | }, |
775 | }; | 774 | }; |
776 | 775 | ||
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 6b6f4c643709..7781e35daec3 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c | |||
@@ -969,8 +969,7 @@ static struct map_desc dm365_io_desc[] = { | |||
969 | .virtual = SRAM_VIRT, | 969 | .virtual = SRAM_VIRT, |
970 | .pfn = __phys_to_pfn(0x00010000), | 970 | .pfn = __phys_to_pfn(0x00010000), |
971 | .length = SZ_32K, | 971 | .length = SZ_32K, |
972 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 972 | .type = MT_MEMORY_NONCACHED, |
973 | .type = MT_DEVICE, | ||
974 | }, | 973 | }, |
975 | }; | 974 | }; |
976 | 975 | ||
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 40fec315c99a..5e5b0a7831fb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -653,8 +653,7 @@ static struct map_desc dm644x_io_desc[] = { | |||
653 | .virtual = SRAM_VIRT, | 653 | .virtual = SRAM_VIRT, |
654 | .pfn = __phys_to_pfn(0x00008000), | 654 | .pfn = __phys_to_pfn(0x00008000), |
655 | .length = SZ_16K, | 655 | .length = SZ_16K, |
656 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 656 | .type = MT_MEMORY_NONCACHED, |
657 | .type = MT_DEVICE, | ||
658 | }, | 657 | }, |
659 | }; | 658 | }; |
660 | 659 | ||
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e4a3df1872ac..26e8a9c7f50b 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -737,8 +737,7 @@ static struct map_desc dm646x_io_desc[] = { | |||
737 | .virtual = SRAM_VIRT, | 737 | .virtual = SRAM_VIRT, |
738 | .pfn = __phys_to_pfn(0x00010000), | 738 | .pfn = __phys_to_pfn(0x00010000), |
739 | .length = SZ_32K, | 739 | .length = SZ_32K, |
740 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 740 | .type = MT_MEMORY_NONCACHED, |
741 | .type = MT_DEVICE, | ||
742 | }, | 741 | }, |
743 | }; | 742 | }; |
744 | 743 | ||
diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h index 3b3e4721ce2e..eb4936ff90ad 100644 --- a/arch/arm/mach-dove/include/mach/io.h +++ b/arch/arm/mach-dove/include/mach/io.h | |||
@@ -13,8 +13,8 @@ | |||
13 | 13 | ||
14 | #define IO_SPACE_LIMIT 0xffffffff | 14 | #define IO_SPACE_LIMIT 0xffffffff |
15 | 15 | ||
16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\ | 16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \ |
17 | DOVE_PCIE0_IO_VIRT_BASE)) | 17 | DOVE_PCIE0_IO_VIRT_BASE)) |
18 | #define __mem_pci(a) (a) | 18 | #define __mem_pci(a) (a) |
19 | 19 | ||
20 | #endif | 20 | #endif |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 61cd4d64b985..24498a932ba6 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -503,6 +503,14 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) | |||
503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); | 503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); |
504 | } | 504 | } |
505 | 505 | ||
506 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
507 | { | ||
508 | if (mask >= SZ_64M - 1) | ||
509 | return 0; | ||
510 | |||
511 | return -EIO; | ||
512 | } | ||
513 | |||
506 | EXPORT_SYMBOL(ixp4xx_pci_read); | 514 | EXPORT_SYMBOL(ixp4xx_pci_read); |
507 | EXPORT_SYMBOL(ixp4xx_pci_write); | 515 | EXPORT_SYMBOL(ixp4xx_pci_write); |
508 | 516 | ||
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index f91ca6d4fbe8..8138371c406e 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF | 26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
30 | |||
29 | #define pcibios_assign_all_busses() 1 | 31 | #define pcibios_assign_all_busses() 1 |
30 | 32 | ||
31 | /* Register locations and bits */ | 33 | /* Register locations and bits */ |
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 93fc2ec95e76..6e924b398919 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 | 39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 |
40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 | 40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 |
41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000 | 41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000 |
42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M | 42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M |
43 | 43 | ||
44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 | 44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 |
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 55e7f00836b7..513ad3102d7c 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c | |||
@@ -117,7 +117,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp) | |||
117 | * IORESOURCE_IO | 117 | * IORESOURCE_IO |
118 | */ | 118 | */ |
119 | pp->res[0].name = "PCIe 0 I/O Space"; | 119 | pp->res[0].name = "PCIe 0 I/O Space"; |
120 | pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; | 120 | pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE; |
121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; | 121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; |
122 | pp->res[0].flags = IORESOURCE_IO; | 122 | pp->res[0].flags = IORESOURCE_IO; |
123 | 123 | ||
@@ -139,7 +139,7 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp) | |||
139 | * IORESOURCE_IO | 139 | * IORESOURCE_IO |
140 | */ | 140 | */ |
141 | pp->res[0].name = "PCIe 1 I/O Space"; | 141 | pp->res[0].name = "PCIe 1 I/O Space"; |
142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE; | 142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE; |
143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; | 143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; |
144 | pp->res[0].flags = IORESOURCE_IO; | 144 | pp->res[0].flags = IORESOURCE_IO; |
145 | 145 | ||
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h index 4f5b0e0ce6cf..1a8a25edb1b4 100644 --- a/arch/arm/mach-mmp/include/mach/system.h +++ b/arch/arm/mach-mmp/include/mach/system.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef __ASM_MACH_SYSTEM_H | 9 | #ifndef __ASM_MACH_SYSTEM_H |
10 | #define __ASM_MACH_SYSTEM_H | 10 | #define __ASM_MACH_SYSTEM_H |
11 | 11 | ||
12 | #include <mach/cputype.h> | ||
13 | |||
12 | static inline void arch_idle(void) | 14 | static inline void arch_idle(void) |
13 | { | 15 | { |
14 | cpu_do_idle(); | 16 | cpu_do_idle(); |
@@ -16,6 +18,9 @@ static inline void arch_idle(void) | |||
16 | 18 | ||
17 | static inline void arch_reset(char mode, const char *cmd) | 19 | static inline void arch_reset(char mode, const char *cmd) |
18 | { | 20 | { |
19 | cpu_reset(0); | 21 | if (cpu_is_pxa168()) |
22 | cpu_reset(0xffff0000); | ||
23 | else | ||
24 | cpu_reset(0); | ||
20 | } | 25 | } |
21 | #endif /* __ASM_MACH_SYSTEM_H */ | 26 | #endif /* __ASM_MACH_SYSTEM_H */ |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 50d5939a78f1..58093d9e07be 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -312,8 +312,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
312 | freqs.cpu = policy->cpu; | 312 | freqs.cpu = policy->cpu; |
313 | 313 | ||
314 | if (freq_debug) | 314 | if (freq_debug) |
315 | pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, " | 315 | pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", |
316 | "(SDRAM %d Mhz)\n", | ||
317 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? | 316 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? |
318 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); | 317 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); |
319 | 318 | ||
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 7f64d24cd564..814f1458a06a 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h | |||
@@ -264,23 +264,35 @@ | |||
264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x | 264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x |
265 | * == 0x3 for pxa300/pxa310/pxa320 | 265 | * == 0x3 for pxa300/pxa310/pxa320 |
266 | */ | 266 | */ |
267 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
267 | #define __cpu_is_pxa2xx(id) \ | 268 | #define __cpu_is_pxa2xx(id) \ |
268 | ({ \ | 269 | ({ \ |
269 | unsigned int _id = (id) >> 13 & 0x7; \ | 270 | unsigned int _id = (id) >> 13 & 0x7; \ |
270 | _id <= 0x2; \ | 271 | _id <= 0x2; \ |
271 | }) | 272 | }) |
273 | #else | ||
274 | #define __cpu_is_pxa2xx(id) (0) | ||
275 | #endif | ||
272 | 276 | ||
277 | #ifdef CONFIG_PXA3xx | ||
273 | #define __cpu_is_pxa3xx(id) \ | 278 | #define __cpu_is_pxa3xx(id) \ |
274 | ({ \ | 279 | ({ \ |
275 | unsigned int _id = (id) >> 13 & 0x7; \ | 280 | unsigned int _id = (id) >> 13 & 0x7; \ |
276 | _id == 0x3; \ | 281 | _id == 0x3; \ |
277 | }) | 282 | }) |
283 | #else | ||
284 | #define __cpu_is_pxa3xx(id) (0) | ||
285 | #endif | ||
278 | 286 | ||
287 | #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) | ||
279 | #define __cpu_is_pxa93x(id) \ | 288 | #define __cpu_is_pxa93x(id) \ |
280 | ({ \ | 289 | ({ \ |
281 | unsigned int _id = (id) >> 4 & 0xfff; \ | 290 | unsigned int _id = (id) >> 4 & 0xfff; \ |
282 | _id == 0x683 || _id == 0x693; \ | 291 | _id == 0x683 || _id == 0x693; \ |
283 | }) | 292 | }) |
293 | #else | ||
294 | #define __cpu_is_pxa93x(id) (0) | ||
295 | #endif | ||
284 | 296 | ||
285 | #define cpu_is_pxa2xx() \ | 297 | #define cpu_is_pxa2xx() \ |
286 | ({ \ | 298 | ({ \ |
@@ -309,7 +321,7 @@ extern unsigned long get_clock_tick_rate(void); | |||
309 | #define PCIBIOS_MIN_IO 0 | 321 | #define PCIBIOS_MIN_IO 0 |
310 | #define PCIBIOS_MIN_MEM 0 | 322 | #define PCIBIOS_MIN_MEM 0 |
311 | #define pcibios_assign_all_busses() 1 | 323 | #define pcibios_assign_all_busses() 1 |
324 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
312 | #endif | 325 | #endif |
313 | 326 | ||
314 | |||
315 | #endif /* _ASM_ARCH_HARDWARE_H */ | 327 | #endif /* _ASM_ARCH_HARDWARE_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 262691fb97d8..fdca3be47d9b 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __ASM_ARM_ARCH_IO_H | 6 | #ifndef __ASM_ARM_ARCH_IO_H |
7 | #define __ASM_ARM_ARCH_IO_H | 7 | #define __ASM_ARM_ARCH_IO_H |
8 | 8 | ||
9 | #include <mach/hardware.h> | ||
10 | |||
9 | #define IO_SPACE_LIMIT 0xffffffff | 11 | #define IO_SPACE_LIMIT 0xffffffff |
10 | 12 | ||
11 | /* | 13 | /* |
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 77ad6d34ab5b..405b92a29793 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c | |||
@@ -469,9 +469,13 @@ static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = { | |||
469 | }, | 469 | }, |
470 | }; | 470 | }; |
471 | 471 | ||
472 | static struct i2c_pxa_platform_data palm27x_i2c_power_info = { | ||
473 | .use_pio = 1, | ||
474 | }; | ||
475 | |||
472 | void __init palm27x_pmic_init(void) | 476 | void __init palm27x_pmic_init(void) |
473 | { | 477 | { |
474 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); | 478 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); |
475 | pxa27x_set_i2c_power_info(NULL); | 479 | pxa27x_set_i2c_power_info(&palm27x_i2c_power_info); |
476 | } | 480 | } |
477 | #endif | 481 | #endif |
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index c9b747cedea8..37d6173bbb66 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c | |||
@@ -240,6 +240,7 @@ static void __init vpac270_onenand_init(void) {} | |||
240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | 240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) |
241 | static struct pxamci_platform_data vpac270_mci_platform_data = { | 241 | static struct pxamci_platform_data vpac270_mci_platform_data = { |
242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
243 | .gpio_power = -1, | ||
243 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, | 244 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, |
244 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, | 245 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, |
245 | .detect_delay_ms = 200, | 246 | .detect_delay_ms = 200, |
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h index 7b1fc984abb6..d5a71abcbaea 100644 --- a/arch/arm/mach-u300/include/mach/gpio.h +++ b/arch/arm/mach-u300/include/mach/gpio.h | |||
@@ -273,6 +273,9 @@ extern void gpio_pullup(unsigned gpio, int value); | |||
273 | extern int gpio_get_value(unsigned gpio); | 273 | extern int gpio_get_value(unsigned gpio); |
274 | extern void gpio_set_value(unsigned gpio, int value); | 274 | extern void gpio_set_value(unsigned gpio, int value); |
275 | 275 | ||
276 | #define gpio_get_value_cansleep gpio_get_value | ||
277 | #define gpio_set_value_cansleep gpio_set_value | ||
278 | |||
276 | /* wrappers to sleep-enable the previous two functions */ | 279 | /* wrappers to sleep-enable the previous two functions */ |
277 | static inline unsigned gpio_to_irq(unsigned gpio) | 280 | static inline unsigned gpio_to_irq(unsigned gpio) |
278 | { | 281 | { |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 577df6cccb08..efb127022d42 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -227,7 +227,13 @@ static void ct_ca9x4_init(void) | |||
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | #ifdef CONFIG_CACHE_L2X0 | 229 | #ifdef CONFIG_CACHE_L2X0 |
230 | l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); | 230 | void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); |
231 | |||
232 | /* set RAM latencies to 1 cycle for this core tile. */ | ||
233 | writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); | ||
234 | writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL); | ||
235 | |||
236 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); | ||
231 | #endif | 237 | #endif |
232 | 238 | ||
233 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 239 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index d073b64ae87e..724ba3bce72c 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
885 | 885 | ||
886 | if (ai_usermode & UM_SIGNAL) | 886 | if (ai_usermode & UM_SIGNAL) |
887 | force_sig(SIGBUS, current); | 887 | force_sig(SIGBUS, current); |
888 | else | 888 | else { |
889 | set_cr(cr_no_alignment); | 889 | /* |
890 | * We're about to disable the alignment trap and return to | ||
891 | * user space. But if an interrupt occurs before actually | ||
892 | * reaching user space, then the IRQ vector entry code will | ||
893 | * notice that we were still in kernel space and therefore | ||
894 | * the alignment trap won't be re-enabled in that case as it | ||
895 | * is presumed to be always on from kernel space. | ||
896 | * Let's prevent that race by disabling interrupts here (they | ||
897 | * are disabled on the way back to user space anyway in | ||
898 | * entry-common.S) and disable the alignment trap only if | ||
899 | * there is no work pending for this thread. | ||
900 | */ | ||
901 | raw_local_irq_disable(); | ||
902 | if (!(current_thread_info()->flags & _TIF_WORK_MASK)) | ||
903 | set_cr(cr_no_alignment); | ||
904 | } | ||
890 | 905 | ||
891 | return 0; | 906 | return 0; |
892 | } | 907 | } |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6e1c4f6a2b3f..6a3a2d0cd6db 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
17 | #include <linux/sort.h> | 17 | #include <linux/sort.h> |
18 | #include <linux/fs.h> | ||
18 | 19 | ||
19 | #include <asm/cputype.h> | 20 | #include <asm/cputype.h> |
20 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
@@ -246,6 +247,9 @@ static struct mem_type mem_types[] = { | |||
246 | .domain = DOMAIN_USER, | 247 | .domain = DOMAIN_USER, |
247 | }, | 248 | }, |
248 | [MT_MEMORY] = { | 249 | [MT_MEMORY] = { |
250 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
251 | L_PTE_USER | L_PTE_EXEC, | ||
252 | .prot_l1 = PMD_TYPE_TABLE, | ||
249 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 253 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
250 | .domain = DOMAIN_KERNEL, | 254 | .domain = DOMAIN_KERNEL, |
251 | }, | 255 | }, |
@@ -254,6 +258,9 @@ static struct mem_type mem_types[] = { | |||
254 | .domain = DOMAIN_KERNEL, | 258 | .domain = DOMAIN_KERNEL, |
255 | }, | 259 | }, |
256 | [MT_MEMORY_NONCACHED] = { | 260 | [MT_MEMORY_NONCACHED] = { |
261 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
262 | L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, | ||
263 | .prot_l1 = PMD_TYPE_TABLE, | ||
257 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 264 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
258 | .domain = DOMAIN_KERNEL, | 265 | .domain = DOMAIN_KERNEL, |
259 | }, | 266 | }, |
@@ -411,9 +418,12 @@ static void __init build_mem_type_table(void) | |||
411 | * Enable CPU-specific coherency if supported. | 418 | * Enable CPU-specific coherency if supported. |
412 | * (Only available on XSC3 at the moment.) | 419 | * (Only available on XSC3 at the moment.) |
413 | */ | 420 | */ |
414 | if (arch_is_coherent() && cpu_is_xsc3()) | 421 | if (arch_is_coherent() && cpu_is_xsc3()) { |
415 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 422 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
416 | 423 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | |
424 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | ||
425 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
426 | } | ||
417 | /* | 427 | /* |
418 | * ARMv6 and above have extended page tables. | 428 | * ARMv6 and above have extended page tables. |
419 | */ | 429 | */ |
@@ -438,7 +448,9 @@ static void __init build_mem_type_table(void) | |||
438 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; | 448 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; |
439 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | 449 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; |
440 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 450 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
451 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | ||
441 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | 452 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; |
453 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
442 | #endif | 454 | #endif |
443 | } | 455 | } |
444 | 456 | ||
@@ -475,6 +487,8 @@ static void __init build_mem_type_table(void) | |||
475 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 487 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
476 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 488 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
477 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 489 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; |
490 | mem_types[MT_MEMORY].prot_pte |= kern_pgprot; | ||
491 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; | ||
478 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 492 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
479 | 493 | ||
480 | switch (cp->pmd) { | 494 | switch (cp->pmd) { |
@@ -498,6 +512,19 @@ static void __init build_mem_type_table(void) | |||
498 | } | 512 | } |
499 | } | 513 | } |
500 | 514 | ||
515 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | ||
516 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
517 | unsigned long size, pgprot_t vma_prot) | ||
518 | { | ||
519 | if (!pfn_valid(pfn)) | ||
520 | return pgprot_noncached(vma_prot); | ||
521 | else if (file->f_flags & O_SYNC) | ||
522 | return pgprot_writecombine(vma_prot); | ||
523 | return vma_prot; | ||
524 | } | ||
525 | EXPORT_SYMBOL(phys_mem_access_prot); | ||
526 | #endif | ||
527 | |||
501 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) | 528 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) |
502 | 529 | ||
503 | static void __init *early_alloc(unsigned long sz) | 530 | static void __init *early_alloc(unsigned long sz) |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 6a8506d99ee9..7563ff0141bd 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -186,13 +186,14 @@ cpu_v7_name: | |||
186 | * It is assumed that: | 186 | * It is assumed that: |
187 | * - cache type register is implemented | 187 | * - cache type register is implemented |
188 | */ | 188 | */ |
189 | __v7_setup: | 189 | __v7_ca9mp_setup: |
190 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
191 | mrc p15, 0, r0, c1, c0, 1 | 191 | mrc p15, 0, r0, c1, c0, 1 |
192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? | 192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? |
193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and | 193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and |
194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting | 194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting |
195 | #endif | 195 | #endif |
196 | __v7_setup: | ||
196 | adr r12, __v7_setup_stack @ the local stack | 197 | adr r12, __v7_setup_stack @ the local stack |
197 | stmia r12, {r0-r5, r7, r9, r11, lr} | 198 | stmia r12, {r0-r5, r7, r9, r11, lr} |
198 | bl v7_flush_dcache_all | 199 | bl v7_flush_dcache_all |
@@ -201,11 +202,16 @@ __v7_setup: | |||
201 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register | 202 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register |
202 | and r10, r0, #0xff000000 @ ARM? | 203 | and r10, r0, #0xff000000 @ ARM? |
203 | teq r10, #0x41000000 | 204 | teq r10, #0x41000000 |
204 | bne 2f | 205 | bne 3f |
205 | and r5, r0, #0x00f00000 @ variant | 206 | and r5, r0, #0x00f00000 @ variant |
206 | and r6, r0, #0x0000000f @ revision | 207 | and r6, r0, #0x0000000f @ revision |
207 | orr r0, r6, r5, lsr #20-4 @ combine variant and revision | 208 | orr r6, r6, r5, lsr #20-4 @ combine variant and revision |
209 | ubfx r0, r0, #4, #12 @ primary part number | ||
208 | 210 | ||
211 | /* Cortex-A8 Errata */ | ||
212 | ldr r10, =0x00000c08 @ Cortex-A8 primary part number | ||
213 | teq r0, r10 | ||
214 | bne 2f | ||
209 | #ifdef CONFIG_ARM_ERRATA_430973 | 215 | #ifdef CONFIG_ARM_ERRATA_430973 |
210 | teq r5, #0x00100000 @ only present in r1p* | 216 | teq r5, #0x00100000 @ only present in r1p* |
211 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
@@ -213,21 +219,42 @@ __v7_setup: | |||
213 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 219 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
214 | #endif | 220 | #endif |
215 | #ifdef CONFIG_ARM_ERRATA_458693 | 221 | #ifdef CONFIG_ARM_ERRATA_458693 |
216 | teq r0, #0x20 @ only present in r2p0 | 222 | teq r6, #0x20 @ only present in r2p0 |
217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 223 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
218 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 | 224 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 |
219 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 | 225 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 |
220 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 226 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
221 | #endif | 227 | #endif |
222 | #ifdef CONFIG_ARM_ERRATA_460075 | 228 | #ifdef CONFIG_ARM_ERRATA_460075 |
223 | teq r0, #0x20 @ only present in r2p0 | 229 | teq r6, #0x20 @ only present in r2p0 |
224 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register | 230 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register |
225 | tsteq r10, #1 << 22 | 231 | tsteq r10, #1 << 22 |
226 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit | 232 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit |
227 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register | 233 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register |
228 | #endif | 234 | #endif |
235 | b 3f | ||
236 | |||
237 | /* Cortex-A9 Errata */ | ||
238 | 2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number | ||
239 | teq r0, r10 | ||
240 | bne 3f | ||
241 | #ifdef CONFIG_ARM_ERRATA_742230 | ||
242 | cmp r6, #0x22 @ only present up to r2p2 | ||
243 | mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
244 | orrle r10, r10, #1 << 4 @ set bit #4 | ||
245 | mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
246 | #endif | ||
247 | #ifdef CONFIG_ARM_ERRATA_742231 | ||
248 | teq r6, #0x20 @ present in r2p0 | ||
249 | teqne r6, #0x21 @ present in r2p1 | ||
250 | teqne r6, #0x22 @ present in r2p2 | ||
251 | mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
252 | orreq r10, r10, #1 << 12 @ set bit #12 | ||
253 | orreq r10, r10, #1 << 22 @ set bit #22 | ||
254 | mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
255 | #endif | ||
229 | 256 | ||
230 | 2: mov r10, #0 | 257 | 3: mov r10, #0 |
231 | #ifdef HARVARD_CACHE | 258 | #ifdef HARVARD_CACHE |
232 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 259 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
233 | #endif | 260 | #endif |
@@ -323,6 +350,29 @@ cpu_elf_name: | |||
323 | 350 | ||
324 | .section ".proc.info.init", #alloc, #execinstr | 351 | .section ".proc.info.init", #alloc, #execinstr |
325 | 352 | ||
353 | .type __v7_ca9mp_proc_info, #object | ||
354 | __v7_ca9mp_proc_info: | ||
355 | .long 0x410fc090 @ Required ID value | ||
356 | .long 0xff0ffff0 @ Mask for ID | ||
357 | .long PMD_TYPE_SECT | \ | ||
358 | PMD_SECT_AP_WRITE | \ | ||
359 | PMD_SECT_AP_READ | \ | ||
360 | PMD_FLAGS | ||
361 | .long PMD_TYPE_SECT | \ | ||
362 | PMD_SECT_XN | \ | ||
363 | PMD_SECT_AP_WRITE | \ | ||
364 | PMD_SECT_AP_READ | ||
365 | b __v7_ca9mp_setup | ||
366 | .long cpu_arch_name | ||
367 | .long cpu_elf_name | ||
368 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | ||
369 | .long cpu_v7_name | ||
370 | .long v7_processor_functions | ||
371 | .long v7wbi_tlb_fns | ||
372 | .long v6_user_fns | ||
373 | .long v7_cache_fns | ||
374 | .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info | ||
375 | |||
326 | /* | 376 | /* |
327 | * Match any ARMv7 processor core. | 377 | * Match any ARMv7 processor core. |
328 | */ | 378 | */ |
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ea3ca86c5283..aedf9c1d645e 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-nomadik/timer.c | 2 | * linux/arch/arm/plat-nomadik/timer.c |
3 | * | 3 | * |
4 | * Copyright (C) 2008 STMicroelectronics | 4 | * Copyright (C) 2008 STMicroelectronics |
5 | * Copyright (C) 2010 Alessandro Rubini | 5 | * Copyright (C) 2010 Alessandro Rubini |
@@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode, | |||
75 | cr = readl(mtu_base + MTU_CR(1)); | 75 | cr = readl(mtu_base + MTU_CR(1)); |
76 | writel(0, mtu_base + MTU_LR(1)); | 76 | writel(0, mtu_base + MTU_LR(1)); |
77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); | 77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); |
78 | writel(0x2, mtu_base + MTU_IMSC); | 78 | writel(1 << 1, mtu_base + MTU_IMSC); |
79 | break; | 79 | break; |
80 | case CLOCK_EVT_MODE_SHUTDOWN: | 80 | case CLOCK_EVT_MODE_SHUTDOWN: |
81 | case CLOCK_EVT_MODE_UNUSED: | 81 | case CLOCK_EVT_MODE_UNUSED: |
@@ -131,25 +131,23 @@ void __init nmdk_timer_init(void) | |||
131 | { | 131 | { |
132 | unsigned long rate; | 132 | unsigned long rate; |
133 | struct clk *clk0; | 133 | struct clk *clk0; |
134 | struct clk *clk1; | 134 | u32 cr = MTU_CRn_32BITS; |
135 | u32 cr; | ||
136 | 135 | ||
137 | clk0 = clk_get_sys("mtu0", NULL); | 136 | clk0 = clk_get_sys("mtu0", NULL); |
138 | BUG_ON(IS_ERR(clk0)); | 137 | BUG_ON(IS_ERR(clk0)); |
139 | 138 | ||
140 | clk1 = clk_get_sys("mtu1", NULL); | ||
141 | BUG_ON(IS_ERR(clk1)); | ||
142 | |||
143 | clk_enable(clk0); | 139 | clk_enable(clk0); |
144 | clk_enable(clk1); | ||
145 | 140 | ||
146 | /* | 141 | /* |
147 | * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: | 142 | * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz |
148 | * use a divide-by-16 counter if it's more than 16MHz | 143 | * for ux500. |
144 | * Use a divide-by-16 counter if the tick rate is more than 32MHz. | ||
145 | * At 32 MHz, the timer (with 32 bit counter) can be programmed | ||
146 | * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer | ||
147 | * with 16 gives too low timer resolution. | ||
149 | */ | 148 | */ |
150 | cr = MTU_CRn_32BITS;; | ||
151 | rate = clk_get_rate(clk0); | 149 | rate = clk_get_rate(clk0); |
152 | if (rate > 16 << 20) { | 150 | if (rate > 32000000) { |
153 | rate /= 16; | 151 | rate /= 16; |
154 | cr |= MTU_CRn_PRESCALE_16; | 152 | cr |= MTU_CRn_PRESCALE_16; |
155 | } else { | 153 | } else { |
@@ -170,15 +168,8 @@ void __init nmdk_timer_init(void) | |||
170 | pr_err("timer: failed to initialize clock source %s\n", | 168 | pr_err("timer: failed to initialize clock source %s\n", |
171 | nmdk_clksrc.name); | 169 | nmdk_clksrc.name); |
172 | 170 | ||
173 | /* Timer 1 is used for events, fix according to rate */ | 171 | /* Timer 1 is used for events */ |
174 | cr = MTU_CRn_32BITS; | 172 | |
175 | rate = clk_get_rate(clk1); | ||
176 | if (rate > 16 << 20) { | ||
177 | rate /= 16; | ||
178 | cr |= MTU_CRn_PRESCALE_16; | ||
179 | } else { | ||
180 | cr |= MTU_CRn_PRESCALE_1; | ||
181 | } | ||
182 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); | 173 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); |
183 | 174 | ||
184 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ | 175 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ |
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index e39a417a368d..a92cb499313f 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig | |||
@@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES | |||
33 | config OMAP_DEBUG_LEDS | 33 | config OMAP_DEBUG_LEDS |
34 | bool | 34 | bool |
35 | depends on OMAP_DEBUG_DEVICES | 35 | depends on OMAP_DEBUG_DEVICES |
36 | default y if LEDS | 36 | default y if LEDS_CLASS |
37 | 37 | ||
38 | config OMAP_RESET_CLOCKS | 38 | config OMAP_RESET_CLOCKS |
39 | bool "Reset unused clocks during boot" | 39 | bool "Reset unused clocks during boot" |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e31496e35b0f..0c8612fd8312 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | |||
156 | /* Writing zero to RSYNC_ERR clears the IRQ */ | 156 | /* Writing zero to RSYNC_ERR clears the IRQ */ |
157 | MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); | 157 | MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); |
158 | } else { | 158 | } else { |
159 | complete(&mcbsp_rx->tx_irq_completion); | 159 | complete(&mcbsp_rx->rx_irq_completion); |
160 | } | 160 | } |
161 | 161 | ||
162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 226b2e858d6c..10b3b4c63372 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -220,20 +220,7 @@ void __init omap_map_sram(void) | |||
220 | if (omap_sram_size == 0) | 220 | if (omap_sram_size == 0) |
221 | return; | 221 | return; |
222 | 222 | ||
223 | if (cpu_is_omap24xx()) { | ||
224 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | ||
225 | |||
226 | base = OMAP2_SRAM_PA; | ||
227 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
228 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
229 | } | ||
230 | |||
231 | if (cpu_is_omap34xx()) { | 223 | if (cpu_is_omap34xx()) { |
232 | omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; | ||
233 | base = OMAP3_SRAM_PA; | ||
234 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
235 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
236 | |||
237 | /* | 224 | /* |
238 | * SRAM must be marked as non-cached on OMAP3 since the | 225 | * SRAM must be marked as non-cached on OMAP3 since the |
239 | * CORE DPLL M2 divider change code (in SRAM) runs with the | 226 | * CORE DPLL M2 divider change code (in SRAM) runs with the |
@@ -244,13 +231,11 @@ void __init omap_map_sram(void) | |||
244 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; | 231 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; |
245 | } | 232 | } |
246 | 233 | ||
247 | if (cpu_is_omap44xx()) { | 234 | omap_sram_io_desc[0].virtual = omap_sram_base; |
248 | omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA; | 235 | base = omap_sram_start; |
249 | base = OMAP4_SRAM_PA; | 236 | base = ROUND_DOWN(base, PAGE_SIZE); |
250 | base = ROUND_DOWN(base, PAGE_SIZE); | 237 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); |
251 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | 238 | omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); |
252 | } | ||
253 | omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ | ||
254 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 239 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
255 | 240 | ||
256 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | 241 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index 98f94d041d9c..a727f54d64d6 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c | |||
@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
314 | vfree(module->arch.syminfo); | 314 | vfree(module->arch.syminfo); |
315 | module->arch.syminfo = NULL; | 315 | module->arch.syminfo = NULL; |
316 | 316 | ||
317 | return module_bug_finalize(hdr, sechdrs, module); | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | void module_arch_cleanup(struct module *module) | 320 | void module_arch_cleanup(struct module *module) |
321 | { | 321 | { |
322 | module_bug_cleanup(module); | ||
323 | } | 322 | } |
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c index 0865e291c20d..db4953dc4e1b 100644 --- a/arch/h8300/kernel/module.c +++ b/arch/h8300/kernel/module.c | |||
@@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
112 | const Elf_Shdr *sechdrs, | 112 | const Elf_Shdr *sechdrs, |
113 | struct module *me) | 113 | struct module *me) |
114 | { | 114 | { |
115 | return module_bug_finalize(hdr, sechdrs, me); | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | void module_arch_cleanup(struct module *mod) | 118 | void module_arch_cleanup(struct module *mod) |
119 | { | 119 | { |
120 | module_bug_cleanup(mod); | ||
121 | } | 120 | } |
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h index 9c1acb2b1a92..b2eeb0de1c8d 100644 --- a/arch/m32r/include/asm/signal.h +++ b/arch/m32r/include/asm/signal.h | |||
@@ -157,7 +157,6 @@ typedef struct sigaltstack { | |||
157 | #undef __HAVE_ARCH_SIG_BITOPS | 157 | #undef __HAVE_ARCH_SIG_BITOPS |
158 | 158 | ||
159 | struct pt_regs; | 159 | struct pt_regs; |
160 | extern int do_signal(struct pt_regs *regs, sigset_t *oldset); | ||
161 | 160 | ||
162 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | 161 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) |
163 | 162 | ||
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index 76125777483c..c70545689da8 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h | |||
@@ -351,6 +351,7 @@ | |||
351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ | 351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ |
352 | #define __ARCH_WANT_SYS_OLDUMOUNT | 352 | #define __ARCH_WANT_SYS_OLDUMOUNT |
353 | #define __ARCH_WANT_SYS_RT_SIGACTION | 353 | #define __ARCH_WANT_SYS_RT_SIGACTION |
354 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
354 | 355 | ||
355 | #define __IGNORE_lchown | 356 | #define __IGNORE_lchown |
356 | #define __IGNORE_setuid | 357 | #define __IGNORE_setuid |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 403869833b98..225412bc227e 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -235,10 +235,9 @@ work_resched: | |||
235 | work_notifysig: ; deal with pending signals and | 235 | work_notifysig: ; deal with pending signals and |
236 | ; notify-resume requests | 236 | ; notify-resume requests |
237 | mv r0, sp ; arg1 : struct pt_regs *regs | 237 | mv r0, sp ; arg1 : struct pt_regs *regs |
238 | ldi r1, #0 ; arg2 : sigset_t *oldset | 238 | mv r1, r9 ; arg2 : __u32 thread_info_flags |
239 | mv r2, r9 ; arg3 : __u32 thread_info_flags | ||
240 | bl do_notify_resume | 239 | bl do_notify_resume |
241 | bra restore_all | 240 | bra resume_userspace |
242 | 241 | ||
243 | ; perform syscall exit tracing | 242 | ; perform syscall exit tracing |
244 | ALIGN | 243 | ALIGN |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index e555091eb97c..0021ade4cba8 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child) | |||
592 | 592 | ||
593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) | 593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) |
594 | != sizeof(insn)) | 594 | != sizeof(insn)) |
595 | break; | 595 | return -EIO; |
596 | 596 | ||
597 | compute_next_pc(insn, pc, &next_pc, child); | 597 | compute_next_pc(insn, pc, &next_pc, child); |
598 | if (next_pc & 0x80000000) | 598 | if (next_pc & 0x80000000) |
599 | break; | 599 | return -EIO; |
600 | 600 | ||
601 | if (embed_debug_trap(child, next_pc)) | 601 | if (embed_debug_trap(child, next_pc)) |
602 | break; | 602 | return -EIO; |
603 | 603 | ||
604 | invalidate_cache(); | 604 | invalidate_cache(); |
605 | return 0; | ||
605 | } | 606 | } |
606 | 607 | ||
607 | void user_disable_single_step(struct task_struct *child) | 608 | void user_disable_single_step(struct task_struct *child) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 144b0f124fc7..7bbe38645ed5 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -28,37 +28,6 @@ | |||
28 | 28 | ||
29 | #define DEBUG_SIG 0 | 29 | #define DEBUG_SIG 0 |
30 | 30 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
32 | |||
33 | int do_signal(struct pt_regs *, sigset_t *); | ||
34 | |||
35 | asmlinkage int | ||
36 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, | ||
37 | unsigned long r2, unsigned long r3, unsigned long r4, | ||
38 | unsigned long r5, unsigned long r6, struct pt_regs *regs) | ||
39 | { | ||
40 | sigset_t newset; | ||
41 | |||
42 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
43 | if (sigsetsize != sizeof(sigset_t)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
47 | return -EFAULT; | ||
48 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
49 | |||
50 | spin_lock_irq(¤t->sighand->siglock); | ||
51 | current->saved_sigmask = current->blocked; | ||
52 | current->blocked = newset; | ||
53 | recalc_sigpending(); | ||
54 | spin_unlock_irq(¤t->sighand->siglock); | ||
55 | |||
56 | current->state = TASK_INTERRUPTIBLE; | ||
57 | schedule(); | ||
58 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
59 | return -ERESTARTNOHAND; | ||
60 | } | ||
61 | |||
62 | asmlinkage int | 31 | asmlinkage int |
63 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 32 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
64 | unsigned long r2, unsigned long r3, unsigned long r4, | 33 | unsigned long r2, unsigned long r3, unsigned long r4, |
@@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | |||
218 | return (void __user *)((sp - frame_size) & -8ul); | 187 | return (void __user *)((sp - frame_size) & -8ul); |
219 | } | 188 | } |
220 | 189 | ||
221 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 190 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
222 | sigset_t *set, struct pt_regs *regs) | 191 | sigset_t *set, struct pt_regs *regs) |
223 | { | 192 | { |
224 | struct rt_sigframe __user *frame; | 193 | struct rt_sigframe __user *frame; |
@@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
275 | current->comm, current->pid, frame, regs->pc); | 244 | current->comm, current->pid, frame, regs->pc); |
276 | #endif | 245 | #endif |
277 | 246 | ||
278 | return; | 247 | return 0; |
279 | 248 | ||
280 | give_sigsegv: | 249 | give_sigsegv: |
281 | force_sigsegv(sig, current); | 250 | force_sigsegv(sig, current); |
251 | return -EFAULT; | ||
252 | } | ||
253 | |||
254 | static int prev_insn(struct pt_regs *regs) | ||
255 | { | ||
256 | u16 inst; | ||
257 | if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) | ||
258 | return -EFAULT; | ||
259 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
260 | regs->bpc -= 2; | ||
261 | else | ||
262 | regs->bpc -= 4; | ||
263 | regs->syscall_nr = -1; | ||
264 | return 0; | ||
282 | } | 265 | } |
283 | 266 | ||
284 | /* | 267 | /* |
285 | * OK, we're invoking a handler | 268 | * OK, we're invoking a handler |
286 | */ | 269 | */ |
287 | 270 | ||
288 | static void | 271 | static int |
289 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 272 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
290 | sigset_t *oldset, struct pt_regs *regs) | 273 | sigset_t *oldset, struct pt_regs *regs) |
291 | { | 274 | { |
292 | unsigned short inst; | ||
293 | |||
294 | /* Are we from a system call? */ | 275 | /* Are we from a system call? */ |
295 | if (regs->syscall_nr >= 0) { | 276 | if (regs->syscall_nr >= 0) { |
296 | /* If so, check system call restarting.. */ | 277 | /* If so, check system call restarting.. */ |
@@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
308 | /* fallthrough */ | 289 | /* fallthrough */ |
309 | case -ERESTARTNOINTR: | 290 | case -ERESTARTNOINTR: |
310 | regs->r0 = regs->orig_r0; | 291 | regs->r0 = regs->orig_r0; |
311 | inst = *(unsigned short *)(regs->bpc - 2); | 292 | if (prev_insn(regs) < 0) |
312 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 293 | return -EFAULT; |
313 | regs->bpc -= 2; | ||
314 | else | ||
315 | regs->bpc -= 4; | ||
316 | } | 294 | } |
317 | } | 295 | } |
318 | 296 | ||
319 | /* Set up the stack frame */ | 297 | /* Set up the stack frame */ |
320 | setup_rt_frame(sig, ka, info, oldset, regs); | 298 | if (setup_rt_frame(sig, ka, info, oldset, regs)) |
299 | return -EFAULT; | ||
321 | 300 | ||
322 | spin_lock_irq(¤t->sighand->siglock); | 301 | spin_lock_irq(¤t->sighand->siglock); |
323 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 302 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
325 | sigaddset(¤t->blocked,sig); | 304 | sigaddset(¤t->blocked,sig); |
326 | recalc_sigpending(); | 305 | recalc_sigpending(); |
327 | spin_unlock_irq(¤t->sighand->siglock); | 306 | spin_unlock_irq(¤t->sighand->siglock); |
307 | return 0; | ||
328 | } | 308 | } |
329 | 309 | ||
330 | /* | 310 | /* |
@@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
332 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 312 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
333 | * mistake. | 313 | * mistake. |
334 | */ | 314 | */ |
335 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 315 | static void do_signal(struct pt_regs *regs) |
336 | { | 316 | { |
337 | siginfo_t info; | 317 | siginfo_t info; |
338 | int signr; | 318 | int signr; |
339 | struct k_sigaction ka; | 319 | struct k_sigaction ka; |
340 | unsigned short inst; | 320 | sigset_t *oldset; |
341 | 321 | ||
342 | /* | 322 | /* |
343 | * We want the common case to go fast, which | 323 | * We want the common case to go fast, which |
@@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
346 | * if so. | 326 | * if so. |
347 | */ | 327 | */ |
348 | if (!user_mode(regs)) | 328 | if (!user_mode(regs)) |
349 | return 1; | 329 | return; |
350 | 330 | ||
351 | if (try_to_freeze()) | 331 | if (try_to_freeze()) |
352 | goto no_signal; | 332 | goto no_signal; |
353 | 333 | ||
354 | if (!oldset) | 334 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
335 | oldset = ¤t->saved_sigmask; | ||
336 | else | ||
355 | oldset = ¤t->blocked; | 337 | oldset = ¤t->blocked; |
356 | 338 | ||
357 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 339 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
@@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
363 | */ | 345 | */ |
364 | 346 | ||
365 | /* Whee! Actually deliver the signal. */ | 347 | /* Whee! Actually deliver the signal. */ |
366 | handle_signal(signr, &ka, &info, oldset, regs); | 348 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) |
367 | return 1; | 349 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
350 | |||
351 | return; | ||
368 | } | 352 | } |
369 | 353 | ||
370 | no_signal: | 354 | no_signal: |
@@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
375 | regs->r0 == -ERESTARTSYS || | 359 | regs->r0 == -ERESTARTSYS || |
376 | regs->r0 == -ERESTARTNOINTR) { | 360 | regs->r0 == -ERESTARTNOINTR) { |
377 | regs->r0 = regs->orig_r0; | 361 | regs->r0 = regs->orig_r0; |
378 | inst = *(unsigned short *)(regs->bpc - 2); | 362 | prev_insn(regs); |
379 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 363 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ |
380 | regs->bpc -= 2; | ||
381 | else | ||
382 | regs->bpc -= 4; | ||
383 | } | ||
384 | if (regs->r0 == -ERESTART_RESTARTBLOCK){ | ||
385 | regs->r0 = regs->orig_r0; | 364 | regs->r0 = regs->orig_r0; |
386 | regs->r7 = __NR_restart_syscall; | 365 | regs->r7 = __NR_restart_syscall; |
387 | inst = *(unsigned short *)(regs->bpc - 2); | 366 | prev_insn(regs); |
388 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
389 | regs->bpc -= 2; | ||
390 | else | ||
391 | regs->bpc -= 4; | ||
392 | } | 367 | } |
393 | } | 368 | } |
394 | return 0; | 369 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
370 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
371 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
372 | } | ||
395 | } | 373 | } |
396 | 374 | ||
397 | /* | 375 | /* |
398 | * notification of userspace execution resumption | 376 | * notification of userspace execution resumption |
399 | * - triggered by current->work.notify_resume | 377 | * - triggered by current->work.notify_resume |
400 | */ | 378 | */ |
401 | void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | 379 | void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) |
402 | __u32 thread_info_flags) | ||
403 | { | 380 | { |
404 | /* Pending single-step? */ | 381 | /* Pending single-step? */ |
405 | if (thread_info_flags & _TIF_SINGLESTEP) | 382 | if (thread_info_flags & _TIF_SINGLESTEP) |
@@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | |||
407 | 384 | ||
408 | /* deal with pending signal delivery */ | 385 | /* deal with pending signal delivery */ |
409 | if (thread_info_flags & _TIF_SIGPENDING) | 386 | if (thread_info_flags & _TIF_SIGPENDING) |
410 | do_signal(regs,oldset); | 387 | do_signal(regs); |
411 | 388 | ||
412 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 389 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
413 | clear_thread_flag(TIF_NOTIFY_RESUME); | 390 | clear_thread_flag(TIF_NOTIFY_RESUME); |
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 8f0640847ad2..05285d08e547 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c | |||
@@ -162,7 +162,7 @@ static void mac_init_asc( void ) | |||
162 | void mac_mksound( unsigned int freq, unsigned int length ) | 162 | void mac_mksound( unsigned int freq, unsigned int length ) |
163 | { | 163 | { |
164 | __u32 cfreq = ( freq << 5 ) / 468; | 164 | __u32 cfreq = ( freq << 5 ) / 468; |
165 | __u32 flags; | 165 | unsigned long flags; |
166 | int i; | 166 | int i; |
167 | 167 | ||
168 | if ( mac_special_bell == NULL ) | 168 | if ( mac_special_bell == NULL ) |
@@ -224,7 +224,7 @@ static void mac_nosound( unsigned long ignored ) | |||
224 | */ | 224 | */ |
225 | static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) | 225 | static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) |
226 | { | 226 | { |
227 | __u32 flags; | 227 | unsigned long flags; |
228 | 228 | ||
229 | /* if the bell is already ringing, ring longer */ | 229 | /* if the bell is already ringing, ring longer */ |
230 | if ( mac_bell_duration > 0 ) | 230 | if ( mac_bell_duration > 0 ) |
@@ -271,7 +271,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig | |||
271 | static void mac_quadra_ring_bell( unsigned long ignored ) | 271 | static void mac_quadra_ring_bell( unsigned long ignored ) |
272 | { | 272 | { |
273 | int i, count = mac_asc_samplespersec / HZ; | 273 | int i, count = mac_asc_samplespersec / HZ; |
274 | __u32 flags; | 274 | unsigned long flags; |
275 | 275 | ||
276 | /* | 276 | /* |
277 | * we neither want a sound buffer overflow nor underflow, so we need to match | 277 | * we neither want a sound buffer overflow nor underflow, so we need to match |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3ad59dde4852..5526faabfc21 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -13,6 +13,7 @@ config MIPS | |||
13 | select HAVE_KPROBES | 13 | select HAVE_KPROBES |
14 | select HAVE_KRETPROBES | 14 | select HAVE_KRETPROBES |
15 | select RTC_LIB if !MACH_LOONGSON | 15 | select RTC_LIB if !MACH_LOONGSON |
16 | select GENERIC_ATOMIC64 if !64BIT | ||
16 | 17 | ||
17 | mainmenu "Linux/MIPS Kernel Configuration" | 18 | mainmenu "Linux/MIPS Kernel Configuration" |
18 | 19 | ||
@@ -1646,8 +1647,16 @@ config MIPS_MT_SMP | |||
1646 | select SYS_SUPPORTS_SMP | 1647 | select SYS_SUPPORTS_SMP |
1647 | select SMP_UP | 1648 | select SMP_UP |
1648 | help | 1649 | help |
1649 | This is a kernel model which is also known a VSMP or lately | 1650 | This is a kernel model which is known a VSMP but lately has been |
1650 | has been marketesed into SMVP. | 1651 | marketesed into SMVP. |
1652 | Virtual SMP uses the processor's VPEs to implement virtual | ||
1653 | processors. In currently available configuration of the 34K processor | ||
1654 | this allows for a dual processor. Both processors will share the same | ||
1655 | primary caches; each will obtain the half of the TLB for it's own | ||
1656 | exclusive use. For a layman this model can be described as similar to | ||
1657 | what Intel calls Hyperthreading. | ||
1658 | |||
1659 | For further information see http://www.linux-mips.org/wiki/34K#VSMP | ||
1651 | 1660 | ||
1652 | config MIPS_MT_SMTC | 1661 | config MIPS_MT_SMTC |
1653 | bool "SMTC: Use all TCs on all VPEs for SMP" | 1662 | bool "SMTC: Use all TCs on all VPEs for SMP" |
@@ -1664,6 +1673,14 @@ config MIPS_MT_SMTC | |||
1664 | help | 1673 | help |
1665 | This is a kernel model which is known a SMTC or lately has been | 1674 | This is a kernel model which is known a SMTC or lately has been |
1666 | marketesed into SMVP. | 1675 | marketesed into SMVP. |
1676 | is presenting the available TC's of the core as processors to Linux. | ||
1677 | On currently available 34K processors this means a Linux system will | ||
1678 | see up to 5 processors. The implementation of the SMTC kernel differs | ||
1679 | significantly from VSMP and cannot efficiently coexist in the same | ||
1680 | kernel binary so the choice between VSMP and SMTC is a compile time | ||
1681 | decision. | ||
1682 | |||
1683 | For further information see http://www.linux-mips.org/wiki/34K#SMTC | ||
1667 | 1684 | ||
1668 | endchoice | 1685 | endchoice |
1669 | 1686 | ||
diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c index c29511b11d44..534021059629 100644 --- a/arch/mips/alchemy/common/prom.c +++ b/arch/mips/alchemy/common/prom.c | |||
@@ -43,7 +43,7 @@ int prom_argc; | |||
43 | char **prom_argv; | 43 | char **prom_argv; |
44 | char **prom_envp; | 44 | char **prom_envp; |
45 | 45 | ||
46 | void prom_init_cmdline(void) | 46 | void __init prom_init_cmdline(void) |
47 | { | 47 | { |
48 | int i; | 48 | int i; |
49 | 49 | ||
@@ -104,7 +104,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | int prom_get_ethernet_addr(char *ethernet_addr) | 107 | int __init prom_get_ethernet_addr(char *ethernet_addr) |
108 | { | 108 | { |
109 | char *ethaddr_str; | 109 | char *ethaddr_str; |
110 | 110 | ||
@@ -123,7 +123,6 @@ int prom_get_ethernet_addr(char *ethernet_addr) | |||
123 | 123 | ||
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | EXPORT_SYMBOL(prom_get_ethernet_addr); | ||
127 | 126 | ||
128 | void __init prom_free_prom_memory(void) | 127 | void __init prom_free_prom_memory(void) |
129 | { | 128 | { |
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index ed9bb709c9a3..5fd7f7a58b7e 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
@@ -59,7 +59,7 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE | |||
59 | hostprogs-y := calc_vmlinuz_load_addr | 59 | hostprogs-y := calc_vmlinuz_load_addr |
60 | 60 | ||
61 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ | 61 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ |
62 | $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS)) | 62 | $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) |
63 | 63 | ||
64 | vmlinuzobjs-y += $(obj)/piggy.o | 64 | vmlinuzobjs-y += $(obj)/piggy.o |
65 | 65 | ||
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index 094c17e38e16..47323ca452dc 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig | |||
@@ -83,3 +83,7 @@ config ARCH_SPARSEMEM_ENABLE | |||
83 | def_bool y | 83 | def_bool y |
84 | select SPARSEMEM_STATIC | 84 | select SPARSEMEM_STATIC |
85 | depends on CPU_CAVIUM_OCTEON | 85 | depends on CPU_CAVIUM_OCTEON |
86 | |||
87 | config CAVIUM_OCTEON_HELPER | ||
88 | def_bool y | ||
89 | depends on OCTEON_ETHERNET || PCI | ||
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c index c664c8cc2b42..a5b427909b5c 100644 --- a/arch/mips/cavium-octeon/cpu.c +++ b/arch/mips/cavium-octeon/cpu.c | |||
@@ -41,7 +41,7 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action, | |||
41 | return NOTIFY_OK; /* Let default notifier send signals */ | 41 | return NOTIFY_OK; /* Let default notifier send signals */ |
42 | } | 42 | } |
43 | 43 | ||
44 | static int cnmips_cu2_setup(void) | 44 | static int __init cnmips_cu2_setup(void) |
45 | { | 45 | { |
46 | return cu2_notifier(cnmips_cu2_call, 0); | 46 | return cu2_notifier(cnmips_cu2_call, 0); |
47 | } | 47 | } |
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile index 2fd66db6939e..7f41c5be2190 100644 --- a/arch/mips/cavium-octeon/executive/Makefile +++ b/arch/mips/cavium-octeon/executive/Makefile | |||
@@ -11,4 +11,4 @@ | |||
11 | 11 | ||
12 | obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o | 12 | obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o |
13 | 13 | ||
14 | obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o | 14 | obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o |
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index c63c56bfd184..47d87da379f9 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h | |||
@@ -782,6 +782,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) | |||
782 | */ | 782 | */ |
783 | #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) | 783 | #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) |
784 | 784 | ||
785 | #else /* !CONFIG_64BIT */ | ||
786 | |||
787 | #include <asm-generic/atomic64.h> | ||
788 | |||
785 | #endif /* CONFIG_64BIT */ | 789 | #endif /* CONFIG_64BIT */ |
786 | 790 | ||
787 | /* | 791 | /* |
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h index 2cb2f0c2c4f8..3532e2c5f098 100644 --- a/arch/mips/include/asm/cop2.h +++ b/arch/mips/include/asm/cop2.h | |||
@@ -24,7 +24,7 @@ extern int cu2_notifier_call_chain(unsigned long val, void *v); | |||
24 | 24 | ||
25 | #define cu2_notifier(fn, pri) \ | 25 | #define cu2_notifier(fn, pri) \ |
26 | ({ \ | 26 | ({ \ |
27 | static struct notifier_block fn##_nb __cpuinitdata = { \ | 27 | static struct notifier_block fn##_nb = { \ |
28 | .notifier_call = fn, \ | 28 | .notifier_call = fn, \ |
29 | .priority = pri \ | 29 | .priority = pri \ |
30 | }; \ | 30 | }; \ |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 9b9436a4d816..86548da650e7 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -321,6 +321,7 @@ struct gic_intrmask_regs { | |||
321 | */ | 321 | */ |
322 | struct gic_intr_map { | 322 | struct gic_intr_map { |
323 | unsigned int cpunum; /* Directed to this CPU */ | 323 | unsigned int cpunum; /* Directed to this CPU */ |
324 | #define GIC_UNUSED 0xdead /* Dummy data */ | ||
324 | unsigned int pin; /* Directed to this Pin */ | 325 | unsigned int pin; /* Directed to this Pin */ |
325 | unsigned int polarity; /* Polarity : +/- */ | 326 | unsigned int polarity; /* Polarity : +/- */ |
326 | unsigned int trigtype; /* Trigger : Edge/Levl */ | 327 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h index b74caf65482b..ff9a8b86cb93 100644 --- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h +++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #ifndef __ASM_MACH_TX49XX_KMALLOC_H | 1 | #ifndef __ASM_MACH_TX49XX_KMALLOC_H |
2 | #define __ASM_MACH_TX49XX_KMALLOC_H | 2 | #define __ASM_MACH_TX49XX_KMALLOC_H |
3 | 3 | ||
4 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES | 4 | #define ARCH_DMA_MINALIGN L1_CACHE_BYTES |
5 | 5 | ||
6 | #endif /* __ASM_MACH_TX49XX_KMALLOC_H */ | 6 | #endif /* __ASM_MACH_TX49XX_KMALLOC_H */ |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index cea872fc6f5c..d11aa02a956a 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
@@ -88,9 +88,6 @@ | |||
88 | 88 | ||
89 | #define GIC_EXT_INTR(x) x | 89 | #define GIC_EXT_INTR(x) x |
90 | 90 | ||
91 | /* Dummy data */ | ||
92 | #define X 0xdead | ||
93 | |||
94 | /* External Interrupts used for IPI */ | 91 | /* External Interrupts used for IPI */ |
95 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 92 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 |
96 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | 93 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index a16beafcea91..e59cd1ac09c2 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -150,6 +150,20 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
150 | ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) | 150 | ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) |
151 | #endif | 151 | #endif |
152 | #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) | 152 | #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) |
153 | |||
154 | /* | ||
155 | * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad | ||
156 | * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The | ||
157 | * discussion can be found in lkml posting | ||
158 | * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is | ||
159 | * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html | ||
160 | * | ||
161 | * It is unclear if the misscompilations mentioned in | ||
162 | * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one | ||
163 | * until GCC 3.x has been retired before we can apply | ||
164 | * https://patchwork.linux-mips.org/patch/1541/ | ||
165 | */ | ||
166 | |||
153 | #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) | 167 | #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) |
154 | 168 | ||
155 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | 169 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 2376f2e06e47..70df9c0d3c5b 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -146,7 +146,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
146 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) | 146 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) |
147 | 147 | ||
148 | /* work to do on interrupt/exception return */ | 148 | /* work to do on interrupt/exception return */ |
149 | #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP) | 149 | #define _TIF_WORK_MASK (0x0000ffef & \ |
150 | ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT)) | ||
150 | /* work to do on any return to u-space */ | 151 | /* work to do on any return to u-space */ |
151 | #define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) | 152 | #define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) |
152 | 153 | ||
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index baa318a59c97..550725b881d5 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
@@ -356,16 +356,19 @@ | |||
356 | #define __NR_perf_event_open (__NR_Linux + 333) | 356 | #define __NR_perf_event_open (__NR_Linux + 333) |
357 | #define __NR_accept4 (__NR_Linux + 334) | 357 | #define __NR_accept4 (__NR_Linux + 334) |
358 | #define __NR_recvmmsg (__NR_Linux + 335) | 358 | #define __NR_recvmmsg (__NR_Linux + 335) |
359 | #define __NR_fanotify_init (__NR_Linux + 336) | ||
360 | #define __NR_fanotify_mark (__NR_Linux + 337) | ||
361 | #define __NR_prlimit64 (__NR_Linux + 338) | ||
359 | 362 | ||
360 | /* | 363 | /* |
361 | * Offset of the last Linux o32 flavoured syscall | 364 | * Offset of the last Linux o32 flavoured syscall |
362 | */ | 365 | */ |
363 | #define __NR_Linux_syscalls 335 | 366 | #define __NR_Linux_syscalls 338 |
364 | 367 | ||
365 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 368 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
366 | 369 | ||
367 | #define __NR_O32_Linux 4000 | 370 | #define __NR_O32_Linux 4000 |
368 | #define __NR_O32_Linux_syscalls 335 | 371 | #define __NR_O32_Linux_syscalls 338 |
369 | 372 | ||
370 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 373 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
371 | 374 | ||
@@ -668,16 +671,19 @@ | |||
668 | #define __NR_perf_event_open (__NR_Linux + 292) | 671 | #define __NR_perf_event_open (__NR_Linux + 292) |
669 | #define __NR_accept4 (__NR_Linux + 293) | 672 | #define __NR_accept4 (__NR_Linux + 293) |
670 | #define __NR_recvmmsg (__NR_Linux + 294) | 673 | #define __NR_recvmmsg (__NR_Linux + 294) |
674 | #define __NR_fanotify_init (__NR_Linux + 295) | ||
675 | #define __NR_fanotify_mark (__NR_Linux + 296) | ||
676 | #define __NR_prlimit64 (__NR_Linux + 297) | ||
671 | 677 | ||
672 | /* | 678 | /* |
673 | * Offset of the last Linux 64-bit flavoured syscall | 679 | * Offset of the last Linux 64-bit flavoured syscall |
674 | */ | 680 | */ |
675 | #define __NR_Linux_syscalls 294 | 681 | #define __NR_Linux_syscalls 297 |
676 | 682 | ||
677 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 683 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
678 | 684 | ||
679 | #define __NR_64_Linux 5000 | 685 | #define __NR_64_Linux 5000 |
680 | #define __NR_64_Linux_syscalls 294 | 686 | #define __NR_64_Linux_syscalls 297 |
681 | 687 | ||
682 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 688 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
683 | 689 | ||
@@ -985,16 +991,19 @@ | |||
985 | #define __NR_accept4 (__NR_Linux + 297) | 991 | #define __NR_accept4 (__NR_Linux + 297) |
986 | #define __NR_recvmmsg (__NR_Linux + 298) | 992 | #define __NR_recvmmsg (__NR_Linux + 298) |
987 | #define __NR_getdents64 (__NR_Linux + 299) | 993 | #define __NR_getdents64 (__NR_Linux + 299) |
994 | #define __NR_fanotify_init (__NR_Linux + 300) | ||
995 | #define __NR_fanotify_mark (__NR_Linux + 301) | ||
996 | #define __NR_prlimit64 (__NR_Linux + 302) | ||
988 | 997 | ||
989 | /* | 998 | /* |
990 | * Offset of the last N32 flavoured syscall | 999 | * Offset of the last N32 flavoured syscall |
991 | */ | 1000 | */ |
992 | #define __NR_Linux_syscalls 299 | 1001 | #define __NR_Linux_syscalls 302 |
993 | 1002 | ||
994 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1003 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
995 | 1004 | ||
996 | #define __NR_N32_Linux 6000 | 1005 | #define __NR_N32_Linux 6000 |
997 | #define __NR_N32_Linux_syscalls 299 | 1006 | #define __NR_N32_Linux_syscalls 302 |
998 | 1007 | ||
999 | #ifdef __KERNEL__ | 1008 | #ifdef __KERNEL__ |
1000 | 1009 | ||
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index b181f2f0ea8e..82ba9f62f49e 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <asm/io.h> | 7 | #include <asm/io.h> |
8 | #include <asm/gic.h> | 8 | #include <asm/gic.h> |
9 | #include <asm/gcmpregs.h> | 9 | #include <asm/gcmpregs.h> |
10 | #include <asm/mips-boards/maltaint.h> | ||
11 | #include <asm/irq.h> | 10 | #include <asm/irq.h> |
12 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
13 | #include <asm-generic/bitops/find.h> | 12 | #include <asm-generic/bitops/find.h> |
@@ -131,7 +130,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
131 | int i; | 130 | int i; |
132 | 131 | ||
133 | irq -= _irqbase; | 132 | irq -= _irqbase; |
134 | pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); | 133 | pr_debug("%s(%d) called\n", __func__, irq); |
135 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 134 | cpumask_and(&tmp, cpumask, cpu_online_mask); |
136 | if (cpus_empty(tmp)) | 135 | if (cpus_empty(tmp)) |
137 | return -1; | 136 | return -1; |
@@ -222,7 +221,7 @@ static void __init gic_basic_init(int numintrs, int numvpes, | |||
222 | /* Setup specifics */ | 221 | /* Setup specifics */ |
223 | for (i = 0; i < mapsize; i++) { | 222 | for (i = 0; i < mapsize; i++) { |
224 | cpu = intrmap[i].cpunum; | 223 | cpu = intrmap[i].cpunum; |
225 | if (cpu == X) | 224 | if (cpu == GIC_UNUSED) |
226 | continue; | 225 | continue; |
227 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | 226 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) |
228 | continue; | 227 | continue; |
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 1f4e2fa64140..f4546e97c60d 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
@@ -283,7 +283,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, | |||
283 | struct pt_regs *regs = args->regs; | 283 | struct pt_regs *regs = args->regs; |
284 | int trap = (regs->cp0_cause & 0x7c) >> 2; | 284 | int trap = (regs->cp0_cause & 0x7c) >> 2; |
285 | 285 | ||
286 | /* Userpace events, ignore. */ | 286 | /* Userspace events, ignore. */ |
287 | if (user_mode(regs)) | 287 | if (user_mode(regs)) |
288 | return NOTIFY_DONE; | 288 | return NOTIFY_DONE; |
289 | 289 | ||
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 80e2ba694bab..29811f043399 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c | |||
@@ -251,7 +251,7 @@ void sp_work_handle_request(void) | |||
251 | memset(&tz, 0, sizeof(tz)); | 251 | memset(&tz, 0, sizeof(tz)); |
252 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, | 252 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, |
253 | (int)&tz, 0, 0)) == 0) | 253 | (int)&tz, 0, 0)) == 0) |
254 | ret.retval = tv.tv_sec; | 254 | ret.retval = tv.tv_sec; |
255 | break; | 255 | break; |
256 | 256 | ||
257 | case MTSP_SYSCALL_EXIT: | 257 | case MTSP_SYSCALL_EXIT: |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index c2dab140dc98..6343b4a5b835 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -341,3 +341,10 @@ asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf, | |||
341 | { | 341 | { |
342 | return sys_lookup_dcookie(merge_64(a0, a1), buf, len); | 342 | return sys_lookup_dcookie(merge_64(a0, a1), buf, len); |
343 | } | 343 | } |
344 | |||
345 | SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags, | ||
346 | u64, a3, u64, a4, int, dfd, const char __user *, pathname) | ||
347 | { | ||
348 | return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4), | ||
349 | dfd, pathname); | ||
350 | } | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 17202bbe843f..584415eef8c9 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -583,7 +583,10 @@ einval: li v0, -ENOSYS | |||
583 | sys sys_rt_tgsigqueueinfo 4 | 583 | sys sys_rt_tgsigqueueinfo 4 |
584 | sys sys_perf_event_open 5 | 584 | sys sys_perf_event_open 5 |
585 | sys sys_accept4 4 | 585 | sys sys_accept4 4 |
586 | sys sys_recvmmsg 5 | 586 | sys sys_recvmmsg 5 /* 4335 */ |
587 | sys sys_fanotify_init 2 | ||
588 | sys sys_fanotify_mark 6 | ||
589 | sys sys_prlimit64 4 | ||
587 | .endm | 590 | .endm |
588 | 591 | ||
589 | /* We pre-compute the number of _instruction_ bytes needed to | 592 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index a8a6c596eb04..5573f8e4e326 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -416,9 +416,12 @@ sys_call_table: | |||
416 | PTR sys_pipe2 | 416 | PTR sys_pipe2 |
417 | PTR sys_inotify_init1 | 417 | PTR sys_inotify_init1 |
418 | PTR sys_preadv | 418 | PTR sys_preadv |
419 | PTR sys_pwritev /* 5390 */ | 419 | PTR sys_pwritev /* 5290 */ |
420 | PTR sys_rt_tgsigqueueinfo | 420 | PTR sys_rt_tgsigqueueinfo |
421 | PTR sys_perf_event_open | 421 | PTR sys_perf_event_open |
422 | PTR sys_accept4 | 422 | PTR sys_accept4 |
423 | PTR sys_recvmmsg | 423 | PTR sys_recvmmsg |
424 | PTR sys_fanotify_init /* 5295 */ | ||
425 | PTR sys_fanotify_mark | ||
426 | PTR sys_prlimit64 | ||
424 | .size sys_call_table,.-sys_call_table | 427 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index a3d66137731a..1e38ec97672e 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -419,5 +419,8 @@ EXPORT(sysn32_call_table) | |||
419 | PTR sys_perf_event_open | 419 | PTR sys_perf_event_open |
420 | PTR sys_accept4 | 420 | PTR sys_accept4 |
421 | PTR compat_sys_recvmmsg | 421 | PTR compat_sys_recvmmsg |
422 | PTR sys_getdents | 422 | PTR sys_getdents64 |
423 | PTR sys_fanotify_init /* 6300 */ | ||
424 | PTR sys_fanotify_mark | ||
425 | PTR sys_prlimit64 | ||
423 | .size sysn32_call_table,.-sysn32_call_table | 426 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 813689ef2384..171979fc98e5 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -538,5 +538,8 @@ sys_call_table: | |||
538 | PTR compat_sys_rt_tgsigqueueinfo | 538 | PTR compat_sys_rt_tgsigqueueinfo |
539 | PTR sys_perf_event_open | 539 | PTR sys_perf_event_open |
540 | PTR sys_accept4 | 540 | PTR sys_accept4 |
541 | PTR compat_sys_recvmmsg | 541 | PTR compat_sys_recvmmsg /* 4335 */ |
542 | PTR sys_fanotify_init | ||
543 | PTR sys_32_fanotify_mark | ||
544 | PTR sys_prlimit64 | ||
542 | .size sys_call_table,.-sys_call_table | 545 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 7ba890860d98..469d4019f795 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -44,27 +44,39 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev) | |||
44 | 44 | ||
45 | static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) | 45 | static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) |
46 | { | 46 | { |
47 | gfp_t dma_flag; | ||
48 | |||
47 | /* ignore region specifiers */ | 49 | /* ignore region specifiers */ |
48 | gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); | 50 | gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); |
49 | 51 | ||
50 | #ifdef CONFIG_ZONE_DMA | 52 | #ifdef CONFIG_ISA |
51 | if (dev == NULL) | 53 | if (dev == NULL) |
52 | gfp |= __GFP_DMA; | 54 | dma_flag = __GFP_DMA; |
53 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(24)) | ||
54 | gfp |= __GFP_DMA; | ||
55 | else | 55 | else |
56 | #endif | 56 | #endif |
57 | #ifdef CONFIG_ZONE_DMA32 | 57 | #if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA) |
58 | if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) | 58 | if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) |
59 | gfp |= __GFP_DMA32; | 59 | dma_flag = __GFP_DMA; |
60 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
61 | dma_flag = __GFP_DMA32; | ||
62 | else | ||
63 | #endif | ||
64 | #if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA) | ||
65 | if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
66 | dma_flag = __GFP_DMA32; | ||
67 | else | ||
68 | #endif | ||
69 | #if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32) | ||
70 | if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
71 | dma_flag = __GFP_DMA; | ||
60 | else | 72 | else |
61 | #endif | 73 | #endif |
62 | ; | 74 | dma_flag = 0; |
63 | 75 | ||
64 | /* Don't invoke OOM killer */ | 76 | /* Don't invoke OOM killer */ |
65 | gfp |= __GFP_NORETRY; | 77 | gfp |= __GFP_NORETRY; |
66 | 78 | ||
67 | return gfp; | 79 | return gfp | dma_flag; |
68 | } | 80 | } |
69 | 81 | ||
70 | void *dma_alloc_noncoherent(struct device *dev, size_t size, | 82 | void *dma_alloc_noncoherent(struct device *dev, size_t size, |
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 1ef75cd80a0d..274af3be1442 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #define tc_lsize 32 | 30 | #define tc_lsize 32 |
31 | 31 | ||
32 | extern unsigned long icache_way_size, dcache_way_size; | 32 | extern unsigned long icache_way_size, dcache_way_size; |
33 | unsigned long tcache_size; | 33 | static unsigned long tcache_size; |
34 | 34 | ||
35 | #include <asm/r4kcache.h> | 35 | #include <asm/r4kcache.h> |
36 | 36 | ||
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 15949b0be811..b79b24afe3a2 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -385,6 +385,8 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); | |||
385 | */ | 385 | */ |
386 | 386 | ||
387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | 387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK |
388 | #define X GIC_UNUSED | ||
389 | |||
388 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | 390 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { |
389 | { X, X, X, X, 0 }, | 391 | { X, X, X, X, 0 }, |
390 | { X, X, X, X, 0 }, | 392 | { X, X, X, X, 0 }, |
@@ -404,6 +406,7 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | |||
404 | { X, X, X, X, 0 }, | 406 | { X, X, X, X, 0 }, |
405 | /* The remainder of this table is initialised by fill_ipi_map */ | 407 | /* The remainder of this table is initialised by fill_ipi_map */ |
406 | }; | 408 | }; |
409 | #undef X | ||
407 | 410 | ||
408 | /* | 411 | /* |
409 | * GCMP needs to be detected before any SMP initialisation | 412 | * GCMP needs to be detected before any SMP initialisation |
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c index 71f7d27b0d4c..f31218e17d3c 100644 --- a/arch/mips/pci/pci-rc32434.c +++ b/arch/mips/pci/pci-rc32434.c | |||
@@ -118,7 +118,7 @@ static int __init rc32434_pcibridge_init(void) | |||
118 | if (!((pcicvalue == PCIM_H_EA) || | 118 | if (!((pcicvalue == PCIM_H_EA) || |
119 | (pcicvalue == PCIM_H_IA_FIX) || | 119 | (pcicvalue == PCIM_H_IA_FIX) || |
120 | (pcicvalue == PCIM_H_IA_RR))) { | 120 | (pcicvalue == PCIM_H_IA_RR))) { |
121 | pr_err(KERN_ERR "PCI init error!!!\n"); | 121 | pr_err("PCI init error!!!\n"); |
122 | /* Not in Host Mode, return ERROR */ | 122 | /* Not in Host Mode, return ERROR */ |
123 | return -1; | 123 | return -1; |
124 | } | 124 | } |
diff --git a/arch/mips/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c index fadd8744a6bc..e7a12ff304b9 100644 --- a/arch/mips/pnx8550/common/reset.c +++ b/arch/mips/pnx8550/common/reset.c | |||
@@ -22,29 +22,19 @@ | |||
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | 24 | ||
25 | #include <asm/processor.h> | ||
25 | #include <asm/reboot.h> | 26 | #include <asm/reboot.h> |
26 | #include <glb.h> | 27 | #include <glb.h> |
27 | 28 | ||
28 | void pnx8550_machine_restart(char *command) | 29 | void pnx8550_machine_restart(char *command) |
29 | { | 30 | { |
30 | char head[] = "************* Machine restart *************"; | ||
31 | char foot[] = "*******************************************"; | ||
32 | |||
33 | printk("\n\n"); | ||
34 | printk("%s\n", head); | ||
35 | if (command != NULL) | ||
36 | printk("* %s\n", command); | ||
37 | printk("%s\n", foot); | ||
38 | |||
39 | PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; | 31 | PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; |
40 | } | 32 | } |
41 | 33 | ||
42 | void pnx8550_machine_halt(void) | 34 | void pnx8550_machine_halt(void) |
43 | { | 35 | { |
44 | printk("*** Machine halt. (Not implemented) ***\n"); | 36 | while (1) { |
45 | } | 37 | if (cpu_wait) |
46 | 38 | cpu_wait(); | |
47 | void pnx8550_machine_power_off(void) | 39 | } |
48 | { | ||
49 | printk("*** Machine power off. (Not implemented) ***\n"); | ||
50 | } | 40 | } |
diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c index 64246c9c875c..43cb3945fdbf 100644 --- a/arch/mips/pnx8550/common/setup.c +++ b/arch/mips/pnx8550/common/setup.c | |||
@@ -44,7 +44,6 @@ | |||
44 | extern void __init board_setup(void); | 44 | extern void __init board_setup(void); |
45 | extern void pnx8550_machine_restart(char *); | 45 | extern void pnx8550_machine_restart(char *); |
46 | extern void pnx8550_machine_halt(void); | 46 | extern void pnx8550_machine_halt(void); |
47 | extern void pnx8550_machine_power_off(void); | ||
48 | extern struct resource ioport_resource; | 47 | extern struct resource ioport_resource; |
49 | extern struct resource iomem_resource; | 48 | extern struct resource iomem_resource; |
50 | extern char *prom_getcmdline(void); | 49 | extern char *prom_getcmdline(void); |
@@ -100,7 +99,7 @@ void __init plat_mem_setup(void) | |||
100 | 99 | ||
101 | _machine_restart = pnx8550_machine_restart; | 100 | _machine_restart = pnx8550_machine_restart; |
102 | _machine_halt = pnx8550_machine_halt; | 101 | _machine_halt = pnx8550_machine_halt; |
103 | pm_power_off = pnx8550_machine_power_off; | 102 | pm_power_off = pnx8550_machine_halt; |
104 | 103 | ||
105 | /* Clear the Global 2 Register, PCI Inta Output Enable Registers | 104 | /* Clear the Global 2 Register, PCI Inta Output Enable Registers |
106 | Bit 1:Enable DAC Powerdown | 105 | Bit 1:Enable DAC Powerdown |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 444b9f918fdf..7c2a2f7f8dc1 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
@@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" | |||
8 | config MN10300 | 8 | config MN10300 |
9 | def_bool y | 9 | def_bool y |
10 | select HAVE_OPROFILE | 10 | select HAVE_OPROFILE |
11 | select HAVE_ARCH_TRACEHOOK | ||
12 | 11 | ||
13 | config AM33 | 12 | config AM33 |
14 | def_bool y | 13 | def_bool y |
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index ff80e86b9bd2..ce83c74b3fd7 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug | |||
@@ -101,7 +101,7 @@ config GDBSTUB_DEBUG_BREAKPOINT | |||
101 | 101 | ||
102 | choice | 102 | choice |
103 | prompt "GDB stub port" | 103 | prompt "GDB stub port" |
104 | default GDBSTUB_TTYSM0 | 104 | default GDBSTUB_ON_TTYSM0 |
105 | depends on GDBSTUB | 105 | depends on GDBSTUB |
106 | help | 106 | help |
107 | Select the serial port used for GDB-stub. | 107 | Select the serial port used for GDB-stub. |
diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index f49ac49e09ad..3f50e9661076 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h | |||
@@ -229,9 +229,9 @@ int ffs(int x) | |||
229 | #include <asm-generic/bitops/hweight.h> | 229 | #include <asm-generic/bitops/hweight.h> |
230 | 230 | ||
231 | #define ext2_set_bit_atomic(lock, nr, addr) \ | 231 | #define ext2_set_bit_atomic(lock, nr, addr) \ |
232 | test_and_set_bit((nr) ^ 0x18, (addr)) | 232 | test_and_set_bit((nr), (addr)) |
233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | 233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ |
234 | test_and_clear_bit((nr) ^ 0x18, (addr)) | 234 | test_and_clear_bit((nr), (addr)) |
235 | 235 | ||
236 | #include <asm-generic/bitops/ext2-non-atomic.h> | 236 | #include <asm-generic/bitops/ext2-non-atomic.h> |
237 | #include <asm-generic/bitops/minix-le.h> | 237 | #include <asm-generic/bitops/minix-le.h> |
diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h index 7e891fce2370..1865d72a86ff 100644 --- a/arch/mn10300/include/asm/signal.h +++ b/arch/mn10300/include/asm/signal.h | |||
@@ -78,7 +78,7 @@ typedef unsigned long sigset_t; | |||
78 | 78 | ||
79 | /* These should not be considered constants from userland. */ | 79 | /* These should not be considered constants from userland. */ |
80 | #define SIGRTMIN 32 | 80 | #define SIGRTMIN 32 |
81 | #define SIGRTMAX (_NSIG-1) | 81 | #define SIGRTMAX _NSIG |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * SA_FLAGS values: | 84 | * SA_FLAGS values: |
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c index 6aea7fd76993..196a111e2e29 100644 --- a/arch/mn10300/kernel/module.c +++ b/arch/mn10300/kernel/module.c | |||
@@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
206 | const Elf_Shdr *sechdrs, | 206 | const Elf_Shdr *sechdrs, |
207 | struct module *me) | 207 | struct module *me) |
208 | { | 208 | { |
209 | return module_bug_finalize(hdr, sechdrs, me); | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
@@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
214 | */ | 214 | */ |
215 | void module_arch_cleanup(struct module *mod) | 215 | void module_arch_cleanup(struct module *mod) |
216 | { | 216 | { |
217 | module_bug_cleanup(mod); | ||
218 | } | 217 | } |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 717db14c2cc3..d4de05ab7864 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig, | |||
65 | old_sigset_t mask; | 65 | old_sigset_t mask; |
66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || | 66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || |
67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | 68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || |
69 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
70 | __get_user(mask, &act->sa_mask)) | ||
69 | return -EFAULT; | 71 | return -EFAULT; |
70 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
71 | __get_user(mask, &act->sa_mask); | ||
72 | siginitset(&new_ka.sa.sa_mask, mask); | 72 | siginitset(&new_ka.sa.sa_mask, mask); |
73 | } | 73 | } |
74 | 74 | ||
@@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig, | |||
77 | if (!ret && oact) { | 77 | if (!ret && oact) { |
78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || | 78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || |
79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | 80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || |
81 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
82 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
81 | return -EFAULT; | 83 | return -EFAULT; |
82 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
83 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
84 | } | 84 | } |
85 | 85 | ||
86 | return ret; | 86 | return ret; |
@@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
102 | { | 102 | { |
103 | unsigned int err = 0; | 103 | unsigned int err = 0; |
104 | 104 | ||
105 | /* Always make any pending restarted system calls return -EINTR */ | ||
106 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
107 | |||
105 | if (is_using_fpu(current)) | 108 | if (is_using_fpu(current)) |
106 | fpu_kill_state(current); | 109 | fpu_kill_state(current); |
107 | 110 | ||
@@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
330 | regs->d0 = sig; | 333 | regs->d0 = sig; |
331 | regs->d1 = (unsigned long) &frame->sc; | 334 | regs->d1 = (unsigned long) &frame->sc; |
332 | 335 | ||
333 | set_fs(USER_DS); | ||
334 | |||
335 | /* the tracer may want to single-step inside the handler */ | 336 | /* the tracer may want to single-step inside the handler */ |
336 | if (test_thread_flag(TIF_SINGLESTEP)) | 337 | if (test_thread_flag(TIF_SINGLESTEP)) |
337 | ptrace_notify(SIGTRAP); | 338 | ptrace_notify(SIGTRAP); |
@@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
345 | return 0; | 346 | return 0; |
346 | 347 | ||
347 | give_sigsegv: | 348 | give_sigsegv: |
348 | force_sig(SIGSEGV, current); | 349 | force_sigsegv(sig, current); |
349 | return -EFAULT; | 350 | return -EFAULT; |
350 | } | 351 | } |
351 | 352 | ||
@@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
413 | regs->d0 = sig; | 414 | regs->d0 = sig; |
414 | regs->d1 = (long) &frame->info; | 415 | regs->d1 = (long) &frame->info; |
415 | 416 | ||
416 | set_fs(USER_DS); | ||
417 | |||
418 | /* the tracer may want to single-step inside the handler */ | 417 | /* the tracer may want to single-step inside the handler */ |
419 | if (test_thread_flag(TIF_SINGLESTEP)) | 418 | if (test_thread_flag(TIF_SINGLESTEP)) |
420 | ptrace_notify(SIGTRAP); | 419 | ptrace_notify(SIGTRAP); |
@@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
428 | return 0; | 427 | return 0; |
429 | 428 | ||
430 | give_sigsegv: | 429 | give_sigsegv: |
431 | force_sig(SIGSEGV, current); | 430 | force_sigsegv(sig, current); |
432 | return -EFAULT; | 431 | return -EFAULT; |
433 | } | 432 | } |
434 | 433 | ||
434 | static inline void stepback(struct pt_regs *regs) | ||
435 | { | ||
436 | regs->pc -= 2; | ||
437 | regs->orig_d0 = -1; | ||
438 | } | ||
439 | |||
435 | /* | 440 | /* |
436 | * handle the actual delivery of a signal to userspace | 441 | * handle the actual delivery of a signal to userspace |
437 | */ | 442 | */ |
@@ -459,7 +464,7 @@ static int handle_signal(int sig, | |||
459 | /* fallthrough */ | 464 | /* fallthrough */ |
460 | case -ERESTARTNOINTR: | 465 | case -ERESTARTNOINTR: |
461 | regs->d0 = regs->orig_d0; | 466 | regs->d0 = regs->orig_d0; |
462 | regs->pc -= 2; | 467 | stepback(regs); |
463 | } | 468 | } |
464 | } | 469 | } |
465 | 470 | ||
@@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs) | |||
527 | case -ERESTARTSYS: | 532 | case -ERESTARTSYS: |
528 | case -ERESTARTNOINTR: | 533 | case -ERESTARTNOINTR: |
529 | regs->d0 = regs->orig_d0; | 534 | regs->d0 = regs->orig_d0; |
530 | regs->pc -= 2; | 535 | stepback(regs); |
531 | break; | 536 | break; |
532 | 537 | ||
533 | case -ERESTART_RESTARTBLOCK: | 538 | case -ERESTART_RESTARTBLOCK: |
534 | regs->d0 = __NR_restart_syscall; | 539 | regs->d0 = __NR_restart_syscall; |
535 | regs->pc -= 2; | 540 | stepback(regs); |
536 | break; | 541 | break; |
537 | } | 542 | } |
538 | } | 543 | } |
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 28b9d983db0c..1557277fbc5c 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile | |||
@@ -2,13 +2,11 @@ | |||
2 | # Makefile for the MN10300-specific memory management code | 2 | # Makefile for the MN10300-specific memory management code |
3 | # | 3 | # |
4 | 4 | ||
5 | cacheflush-y := cache.o cache-mn10300.o | ||
6 | cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o | ||
7 | |||
8 | cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o | ||
9 | |||
5 | obj-y := \ | 10 | obj-y := \ |
6 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ | 11 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ |
7 | misalignment.o dma-alloc.o | 12 | misalignment.o dma-alloc.o $(cacheflush-y) |
8 | |||
9 | ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y) | ||
10 | obj-y += cache.o cache-mn10300.o | ||
11 | ifeq ($(CONFIG_MN10300_CACHE_WBACK),y) | ||
12 | obj-y += cache-flush-mn10300.o | ||
13 | endif | ||
14 | endif | ||
diff --git a/arch/mn10300/mm/cache-disabled.c b/arch/mn10300/mm/cache-disabled.c new file mode 100644 index 000000000000..f669ea42aba6 --- /dev/null +++ b/arch/mn10300/mm/cache-disabled.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* Handle the cache being disabled | ||
2 | * | ||
3 | * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/mm.h> | ||
12 | |||
13 | /* | ||
14 | * allow userspace to flush the instruction cache | ||
15 | */ | ||
16 | asmlinkage long sys_cacheflush(unsigned long start, unsigned long end) | ||
17 | { | ||
18 | if (end < start) | ||
19 | return -EINVAL; | ||
20 | return 0; | ||
21 | } | ||
diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c index 1b76719ec1c3..9261217e8d2c 100644 --- a/arch/mn10300/mm/cache.c +++ b/arch/mn10300/mm/cache.c | |||
@@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page); | |||
54 | void flush_icache_range(unsigned long start, unsigned long end) | 54 | void flush_icache_range(unsigned long start, unsigned long end) |
55 | { | 55 | { |
56 | #ifdef CONFIG_MN10300_CACHE_WBACK | 56 | #ifdef CONFIG_MN10300_CACHE_WBACK |
57 | unsigned long addr, size, off; | 57 | unsigned long addr, size, base, off; |
58 | struct page *page; | 58 | struct page *page; |
59 | pgd_t *pgd; | 59 | pgd_t *pgd; |
60 | pud_t *pud; | 60 | pud_t *pud; |
61 | pmd_t *pmd; | 61 | pmd_t *pmd; |
62 | pte_t *ppte, pte; | 62 | pte_t *ppte, pte; |
63 | 63 | ||
64 | if (end > 0x80000000UL) { | ||
65 | /* addresses above 0xa0000000 do not go through the cache */ | ||
66 | if (end > 0xa0000000UL) { | ||
67 | end = 0xa0000000UL; | ||
68 | if (start >= end) | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | /* kernel addresses between 0x80000000 and 0x9fffffff do not | ||
73 | * require page tables, so we just map such addresses directly */ | ||
74 | base = (start >= 0x80000000UL) ? start : 0x80000000UL; | ||
75 | mn10300_dcache_flush_range(base, end); | ||
76 | if (base == start) | ||
77 | goto invalidate; | ||
78 | end = base; | ||
79 | } | ||
80 | |||
64 | for (; start < end; start += size) { | 81 | for (; start < end; start += size) { |
65 | /* work out how much of the page to flush */ | 82 | /* work out how much of the page to flush */ |
66 | off = start & (PAGE_SIZE - 1); | 83 | off = start & (PAGE_SIZE - 1); |
@@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end) | |||
104 | } | 121 | } |
105 | #endif | 122 | #endif |
106 | 123 | ||
124 | invalidate: | ||
107 | mn10300_icache_inv(); | 125 | mn10300_icache_inv(); |
108 | } | 126 | } |
109 | EXPORT_SYMBOL(flush_icache_range); | 127 | EXPORT_SYMBOL(flush_icache_range); |
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 159a2b81e90c..6e81bb596e5b 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
941 | nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; | 941 | nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; |
942 | DEBUGP("NEW num_symtab %lu\n", nsyms); | 942 | DEBUGP("NEW num_symtab %lu\n", nsyms); |
943 | symhdr->sh_size = nsyms * sizeof(Elf_Sym); | 943 | symhdr->sh_size = nsyms * sizeof(Elf_Sym); |
944 | return module_bug_finalize(hdr, sechdrs, me); | 944 | return 0; |
945 | } | 945 | } |
946 | 946 | ||
947 | void module_arch_cleanup(struct module *mod) | 947 | void module_arch_cleanup(struct module *mod) |
948 | { | 948 | { |
949 | deregister_unwind_table(mod); | 949 | deregister_unwind_table(mod); |
950 | module_bug_cleanup(mod); | ||
951 | } | 950 | } |
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 477c663e0140..49cee9df225b 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c | |||
@@ -63,11 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
63 | const Elf_Shdr *sechdrs, struct module *me) | 63 | const Elf_Shdr *sechdrs, struct module *me) |
64 | { | 64 | { |
65 | const Elf_Shdr *sect; | 65 | const Elf_Shdr *sect; |
66 | int err; | ||
67 | |||
68 | err = module_bug_finalize(hdr, sechdrs, me); | ||
69 | if (err) | ||
70 | return err; | ||
71 | 66 | ||
72 | /* Apply feature fixups */ | 67 | /* Apply feature fixups */ |
73 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); | 68 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); |
@@ -101,5 +96,4 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
101 | 96 | ||
102 | void module_arch_cleanup(struct module *mod) | 97 | void module_arch_cleanup(struct module *mod) |
103 | { | 98 | { |
104 | module_bug_cleanup(mod); | ||
105 | } | 99 | } |
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c index 95ad9dad298e..d05ae4204bbf 100644 --- a/arch/powerpc/kernel/perf_callchain.c +++ b/arch/powerpc/kernel/perf_callchain.c | |||
@@ -23,18 +23,6 @@ | |||
23 | #include "ppc32.h" | 23 | #include "ppc32.h" |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | /* | ||
27 | * Store another value in a callchain_entry. | ||
28 | */ | ||
29 | static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
30 | { | ||
31 | unsigned int nr = entry->nr; | ||
32 | |||
33 | if (nr < PERF_MAX_STACK_DEPTH) { | ||
34 | entry->ip[nr] = ip; | ||
35 | entry->nr = nr + 1; | ||
36 | } | ||
37 | } | ||
38 | 26 | ||
39 | /* | 27 | /* |
40 | * Is sp valid as the address of the next kernel stack frame after prev_sp? | 28 | * Is sp valid as the address of the next kernel stack frame after prev_sp? |
@@ -58,8 +46,8 @@ static int valid_next_sp(unsigned long sp, unsigned long prev_sp) | |||
58 | return 0; | 46 | return 0; |
59 | } | 47 | } |
60 | 48 | ||
61 | static void perf_callchain_kernel(struct pt_regs *regs, | 49 | void |
62 | struct perf_callchain_entry *entry) | 50 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
63 | { | 51 | { |
64 | unsigned long sp, next_sp; | 52 | unsigned long sp, next_sp; |
65 | unsigned long next_ip; | 53 | unsigned long next_ip; |
@@ -69,8 +57,7 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
69 | 57 | ||
70 | lr = regs->link; | 58 | lr = regs->link; |
71 | sp = regs->gpr[1]; | 59 | sp = regs->gpr[1]; |
72 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 60 | perf_callchain_store(entry, regs->nip); |
73 | callchain_store(entry, regs->nip); | ||
74 | 61 | ||
75 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) | 62 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) |
76 | return; | 63 | return; |
@@ -89,7 +76,7 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
89 | next_ip = regs->nip; | 76 | next_ip = regs->nip; |
90 | lr = regs->link; | 77 | lr = regs->link; |
91 | level = 0; | 78 | level = 0; |
92 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 79 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); |
93 | 80 | ||
94 | } else { | 81 | } else { |
95 | if (level == 0) | 82 | if (level == 0) |
@@ -111,7 +98,7 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
111 | ++level; | 98 | ++level; |
112 | } | 99 | } |
113 | 100 | ||
114 | callchain_store(entry, next_ip); | 101 | perf_callchain_store(entry, next_ip); |
115 | if (!valid_next_sp(next_sp, sp)) | 102 | if (!valid_next_sp(next_sp, sp)) |
116 | return; | 103 | return; |
117 | sp = next_sp; | 104 | sp = next_sp; |
@@ -233,8 +220,8 @@ static int sane_signal_64_frame(unsigned long sp) | |||
233 | puc == (unsigned long) &sf->uc; | 220 | puc == (unsigned long) &sf->uc; |
234 | } | 221 | } |
235 | 222 | ||
236 | static void perf_callchain_user_64(struct pt_regs *regs, | 223 | static void perf_callchain_user_64(struct perf_callchain_entry *entry, |
237 | struct perf_callchain_entry *entry) | 224 | struct pt_regs *regs) |
238 | { | 225 | { |
239 | unsigned long sp, next_sp; | 226 | unsigned long sp, next_sp; |
240 | unsigned long next_ip; | 227 | unsigned long next_ip; |
@@ -246,8 +233,7 @@ static void perf_callchain_user_64(struct pt_regs *regs, | |||
246 | next_ip = regs->nip; | 233 | next_ip = regs->nip; |
247 | lr = regs->link; | 234 | lr = regs->link; |
248 | sp = regs->gpr[1]; | 235 | sp = regs->gpr[1]; |
249 | callchain_store(entry, PERF_CONTEXT_USER); | 236 | perf_callchain_store(entry, next_ip); |
250 | callchain_store(entry, next_ip); | ||
251 | 237 | ||
252 | for (;;) { | 238 | for (;;) { |
253 | fp = (unsigned long __user *) sp; | 239 | fp = (unsigned long __user *) sp; |
@@ -276,14 +262,14 @@ static void perf_callchain_user_64(struct pt_regs *regs, | |||
276 | read_user_stack_64(&uregs[PT_R1], &sp)) | 262 | read_user_stack_64(&uregs[PT_R1], &sp)) |
277 | return; | 263 | return; |
278 | level = 0; | 264 | level = 0; |
279 | callchain_store(entry, PERF_CONTEXT_USER); | 265 | perf_callchain_store(entry, PERF_CONTEXT_USER); |
280 | callchain_store(entry, next_ip); | 266 | perf_callchain_store(entry, next_ip); |
281 | continue; | 267 | continue; |
282 | } | 268 | } |
283 | 269 | ||
284 | if (level == 0) | 270 | if (level == 0) |
285 | next_ip = lr; | 271 | next_ip = lr; |
286 | callchain_store(entry, next_ip); | 272 | perf_callchain_store(entry, next_ip); |
287 | ++level; | 273 | ++level; |
288 | sp = next_sp; | 274 | sp = next_sp; |
289 | } | 275 | } |
@@ -315,8 +301,8 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) | |||
315 | return __get_user_inatomic(*ret, ptr); | 301 | return __get_user_inatomic(*ret, ptr); |
316 | } | 302 | } |
317 | 303 | ||
318 | static inline void perf_callchain_user_64(struct pt_regs *regs, | 304 | static inline void perf_callchain_user_64(struct perf_callchain_entry *entry, |
319 | struct perf_callchain_entry *entry) | 305 | struct pt_regs *regs) |
320 | { | 306 | { |
321 | } | 307 | } |
322 | 308 | ||
@@ -435,8 +421,8 @@ static unsigned int __user *signal_frame_32_regs(unsigned int sp, | |||
435 | return mctx->mc_gregs; | 421 | return mctx->mc_gregs; |
436 | } | 422 | } |
437 | 423 | ||
438 | static void perf_callchain_user_32(struct pt_regs *regs, | 424 | static void perf_callchain_user_32(struct perf_callchain_entry *entry, |
439 | struct perf_callchain_entry *entry) | 425 | struct pt_regs *regs) |
440 | { | 426 | { |
441 | unsigned int sp, next_sp; | 427 | unsigned int sp, next_sp; |
442 | unsigned int next_ip; | 428 | unsigned int next_ip; |
@@ -447,8 +433,7 @@ static void perf_callchain_user_32(struct pt_regs *regs, | |||
447 | next_ip = regs->nip; | 433 | next_ip = regs->nip; |
448 | lr = regs->link; | 434 | lr = regs->link; |
449 | sp = regs->gpr[1]; | 435 | sp = regs->gpr[1]; |
450 | callchain_store(entry, PERF_CONTEXT_USER); | 436 | perf_callchain_store(entry, next_ip); |
451 | callchain_store(entry, next_ip); | ||
452 | 437 | ||
453 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | 438 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
454 | fp = (unsigned int __user *) (unsigned long) sp; | 439 | fp = (unsigned int __user *) (unsigned long) sp; |
@@ -470,45 +455,24 @@ static void perf_callchain_user_32(struct pt_regs *regs, | |||
470 | read_user_stack_32(&uregs[PT_R1], &sp)) | 455 | read_user_stack_32(&uregs[PT_R1], &sp)) |
471 | return; | 456 | return; |
472 | level = 0; | 457 | level = 0; |
473 | callchain_store(entry, PERF_CONTEXT_USER); | 458 | perf_callchain_store(entry, PERF_CONTEXT_USER); |
474 | callchain_store(entry, next_ip); | 459 | perf_callchain_store(entry, next_ip); |
475 | continue; | 460 | continue; |
476 | } | 461 | } |
477 | 462 | ||
478 | if (level == 0) | 463 | if (level == 0) |
479 | next_ip = lr; | 464 | next_ip = lr; |
480 | callchain_store(entry, next_ip); | 465 | perf_callchain_store(entry, next_ip); |
481 | ++level; | 466 | ++level; |
482 | sp = next_sp; | 467 | sp = next_sp; |
483 | } | 468 | } |
484 | } | 469 | } |
485 | 470 | ||
486 | /* | 471 | void |
487 | * Since we can't get PMU interrupts inside a PMU interrupt handler, | 472 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) |
488 | * we don't need separate irq and nmi entries here. | ||
489 | */ | ||
490 | static DEFINE_PER_CPU(struct perf_callchain_entry, cpu_perf_callchain); | ||
491 | |||
492 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
493 | { | 473 | { |
494 | struct perf_callchain_entry *entry = &__get_cpu_var(cpu_perf_callchain); | 474 | if (current_is_64bit()) |
495 | 475 | perf_callchain_user_64(entry, regs); | |
496 | entry->nr = 0; | 476 | else |
497 | 477 | perf_callchain_user_32(entry, regs); | |
498 | if (!user_mode(regs)) { | ||
499 | perf_callchain_kernel(regs, entry); | ||
500 | if (current->mm) | ||
501 | regs = task_pt_regs(current); | ||
502 | else | ||
503 | regs = NULL; | ||
504 | } | ||
505 | |||
506 | if (regs) { | ||
507 | if (current_is_64bit()) | ||
508 | perf_callchain_user_64(regs, entry); | ||
509 | else | ||
510 | perf_callchain_user_32(regs, entry); | ||
511 | } | ||
512 | |||
513 | return entry; | ||
514 | } | 478 | } |
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index d301a30445e0..9cb4924b6c07 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c | |||
@@ -402,6 +402,9 @@ static void power_pmu_read(struct perf_event *event) | |||
402 | { | 402 | { |
403 | s64 val, delta, prev; | 403 | s64 val, delta, prev; |
404 | 404 | ||
405 | if (event->hw.state & PERF_HES_STOPPED) | ||
406 | return; | ||
407 | |||
405 | if (!event->hw.idx) | 408 | if (!event->hw.idx) |
406 | return; | 409 | return; |
407 | /* | 410 | /* |
@@ -517,7 +520,7 @@ static void write_mmcr0(struct cpu_hw_events *cpuhw, unsigned long mmcr0) | |||
517 | * Disable all events to prevent PMU interrupts and to allow | 520 | * Disable all events to prevent PMU interrupts and to allow |
518 | * events to be added or removed. | 521 | * events to be added or removed. |
519 | */ | 522 | */ |
520 | void hw_perf_disable(void) | 523 | static void power_pmu_disable(struct pmu *pmu) |
521 | { | 524 | { |
522 | struct cpu_hw_events *cpuhw; | 525 | struct cpu_hw_events *cpuhw; |
523 | unsigned long flags; | 526 | unsigned long flags; |
@@ -565,7 +568,7 @@ void hw_perf_disable(void) | |||
565 | * If we were previously disabled and events were added, then | 568 | * If we were previously disabled and events were added, then |
566 | * put the new config on the PMU. | 569 | * put the new config on the PMU. |
567 | */ | 570 | */ |
568 | void hw_perf_enable(void) | 571 | static void power_pmu_enable(struct pmu *pmu) |
569 | { | 572 | { |
570 | struct perf_event *event; | 573 | struct perf_event *event; |
571 | struct cpu_hw_events *cpuhw; | 574 | struct cpu_hw_events *cpuhw; |
@@ -672,6 +675,8 @@ void hw_perf_enable(void) | |||
672 | } | 675 | } |
673 | local64_set(&event->hw.prev_count, val); | 676 | local64_set(&event->hw.prev_count, val); |
674 | event->hw.idx = idx; | 677 | event->hw.idx = idx; |
678 | if (event->hw.state & PERF_HES_STOPPED) | ||
679 | val = 0; | ||
675 | write_pmc(idx, val); | 680 | write_pmc(idx, val); |
676 | perf_event_update_userpage(event); | 681 | perf_event_update_userpage(event); |
677 | } | 682 | } |
@@ -727,7 +732,7 @@ static int collect_events(struct perf_event *group, int max_count, | |||
727 | * re-enable the PMU in order to get hw_perf_enable to do the | 732 | * re-enable the PMU in order to get hw_perf_enable to do the |
728 | * actual work of reconfiguring the PMU. | 733 | * actual work of reconfiguring the PMU. |
729 | */ | 734 | */ |
730 | static int power_pmu_enable(struct perf_event *event) | 735 | static int power_pmu_add(struct perf_event *event, int ef_flags) |
731 | { | 736 | { |
732 | struct cpu_hw_events *cpuhw; | 737 | struct cpu_hw_events *cpuhw; |
733 | unsigned long flags; | 738 | unsigned long flags; |
@@ -735,7 +740,7 @@ static int power_pmu_enable(struct perf_event *event) | |||
735 | int ret = -EAGAIN; | 740 | int ret = -EAGAIN; |
736 | 741 | ||
737 | local_irq_save(flags); | 742 | local_irq_save(flags); |
738 | perf_disable(); | 743 | perf_pmu_disable(event->pmu); |
739 | 744 | ||
740 | /* | 745 | /* |
741 | * Add the event to the list (if there is room) | 746 | * Add the event to the list (if there is room) |
@@ -749,6 +754,9 @@ static int power_pmu_enable(struct perf_event *event) | |||
749 | cpuhw->events[n0] = event->hw.config; | 754 | cpuhw->events[n0] = event->hw.config; |
750 | cpuhw->flags[n0] = event->hw.event_base; | 755 | cpuhw->flags[n0] = event->hw.event_base; |
751 | 756 | ||
757 | if (!(ef_flags & PERF_EF_START)) | ||
758 | event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
759 | |||
752 | /* | 760 | /* |
753 | * If group events scheduling transaction was started, | 761 | * If group events scheduling transaction was started, |
754 | * skip the schedulability test here, it will be peformed | 762 | * skip the schedulability test here, it will be peformed |
@@ -769,7 +777,7 @@ nocheck: | |||
769 | 777 | ||
770 | ret = 0; | 778 | ret = 0; |
771 | out: | 779 | out: |
772 | perf_enable(); | 780 | perf_pmu_enable(event->pmu); |
773 | local_irq_restore(flags); | 781 | local_irq_restore(flags); |
774 | return ret; | 782 | return ret; |
775 | } | 783 | } |
@@ -777,14 +785,14 @@ nocheck: | |||
777 | /* | 785 | /* |
778 | * Remove a event from the PMU. | 786 | * Remove a event from the PMU. |
779 | */ | 787 | */ |
780 | static void power_pmu_disable(struct perf_event *event) | 788 | static void power_pmu_del(struct perf_event *event, int ef_flags) |
781 | { | 789 | { |
782 | struct cpu_hw_events *cpuhw; | 790 | struct cpu_hw_events *cpuhw; |
783 | long i; | 791 | long i; |
784 | unsigned long flags; | 792 | unsigned long flags; |
785 | 793 | ||
786 | local_irq_save(flags); | 794 | local_irq_save(flags); |
787 | perf_disable(); | 795 | perf_pmu_disable(event->pmu); |
788 | 796 | ||
789 | power_pmu_read(event); | 797 | power_pmu_read(event); |
790 | 798 | ||
@@ -821,34 +829,60 @@ static void power_pmu_disable(struct perf_event *event) | |||
821 | cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); | 829 | cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); |
822 | } | 830 | } |
823 | 831 | ||
824 | perf_enable(); | 832 | perf_pmu_enable(event->pmu); |
825 | local_irq_restore(flags); | 833 | local_irq_restore(flags); |
826 | } | 834 | } |
827 | 835 | ||
828 | /* | 836 | /* |
829 | * Re-enable interrupts on a event after they were throttled | 837 | * POWER-PMU does not support disabling individual counters, hence |
830 | * because they were coming too fast. | 838 | * program their cycle counter to their max value and ignore the interrupts. |
831 | */ | 839 | */ |
832 | static void power_pmu_unthrottle(struct perf_event *event) | 840 | |
841 | static void power_pmu_start(struct perf_event *event, int ef_flags) | ||
842 | { | ||
843 | unsigned long flags; | ||
844 | s64 left; | ||
845 | |||
846 | if (!event->hw.idx || !event->hw.sample_period) | ||
847 | return; | ||
848 | |||
849 | if (!(event->hw.state & PERF_HES_STOPPED)) | ||
850 | return; | ||
851 | |||
852 | if (ef_flags & PERF_EF_RELOAD) | ||
853 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
854 | |||
855 | local_irq_save(flags); | ||
856 | perf_pmu_disable(event->pmu); | ||
857 | |||
858 | event->hw.state = 0; | ||
859 | left = local64_read(&event->hw.period_left); | ||
860 | write_pmc(event->hw.idx, left); | ||
861 | |||
862 | perf_event_update_userpage(event); | ||
863 | perf_pmu_enable(event->pmu); | ||
864 | local_irq_restore(flags); | ||
865 | } | ||
866 | |||
867 | static void power_pmu_stop(struct perf_event *event, int ef_flags) | ||
833 | { | 868 | { |
834 | s64 val, left; | ||
835 | unsigned long flags; | 869 | unsigned long flags; |
836 | 870 | ||
837 | if (!event->hw.idx || !event->hw.sample_period) | 871 | if (!event->hw.idx || !event->hw.sample_period) |
838 | return; | 872 | return; |
873 | |||
874 | if (event->hw.state & PERF_HES_STOPPED) | ||
875 | return; | ||
876 | |||
839 | local_irq_save(flags); | 877 | local_irq_save(flags); |
840 | perf_disable(); | 878 | perf_pmu_disable(event->pmu); |
879 | |||
841 | power_pmu_read(event); | 880 | power_pmu_read(event); |
842 | left = event->hw.sample_period; | 881 | event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; |
843 | event->hw.last_period = left; | 882 | write_pmc(event->hw.idx, 0); |
844 | val = 0; | 883 | |
845 | if (left < 0x80000000L) | ||
846 | val = 0x80000000L - left; | ||
847 | write_pmc(event->hw.idx, val); | ||
848 | local64_set(&event->hw.prev_count, val); | ||
849 | local64_set(&event->hw.period_left, left); | ||
850 | perf_event_update_userpage(event); | 884 | perf_event_update_userpage(event); |
851 | perf_enable(); | 885 | perf_pmu_enable(event->pmu); |
852 | local_irq_restore(flags); | 886 | local_irq_restore(flags); |
853 | } | 887 | } |
854 | 888 | ||
@@ -857,10 +891,11 @@ static void power_pmu_unthrottle(struct perf_event *event) | |||
857 | * Set the flag to make pmu::enable() not perform the | 891 | * Set the flag to make pmu::enable() not perform the |
858 | * schedulability test, it will be performed at commit time | 892 | * schedulability test, it will be performed at commit time |
859 | */ | 893 | */ |
860 | void power_pmu_start_txn(const struct pmu *pmu) | 894 | void power_pmu_start_txn(struct pmu *pmu) |
861 | { | 895 | { |
862 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | 896 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); |
863 | 897 | ||
898 | perf_pmu_disable(pmu); | ||
864 | cpuhw->group_flag |= PERF_EVENT_TXN; | 899 | cpuhw->group_flag |= PERF_EVENT_TXN; |
865 | cpuhw->n_txn_start = cpuhw->n_events; | 900 | cpuhw->n_txn_start = cpuhw->n_events; |
866 | } | 901 | } |
@@ -870,11 +905,12 @@ void power_pmu_start_txn(const struct pmu *pmu) | |||
870 | * Clear the flag and pmu::enable() will perform the | 905 | * Clear the flag and pmu::enable() will perform the |
871 | * schedulability test. | 906 | * schedulability test. |
872 | */ | 907 | */ |
873 | void power_pmu_cancel_txn(const struct pmu *pmu) | 908 | void power_pmu_cancel_txn(struct pmu *pmu) |
874 | { | 909 | { |
875 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | 910 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); |
876 | 911 | ||
877 | cpuhw->group_flag &= ~PERF_EVENT_TXN; | 912 | cpuhw->group_flag &= ~PERF_EVENT_TXN; |
913 | perf_pmu_enable(pmu); | ||
878 | } | 914 | } |
879 | 915 | ||
880 | /* | 916 | /* |
@@ -882,7 +918,7 @@ void power_pmu_cancel_txn(const struct pmu *pmu) | |||
882 | * Perform the group schedulability test as a whole | 918 | * Perform the group schedulability test as a whole |
883 | * Return 0 if success | 919 | * Return 0 if success |
884 | */ | 920 | */ |
885 | int power_pmu_commit_txn(const struct pmu *pmu) | 921 | int power_pmu_commit_txn(struct pmu *pmu) |
886 | { | 922 | { |
887 | struct cpu_hw_events *cpuhw; | 923 | struct cpu_hw_events *cpuhw; |
888 | long i, n; | 924 | long i, n; |
@@ -901,19 +937,10 @@ int power_pmu_commit_txn(const struct pmu *pmu) | |||
901 | cpuhw->event[i]->hw.config = cpuhw->events[i]; | 937 | cpuhw->event[i]->hw.config = cpuhw->events[i]; |
902 | 938 | ||
903 | cpuhw->group_flag &= ~PERF_EVENT_TXN; | 939 | cpuhw->group_flag &= ~PERF_EVENT_TXN; |
940 | perf_pmu_enable(pmu); | ||
904 | return 0; | 941 | return 0; |
905 | } | 942 | } |
906 | 943 | ||
907 | struct pmu power_pmu = { | ||
908 | .enable = power_pmu_enable, | ||
909 | .disable = power_pmu_disable, | ||
910 | .read = power_pmu_read, | ||
911 | .unthrottle = power_pmu_unthrottle, | ||
912 | .start_txn = power_pmu_start_txn, | ||
913 | .cancel_txn = power_pmu_cancel_txn, | ||
914 | .commit_txn = power_pmu_commit_txn, | ||
915 | }; | ||
916 | |||
917 | /* | 944 | /* |
918 | * Return 1 if we might be able to put event on a limited PMC, | 945 | * Return 1 if we might be able to put event on a limited PMC, |
919 | * or 0 if not. | 946 | * or 0 if not. |
@@ -1014,7 +1041,7 @@ static int hw_perf_cache_event(u64 config, u64 *eventp) | |||
1014 | return 0; | 1041 | return 0; |
1015 | } | 1042 | } |
1016 | 1043 | ||
1017 | const struct pmu *hw_perf_event_init(struct perf_event *event) | 1044 | static int power_pmu_event_init(struct perf_event *event) |
1018 | { | 1045 | { |
1019 | u64 ev; | 1046 | u64 ev; |
1020 | unsigned long flags; | 1047 | unsigned long flags; |
@@ -1026,25 +1053,27 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
1026 | struct cpu_hw_events *cpuhw; | 1053 | struct cpu_hw_events *cpuhw; |
1027 | 1054 | ||
1028 | if (!ppmu) | 1055 | if (!ppmu) |
1029 | return ERR_PTR(-ENXIO); | 1056 | return -ENOENT; |
1057 | |||
1030 | switch (event->attr.type) { | 1058 | switch (event->attr.type) { |
1031 | case PERF_TYPE_HARDWARE: | 1059 | case PERF_TYPE_HARDWARE: |
1032 | ev = event->attr.config; | 1060 | ev = event->attr.config; |
1033 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) | 1061 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) |
1034 | return ERR_PTR(-EOPNOTSUPP); | 1062 | return -EOPNOTSUPP; |
1035 | ev = ppmu->generic_events[ev]; | 1063 | ev = ppmu->generic_events[ev]; |
1036 | break; | 1064 | break; |
1037 | case PERF_TYPE_HW_CACHE: | 1065 | case PERF_TYPE_HW_CACHE: |
1038 | err = hw_perf_cache_event(event->attr.config, &ev); | 1066 | err = hw_perf_cache_event(event->attr.config, &ev); |
1039 | if (err) | 1067 | if (err) |
1040 | return ERR_PTR(err); | 1068 | return err; |
1041 | break; | 1069 | break; |
1042 | case PERF_TYPE_RAW: | 1070 | case PERF_TYPE_RAW: |
1043 | ev = event->attr.config; | 1071 | ev = event->attr.config; |
1044 | break; | 1072 | break; |
1045 | default: | 1073 | default: |
1046 | return ERR_PTR(-EINVAL); | 1074 | return -ENOENT; |
1047 | } | 1075 | } |
1076 | |||
1048 | event->hw.config_base = ev; | 1077 | event->hw.config_base = ev; |
1049 | event->hw.idx = 0; | 1078 | event->hw.idx = 0; |
1050 | 1079 | ||
@@ -1081,7 +1110,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
1081 | */ | 1110 | */ |
1082 | ev = normal_pmc_alternative(ev, flags); | 1111 | ev = normal_pmc_alternative(ev, flags); |
1083 | if (!ev) | 1112 | if (!ev) |
1084 | return ERR_PTR(-EINVAL); | 1113 | return -EINVAL; |
1085 | } | 1114 | } |
1086 | } | 1115 | } |
1087 | 1116 | ||
@@ -1095,19 +1124,19 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
1095 | n = collect_events(event->group_leader, ppmu->n_counter - 1, | 1124 | n = collect_events(event->group_leader, ppmu->n_counter - 1, |
1096 | ctrs, events, cflags); | 1125 | ctrs, events, cflags); |
1097 | if (n < 0) | 1126 | if (n < 0) |
1098 | return ERR_PTR(-EINVAL); | 1127 | return -EINVAL; |
1099 | } | 1128 | } |
1100 | events[n] = ev; | 1129 | events[n] = ev; |
1101 | ctrs[n] = event; | 1130 | ctrs[n] = event; |
1102 | cflags[n] = flags; | 1131 | cflags[n] = flags; |
1103 | if (check_excludes(ctrs, cflags, n, 1)) | 1132 | if (check_excludes(ctrs, cflags, n, 1)) |
1104 | return ERR_PTR(-EINVAL); | 1133 | return -EINVAL; |
1105 | 1134 | ||
1106 | cpuhw = &get_cpu_var(cpu_hw_events); | 1135 | cpuhw = &get_cpu_var(cpu_hw_events); |
1107 | err = power_check_constraints(cpuhw, events, cflags, n + 1); | 1136 | err = power_check_constraints(cpuhw, events, cflags, n + 1); |
1108 | put_cpu_var(cpu_hw_events); | 1137 | put_cpu_var(cpu_hw_events); |
1109 | if (err) | 1138 | if (err) |
1110 | return ERR_PTR(-EINVAL); | 1139 | return -EINVAL; |
1111 | 1140 | ||
1112 | event->hw.config = events[n]; | 1141 | event->hw.config = events[n]; |
1113 | event->hw.event_base = cflags[n]; | 1142 | event->hw.event_base = cflags[n]; |
@@ -1132,11 +1161,23 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
1132 | } | 1161 | } |
1133 | event->destroy = hw_perf_event_destroy; | 1162 | event->destroy = hw_perf_event_destroy; |
1134 | 1163 | ||
1135 | if (err) | 1164 | return err; |
1136 | return ERR_PTR(err); | ||
1137 | return &power_pmu; | ||
1138 | } | 1165 | } |
1139 | 1166 | ||
1167 | struct pmu power_pmu = { | ||
1168 | .pmu_enable = power_pmu_enable, | ||
1169 | .pmu_disable = power_pmu_disable, | ||
1170 | .event_init = power_pmu_event_init, | ||
1171 | .add = power_pmu_add, | ||
1172 | .del = power_pmu_del, | ||
1173 | .start = power_pmu_start, | ||
1174 | .stop = power_pmu_stop, | ||
1175 | .read = power_pmu_read, | ||
1176 | .start_txn = power_pmu_start_txn, | ||
1177 | .cancel_txn = power_pmu_cancel_txn, | ||
1178 | .commit_txn = power_pmu_commit_txn, | ||
1179 | }; | ||
1180 | |||
1140 | /* | 1181 | /* |
1141 | * A counter has overflowed; update its count and record | 1182 | * A counter has overflowed; update its count and record |
1142 | * things if requested. Note that interrupts are hard-disabled | 1183 | * things if requested. Note that interrupts are hard-disabled |
@@ -1149,6 +1190,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
1149 | s64 prev, delta, left; | 1190 | s64 prev, delta, left; |
1150 | int record = 0; | 1191 | int record = 0; |
1151 | 1192 | ||
1193 | if (event->hw.state & PERF_HES_STOPPED) { | ||
1194 | write_pmc(event->hw.idx, 0); | ||
1195 | return; | ||
1196 | } | ||
1197 | |||
1152 | /* we don't have to worry about interrupts here */ | 1198 | /* we don't have to worry about interrupts here */ |
1153 | prev = local64_read(&event->hw.prev_count); | 1199 | prev = local64_read(&event->hw.prev_count); |
1154 | delta = (val - prev) & 0xfffffffful; | 1200 | delta = (val - prev) & 0xfffffffful; |
@@ -1171,6 +1217,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
1171 | val = 0x80000000LL - left; | 1217 | val = 0x80000000LL - left; |
1172 | } | 1218 | } |
1173 | 1219 | ||
1220 | write_pmc(event->hw.idx, val); | ||
1221 | local64_set(&event->hw.prev_count, val); | ||
1222 | local64_set(&event->hw.period_left, left); | ||
1223 | perf_event_update_userpage(event); | ||
1224 | |||
1174 | /* | 1225 | /* |
1175 | * Finally record data if requested. | 1226 | * Finally record data if requested. |
1176 | */ | 1227 | */ |
@@ -1183,23 +1234,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
1183 | if (event->attr.sample_type & PERF_SAMPLE_ADDR) | 1234 | if (event->attr.sample_type & PERF_SAMPLE_ADDR) |
1184 | perf_get_data_addr(regs, &data.addr); | 1235 | perf_get_data_addr(regs, &data.addr); |
1185 | 1236 | ||
1186 | if (perf_event_overflow(event, nmi, &data, regs)) { | 1237 | if (perf_event_overflow(event, nmi, &data, regs)) |
1187 | /* | 1238 | power_pmu_stop(event, 0); |
1188 | * Interrupts are coming too fast - throttle them | ||
1189 | * by setting the event to 0, so it will be | ||
1190 | * at least 2^30 cycles until the next interrupt | ||
1191 | * (assuming each event counts at most 2 counts | ||
1192 | * per cycle). | ||
1193 | */ | ||
1194 | val = 0; | ||
1195 | left = ~0ULL >> 1; | ||
1196 | } | ||
1197 | } | 1239 | } |
1198 | |||
1199 | write_pmc(event->hw.idx, val); | ||
1200 | local64_set(&event->hw.prev_count, val); | ||
1201 | local64_set(&event->hw.period_left, left); | ||
1202 | perf_event_update_userpage(event); | ||
1203 | } | 1240 | } |
1204 | 1241 | ||
1205 | /* | 1242 | /* |
@@ -1342,6 +1379,7 @@ int register_power_pmu(struct power_pmu *pmu) | |||
1342 | freeze_events_kernel = MMCR0_FCHV; | 1379 | freeze_events_kernel = MMCR0_FCHV; |
1343 | #endif /* CONFIG_PPC64 */ | 1380 | #endif /* CONFIG_PPC64 */ |
1344 | 1381 | ||
1382 | perf_pmu_register(&power_pmu); | ||
1345 | perf_cpu_notifier(power_pmu_notifier); | 1383 | perf_cpu_notifier(power_pmu_notifier); |
1346 | 1384 | ||
1347 | return 0; | 1385 | return 0; |
diff --git a/arch/powerpc/kernel/perf_event_fsl_emb.c b/arch/powerpc/kernel/perf_event_fsl_emb.c index 1ba45471ae43..7ecca59ddf77 100644 --- a/arch/powerpc/kernel/perf_event_fsl_emb.c +++ b/arch/powerpc/kernel/perf_event_fsl_emb.c | |||
@@ -156,6 +156,9 @@ static void fsl_emb_pmu_read(struct perf_event *event) | |||
156 | { | 156 | { |
157 | s64 val, delta, prev; | 157 | s64 val, delta, prev; |
158 | 158 | ||
159 | if (event->hw.state & PERF_HES_STOPPED) | ||
160 | return; | ||
161 | |||
159 | /* | 162 | /* |
160 | * Performance monitor interrupts come even when interrupts | 163 | * Performance monitor interrupts come even when interrupts |
161 | * are soft-disabled, as long as interrupts are hard-enabled. | 164 | * are soft-disabled, as long as interrupts are hard-enabled. |
@@ -177,7 +180,7 @@ static void fsl_emb_pmu_read(struct perf_event *event) | |||
177 | * Disable all events to prevent PMU interrupts and to allow | 180 | * Disable all events to prevent PMU interrupts and to allow |
178 | * events to be added or removed. | 181 | * events to be added or removed. |
179 | */ | 182 | */ |
180 | void hw_perf_disable(void) | 183 | static void fsl_emb_pmu_disable(struct pmu *pmu) |
181 | { | 184 | { |
182 | struct cpu_hw_events *cpuhw; | 185 | struct cpu_hw_events *cpuhw; |
183 | unsigned long flags; | 186 | unsigned long flags; |
@@ -216,7 +219,7 @@ void hw_perf_disable(void) | |||
216 | * If we were previously disabled and events were added, then | 219 | * If we were previously disabled and events were added, then |
217 | * put the new config on the PMU. | 220 | * put the new config on the PMU. |
218 | */ | 221 | */ |
219 | void hw_perf_enable(void) | 222 | static void fsl_emb_pmu_enable(struct pmu *pmu) |
220 | { | 223 | { |
221 | struct cpu_hw_events *cpuhw; | 224 | struct cpu_hw_events *cpuhw; |
222 | unsigned long flags; | 225 | unsigned long flags; |
@@ -262,8 +265,8 @@ static int collect_events(struct perf_event *group, int max_count, | |||
262 | return n; | 265 | return n; |
263 | } | 266 | } |
264 | 267 | ||
265 | /* perf must be disabled, context locked on entry */ | 268 | /* context locked on entry */ |
266 | static int fsl_emb_pmu_enable(struct perf_event *event) | 269 | static int fsl_emb_pmu_add(struct perf_event *event, int flags) |
267 | { | 270 | { |
268 | struct cpu_hw_events *cpuhw; | 271 | struct cpu_hw_events *cpuhw; |
269 | int ret = -EAGAIN; | 272 | int ret = -EAGAIN; |
@@ -271,6 +274,7 @@ static int fsl_emb_pmu_enable(struct perf_event *event) | |||
271 | u64 val; | 274 | u64 val; |
272 | int i; | 275 | int i; |
273 | 276 | ||
277 | perf_pmu_disable(event->pmu); | ||
274 | cpuhw = &get_cpu_var(cpu_hw_events); | 278 | cpuhw = &get_cpu_var(cpu_hw_events); |
275 | 279 | ||
276 | if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) | 280 | if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) |
@@ -301,6 +305,12 @@ static int fsl_emb_pmu_enable(struct perf_event *event) | |||
301 | val = 0x80000000L - left; | 305 | val = 0x80000000L - left; |
302 | } | 306 | } |
303 | local64_set(&event->hw.prev_count, val); | 307 | local64_set(&event->hw.prev_count, val); |
308 | |||
309 | if (!(flags & PERF_EF_START)) { | ||
310 | event->hw.state = PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
311 | val = 0; | ||
312 | } | ||
313 | |||
304 | write_pmc(i, val); | 314 | write_pmc(i, val); |
305 | perf_event_update_userpage(event); | 315 | perf_event_update_userpage(event); |
306 | 316 | ||
@@ -310,15 +320,17 @@ static int fsl_emb_pmu_enable(struct perf_event *event) | |||
310 | ret = 0; | 320 | ret = 0; |
311 | out: | 321 | out: |
312 | put_cpu_var(cpu_hw_events); | 322 | put_cpu_var(cpu_hw_events); |
323 | perf_pmu_enable(event->pmu); | ||
313 | return ret; | 324 | return ret; |
314 | } | 325 | } |
315 | 326 | ||
316 | /* perf must be disabled, context locked on entry */ | 327 | /* context locked on entry */ |
317 | static void fsl_emb_pmu_disable(struct perf_event *event) | 328 | static void fsl_emb_pmu_del(struct perf_event *event, int flags) |
318 | { | 329 | { |
319 | struct cpu_hw_events *cpuhw; | 330 | struct cpu_hw_events *cpuhw; |
320 | int i = event->hw.idx; | 331 | int i = event->hw.idx; |
321 | 332 | ||
333 | perf_pmu_disable(event->pmu); | ||
322 | if (i < 0) | 334 | if (i < 0) |
323 | goto out; | 335 | goto out; |
324 | 336 | ||
@@ -346,44 +358,57 @@ static void fsl_emb_pmu_disable(struct perf_event *event) | |||
346 | cpuhw->n_events--; | 358 | cpuhw->n_events--; |
347 | 359 | ||
348 | out: | 360 | out: |
361 | perf_pmu_enable(event->pmu); | ||
349 | put_cpu_var(cpu_hw_events); | 362 | put_cpu_var(cpu_hw_events); |
350 | } | 363 | } |
351 | 364 | ||
352 | /* | 365 | static void fsl_emb_pmu_start(struct perf_event *event, int ef_flags) |
353 | * Re-enable interrupts on a event after they were throttled | ||
354 | * because they were coming too fast. | ||
355 | * | ||
356 | * Context is locked on entry, but perf is not disabled. | ||
357 | */ | ||
358 | static void fsl_emb_pmu_unthrottle(struct perf_event *event) | ||
359 | { | 366 | { |
360 | s64 val, left; | ||
361 | unsigned long flags; | 367 | unsigned long flags; |
368 | s64 left; | ||
362 | 369 | ||
363 | if (event->hw.idx < 0 || !event->hw.sample_period) | 370 | if (event->hw.idx < 0 || !event->hw.sample_period) |
364 | return; | 371 | return; |
372 | |||
373 | if (!(event->hw.state & PERF_HES_STOPPED)) | ||
374 | return; | ||
375 | |||
376 | if (ef_flags & PERF_EF_RELOAD) | ||
377 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
378 | |||
365 | local_irq_save(flags); | 379 | local_irq_save(flags); |
366 | perf_disable(); | 380 | perf_pmu_disable(event->pmu); |
367 | fsl_emb_pmu_read(event); | 381 | |
368 | left = event->hw.sample_period; | 382 | event->hw.state = 0; |
369 | event->hw.last_period = left; | 383 | left = local64_read(&event->hw.period_left); |
370 | val = 0; | 384 | write_pmc(event->hw.idx, left); |
371 | if (left < 0x80000000L) | 385 | |
372 | val = 0x80000000L - left; | ||
373 | write_pmc(event->hw.idx, val); | ||
374 | local64_set(&event->hw.prev_count, val); | ||
375 | local64_set(&event->hw.period_left, left); | ||
376 | perf_event_update_userpage(event); | 386 | perf_event_update_userpage(event); |
377 | perf_enable(); | 387 | perf_pmu_enable(event->pmu); |
378 | local_irq_restore(flags); | 388 | local_irq_restore(flags); |
379 | } | 389 | } |
380 | 390 | ||
381 | static struct pmu fsl_emb_pmu = { | 391 | static void fsl_emb_pmu_stop(struct perf_event *event, int ef_flags) |
382 | .enable = fsl_emb_pmu_enable, | 392 | { |
383 | .disable = fsl_emb_pmu_disable, | 393 | unsigned long flags; |
384 | .read = fsl_emb_pmu_read, | 394 | |
385 | .unthrottle = fsl_emb_pmu_unthrottle, | 395 | if (event->hw.idx < 0 || !event->hw.sample_period) |
386 | }; | 396 | return; |
397 | |||
398 | if (event->hw.state & PERF_HES_STOPPED) | ||
399 | return; | ||
400 | |||
401 | local_irq_save(flags); | ||
402 | perf_pmu_disable(event->pmu); | ||
403 | |||
404 | fsl_emb_pmu_read(event); | ||
405 | event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; | ||
406 | write_pmc(event->hw.idx, 0); | ||
407 | |||
408 | perf_event_update_userpage(event); | ||
409 | perf_pmu_enable(event->pmu); | ||
410 | local_irq_restore(flags); | ||
411 | } | ||
387 | 412 | ||
388 | /* | 413 | /* |
389 | * Release the PMU if this is the last perf_event. | 414 | * Release the PMU if this is the last perf_event. |
@@ -428,7 +453,7 @@ static int hw_perf_cache_event(u64 config, u64 *eventp) | |||
428 | return 0; | 453 | return 0; |
429 | } | 454 | } |
430 | 455 | ||
431 | const struct pmu *hw_perf_event_init(struct perf_event *event) | 456 | static int fsl_emb_pmu_event_init(struct perf_event *event) |
432 | { | 457 | { |
433 | u64 ev; | 458 | u64 ev; |
434 | struct perf_event *events[MAX_HWEVENTS]; | 459 | struct perf_event *events[MAX_HWEVENTS]; |
@@ -441,14 +466,14 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
441 | case PERF_TYPE_HARDWARE: | 466 | case PERF_TYPE_HARDWARE: |
442 | ev = event->attr.config; | 467 | ev = event->attr.config; |
443 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) | 468 | if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) |
444 | return ERR_PTR(-EOPNOTSUPP); | 469 | return -EOPNOTSUPP; |
445 | ev = ppmu->generic_events[ev]; | 470 | ev = ppmu->generic_events[ev]; |
446 | break; | 471 | break; |
447 | 472 | ||
448 | case PERF_TYPE_HW_CACHE: | 473 | case PERF_TYPE_HW_CACHE: |
449 | err = hw_perf_cache_event(event->attr.config, &ev); | 474 | err = hw_perf_cache_event(event->attr.config, &ev); |
450 | if (err) | 475 | if (err) |
451 | return ERR_PTR(err); | 476 | return err; |
452 | break; | 477 | break; |
453 | 478 | ||
454 | case PERF_TYPE_RAW: | 479 | case PERF_TYPE_RAW: |
@@ -456,12 +481,12 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
456 | break; | 481 | break; |
457 | 482 | ||
458 | default: | 483 | default: |
459 | return ERR_PTR(-EINVAL); | 484 | return -ENOENT; |
460 | } | 485 | } |
461 | 486 | ||
462 | event->hw.config = ppmu->xlate_event(ev); | 487 | event->hw.config = ppmu->xlate_event(ev); |
463 | if (!(event->hw.config & FSL_EMB_EVENT_VALID)) | 488 | if (!(event->hw.config & FSL_EMB_EVENT_VALID)) |
464 | return ERR_PTR(-EINVAL); | 489 | return -EINVAL; |
465 | 490 | ||
466 | /* | 491 | /* |
467 | * If this is in a group, check if it can go on with all the | 492 | * If this is in a group, check if it can go on with all the |
@@ -473,7 +498,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
473 | n = collect_events(event->group_leader, | 498 | n = collect_events(event->group_leader, |
474 | ppmu->n_counter - 1, events); | 499 | ppmu->n_counter - 1, events); |
475 | if (n < 0) | 500 | if (n < 0) |
476 | return ERR_PTR(-EINVAL); | 501 | return -EINVAL; |
477 | } | 502 | } |
478 | 503 | ||
479 | if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) { | 504 | if (event->hw.config & FSL_EMB_EVENT_RESTRICTED) { |
@@ -484,7 +509,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
484 | } | 509 | } |
485 | 510 | ||
486 | if (num_restricted >= ppmu->n_restricted) | 511 | if (num_restricted >= ppmu->n_restricted) |
487 | return ERR_PTR(-EINVAL); | 512 | return -EINVAL; |
488 | } | 513 | } |
489 | 514 | ||
490 | event->hw.idx = -1; | 515 | event->hw.idx = -1; |
@@ -497,7 +522,7 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
497 | if (event->attr.exclude_kernel) | 522 | if (event->attr.exclude_kernel) |
498 | event->hw.config_base |= PMLCA_FCS; | 523 | event->hw.config_base |= PMLCA_FCS; |
499 | if (event->attr.exclude_idle) | 524 | if (event->attr.exclude_idle) |
500 | return ERR_PTR(-ENOTSUPP); | 525 | return -ENOTSUPP; |
501 | 526 | ||
502 | event->hw.last_period = event->hw.sample_period; | 527 | event->hw.last_period = event->hw.sample_period; |
503 | local64_set(&event->hw.period_left, event->hw.last_period); | 528 | local64_set(&event->hw.period_left, event->hw.last_period); |
@@ -523,11 +548,20 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
523 | } | 548 | } |
524 | event->destroy = hw_perf_event_destroy; | 549 | event->destroy = hw_perf_event_destroy; |
525 | 550 | ||
526 | if (err) | 551 | return err; |
527 | return ERR_PTR(err); | ||
528 | return &fsl_emb_pmu; | ||
529 | } | 552 | } |
530 | 553 | ||
554 | static struct pmu fsl_emb_pmu = { | ||
555 | .pmu_enable = fsl_emb_pmu_enable, | ||
556 | .pmu_disable = fsl_emb_pmu_disable, | ||
557 | .event_init = fsl_emb_pmu_event_init, | ||
558 | .add = fsl_emb_pmu_add, | ||
559 | .del = fsl_emb_pmu_del, | ||
560 | .start = fsl_emb_pmu_start, | ||
561 | .stop = fsl_emb_pmu_stop, | ||
562 | .read = fsl_emb_pmu_read, | ||
563 | }; | ||
564 | |||
531 | /* | 565 | /* |
532 | * A counter has overflowed; update its count and record | 566 | * A counter has overflowed; update its count and record |
533 | * things if requested. Note that interrupts are hard-disabled | 567 | * things if requested. Note that interrupts are hard-disabled |
@@ -540,6 +574,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
540 | s64 prev, delta, left; | 574 | s64 prev, delta, left; |
541 | int record = 0; | 575 | int record = 0; |
542 | 576 | ||
577 | if (event->hw.state & PERF_HES_STOPPED) { | ||
578 | write_pmc(event->hw.idx, 0); | ||
579 | return; | ||
580 | } | ||
581 | |||
543 | /* we don't have to worry about interrupts here */ | 582 | /* we don't have to worry about interrupts here */ |
544 | prev = local64_read(&event->hw.prev_count); | 583 | prev = local64_read(&event->hw.prev_count); |
545 | delta = (val - prev) & 0xfffffffful; | 584 | delta = (val - prev) & 0xfffffffful; |
@@ -562,6 +601,11 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
562 | val = 0x80000000LL - left; | 601 | val = 0x80000000LL - left; |
563 | } | 602 | } |
564 | 603 | ||
604 | write_pmc(event->hw.idx, val); | ||
605 | local64_set(&event->hw.prev_count, val); | ||
606 | local64_set(&event->hw.period_left, left); | ||
607 | perf_event_update_userpage(event); | ||
608 | |||
565 | /* | 609 | /* |
566 | * Finally record data if requested. | 610 | * Finally record data if requested. |
567 | */ | 611 | */ |
@@ -571,23 +615,9 @@ static void record_and_restart(struct perf_event *event, unsigned long val, | |||
571 | perf_sample_data_init(&data, 0); | 615 | perf_sample_data_init(&data, 0); |
572 | data.period = event->hw.last_period; | 616 | data.period = event->hw.last_period; |
573 | 617 | ||
574 | if (perf_event_overflow(event, nmi, &data, regs)) { | 618 | if (perf_event_overflow(event, nmi, &data, regs)) |
575 | /* | 619 | fsl_emb_pmu_stop(event, 0); |
576 | * Interrupts are coming too fast - throttle them | ||
577 | * by setting the event to 0, so it will be | ||
578 | * at least 2^30 cycles until the next interrupt | ||
579 | * (assuming each event counts at most 2 counts | ||
580 | * per cycle). | ||
581 | */ | ||
582 | val = 0; | ||
583 | left = ~0ULL >> 1; | ||
584 | } | ||
585 | } | 620 | } |
586 | |||
587 | write_pmc(event->hw.idx, val); | ||
588 | local64_set(&event->hw.prev_count, val); | ||
589 | local64_set(&event->hw.period_left, left); | ||
590 | perf_event_update_userpage(event); | ||
591 | } | 621 | } |
592 | 622 | ||
593 | static void perf_event_interrupt(struct pt_regs *regs) | 623 | static void perf_event_interrupt(struct pt_regs *regs) |
@@ -651,5 +681,7 @@ int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu) | |||
651 | pr_info("%s performance monitor hardware support registered\n", | 681 | pr_info("%s performance monitor hardware support registered\n", |
652 | pmu->name); | 682 | pmu->name); |
653 | 683 | ||
684 | perf_pmu_register(&fsl_emb_pmu); | ||
685 | |||
654 | return 0; | 686 | return 0; |
655 | } | 687 | } |
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 5b243bd3eb3b..3dc2a8d262b8 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
@@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id) | |||
57 | int id_match = 0; | 57 | int id_match = 0; |
58 | 58 | ||
59 | if (dev == NULL || id == NULL) | 59 | if (dev == NULL || id == NULL) |
60 | return NULL; | 60 | return clk; |
61 | 61 | ||
62 | mutex_lock(&clocks_mutex); | 62 | mutex_lock(&clocks_mutex); |
63 | list_for_each_entry(p, &clocks, node) { | 63 | list_for_each_entry(p, &clocks, node) { |
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 45c0cb9b67e6..18c104820198 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c | |||
@@ -99,7 +99,7 @@ static void __init efika_pcisetup(void) | |||
99 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 99 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
100 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | 100 | printk(KERN_WARNING EFIKA_PLATFORM_NAME |
101 | ": Can't get bus-range for %s\n", pcictrl->full_name); | 101 | ": Can't get bus-range for %s\n", pcictrl->full_name); |
102 | return; | 102 | goto out_put; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (bus_range[1] == bus_range[0]) | 105 | if (bus_range[1] == bus_range[0]) |
@@ -111,12 +111,12 @@ static void __init efika_pcisetup(void) | |||
111 | printk(" controlled by %s\n", pcictrl->full_name); | 111 | printk(" controlled by %s\n", pcictrl->full_name); |
112 | printk("\n"); | 112 | printk("\n"); |
113 | 113 | ||
114 | hose = pcibios_alloc_controller(of_node_get(pcictrl)); | 114 | hose = pcibios_alloc_controller(pcictrl); |
115 | if (!hose) { | 115 | if (!hose) { |
116 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | 116 | printk(KERN_WARNING EFIKA_PLATFORM_NAME |
117 | ": Can't allocate PCI controller structure for %s\n", | 117 | ": Can't allocate PCI controller structure for %s\n", |
118 | pcictrl->full_name); | 118 | pcictrl->full_name); |
119 | return; | 119 | goto out_put; |
120 | } | 120 | } |
121 | 121 | ||
122 | hose->first_busno = bus_range[0]; | 122 | hose->first_busno = bus_range[0]; |
@@ -124,6 +124,9 @@ static void __init efika_pcisetup(void) | |||
124 | hose->ops = &rtas_pci_ops; | 124 | hose->ops = &rtas_pci_ops; |
125 | 125 | ||
126 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); | 126 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); |
127 | return; | ||
128 | out_put: | ||
129 | of_node_put(pcictrl); | ||
127 | } | 130 | } |
128 | 131 | ||
129 | #else | 132 | #else |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 6e905314ad5d..41f3a7eda1de 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c | |||
@@ -325,12 +325,16 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number) | |||
325 | clrbits32(&simple_gpio->simple_dvo, sync | out); | 325 | clrbits32(&simple_gpio->simple_dvo, sync | out); |
326 | clrbits8(&wkup_gpio->wkup_dvo, reset); | 326 | clrbits8(&wkup_gpio->wkup_dvo, reset); |
327 | 327 | ||
328 | /* wait at lease 1 us */ | 328 | /* wait for 1 us */ |
329 | udelay(2); | 329 | udelay(1); |
330 | 330 | ||
331 | /* Deassert reset */ | 331 | /* Deassert reset */ |
332 | setbits8(&wkup_gpio->wkup_dvo, reset); | 332 | setbits8(&wkup_gpio->wkup_dvo, reset); |
333 | 333 | ||
334 | /* wait at least 200ns */ | ||
335 | /* 7 ~= (200ns * timebase) / ns2sec */ | ||
336 | __delay(7); | ||
337 | |||
334 | /* Restore pin-muxing */ | 338 | /* Restore pin-muxing */ |
335 | out_be32(&simple_gpio->port_config, mux); | 339 | out_be32(&simple_gpio->port_config, mux); |
336 | 340 | ||
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 22cfd634c355..f7167ee4604c 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
407 | { | 407 | { |
408 | vfree(me->arch.syminfo); | 408 | vfree(me->arch.syminfo); |
409 | me->arch.syminfo = NULL; | 409 | me->arch.syminfo = NULL; |
410 | return module_bug_finalize(hdr, sechdrs, me); | 410 | return 0; |
411 | } | 411 | } |
412 | 412 | ||
413 | void module_arch_cleanup(struct module *mod) | 413 | void module_arch_cleanup(struct module *mod) |
414 | { | 414 | { |
415 | module_bug_cleanup(mod); | ||
416 | } | 415 | } |
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index 43adddfe4c04..ae0be697a89e 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c | |||
@@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
149 | int ret = 0; | 149 | int ret = 0; |
150 | 150 | ||
151 | ret |= module_dwarf_finalize(hdr, sechdrs, me); | 151 | ret |= module_dwarf_finalize(hdr, sechdrs, me); |
152 | ret |= module_bug_finalize(hdr, sechdrs, me); | ||
153 | 152 | ||
154 | return ret; | 153 | return ret; |
155 | } | 154 | } |
156 | 155 | ||
157 | void module_arch_cleanup(struct module *mod) | 156 | void module_arch_cleanup(struct module *mod) |
158 | { | 157 | { |
159 | module_bug_cleanup(mod); | ||
160 | module_dwarf_cleanup(mod); | 158 | module_dwarf_cleanup(mod); |
161 | } | 159 | } |
diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c index a9dd3abde28e..d5ca1ef50fa9 100644 --- a/arch/sh/kernel/perf_callchain.c +++ b/arch/sh/kernel/perf_callchain.c | |||
@@ -14,11 +14,6 @@ | |||
14 | #include <asm/unwinder.h> | 14 | #include <asm/unwinder.h> |
15 | #include <asm/ptrace.h> | 15 | #include <asm/ptrace.h> |
16 | 16 | ||
17 | static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
18 | { | ||
19 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
20 | entry->ip[entry->nr++] = ip; | ||
21 | } | ||
22 | 17 | ||
23 | static void callchain_warning(void *data, char *msg) | 18 | static void callchain_warning(void *data, char *msg) |
24 | { | 19 | { |
@@ -39,7 +34,7 @@ static void callchain_address(void *data, unsigned long addr, int reliable) | |||
39 | struct perf_callchain_entry *entry = data; | 34 | struct perf_callchain_entry *entry = data; |
40 | 35 | ||
41 | if (reliable) | 36 | if (reliable) |
42 | callchain_store(entry, addr); | 37 | perf_callchain_store(entry, addr); |
43 | } | 38 | } |
44 | 39 | ||
45 | static const struct stacktrace_ops callchain_ops = { | 40 | static const struct stacktrace_ops callchain_ops = { |
@@ -49,47 +44,10 @@ static const struct stacktrace_ops callchain_ops = { | |||
49 | .address = callchain_address, | 44 | .address = callchain_address, |
50 | }; | 45 | }; |
51 | 46 | ||
52 | static void | 47 | void |
53 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) | 48 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
54 | { | 49 | { |
55 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 50 | perf_callchain_store(entry, regs->pc); |
56 | callchain_store(entry, regs->pc); | ||
57 | 51 | ||
58 | unwind_stack(NULL, regs, NULL, &callchain_ops, entry); | 52 | unwind_stack(NULL, regs, NULL, &callchain_ops, entry); |
59 | } | 53 | } |
60 | |||
61 | static void | ||
62 | perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
63 | { | ||
64 | int is_user; | ||
65 | |||
66 | if (!regs) | ||
67 | return; | ||
68 | |||
69 | is_user = user_mode(regs); | ||
70 | |||
71 | if (is_user && current->state != TASK_RUNNING) | ||
72 | return; | ||
73 | |||
74 | /* | ||
75 | * Only the kernel side is implemented for now. | ||
76 | */ | ||
77 | if (!is_user) | ||
78 | perf_callchain_kernel(regs, entry); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * No need for separate IRQ and NMI entries. | ||
83 | */ | ||
84 | static DEFINE_PER_CPU(struct perf_callchain_entry, callchain); | ||
85 | |||
86 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
87 | { | ||
88 | struct perf_callchain_entry *entry = &__get_cpu_var(callchain); | ||
89 | |||
90 | entry->nr = 0; | ||
91 | |||
92 | perf_do_callchain(regs, entry); | ||
93 | |||
94 | return entry; | ||
95 | } | ||
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c index 55fe89bbdfe0..5a4b33435650 100644 --- a/arch/sh/kernel/perf_event.c +++ b/arch/sh/kernel/perf_event.c | |||
@@ -224,50 +224,80 @@ again: | |||
224 | local64_add(delta, &event->count); | 224 | local64_add(delta, &event->count); |
225 | } | 225 | } |
226 | 226 | ||
227 | static void sh_pmu_disable(struct perf_event *event) | 227 | static void sh_pmu_stop(struct perf_event *event, int flags) |
228 | { | 228 | { |
229 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 229 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
230 | struct hw_perf_event *hwc = &event->hw; | 230 | struct hw_perf_event *hwc = &event->hw; |
231 | int idx = hwc->idx; | 231 | int idx = hwc->idx; |
232 | 232 | ||
233 | clear_bit(idx, cpuc->active_mask); | 233 | if (!(event->hw.state & PERF_HES_STOPPED)) { |
234 | sh_pmu->disable(hwc, idx); | 234 | sh_pmu->disable(hwc, idx); |
235 | cpuc->events[idx] = NULL; | ||
236 | event->hw.state |= PERF_HES_STOPPED; | ||
237 | } | ||
238 | |||
239 | if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) { | ||
240 | sh_perf_event_update(event, &event->hw, idx); | ||
241 | event->hw.state |= PERF_HES_UPTODATE; | ||
242 | } | ||
243 | } | ||
235 | 244 | ||
236 | barrier(); | 245 | static void sh_pmu_start(struct perf_event *event, int flags) |
246 | { | ||
247 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
248 | struct hw_perf_event *hwc = &event->hw; | ||
249 | int idx = hwc->idx; | ||
237 | 250 | ||
238 | sh_perf_event_update(event, &event->hw, idx); | 251 | if (WARN_ON_ONCE(idx == -1)) |
252 | return; | ||
253 | |||
254 | if (flags & PERF_EF_RELOAD) | ||
255 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
256 | |||
257 | cpuc->events[idx] = event; | ||
258 | event->hw.state = 0; | ||
259 | sh_pmu->enable(hwc, idx); | ||
260 | } | ||
261 | |||
262 | static void sh_pmu_del(struct perf_event *event, int flags) | ||
263 | { | ||
264 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
239 | 265 | ||
240 | cpuc->events[idx] = NULL; | 266 | sh_pmu_stop(event, PERF_EF_UPDATE); |
241 | clear_bit(idx, cpuc->used_mask); | 267 | __clear_bit(event->hw.idx, cpuc->used_mask); |
242 | 268 | ||
243 | perf_event_update_userpage(event); | 269 | perf_event_update_userpage(event); |
244 | } | 270 | } |
245 | 271 | ||
246 | static int sh_pmu_enable(struct perf_event *event) | 272 | static int sh_pmu_add(struct perf_event *event, int flags) |
247 | { | 273 | { |
248 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 274 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
249 | struct hw_perf_event *hwc = &event->hw; | 275 | struct hw_perf_event *hwc = &event->hw; |
250 | int idx = hwc->idx; | 276 | int idx = hwc->idx; |
277 | int ret = -EAGAIN; | ||
278 | |||
279 | perf_pmu_disable(event->pmu); | ||
251 | 280 | ||
252 | if (test_and_set_bit(idx, cpuc->used_mask)) { | 281 | if (__test_and_set_bit(idx, cpuc->used_mask)) { |
253 | idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events); | 282 | idx = find_first_zero_bit(cpuc->used_mask, sh_pmu->num_events); |
254 | if (idx == sh_pmu->num_events) | 283 | if (idx == sh_pmu->num_events) |
255 | return -EAGAIN; | 284 | goto out; |
256 | 285 | ||
257 | set_bit(idx, cpuc->used_mask); | 286 | __set_bit(idx, cpuc->used_mask); |
258 | hwc->idx = idx; | 287 | hwc->idx = idx; |
259 | } | 288 | } |
260 | 289 | ||
261 | sh_pmu->disable(hwc, idx); | 290 | sh_pmu->disable(hwc, idx); |
262 | 291 | ||
263 | cpuc->events[idx] = event; | 292 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; |
264 | set_bit(idx, cpuc->active_mask); | 293 | if (flags & PERF_EF_START) |
265 | 294 | sh_pmu_start(event, PERF_EF_RELOAD); | |
266 | sh_pmu->enable(hwc, idx); | ||
267 | 295 | ||
268 | perf_event_update_userpage(event); | 296 | perf_event_update_userpage(event); |
269 | 297 | ret = 0; | |
270 | return 0; | 298 | out: |
299 | perf_pmu_enable(event->pmu); | ||
300 | return ret; | ||
271 | } | 301 | } |
272 | 302 | ||
273 | static void sh_pmu_read(struct perf_event *event) | 303 | static void sh_pmu_read(struct perf_event *event) |
@@ -275,24 +305,56 @@ static void sh_pmu_read(struct perf_event *event) | |||
275 | sh_perf_event_update(event, &event->hw, event->hw.idx); | 305 | sh_perf_event_update(event, &event->hw, event->hw.idx); |
276 | } | 306 | } |
277 | 307 | ||
278 | static const struct pmu pmu = { | 308 | static int sh_pmu_event_init(struct perf_event *event) |
279 | .enable = sh_pmu_enable, | ||
280 | .disable = sh_pmu_disable, | ||
281 | .read = sh_pmu_read, | ||
282 | }; | ||
283 | |||
284 | const struct pmu *hw_perf_event_init(struct perf_event *event) | ||
285 | { | 309 | { |
286 | int err = __hw_perf_event_init(event); | 310 | int err; |
311 | |||
312 | switch (event->attr.type) { | ||
313 | case PERF_TYPE_RAW: | ||
314 | case PERF_TYPE_HW_CACHE: | ||
315 | case PERF_TYPE_HARDWARE: | ||
316 | err = __hw_perf_event_init(event); | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | return -ENOENT; | ||
321 | } | ||
322 | |||
287 | if (unlikely(err)) { | 323 | if (unlikely(err)) { |
288 | if (event->destroy) | 324 | if (event->destroy) |
289 | event->destroy(event); | 325 | event->destroy(event); |
290 | return ERR_PTR(err); | ||
291 | } | 326 | } |
292 | 327 | ||
293 | return &pmu; | 328 | return err; |
329 | } | ||
330 | |||
331 | static void sh_pmu_enable(struct pmu *pmu) | ||
332 | { | ||
333 | if (!sh_pmu_initialized()) | ||
334 | return; | ||
335 | |||
336 | sh_pmu->enable_all(); | ||
337 | } | ||
338 | |||
339 | static void sh_pmu_disable(struct pmu *pmu) | ||
340 | { | ||
341 | if (!sh_pmu_initialized()) | ||
342 | return; | ||
343 | |||
344 | sh_pmu->disable_all(); | ||
294 | } | 345 | } |
295 | 346 | ||
347 | static struct pmu pmu = { | ||
348 | .pmu_enable = sh_pmu_enable, | ||
349 | .pmu_disable = sh_pmu_disable, | ||
350 | .event_init = sh_pmu_event_init, | ||
351 | .add = sh_pmu_add, | ||
352 | .del = sh_pmu_del, | ||
353 | .start = sh_pmu_start, | ||
354 | .stop = sh_pmu_stop, | ||
355 | .read = sh_pmu_read, | ||
356 | }; | ||
357 | |||
296 | static void sh_pmu_setup(int cpu) | 358 | static void sh_pmu_setup(int cpu) |
297 | { | 359 | { |
298 | struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); | 360 | struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); |
@@ -317,32 +379,17 @@ sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | |||
317 | return NOTIFY_OK; | 379 | return NOTIFY_OK; |
318 | } | 380 | } |
319 | 381 | ||
320 | void hw_perf_enable(void) | 382 | int __cpuinit register_sh_pmu(struct sh_pmu *_pmu) |
321 | { | ||
322 | if (!sh_pmu_initialized()) | ||
323 | return; | ||
324 | |||
325 | sh_pmu->enable_all(); | ||
326 | } | ||
327 | |||
328 | void hw_perf_disable(void) | ||
329 | { | ||
330 | if (!sh_pmu_initialized()) | ||
331 | return; | ||
332 | |||
333 | sh_pmu->disable_all(); | ||
334 | } | ||
335 | |||
336 | int __cpuinit register_sh_pmu(struct sh_pmu *pmu) | ||
337 | { | 383 | { |
338 | if (sh_pmu) | 384 | if (sh_pmu) |
339 | return -EBUSY; | 385 | return -EBUSY; |
340 | sh_pmu = pmu; | 386 | sh_pmu = _pmu; |
341 | 387 | ||
342 | pr_info("Performance Events: %s support registered\n", pmu->name); | 388 | pr_info("Performance Events: %s support registered\n", _pmu->name); |
343 | 389 | ||
344 | WARN_ON(pmu->num_events > MAX_HWEVENTS); | 390 | WARN_ON(_pmu->num_events > MAX_HWEVENTS); |
345 | 391 | ||
392 | perf_pmu_register(&pmu); | ||
346 | perf_cpu_notifier(sh_pmu_notifier); | 393 | perf_cpu_notifier(sh_pmu_notifier); |
347 | return 0; | 394 | return 0; |
348 | } | 395 | } |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 491e9d6de191..9212cd42a832 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -30,6 +30,7 @@ config SPARC | |||
30 | select PERF_USE_VMALLOC | 30 | select PERF_USE_VMALLOC |
31 | select HAVE_DMA_ATTRS | 31 | select HAVE_DMA_ATTRS |
32 | select HAVE_DMA_API_DEBUG | 32 | select HAVE_DMA_API_DEBUG |
33 | select HAVE_ARCH_JUMP_LABEL | ||
33 | 34 | ||
34 | config SPARC32 | 35 | config SPARC32 |
35 | def_bool !64BIT | 36 | def_bool !64BIT |
diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h new file mode 100644 index 000000000000..62e66d7b2fb6 --- /dev/null +++ b/arch/sparc/include/asm/jump_label.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _ASM_SPARC_JUMP_LABEL_H | ||
2 | #define _ASM_SPARC_JUMP_LABEL_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | |||
6 | #include <linux/types.h> | ||
7 | #include <asm/system.h> | ||
8 | |||
9 | #define JUMP_LABEL_NOP_SIZE 4 | ||
10 | |||
11 | #define JUMP_LABEL(key, label) \ | ||
12 | do { \ | ||
13 | asm goto("1:\n\t" \ | ||
14 | "nop\n\t" \ | ||
15 | "nop\n\t" \ | ||
16 | ".pushsection __jump_table, \"a\"\n\t"\ | ||
17 | ".word 1b, %l[" #label "], %c0\n\t" \ | ||
18 | ".popsection \n\t" \ | ||
19 | : : "i" (key) : : label);\ | ||
20 | } while (0) | ||
21 | |||
22 | #endif /* __KERNEL__ */ | ||
23 | |||
24 | typedef u32 jump_label_t; | ||
25 | |||
26 | struct jump_entry { | ||
27 | jump_label_t code; | ||
28 | jump_label_t target; | ||
29 | jump_label_t key; | ||
30 | }; | ||
31 | |||
32 | #endif | ||
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 0c2dc1f24a9a..599398fbbc7c 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -119,3 +119,5 @@ obj-$(CONFIG_COMPAT) += $(audit--y) | |||
119 | 119 | ||
120 | pc--$(CONFIG_PERF_EVENTS) := perf_event.o | 120 | pc--$(CONFIG_PERF_EVENTS) := perf_event.o |
121 | obj-$(CONFIG_SPARC64) += $(pc--y) | 121 | obj-$(CONFIG_SPARC64) += $(pc--y) |
122 | |||
123 | obj-$(CONFIG_SPARC64) += jump_label.o | ||
diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c new file mode 100644 index 000000000000..ea2dafc93d78 --- /dev/null +++ b/arch/sparc/kernel/jump_label.c | |||
@@ -0,0 +1,47 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/mutex.h> | ||
4 | #include <linux/cpu.h> | ||
5 | |||
6 | #include <linux/jump_label.h> | ||
7 | #include <linux/memory.h> | ||
8 | |||
9 | #ifdef HAVE_JUMP_LABEL | ||
10 | |||
11 | void arch_jump_label_transform(struct jump_entry *entry, | ||
12 | enum jump_label_type type) | ||
13 | { | ||
14 | u32 val; | ||
15 | u32 *insn = (u32 *) (unsigned long) entry->code; | ||
16 | |||
17 | if (type == JUMP_LABEL_ENABLE) { | ||
18 | s32 off = (s32)entry->target - (s32)entry->code; | ||
19 | |||
20 | #ifdef CONFIG_SPARC64 | ||
21 | /* ba,pt %xcc, . + (off << 2) */ | ||
22 | val = 0x10680000 | ((u32) off >> 2); | ||
23 | #else | ||
24 | /* ba . + (off << 2) */ | ||
25 | val = 0x10800000 | ((u32) off >> 2); | ||
26 | #endif | ||
27 | } else { | ||
28 | val = 0x01000000; | ||
29 | } | ||
30 | |||
31 | get_online_cpus(); | ||
32 | mutex_lock(&text_mutex); | ||
33 | *insn = val; | ||
34 | flushi(insn); | ||
35 | mutex_unlock(&text_mutex); | ||
36 | put_online_cpus(); | ||
37 | } | ||
38 | |||
39 | void arch_jump_label_text_poke_early(jump_label_t addr) | ||
40 | { | ||
41 | u32 *insn_p = (u32 *) (unsigned long) addr; | ||
42 | |||
43 | *insn_p = 0x01000000; | ||
44 | flushi(insn_p); | ||
45 | } | ||
46 | |||
47 | #endif | ||
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index f848aadf54dc..ee3c7dde8d9f 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
@@ -18,6 +18,9 @@ | |||
18 | #include <asm/spitfire.h> | 18 | #include <asm/spitfire.h> |
19 | 19 | ||
20 | #ifdef CONFIG_SPARC64 | 20 | #ifdef CONFIG_SPARC64 |
21 | |||
22 | #include <linux/jump_label.h> | ||
23 | |||
21 | static void *module_map(unsigned long size) | 24 | static void *module_map(unsigned long size) |
22 | { | 25 | { |
23 | struct vm_struct *area; | 26 | struct vm_struct *area; |
@@ -227,6 +230,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
227 | const Elf_Shdr *sechdrs, | 230 | const Elf_Shdr *sechdrs, |
228 | struct module *me) | 231 | struct module *me) |
229 | { | 232 | { |
233 | /* make jump label nops */ | ||
234 | jump_label_apply_nops(me); | ||
235 | |||
230 | /* Cheetah's I-cache is fully coherent. */ | 236 | /* Cheetah's I-cache is fully coherent. */ |
231 | if (tlb_type == spitfire) { | 237 | if (tlb_type == spitfire) { |
232 | unsigned long va; | 238 | unsigned long va; |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 6318e622cfb0..0d6deb55a2ae 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -658,13 +658,16 @@ static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr) | |||
658 | 658 | ||
659 | enc = perf_event_get_enc(cpuc->events[i]); | 659 | enc = perf_event_get_enc(cpuc->events[i]); |
660 | pcr &= ~mask_for_index(idx); | 660 | pcr &= ~mask_for_index(idx); |
661 | pcr |= event_encoding(enc, idx); | 661 | if (hwc->state & PERF_HES_STOPPED) |
662 | pcr |= nop_for_index(idx); | ||
663 | else | ||
664 | pcr |= event_encoding(enc, idx); | ||
662 | } | 665 | } |
663 | out: | 666 | out: |
664 | return pcr; | 667 | return pcr; |
665 | } | 668 | } |
666 | 669 | ||
667 | void hw_perf_enable(void) | 670 | static void sparc_pmu_enable(struct pmu *pmu) |
668 | { | 671 | { |
669 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 672 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
670 | u64 pcr; | 673 | u64 pcr; |
@@ -691,7 +694,7 @@ void hw_perf_enable(void) | |||
691 | pcr_ops->write(cpuc->pcr); | 694 | pcr_ops->write(cpuc->pcr); |
692 | } | 695 | } |
693 | 696 | ||
694 | void hw_perf_disable(void) | 697 | static void sparc_pmu_disable(struct pmu *pmu) |
695 | { | 698 | { |
696 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 699 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
697 | u64 val; | 700 | u64 val; |
@@ -710,19 +713,65 @@ void hw_perf_disable(void) | |||
710 | pcr_ops->write(cpuc->pcr); | 713 | pcr_ops->write(cpuc->pcr); |
711 | } | 714 | } |
712 | 715 | ||
713 | static void sparc_pmu_disable(struct perf_event *event) | 716 | static int active_event_index(struct cpu_hw_events *cpuc, |
717 | struct perf_event *event) | ||
718 | { | ||
719 | int i; | ||
720 | |||
721 | for (i = 0; i < cpuc->n_events; i++) { | ||
722 | if (cpuc->event[i] == event) | ||
723 | break; | ||
724 | } | ||
725 | BUG_ON(i == cpuc->n_events); | ||
726 | return cpuc->current_idx[i]; | ||
727 | } | ||
728 | |||
729 | static void sparc_pmu_start(struct perf_event *event, int flags) | ||
730 | { | ||
731 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
732 | int idx = active_event_index(cpuc, event); | ||
733 | |||
734 | if (flags & PERF_EF_RELOAD) { | ||
735 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
736 | sparc_perf_event_set_period(event, &event->hw, idx); | ||
737 | } | ||
738 | |||
739 | event->hw.state = 0; | ||
740 | |||
741 | sparc_pmu_enable_event(cpuc, &event->hw, idx); | ||
742 | } | ||
743 | |||
744 | static void sparc_pmu_stop(struct perf_event *event, int flags) | ||
745 | { | ||
746 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
747 | int idx = active_event_index(cpuc, event); | ||
748 | |||
749 | if (!(event->hw.state & PERF_HES_STOPPED)) { | ||
750 | sparc_pmu_disable_event(cpuc, &event->hw, idx); | ||
751 | event->hw.state |= PERF_HES_STOPPED; | ||
752 | } | ||
753 | |||
754 | if (!(event->hw.state & PERF_HES_UPTODATE) && (flags & PERF_EF_UPDATE)) { | ||
755 | sparc_perf_event_update(event, &event->hw, idx); | ||
756 | event->hw.state |= PERF_HES_UPTODATE; | ||
757 | } | ||
758 | } | ||
759 | |||
760 | static void sparc_pmu_del(struct perf_event *event, int _flags) | ||
714 | { | 761 | { |
715 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 762 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
716 | struct hw_perf_event *hwc = &event->hw; | ||
717 | unsigned long flags; | 763 | unsigned long flags; |
718 | int i; | 764 | int i; |
719 | 765 | ||
720 | local_irq_save(flags); | 766 | local_irq_save(flags); |
721 | perf_disable(); | 767 | perf_pmu_disable(event->pmu); |
722 | 768 | ||
723 | for (i = 0; i < cpuc->n_events; i++) { | 769 | for (i = 0; i < cpuc->n_events; i++) { |
724 | if (event == cpuc->event[i]) { | 770 | if (event == cpuc->event[i]) { |
725 | int idx = cpuc->current_idx[i]; | 771 | /* Absorb the final count and turn off the |
772 | * event. | ||
773 | */ | ||
774 | sparc_pmu_stop(event, PERF_EF_UPDATE); | ||
726 | 775 | ||
727 | /* Shift remaining entries down into | 776 | /* Shift remaining entries down into |
728 | * the existing slot. | 777 | * the existing slot. |
@@ -734,13 +783,6 @@ static void sparc_pmu_disable(struct perf_event *event) | |||
734 | cpuc->current_idx[i]; | 783 | cpuc->current_idx[i]; |
735 | } | 784 | } |
736 | 785 | ||
737 | /* Absorb the final count and turn off the | ||
738 | * event. | ||
739 | */ | ||
740 | sparc_pmu_disable_event(cpuc, hwc, idx); | ||
741 | barrier(); | ||
742 | sparc_perf_event_update(event, hwc, idx); | ||
743 | |||
744 | perf_event_update_userpage(event); | 786 | perf_event_update_userpage(event); |
745 | 787 | ||
746 | cpuc->n_events--; | 788 | cpuc->n_events--; |
@@ -748,23 +790,10 @@ static void sparc_pmu_disable(struct perf_event *event) | |||
748 | } | 790 | } |
749 | } | 791 | } |
750 | 792 | ||
751 | perf_enable(); | 793 | perf_pmu_enable(event->pmu); |
752 | local_irq_restore(flags); | 794 | local_irq_restore(flags); |
753 | } | 795 | } |
754 | 796 | ||
755 | static int active_event_index(struct cpu_hw_events *cpuc, | ||
756 | struct perf_event *event) | ||
757 | { | ||
758 | int i; | ||
759 | |||
760 | for (i = 0; i < cpuc->n_events; i++) { | ||
761 | if (cpuc->event[i] == event) | ||
762 | break; | ||
763 | } | ||
764 | BUG_ON(i == cpuc->n_events); | ||
765 | return cpuc->current_idx[i]; | ||
766 | } | ||
767 | |||
768 | static void sparc_pmu_read(struct perf_event *event) | 797 | static void sparc_pmu_read(struct perf_event *event) |
769 | { | 798 | { |
770 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 799 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
@@ -774,15 +803,6 @@ static void sparc_pmu_read(struct perf_event *event) | |||
774 | sparc_perf_event_update(event, hwc, idx); | 803 | sparc_perf_event_update(event, hwc, idx); |
775 | } | 804 | } |
776 | 805 | ||
777 | static void sparc_pmu_unthrottle(struct perf_event *event) | ||
778 | { | ||
779 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
780 | int idx = active_event_index(cpuc, event); | ||
781 | struct hw_perf_event *hwc = &event->hw; | ||
782 | |||
783 | sparc_pmu_enable_event(cpuc, hwc, idx); | ||
784 | } | ||
785 | |||
786 | static atomic_t active_events = ATOMIC_INIT(0); | 806 | static atomic_t active_events = ATOMIC_INIT(0); |
787 | static DEFINE_MUTEX(pmc_grab_mutex); | 807 | static DEFINE_MUTEX(pmc_grab_mutex); |
788 | 808 | ||
@@ -877,7 +897,7 @@ static int sparc_check_constraints(struct perf_event **evts, | |||
877 | if (!n_ev) | 897 | if (!n_ev) |
878 | return 0; | 898 | return 0; |
879 | 899 | ||
880 | if (n_ev > perf_max_events) | 900 | if (n_ev > MAX_HWEVENTS) |
881 | return -1; | 901 | return -1; |
882 | 902 | ||
883 | msk0 = perf_event_get_msk(events[0]); | 903 | msk0 = perf_event_get_msk(events[0]); |
@@ -984,23 +1004,27 @@ static int collect_events(struct perf_event *group, int max_count, | |||
984 | return n; | 1004 | return n; |
985 | } | 1005 | } |
986 | 1006 | ||
987 | static int sparc_pmu_enable(struct perf_event *event) | 1007 | static int sparc_pmu_add(struct perf_event *event, int ef_flags) |
988 | { | 1008 | { |
989 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1009 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
990 | int n0, ret = -EAGAIN; | 1010 | int n0, ret = -EAGAIN; |
991 | unsigned long flags; | 1011 | unsigned long flags; |
992 | 1012 | ||
993 | local_irq_save(flags); | 1013 | local_irq_save(flags); |
994 | perf_disable(); | 1014 | perf_pmu_disable(event->pmu); |
995 | 1015 | ||
996 | n0 = cpuc->n_events; | 1016 | n0 = cpuc->n_events; |
997 | if (n0 >= perf_max_events) | 1017 | if (n0 >= MAX_HWEVENTS) |
998 | goto out; | 1018 | goto out; |
999 | 1019 | ||
1000 | cpuc->event[n0] = event; | 1020 | cpuc->event[n0] = event; |
1001 | cpuc->events[n0] = event->hw.event_base; | 1021 | cpuc->events[n0] = event->hw.event_base; |
1002 | cpuc->current_idx[n0] = PIC_NO_INDEX; | 1022 | cpuc->current_idx[n0] = PIC_NO_INDEX; |
1003 | 1023 | ||
1024 | event->hw.state = PERF_HES_UPTODATE; | ||
1025 | if (!(ef_flags & PERF_EF_START)) | ||
1026 | event->hw.state |= PERF_HES_STOPPED; | ||
1027 | |||
1004 | /* | 1028 | /* |
1005 | * If group events scheduling transaction was started, | 1029 | * If group events scheduling transaction was started, |
1006 | * skip the schedulability test here, it will be peformed | 1030 | * skip the schedulability test here, it will be peformed |
@@ -1020,12 +1044,12 @@ nocheck: | |||
1020 | 1044 | ||
1021 | ret = 0; | 1045 | ret = 0; |
1022 | out: | 1046 | out: |
1023 | perf_enable(); | 1047 | perf_pmu_enable(event->pmu); |
1024 | local_irq_restore(flags); | 1048 | local_irq_restore(flags); |
1025 | return ret; | 1049 | return ret; |
1026 | } | 1050 | } |
1027 | 1051 | ||
1028 | static int __hw_perf_event_init(struct perf_event *event) | 1052 | static int sparc_pmu_event_init(struct perf_event *event) |
1029 | { | 1053 | { |
1030 | struct perf_event_attr *attr = &event->attr; | 1054 | struct perf_event_attr *attr = &event->attr; |
1031 | struct perf_event *evts[MAX_HWEVENTS]; | 1055 | struct perf_event *evts[MAX_HWEVENTS]; |
@@ -1038,22 +1062,33 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1038 | if (atomic_read(&nmi_active) < 0) | 1062 | if (atomic_read(&nmi_active) < 0) |
1039 | return -ENODEV; | 1063 | return -ENODEV; |
1040 | 1064 | ||
1041 | pmap = NULL; | 1065 | switch (attr->type) { |
1042 | if (attr->type == PERF_TYPE_HARDWARE) { | 1066 | case PERF_TYPE_HARDWARE: |
1043 | if (attr->config >= sparc_pmu->max_events) | 1067 | if (attr->config >= sparc_pmu->max_events) |
1044 | return -EINVAL; | 1068 | return -EINVAL; |
1045 | pmap = sparc_pmu->event_map(attr->config); | 1069 | pmap = sparc_pmu->event_map(attr->config); |
1046 | } else if (attr->type == PERF_TYPE_HW_CACHE) { | 1070 | break; |
1071 | |||
1072 | case PERF_TYPE_HW_CACHE: | ||
1047 | pmap = sparc_map_cache_event(attr->config); | 1073 | pmap = sparc_map_cache_event(attr->config); |
1048 | if (IS_ERR(pmap)) | 1074 | if (IS_ERR(pmap)) |
1049 | return PTR_ERR(pmap); | 1075 | return PTR_ERR(pmap); |
1050 | } else if (attr->type != PERF_TYPE_RAW) | 1076 | break; |
1051 | return -EOPNOTSUPP; | 1077 | |
1078 | case PERF_TYPE_RAW: | ||
1079 | pmap = NULL; | ||
1080 | break; | ||
1081 | |||
1082 | default: | ||
1083 | return -ENOENT; | ||
1084 | |||
1085 | } | ||
1052 | 1086 | ||
1053 | if (pmap) { | 1087 | if (pmap) { |
1054 | hwc->event_base = perf_event_encode(pmap); | 1088 | hwc->event_base = perf_event_encode(pmap); |
1055 | } else { | 1089 | } else { |
1056 | /* User gives us "(encoding << 16) | pic_mask" for | 1090 | /* |
1091 | * User gives us "(encoding << 16) | pic_mask" for | ||
1057 | * PERF_TYPE_RAW events. | 1092 | * PERF_TYPE_RAW events. |
1058 | */ | 1093 | */ |
1059 | hwc->event_base = attr->config; | 1094 | hwc->event_base = attr->config; |
@@ -1071,7 +1106,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1071 | n = 0; | 1106 | n = 0; |
1072 | if (event->group_leader != event) { | 1107 | if (event->group_leader != event) { |
1073 | n = collect_events(event->group_leader, | 1108 | n = collect_events(event->group_leader, |
1074 | perf_max_events - 1, | 1109 | MAX_HWEVENTS - 1, |
1075 | evts, events, current_idx_dmy); | 1110 | evts, events, current_idx_dmy); |
1076 | if (n < 0) | 1111 | if (n < 0) |
1077 | return -EINVAL; | 1112 | return -EINVAL; |
@@ -1107,10 +1142,11 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1107 | * Set the flag to make pmu::enable() not perform the | 1142 | * Set the flag to make pmu::enable() not perform the |
1108 | * schedulability test, it will be performed at commit time | 1143 | * schedulability test, it will be performed at commit time |
1109 | */ | 1144 | */ |
1110 | static void sparc_pmu_start_txn(const struct pmu *pmu) | 1145 | static void sparc_pmu_start_txn(struct pmu *pmu) |
1111 | { | 1146 | { |
1112 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | 1147 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); |
1113 | 1148 | ||
1149 | perf_pmu_disable(pmu); | ||
1114 | cpuhw->group_flag |= PERF_EVENT_TXN; | 1150 | cpuhw->group_flag |= PERF_EVENT_TXN; |
1115 | } | 1151 | } |
1116 | 1152 | ||
@@ -1119,11 +1155,12 @@ static void sparc_pmu_start_txn(const struct pmu *pmu) | |||
1119 | * Clear the flag and pmu::enable() will perform the | 1155 | * Clear the flag and pmu::enable() will perform the |
1120 | * schedulability test. | 1156 | * schedulability test. |
1121 | */ | 1157 | */ |
1122 | static void sparc_pmu_cancel_txn(const struct pmu *pmu) | 1158 | static void sparc_pmu_cancel_txn(struct pmu *pmu) |
1123 | { | 1159 | { |
1124 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); | 1160 | struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); |
1125 | 1161 | ||
1126 | cpuhw->group_flag &= ~PERF_EVENT_TXN; | 1162 | cpuhw->group_flag &= ~PERF_EVENT_TXN; |
1163 | perf_pmu_enable(pmu); | ||
1127 | } | 1164 | } |
1128 | 1165 | ||
1129 | /* | 1166 | /* |
@@ -1131,7 +1168,7 @@ static void sparc_pmu_cancel_txn(const struct pmu *pmu) | |||
1131 | * Perform the group schedulability test as a whole | 1168 | * Perform the group schedulability test as a whole |
1132 | * Return 0 if success | 1169 | * Return 0 if success |
1133 | */ | 1170 | */ |
1134 | static int sparc_pmu_commit_txn(const struct pmu *pmu) | 1171 | static int sparc_pmu_commit_txn(struct pmu *pmu) |
1135 | { | 1172 | { |
1136 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1173 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1137 | int n; | 1174 | int n; |
@@ -1147,28 +1184,24 @@ static int sparc_pmu_commit_txn(const struct pmu *pmu) | |||
1147 | return -EAGAIN; | 1184 | return -EAGAIN; |
1148 | 1185 | ||
1149 | cpuc->group_flag &= ~PERF_EVENT_TXN; | 1186 | cpuc->group_flag &= ~PERF_EVENT_TXN; |
1187 | perf_pmu_enable(pmu); | ||
1150 | return 0; | 1188 | return 0; |
1151 | } | 1189 | } |
1152 | 1190 | ||
1153 | static const struct pmu pmu = { | 1191 | static struct pmu pmu = { |
1154 | .enable = sparc_pmu_enable, | 1192 | .pmu_enable = sparc_pmu_enable, |
1155 | .disable = sparc_pmu_disable, | 1193 | .pmu_disable = sparc_pmu_disable, |
1194 | .event_init = sparc_pmu_event_init, | ||
1195 | .add = sparc_pmu_add, | ||
1196 | .del = sparc_pmu_del, | ||
1197 | .start = sparc_pmu_start, | ||
1198 | .stop = sparc_pmu_stop, | ||
1156 | .read = sparc_pmu_read, | 1199 | .read = sparc_pmu_read, |
1157 | .unthrottle = sparc_pmu_unthrottle, | ||
1158 | .start_txn = sparc_pmu_start_txn, | 1200 | .start_txn = sparc_pmu_start_txn, |
1159 | .cancel_txn = sparc_pmu_cancel_txn, | 1201 | .cancel_txn = sparc_pmu_cancel_txn, |
1160 | .commit_txn = sparc_pmu_commit_txn, | 1202 | .commit_txn = sparc_pmu_commit_txn, |
1161 | }; | 1203 | }; |
1162 | 1204 | ||
1163 | const struct pmu *hw_perf_event_init(struct perf_event *event) | ||
1164 | { | ||
1165 | int err = __hw_perf_event_init(event); | ||
1166 | |||
1167 | if (err) | ||
1168 | return ERR_PTR(err); | ||
1169 | return &pmu; | ||
1170 | } | ||
1171 | |||
1172 | void perf_event_print_debug(void) | 1205 | void perf_event_print_debug(void) |
1173 | { | 1206 | { |
1174 | unsigned long flags; | 1207 | unsigned long flags; |
@@ -1244,7 +1277,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, | |||
1244 | continue; | 1277 | continue; |
1245 | 1278 | ||
1246 | if (perf_event_overflow(event, 1, &data, regs)) | 1279 | if (perf_event_overflow(event, 1, &data, regs)) |
1247 | sparc_pmu_disable_event(cpuc, hwc, idx); | 1280 | sparc_pmu_stop(event, 0); |
1248 | } | 1281 | } |
1249 | 1282 | ||
1250 | return NOTIFY_STOP; | 1283 | return NOTIFY_STOP; |
@@ -1285,28 +1318,21 @@ void __init init_hw_perf_events(void) | |||
1285 | 1318 | ||
1286 | pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type); | 1319 | pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type); |
1287 | 1320 | ||
1288 | /* All sparc64 PMUs currently have 2 events. */ | 1321 | perf_pmu_register(&pmu); |
1289 | perf_max_events = 2; | ||
1290 | |||
1291 | register_die_notifier(&perf_event_nmi_notifier); | 1322 | register_die_notifier(&perf_event_nmi_notifier); |
1292 | } | 1323 | } |
1293 | 1324 | ||
1294 | static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) | 1325 | void perf_callchain_kernel(struct perf_callchain_entry *entry, |
1295 | { | 1326 | struct pt_regs *regs) |
1296 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
1297 | entry->ip[entry->nr++] = ip; | ||
1298 | } | ||
1299 | |||
1300 | static void perf_callchain_kernel(struct pt_regs *regs, | ||
1301 | struct perf_callchain_entry *entry) | ||
1302 | { | 1327 | { |
1303 | unsigned long ksp, fp; | 1328 | unsigned long ksp, fp; |
1304 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1329 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1305 | int graph = 0; | 1330 | int graph = 0; |
1306 | #endif | 1331 | #endif |
1307 | 1332 | ||
1308 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 1333 | stack_trace_flush(); |
1309 | callchain_store(entry, regs->tpc); | 1334 | |
1335 | perf_callchain_store(entry, regs->tpc); | ||
1310 | 1336 | ||
1311 | ksp = regs->u_regs[UREG_I6]; | 1337 | ksp = regs->u_regs[UREG_I6]; |
1312 | fp = ksp + STACK_BIAS; | 1338 | fp = ksp + STACK_BIAS; |
@@ -1330,13 +1356,13 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
1330 | pc = sf->callers_pc; | 1356 | pc = sf->callers_pc; |
1331 | fp = (unsigned long)sf->fp + STACK_BIAS; | 1357 | fp = (unsigned long)sf->fp + STACK_BIAS; |
1332 | } | 1358 | } |
1333 | callchain_store(entry, pc); | 1359 | perf_callchain_store(entry, pc); |
1334 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 1360 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1335 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | 1361 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { |
1336 | int index = current->curr_ret_stack; | 1362 | int index = current->curr_ret_stack; |
1337 | if (current->ret_stack && index >= graph) { | 1363 | if (current->ret_stack && index >= graph) { |
1338 | pc = current->ret_stack[index - graph].ret; | 1364 | pc = current->ret_stack[index - graph].ret; |
1339 | callchain_store(entry, pc); | 1365 | perf_callchain_store(entry, pc); |
1340 | graph++; | 1366 | graph++; |
1341 | } | 1367 | } |
1342 | } | 1368 | } |
@@ -1344,13 +1370,12 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
1344 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1370 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
1345 | } | 1371 | } |
1346 | 1372 | ||
1347 | static void perf_callchain_user_64(struct pt_regs *regs, | 1373 | static void perf_callchain_user_64(struct perf_callchain_entry *entry, |
1348 | struct perf_callchain_entry *entry) | 1374 | struct pt_regs *regs) |
1349 | { | 1375 | { |
1350 | unsigned long ufp; | 1376 | unsigned long ufp; |
1351 | 1377 | ||
1352 | callchain_store(entry, PERF_CONTEXT_USER); | 1378 | perf_callchain_store(entry, regs->tpc); |
1353 | callchain_store(entry, regs->tpc); | ||
1354 | 1379 | ||
1355 | ufp = regs->u_regs[UREG_I6] + STACK_BIAS; | 1380 | ufp = regs->u_regs[UREG_I6] + STACK_BIAS; |
1356 | do { | 1381 | do { |
@@ -1363,17 +1388,16 @@ static void perf_callchain_user_64(struct pt_regs *regs, | |||
1363 | 1388 | ||
1364 | pc = sf.callers_pc; | 1389 | pc = sf.callers_pc; |
1365 | ufp = (unsigned long)sf.fp + STACK_BIAS; | 1390 | ufp = (unsigned long)sf.fp + STACK_BIAS; |
1366 | callchain_store(entry, pc); | 1391 | perf_callchain_store(entry, pc); |
1367 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1392 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
1368 | } | 1393 | } |
1369 | 1394 | ||
1370 | static void perf_callchain_user_32(struct pt_regs *regs, | 1395 | static void perf_callchain_user_32(struct perf_callchain_entry *entry, |
1371 | struct perf_callchain_entry *entry) | 1396 | struct pt_regs *regs) |
1372 | { | 1397 | { |
1373 | unsigned long ufp; | 1398 | unsigned long ufp; |
1374 | 1399 | ||
1375 | callchain_store(entry, PERF_CONTEXT_USER); | 1400 | perf_callchain_store(entry, regs->tpc); |
1376 | callchain_store(entry, regs->tpc); | ||
1377 | 1401 | ||
1378 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; | 1402 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
1379 | do { | 1403 | do { |
@@ -1386,34 +1410,16 @@ static void perf_callchain_user_32(struct pt_regs *regs, | |||
1386 | 1410 | ||
1387 | pc = sf.callers_pc; | 1411 | pc = sf.callers_pc; |
1388 | ufp = (unsigned long)sf.fp; | 1412 | ufp = (unsigned long)sf.fp; |
1389 | callchain_store(entry, pc); | 1413 | perf_callchain_store(entry, pc); |
1390 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1414 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
1391 | } | 1415 | } |
1392 | 1416 | ||
1393 | /* Like powerpc we can't get PMU interrupts within the PMU handler, | 1417 | void |
1394 | * so no need for separate NMI and IRQ chains as on x86. | 1418 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) |
1395 | */ | ||
1396 | static DEFINE_PER_CPU(struct perf_callchain_entry, callchain); | ||
1397 | |||
1398 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
1399 | { | 1419 | { |
1400 | struct perf_callchain_entry *entry = &__get_cpu_var(callchain); | 1420 | flushw_user(); |
1401 | 1421 | if (test_thread_flag(TIF_32BIT)) | |
1402 | entry->nr = 0; | 1422 | perf_callchain_user_32(entry, regs); |
1403 | if (!user_mode(regs)) { | 1423 | else |
1404 | stack_trace_flush(); | 1424 | perf_callchain_user_64(entry, regs); |
1405 | perf_callchain_kernel(regs, entry); | ||
1406 | if (current->mm) | ||
1407 | regs = task_pt_regs(current); | ||
1408 | else | ||
1409 | regs = NULL; | ||
1410 | } | ||
1411 | if (regs) { | ||
1412 | flushw_user(); | ||
1413 | if (test_thread_flag(TIF_32BIT)) | ||
1414 | perf_callchain_user_32(regs, entry); | ||
1415 | else | ||
1416 | perf_callchain_user_64(regs, entry); | ||
1417 | } | ||
1418 | return entry; | ||
1419 | } | 1425 | } |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 84f296ca9e63..8f58bdff20d7 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -1506,13 +1506,6 @@ handle_ill: | |||
1506 | } | 1506 | } |
1507 | STD_ENDPROC(handle_ill) | 1507 | STD_ENDPROC(handle_ill) |
1508 | 1508 | ||
1509 | .pushsection .rodata, "a" | ||
1510 | .align 8 | ||
1511 | bpt_code: | ||
1512 | bpt | ||
1513 | ENDPROC(bpt_code) | ||
1514 | .popsection | ||
1515 | |||
1516 | /* Various stub interrupt handlers and syscall handlers */ | 1509 | /* Various stub interrupt handlers and syscall handlers */ |
1517 | 1510 | ||
1518 | STD_ENTRY_LOCAL(_kernel_double_fault) | 1511 | STD_ENTRY_LOCAL(_kernel_double_fault) |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 2ab233ba32c1..47d0c37897d5 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -255,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev) | |||
255 | netif_wake_queue(dev); | 255 | netif_wake_queue(dev); |
256 | } | 256 | } |
257 | 257 | ||
258 | static int uml_net_set_mac(struct net_device *dev, void *addr) | ||
259 | { | ||
260 | struct uml_net_private *lp = netdev_priv(dev); | ||
261 | struct sockaddr *hwaddr = addr; | ||
262 | |||
263 | spin_lock_irq(&lp->lock); | ||
264 | eth_mac_addr(dev, hwaddr->sa_data); | ||
265 | spin_unlock_irq(&lp->lock); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) | 258 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) |
271 | { | 259 | { |
272 | dev->mtu = new_mtu; | 260 | dev->mtu = new_mtu; |
@@ -373,7 +361,7 @@ static const struct net_device_ops uml_netdev_ops = { | |||
373 | .ndo_start_xmit = uml_net_start_xmit, | 361 | .ndo_start_xmit = uml_net_start_xmit, |
374 | .ndo_set_multicast_list = uml_net_set_multicast_list, | 362 | .ndo_set_multicast_list = uml_net_set_multicast_list, |
375 | .ndo_tx_timeout = uml_net_tx_timeout, | 363 | .ndo_tx_timeout = uml_net_tx_timeout, |
376 | .ndo_set_mac_address = uml_net_set_mac, | 364 | .ndo_set_mac_address = eth_mac_addr, |
377 | .ndo_change_mtu = uml_net_change_mtu, | 365 | .ndo_change_mtu = uml_net_change_mtu, |
378 | .ndo_validate_addr = eth_validate_addr, | 366 | .ndo_validate_addr = eth_validate_addr, |
379 | }; | 367 | }; |
@@ -472,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac, | |||
472 | ((*transport->user->init)(&lp->user, dev) != 0)) | 460 | ((*transport->user->init)(&lp->user, dev) != 0)) |
473 | goto out_unregister; | 461 | goto out_unregister; |
474 | 462 | ||
475 | eth_mac_addr(dev, device->mac); | 463 | /* don't use eth_mac_addr, it will not work here */ |
464 | memcpy(dev->dev_addr, device->mac, ETH_ALEN); | ||
476 | dev->mtu = transport->user->mtu; | 465 | dev->mtu = transport->user->mtu; |
477 | dev->netdev_ops = ¨_netdev_ops; | 466 | dev->netdev_ops = ¨_netdev_ops; |
478 | dev->ethtool_ops = ¨_net_ethtool_ops; | 467 | dev->ethtool_ops = ¨_net_ethtool_ops; |
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index cd145eda3579..49b5e1eb3262 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -62,7 +62,7 @@ static long execve1(const char *file, | |||
62 | return error; | 62 | return error; |
63 | } | 63 | } |
64 | 64 | ||
65 | long um_execve(const char *file, char __user *__user *argv, char __user *__user *env) | 65 | long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) |
66 | { | 66 | { |
67 | long err; | 67 | long err; |
68 | 68 | ||
@@ -72,8 +72,8 @@ long um_execve(const char *file, char __user *__user *argv, char __user *__user | |||
72 | return err; | 72 | return err; |
73 | } | 73 | } |
74 | 74 | ||
75 | long sys_execve(const char __user *file, char __user *__user *argv, | 75 | long sys_execve(const char __user *file, const char __user *const __user *argv, |
76 | char __user *__user *env) | 76 | const char __user *const __user *env) |
77 | { | 77 | { |
78 | long error; | 78 | long error; |
79 | char *filename; | 79 | char *filename; |
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h index 1303a105fe91..5bf97db24a04 100644 --- a/arch/um/kernel/internal.h +++ b/arch/um/kernel/internal.h | |||
@@ -1 +1 @@ | |||
extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env); | extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env); | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 5ddb246626db..f958cb876ee3 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -60,8 +60,8 @@ int kernel_execve(const char *filename, | |||
60 | 60 | ||
61 | fs = get_fs(); | 61 | fs = get_fs(); |
62 | set_fs(KERNEL_DS); | 62 | set_fs(KERNEL_DS); |
63 | ret = um_execve(filename, (char __user *__user *)argv, | 63 | ret = um_execve(filename, (const char __user *const __user *)argv, |
64 | (char __user *__user *) envp); | 64 | (const char __user *const __user *) envp); |
65 | set_fs(fs); | 65 | set_fs(fs); |
66 | 66 | ||
67 | return ret; | 67 | return ret; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cea0cd9a316f..9815221976a7 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -33,6 +33,7 @@ config X86 | |||
33 | select HAVE_KRETPROBES | 33 | select HAVE_KRETPROBES |
34 | select HAVE_OPTPROBES | 34 | select HAVE_OPTPROBES |
35 | select HAVE_FTRACE_MCOUNT_RECORD | 35 | select HAVE_FTRACE_MCOUNT_RECORD |
36 | select HAVE_C_RECORDMCOUNT | ||
36 | select HAVE_DYNAMIC_FTRACE | 37 | select HAVE_DYNAMIC_FTRACE |
37 | select HAVE_FUNCTION_TRACER | 38 | select HAVE_FUNCTION_TRACER |
38 | select HAVE_FUNCTION_GRAPH_TRACER | 39 | select HAVE_FUNCTION_GRAPH_TRACER |
@@ -59,6 +60,8 @@ config X86 | |||
59 | select ANON_INODES | 60 | select ANON_INODES |
60 | select HAVE_ARCH_KMEMCHECK | 61 | select HAVE_ARCH_KMEMCHECK |
61 | select HAVE_USER_RETURN_NOTIFIER | 62 | select HAVE_USER_RETURN_NOTIFIER |
63 | select HAVE_ARCH_JUMP_LABEL | ||
64 | select HAVE_TEXT_POKE_SMP | ||
62 | 65 | ||
63 | config INSTRUCTION_DECODER | 66 | config INSTRUCTION_DECODER |
64 | def_bool (KPROBES || PERF_EVENTS) | 67 | def_bool (KPROBES || PERF_EVENTS) |
@@ -2125,6 +2128,10 @@ config HAVE_ATOMIC_IOMAP | |||
2125 | def_bool y | 2128 | def_bool y |
2126 | depends on X86_32 | 2129 | depends on X86_32 |
2127 | 2130 | ||
2131 | config HAVE_TEXT_POKE_SMP | ||
2132 | bool | ||
2133 | select STOP_MACHINE if SMP | ||
2134 | |||
2128 | source "net/Kconfig" | 2135 | source "net/Kconfig" |
2129 | 2136 | ||
2130 | source "drivers/Kconfig" | 2137 | source "drivers/Kconfig" |
diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c index 030f4b93e255..5df2869c874b 100644 --- a/arch/x86/boot/early_serial_console.c +++ b/arch/x86/boot/early_serial_console.c | |||
@@ -58,7 +58,19 @@ static void parse_earlyprintk(void) | |||
58 | if (arg[pos] == ',') | 58 | if (arg[pos] == ',') |
59 | pos++; | 59 | pos++; |
60 | 60 | ||
61 | if (!strncmp(arg, "ttyS", 4)) { | 61 | /* |
62 | * make sure we have | ||
63 | * "serial,0x3f8,115200" | ||
64 | * "serial,ttyS0,115200" | ||
65 | * "ttyS0,115200" | ||
66 | */ | ||
67 | if (pos == 7 && !strncmp(arg + pos, "0x", 2)) { | ||
68 | port = simple_strtoull(arg + pos, &e, 16); | ||
69 | if (port == 0 || arg + pos == e) | ||
70 | port = DEFAULT_SERIAL_PORT; | ||
71 | else | ||
72 | pos = e - arg; | ||
73 | } else if (!strncmp(arg + pos, "ttyS", 4)) { | ||
62 | static const int bases[] = { 0x3f8, 0x2f8 }; | 74 | static const int bases[] = { 0x3f8, 0x2f8 }; |
63 | int idx = 0; | 75 | int idx = 0; |
64 | 76 | ||
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index bc6abb7bc7ee..76561d20ea2f 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/stringify.h> | 6 | #include <linux/stringify.h> |
7 | #include <linux/jump_label.h> | ||
7 | #include <asm/asm.h> | 8 | #include <asm/asm.h> |
8 | 9 | ||
9 | /* | 10 | /* |
@@ -160,6 +161,8 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, | |||
160 | #define __parainstructions_end NULL | 161 | #define __parainstructions_end NULL |
161 | #endif | 162 | #endif |
162 | 163 | ||
164 | extern void *text_poke_early(void *addr, const void *opcode, size_t len); | ||
165 | |||
163 | /* | 166 | /* |
164 | * Clear and restore the kernel write-protection flag on the local CPU. | 167 | * Clear and restore the kernel write-protection flag on the local CPU. |
165 | * Allows the kernel to edit read-only pages. | 168 | * Allows the kernel to edit read-only pages. |
@@ -180,4 +183,12 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, | |||
180 | extern void *text_poke(void *addr, const void *opcode, size_t len); | 183 | extern void *text_poke(void *addr, const void *opcode, size_t len); |
181 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); | 184 | extern void *text_poke_smp(void *addr, const void *opcode, size_t len); |
182 | 185 | ||
186 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) | ||
187 | #define IDEAL_NOP_SIZE_5 5 | ||
188 | extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; | ||
189 | extern void arch_init_ideal_nop5(void); | ||
190 | #else | ||
191 | static inline void arch_init_ideal_nop5(void) {} | ||
192 | #endif | ||
193 | |||
183 | #endif /* _ASM_X86_ALTERNATIVE_H */ | 194 | #endif /* _ASM_X86_ALTERNATIVE_H */ |
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index d2544f1d705d..cb030374b90a 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
@@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(void) { } | |||
38 | 38 | ||
39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ | 39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ |
40 | 40 | ||
41 | static inline bool is_rd890_iommu(struct pci_dev *pdev) | ||
42 | { | ||
43 | return (pdev->vendor == PCI_VENDOR_ID_ATI) && | ||
44 | (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); | ||
45 | } | ||
46 | |||
41 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ | 47 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 7014e88bc779..08616180deaf 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -368,6 +368,9 @@ struct amd_iommu { | |||
368 | /* capabilities of that IOMMU read from ACPI */ | 368 | /* capabilities of that IOMMU read from ACPI */ |
369 | u32 cap; | 369 | u32 cap; |
370 | 370 | ||
371 | /* flags read from acpi table */ | ||
372 | u8 acpi_flags; | ||
373 | |||
371 | /* | 374 | /* |
372 | * Capability pointer. There could be more than one IOMMU per PCI | 375 | * Capability pointer. There could be more than one IOMMU per PCI |
373 | * device function if there are more than one AMD IOMMU capability | 376 | * device function if there are more than one AMD IOMMU capability |
@@ -411,6 +414,15 @@ struct amd_iommu { | |||
411 | 414 | ||
412 | /* default dma_ops domain for that IOMMU */ | 415 | /* default dma_ops domain for that IOMMU */ |
413 | struct dma_ops_domain *default_dom; | 416 | struct dma_ops_domain *default_dom; |
417 | |||
418 | /* | ||
419 | * This array is required to work around a potential BIOS bug. | ||
420 | * The BIOS may miss to restore parts of the PCI configuration | ||
421 | * space when the system resumes from S3. The result is that the | ||
422 | * IOMMU does not execute commands anymore which leads to system | ||
423 | * failure. | ||
424 | */ | ||
425 | u32 cache_cfg[4]; | ||
414 | }; | 426 | }; |
415 | 427 | ||
416 | /* | 428 | /* |
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 545776efeb16..bafd80defa43 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -309,7 +309,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) |
310 | { | 310 | { |
311 | return ((1UL << (nr % BITS_PER_LONG)) & | 311 | return ((1UL << (nr % BITS_PER_LONG)) & |
312 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; | 312 | (addr[nr / BITS_PER_LONG])) != 0; |
313 | } | 313 | } |
314 | 314 | ||
315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) | 315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index c6fbb7b430d1..3f76523589af 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -168,6 +168,7 @@ | |||
168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ | 168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ |
169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ | 169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ |
170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ | 170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ |
171 | #define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ | ||
171 | 172 | ||
172 | /* Virtualization flags: Linux defined, word 8 */ | 173 | /* Virtualization flags: Linux defined, word 8 */ |
173 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ | 174 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ |
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h new file mode 100644 index 000000000000..f52d42e80585 --- /dev/null +++ b/arch/x86/include/asm/jump_label.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef _ASM_X86_JUMP_LABEL_H | ||
2 | #define _ASM_X86_JUMP_LABEL_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | |||
6 | #include <linux/types.h> | ||
7 | #include <asm/nops.h> | ||
8 | |||
9 | #define JUMP_LABEL_NOP_SIZE 5 | ||
10 | |||
11 | # define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" | ||
12 | |||
13 | # define JUMP_LABEL(key, label) \ | ||
14 | do { \ | ||
15 | asm goto("1:" \ | ||
16 | JUMP_LABEL_INITIAL_NOP \ | ||
17 | ".pushsection __jump_table, \"a\" \n\t"\ | ||
18 | _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \ | ||
19 | ".popsection \n\t" \ | ||
20 | : : "i" (key) : : label); \ | ||
21 | } while (0) | ||
22 | |||
23 | #endif /* __KERNEL__ */ | ||
24 | |||
25 | #ifdef CONFIG_X86_64 | ||
26 | typedef u64 jump_label_t; | ||
27 | #else | ||
28 | typedef u32 jump_label_t; | ||
29 | #endif | ||
30 | |||
31 | struct jump_entry { | ||
32 | jump_label_t code; | ||
33 | jump_label_t target; | ||
34 | jump_label_t key; | ||
35 | }; | ||
36 | |||
37 | #endif | ||
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index def500776b16..a70cd216be5d 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h | |||
@@ -36,19 +36,6 @@ | |||
36 | #define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT) | 36 | #define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT) |
37 | #define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT) | 37 | #define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT) |
38 | 38 | ||
39 | /* Non HT mask */ | ||
40 | #define P4_ESCR_MASK \ | ||
41 | (P4_ESCR_EVENT_MASK | \ | ||
42 | P4_ESCR_EVENTMASK_MASK | \ | ||
43 | P4_ESCR_TAG_MASK | \ | ||
44 | P4_ESCR_TAG_ENABLE | \ | ||
45 | P4_ESCR_T0_OS | \ | ||
46 | P4_ESCR_T0_USR) | ||
47 | |||
48 | /* HT mask */ | ||
49 | #define P4_ESCR_MASK_HT \ | ||
50 | (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR) | ||
51 | |||
52 | #define P4_CCCR_OVF 0x80000000U | 39 | #define P4_CCCR_OVF 0x80000000U |
53 | #define P4_CCCR_CASCADE 0x40000000U | 40 | #define P4_CCCR_CASCADE 0x40000000U |
54 | #define P4_CCCR_OVF_PMI_T0 0x04000000U | 41 | #define P4_CCCR_OVF_PMI_T0 0x04000000U |
@@ -70,23 +57,6 @@ | |||
70 | #define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) | 57 | #define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) |
71 | #define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) | 58 | #define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) |
72 | 59 | ||
73 | /* Non HT mask */ | ||
74 | #define P4_CCCR_MASK \ | ||
75 | (P4_CCCR_OVF | \ | ||
76 | P4_CCCR_CASCADE | \ | ||
77 | P4_CCCR_OVF_PMI_T0 | \ | ||
78 | P4_CCCR_FORCE_OVF | \ | ||
79 | P4_CCCR_EDGE | \ | ||
80 | P4_CCCR_THRESHOLD_MASK | \ | ||
81 | P4_CCCR_COMPLEMENT | \ | ||
82 | P4_CCCR_COMPARE | \ | ||
83 | P4_CCCR_ESCR_SELECT_MASK | \ | ||
84 | P4_CCCR_ENABLE) | ||
85 | |||
86 | /* HT mask */ | ||
87 | #define P4_CCCR_MASK_HT \ | ||
88 | (P4_CCCR_MASK | P4_CCCR_OVF_PMI_T1 | P4_CCCR_THREAD_ANY) | ||
89 | |||
90 | #define P4_GEN_ESCR_EMASK(class, name, bit) \ | 60 | #define P4_GEN_ESCR_EMASK(class, name, bit) \ |
91 | class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT) | 61 | class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT) |
92 | #define P4_ESCR_EMASK_BIT(class, name) class##__##name | 62 | #define P4_ESCR_EMASK_BIT(class, name) class##__##name |
@@ -127,6 +97,28 @@ | |||
127 | #define P4_CONFIG_HT_SHIFT 63 | 97 | #define P4_CONFIG_HT_SHIFT 63 |
128 | #define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) | 98 | #define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT) |
129 | 99 | ||
100 | /* | ||
101 | * The bits we allow to pass for RAW events | ||
102 | */ | ||
103 | #define P4_CONFIG_MASK_ESCR \ | ||
104 | P4_ESCR_EVENT_MASK | \ | ||
105 | P4_ESCR_EVENTMASK_MASK | \ | ||
106 | P4_ESCR_TAG_MASK | \ | ||
107 | P4_ESCR_TAG_ENABLE | ||
108 | |||
109 | #define P4_CONFIG_MASK_CCCR \ | ||
110 | P4_CCCR_EDGE | \ | ||
111 | P4_CCCR_THRESHOLD_MASK | \ | ||
112 | P4_CCCR_COMPLEMENT | \ | ||
113 | P4_CCCR_COMPARE | \ | ||
114 | P4_CCCR_THREAD_ANY | \ | ||
115 | P4_CCCR_RESERVED | ||
116 | |||
117 | /* some dangerous bits are reserved for kernel internals */ | ||
118 | #define P4_CONFIG_MASK \ | ||
119 | (p4_config_pack_escr(P4_CONFIG_MASK_ESCR)) | \ | ||
120 | (p4_config_pack_cccr(P4_CONFIG_MASK_CCCR)) | ||
121 | |||
130 | static inline bool p4_is_event_cascaded(u64 config) | 122 | static inline bool p4_is_event_cascaded(u64 config) |
131 | { | 123 | { |
132 | u32 cccr = p4_config_unpack_cccr(config); | 124 | u32 cccr = p4_config_unpack_cccr(config); |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index fedf32a8c3ec..9d3f485e5dd0 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -34,7 +34,7 @@ GCOV_PROFILE_paravirt.o := n | |||
34 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o | 34 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o |
35 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o | 35 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o |
36 | obj-y += time.o ioport.o ldt.o dumpstack.o | 36 | obj-y += time.o ioport.o ldt.o dumpstack.o |
37 | obj-y += setup.o x86_init.o i8259.o irqinit.o | 37 | obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o |
38 | obj-$(CONFIG_X86_VISWS) += visws_quirks.o | 38 | obj-$(CONFIG_X86_VISWS) += visws_quirks.o |
39 | obj-$(CONFIG_X86_32) += probe_roms_32.o | 39 | obj-$(CONFIG_X86_32) += probe_roms_32.o |
40 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o | 40 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o |
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index fb7a5f052e2b..fb16f17e59be 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c | |||
@@ -61,7 +61,7 @@ struct cstate_entry { | |||
61 | unsigned int ecx; | 61 | unsigned int ecx; |
62 | } states[ACPI_PROCESSOR_MAX_POWER]; | 62 | } states[ACPI_PROCESSOR_MAX_POWER]; |
63 | }; | 63 | }; |
64 | static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ | 64 | static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */ |
65 | 65 | ||
66 | static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; | 66 | static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; |
67 | 67 | ||
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index f65ab8b014c4..a36bb90aef53 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -195,7 +195,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len) | |||
195 | 195 | ||
196 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | 196 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; |
197 | extern s32 __smp_locks[], __smp_locks_end[]; | 197 | extern s32 __smp_locks[], __smp_locks_end[]; |
198 | static void *text_poke_early(void *addr, const void *opcode, size_t len); | 198 | void *text_poke_early(void *addr, const void *opcode, size_t len); |
199 | 199 | ||
200 | /* Replace instructions with better alternatives for this CPU type. | 200 | /* Replace instructions with better alternatives for this CPU type. |
201 | This runs before SMP is initialized to avoid SMP problems with | 201 | This runs before SMP is initialized to avoid SMP problems with |
@@ -522,7 +522,7 @@ void __init alternative_instructions(void) | |||
522 | * instructions. And on the local CPU you need to be protected again NMI or MCE | 522 | * instructions. And on the local CPU you need to be protected again NMI or MCE |
523 | * handlers seeing an inconsistent instruction while you patch. | 523 | * handlers seeing an inconsistent instruction while you patch. |
524 | */ | 524 | */ |
525 | static void *__init_or_module text_poke_early(void *addr, const void *opcode, | 525 | void *__init_or_module text_poke_early(void *addr, const void *opcode, |
526 | size_t len) | 526 | size_t len) |
527 | { | 527 | { |
528 | unsigned long flags; | 528 | unsigned long flags; |
@@ -637,7 +637,72 @@ void *__kprobes text_poke_smp(void *addr, const void *opcode, size_t len) | |||
637 | tpp.len = len; | 637 | tpp.len = len; |
638 | atomic_set(&stop_machine_first, 1); | 638 | atomic_set(&stop_machine_first, 1); |
639 | wrote_text = 0; | 639 | wrote_text = 0; |
640 | stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); | 640 | /* Use __stop_machine() because the caller already got online_cpus. */ |
641 | __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); | ||
641 | return addr; | 642 | return addr; |
642 | } | 643 | } |
643 | 644 | ||
645 | #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) | ||
646 | |||
647 | unsigned char ideal_nop5[IDEAL_NOP_SIZE_5]; | ||
648 | |||
649 | void __init arch_init_ideal_nop5(void) | ||
650 | { | ||
651 | extern const unsigned char ftrace_test_p6nop[]; | ||
652 | extern const unsigned char ftrace_test_nop5[]; | ||
653 | extern const unsigned char ftrace_test_jmp[]; | ||
654 | int faulted = 0; | ||
655 | |||
656 | /* | ||
657 | * There is no good nop for all x86 archs. | ||
658 | * We will default to using the P6_NOP5, but first we | ||
659 | * will test to make sure that the nop will actually | ||
660 | * work on this CPU. If it faults, we will then | ||
661 | * go to a lesser efficient 5 byte nop. If that fails | ||
662 | * we then just use a jmp as our nop. This isn't the most | ||
663 | * efficient nop, but we can not use a multi part nop | ||
664 | * since we would then risk being preempted in the middle | ||
665 | * of that nop, and if we enabled tracing then, it might | ||
666 | * cause a system crash. | ||
667 | * | ||
668 | * TODO: check the cpuid to determine the best nop. | ||
669 | */ | ||
670 | asm volatile ( | ||
671 | "ftrace_test_jmp:" | ||
672 | "jmp ftrace_test_p6nop\n" | ||
673 | "nop\n" | ||
674 | "nop\n" | ||
675 | "nop\n" /* 2 byte jmp + 3 bytes */ | ||
676 | "ftrace_test_p6nop:" | ||
677 | P6_NOP5 | ||
678 | "jmp 1f\n" | ||
679 | "ftrace_test_nop5:" | ||
680 | ".byte 0x66,0x66,0x66,0x66,0x90\n" | ||
681 | "1:" | ||
682 | ".section .fixup, \"ax\"\n" | ||
683 | "2: movl $1, %0\n" | ||
684 | " jmp ftrace_test_nop5\n" | ||
685 | "3: movl $2, %0\n" | ||
686 | " jmp 1b\n" | ||
687 | ".previous\n" | ||
688 | _ASM_EXTABLE(ftrace_test_p6nop, 2b) | ||
689 | _ASM_EXTABLE(ftrace_test_nop5, 3b) | ||
690 | : "=r"(faulted) : "0" (faulted)); | ||
691 | |||
692 | switch (faulted) { | ||
693 | case 0: | ||
694 | pr_info("converting mcount calls to 0f 1f 44 00 00\n"); | ||
695 | memcpy(ideal_nop5, ftrace_test_p6nop, IDEAL_NOP_SIZE_5); | ||
696 | break; | ||
697 | case 1: | ||
698 | pr_info("converting mcount calls to 66 66 66 66 90\n"); | ||
699 | memcpy(ideal_nop5, ftrace_test_nop5, IDEAL_NOP_SIZE_5); | ||
700 | break; | ||
701 | case 2: | ||
702 | pr_info("converting mcount calls to jmp . + 5\n"); | ||
703 | memcpy(ideal_nop5, ftrace_test_jmp, IDEAL_NOP_SIZE_5); | ||
704 | break; | ||
705 | } | ||
706 | |||
707 | } | ||
708 | #endif | ||
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index fa044e1e30a2..679b6450382b 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1953,6 +1953,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1953 | size_t size, | 1953 | size_t size, |
1954 | int dir) | 1954 | int dir) |
1955 | { | 1955 | { |
1956 | dma_addr_t flush_addr; | ||
1956 | dma_addr_t i, start; | 1957 | dma_addr_t i, start; |
1957 | unsigned int pages; | 1958 | unsigned int pages; |
1958 | 1959 | ||
@@ -1960,6 +1961,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1960 | (dma_addr + size > dma_dom->aperture_size)) | 1961 | (dma_addr + size > dma_dom->aperture_size)) |
1961 | return; | 1962 | return; |
1962 | 1963 | ||
1964 | flush_addr = dma_addr; | ||
1963 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); | 1965 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
1964 | dma_addr &= PAGE_MASK; | 1966 | dma_addr &= PAGE_MASK; |
1965 | start = dma_addr; | 1967 | start = dma_addr; |
@@ -1974,7 +1976,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1974 | dma_ops_free_addresses(dma_dom, dma_addr, pages); | 1976 | dma_ops_free_addresses(dma_dom, dma_addr, pages); |
1975 | 1977 | ||
1976 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { | 1978 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { |
1977 | iommu_flush_pages(&dma_dom->domain, dma_addr, size); | 1979 | iommu_flush_pages(&dma_dom->domain, flush_addr, size); |
1978 | dma_dom->need_flush = false; | 1980 | dma_dom->need_flush = false; |
1979 | } | 1981 | } |
1980 | } | 1982 | } |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cc63e2b8dd4..5a170cbbbed8 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) | |||
632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), | 632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), |
633 | MMIO_GET_LD(range)); | 633 | MMIO_GET_LD(range)); |
634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); | 634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); |
635 | |||
636 | if (is_rd890_iommu(iommu->dev)) { | ||
637 | pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]); | ||
638 | pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]); | ||
639 | pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]); | ||
640 | pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]); | ||
641 | } | ||
635 | } | 642 | } |
636 | 643 | ||
637 | /* | 644 | /* |
@@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
649 | struct ivhd_entry *e; | 656 | struct ivhd_entry *e; |
650 | 657 | ||
651 | /* | 658 | /* |
652 | * First set the recommended feature enable bits from ACPI | 659 | * First save the recommended feature enable bits from ACPI |
653 | * into the IOMMU control registers | ||
654 | */ | 660 | */ |
655 | h->flags & IVHD_FLAG_HT_TUN_EN_MASK ? | 661 | iommu->acpi_flags = h->flags; |
656 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
657 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
658 | |||
659 | h->flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
660 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
661 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
662 | |||
663 | h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
664 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
665 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
666 | |||
667 | h->flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
668 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
669 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
670 | |||
671 | /* | ||
672 | * make IOMMU memory accesses cache coherent | ||
673 | */ | ||
674 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
675 | 662 | ||
676 | /* | 663 | /* |
677 | * Done. Now parse the device entries | 664 | * Done. Now parse the device entries |
@@ -1116,6 +1103,40 @@ static void init_device_table(void) | |||
1116 | } | 1103 | } |
1117 | } | 1104 | } |
1118 | 1105 | ||
1106 | static void iommu_init_flags(struct amd_iommu *iommu) | ||
1107 | { | ||
1108 | iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? | ||
1109 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
1110 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
1111 | |||
1112 | iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
1113 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
1114 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
1115 | |||
1116 | iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
1117 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
1118 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
1119 | |||
1120 | iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
1121 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
1122 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
1123 | |||
1124 | /* | ||
1125 | * make IOMMU memory accesses cache coherent | ||
1126 | */ | ||
1127 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
1128 | } | ||
1129 | |||
1130 | static void iommu_apply_quirks(struct amd_iommu *iommu) | ||
1131 | { | ||
1132 | if (is_rd890_iommu(iommu->dev)) { | ||
1133 | pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]); | ||
1134 | pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]); | ||
1135 | pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]); | ||
1136 | pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1119 | /* | 1140 | /* |
1120 | * This function finally enables all IOMMUs found in the system after | 1141 | * This function finally enables all IOMMUs found in the system after |
1121 | * they have been initialized | 1142 | * they have been initialized |
@@ -1126,6 +1147,8 @@ static void enable_iommus(void) | |||
1126 | 1147 | ||
1127 | for_each_iommu(iommu) { | 1148 | for_each_iommu(iommu) { |
1128 | iommu_disable(iommu); | 1149 | iommu_disable(iommu); |
1150 | iommu_apply_quirks(iommu); | ||
1151 | iommu_init_flags(iommu); | ||
1129 | iommu_set_device_table(iommu); | 1152 | iommu_set_device_table(iommu); |
1130 | iommu_enable_command_buffer(iommu); | 1153 | iommu_enable_command_buffer(iommu); |
1131 | iommu_enable_event_buffer(iommu); | 1154 | iommu_enable_event_buffer(iommu); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f1efebaf5510..5c5b8f3dddb5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -306,14 +306,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, | |||
306 | 306 | ||
307 | old_cfg = old_desc->chip_data; | 307 | old_cfg = old_desc->chip_data; |
308 | 308 | ||
309 | memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); | 309 | cfg->vector = old_cfg->vector; |
310 | cfg->move_in_progress = old_cfg->move_in_progress; | ||
311 | cpumask_copy(cfg->domain, old_cfg->domain); | ||
312 | cpumask_copy(cfg->old_domain, old_cfg->old_domain); | ||
310 | 313 | ||
311 | init_copy_irq_2_pin(old_cfg, cfg, node); | 314 | init_copy_irq_2_pin(old_cfg, cfg, node); |
312 | } | 315 | } |
313 | 316 | ||
314 | static void free_irq_cfg(struct irq_cfg *old_cfg) | 317 | static void free_irq_cfg(struct irq_cfg *cfg) |
315 | { | 318 | { |
316 | kfree(old_cfg); | 319 | free_cpumask_var(cfg->domain); |
320 | free_cpumask_var(cfg->old_domain); | ||
321 | kfree(cfg); | ||
317 | } | 322 | } |
318 | 323 | ||
319 | void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) | 324 | void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 490dac63c2d2..f2f9ac7da25c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) | |||
545 | } | 545 | } |
546 | } | 546 | } |
547 | 547 | ||
548 | static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) | 548 | void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) |
549 | { | 549 | { |
550 | u32 tfms, xlvl; | 550 | u32 tfms, xlvl; |
551 | u32 ebx; | 551 | u32 ebx; |
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 3624e8a0f71b..f668bb1f7d43 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
@@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], | |||
33 | *const __x86_cpu_dev_end[]; | 33 | *const __x86_cpu_dev_end[]; |
34 | 34 | ||
35 | extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); | 35 | extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); |
36 | extern void get_cpu_cap(struct cpuinfo_x86 *c); | ||
36 | 37 | ||
37 | #endif | 38 | #endif |
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index 994230d4dc4e..4f6f679f2799 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | |||
@@ -368,16 +368,22 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle) | |||
368 | return -ENODEV; | 368 | return -ENODEV; |
369 | 369 | ||
370 | out_obj = output.pointer; | 370 | out_obj = output.pointer; |
371 | if (out_obj->type != ACPI_TYPE_BUFFER) | 371 | if (out_obj->type != ACPI_TYPE_BUFFER) { |
372 | return -ENODEV; | 372 | ret = -ENODEV; |
373 | goto out_free; | ||
374 | } | ||
373 | 375 | ||
374 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); | 376 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
375 | if (errors) | 377 | if (errors) { |
376 | return -ENODEV; | 378 | ret = -ENODEV; |
379 | goto out_free; | ||
380 | } | ||
377 | 381 | ||
378 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); | 382 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); |
379 | if (!(supported & 0x1)) | 383 | if (!(supported & 0x1)) { |
380 | return -ENODEV; | 384 | ret = -ENODEV; |
385 | goto out_free; | ||
386 | } | ||
381 | 387 | ||
382 | out_free: | 388 | out_free: |
383 | kfree(output.pointer); | 389 | kfree(output.pointer); |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 85f69cdeae10..b4389441efbb 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
39 | misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; | 39 | misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; |
40 | wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); | 40 | wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); |
41 | c->cpuid_level = cpuid_eax(0); | 41 | c->cpuid_level = cpuid_eax(0); |
42 | get_cpu_cap(c); | ||
42 | } | 43 | } |
43 | } | 44 | } |
44 | 45 | ||
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 03a5b0385ad6..e2513f26ba8b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -531,7 +531,7 @@ static int x86_pmu_hw_config(struct perf_event *event) | |||
531 | /* | 531 | /* |
532 | * Setup the hardware configuration for a given attr_type | 532 | * Setup the hardware configuration for a given attr_type |
533 | */ | 533 | */ |
534 | static int __hw_perf_event_init(struct perf_event *event) | 534 | static int __x86_pmu_event_init(struct perf_event *event) |
535 | { | 535 | { |
536 | int err; | 536 | int err; |
537 | 537 | ||
@@ -584,7 +584,7 @@ static void x86_pmu_disable_all(void) | |||
584 | } | 584 | } |
585 | } | 585 | } |
586 | 586 | ||
587 | void hw_perf_disable(void) | 587 | static void x86_pmu_disable(struct pmu *pmu) |
588 | { | 588 | { |
589 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 589 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
590 | 590 | ||
@@ -619,7 +619,7 @@ static void x86_pmu_enable_all(int added) | |||
619 | } | 619 | } |
620 | } | 620 | } |
621 | 621 | ||
622 | static const struct pmu pmu; | 622 | static struct pmu pmu; |
623 | 623 | ||
624 | static inline int is_x86_event(struct perf_event *event) | 624 | static inline int is_x86_event(struct perf_event *event) |
625 | { | 625 | { |
@@ -801,10 +801,10 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc, | |||
801 | hwc->last_tag == cpuc->tags[i]; | 801 | hwc->last_tag == cpuc->tags[i]; |
802 | } | 802 | } |
803 | 803 | ||
804 | static int x86_pmu_start(struct perf_event *event); | 804 | static void x86_pmu_start(struct perf_event *event, int flags); |
805 | static void x86_pmu_stop(struct perf_event *event); | 805 | static void x86_pmu_stop(struct perf_event *event, int flags); |
806 | 806 | ||
807 | void hw_perf_enable(void) | 807 | static void x86_pmu_enable(struct pmu *pmu) |
808 | { | 808 | { |
809 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 809 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
810 | struct perf_event *event; | 810 | struct perf_event *event; |
@@ -840,7 +840,14 @@ void hw_perf_enable(void) | |||
840 | match_prev_assignment(hwc, cpuc, i)) | 840 | match_prev_assignment(hwc, cpuc, i)) |
841 | continue; | 841 | continue; |
842 | 842 | ||
843 | x86_pmu_stop(event); | 843 | /* |
844 | * Ensure we don't accidentally enable a stopped | ||
845 | * counter simply because we rescheduled. | ||
846 | */ | ||
847 | if (hwc->state & PERF_HES_STOPPED) | ||
848 | hwc->state |= PERF_HES_ARCH; | ||
849 | |||
850 | x86_pmu_stop(event, PERF_EF_UPDATE); | ||
844 | } | 851 | } |
845 | 852 | ||
846 | for (i = 0; i < cpuc->n_events; i++) { | 853 | for (i = 0; i < cpuc->n_events; i++) { |
@@ -852,7 +859,10 @@ void hw_perf_enable(void) | |||
852 | else if (i < n_running) | 859 | else if (i < n_running) |
853 | continue; | 860 | continue; |
854 | 861 | ||
855 | x86_pmu_start(event); | 862 | if (hwc->state & PERF_HES_ARCH) |
863 | continue; | ||
864 | |||
865 | x86_pmu_start(event, PERF_EF_RELOAD); | ||
856 | } | 866 | } |
857 | cpuc->n_added = 0; | 867 | cpuc->n_added = 0; |
858 | perf_events_lapic_init(); | 868 | perf_events_lapic_init(); |
@@ -953,15 +963,12 @@ static void x86_pmu_enable_event(struct perf_event *event) | |||
953 | } | 963 | } |
954 | 964 | ||
955 | /* | 965 | /* |
956 | * activate a single event | 966 | * Add a single event to the PMU. |
957 | * | 967 | * |
958 | * The event is added to the group of enabled events | 968 | * The event is added to the group of enabled events |
959 | * but only if it can be scehduled with existing events. | 969 | * but only if it can be scehduled with existing events. |
960 | * | ||
961 | * Called with PMU disabled. If successful and return value 1, | ||
962 | * then guaranteed to call perf_enable() and hw_perf_enable() | ||
963 | */ | 970 | */ |
964 | static int x86_pmu_enable(struct perf_event *event) | 971 | static int x86_pmu_add(struct perf_event *event, int flags) |
965 | { | 972 | { |
966 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 973 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
967 | struct hw_perf_event *hwc; | 974 | struct hw_perf_event *hwc; |
@@ -970,58 +977,67 @@ static int x86_pmu_enable(struct perf_event *event) | |||
970 | 977 | ||
971 | hwc = &event->hw; | 978 | hwc = &event->hw; |
972 | 979 | ||
980 | perf_pmu_disable(event->pmu); | ||
973 | n0 = cpuc->n_events; | 981 | n0 = cpuc->n_events; |
974 | n = collect_events(cpuc, event, false); | 982 | ret = n = collect_events(cpuc, event, false); |
975 | if (n < 0) | 983 | if (ret < 0) |
976 | return n; | 984 | goto out; |
985 | |||
986 | hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
987 | if (!(flags & PERF_EF_START)) | ||
988 | hwc->state |= PERF_HES_ARCH; | ||
977 | 989 | ||
978 | /* | 990 | /* |
979 | * If group events scheduling transaction was started, | 991 | * If group events scheduling transaction was started, |
980 | * skip the schedulability test here, it will be peformed | 992 | * skip the schedulability test here, it will be peformed |
981 | * at commit time(->commit_txn) as a whole | 993 | * at commit time (->commit_txn) as a whole |
982 | */ | 994 | */ |
983 | if (cpuc->group_flag & PERF_EVENT_TXN) | 995 | if (cpuc->group_flag & PERF_EVENT_TXN) |
984 | goto out; | 996 | goto done_collect; |
985 | 997 | ||
986 | ret = x86_pmu.schedule_events(cpuc, n, assign); | 998 | ret = x86_pmu.schedule_events(cpuc, n, assign); |
987 | if (ret) | 999 | if (ret) |
988 | return ret; | 1000 | goto out; |
989 | /* | 1001 | /* |
990 | * copy new assignment, now we know it is possible | 1002 | * copy new assignment, now we know it is possible |
991 | * will be used by hw_perf_enable() | 1003 | * will be used by hw_perf_enable() |
992 | */ | 1004 | */ |
993 | memcpy(cpuc->assign, assign, n*sizeof(int)); | 1005 | memcpy(cpuc->assign, assign, n*sizeof(int)); |
994 | 1006 | ||
995 | out: | 1007 | done_collect: |
996 | cpuc->n_events = n; | 1008 | cpuc->n_events = n; |
997 | cpuc->n_added += n - n0; | 1009 | cpuc->n_added += n - n0; |
998 | cpuc->n_txn += n - n0; | 1010 | cpuc->n_txn += n - n0; |
999 | 1011 | ||
1000 | return 0; | 1012 | ret = 0; |
1013 | out: | ||
1014 | perf_pmu_enable(event->pmu); | ||
1015 | return ret; | ||
1001 | } | 1016 | } |
1002 | 1017 | ||
1003 | static int x86_pmu_start(struct perf_event *event) | 1018 | static void x86_pmu_start(struct perf_event *event, int flags) |
1004 | { | 1019 | { |
1005 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1020 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1006 | int idx = event->hw.idx; | 1021 | int idx = event->hw.idx; |
1007 | 1022 | ||
1008 | if (idx == -1) | 1023 | if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) |
1009 | return -EAGAIN; | 1024 | return; |
1025 | |||
1026 | if (WARN_ON_ONCE(idx == -1)) | ||
1027 | return; | ||
1028 | |||
1029 | if (flags & PERF_EF_RELOAD) { | ||
1030 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
1031 | x86_perf_event_set_period(event); | ||
1032 | } | ||
1033 | |||
1034 | event->hw.state = 0; | ||
1010 | 1035 | ||
1011 | x86_perf_event_set_period(event); | ||
1012 | cpuc->events[idx] = event; | 1036 | cpuc->events[idx] = event; |
1013 | __set_bit(idx, cpuc->active_mask); | 1037 | __set_bit(idx, cpuc->active_mask); |
1014 | __set_bit(idx, cpuc->running); | 1038 | __set_bit(idx, cpuc->running); |
1015 | x86_pmu.enable(event); | 1039 | x86_pmu.enable(event); |
1016 | perf_event_update_userpage(event); | 1040 | perf_event_update_userpage(event); |
1017 | |||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | static void x86_pmu_unthrottle(struct perf_event *event) | ||
1022 | { | ||
1023 | int ret = x86_pmu_start(event); | ||
1024 | WARN_ON_ONCE(ret); | ||
1025 | } | 1041 | } |
1026 | 1042 | ||
1027 | void perf_event_print_debug(void) | 1043 | void perf_event_print_debug(void) |
@@ -1078,27 +1094,29 @@ void perf_event_print_debug(void) | |||
1078 | local_irq_restore(flags); | 1094 | local_irq_restore(flags); |
1079 | } | 1095 | } |
1080 | 1096 | ||
1081 | static void x86_pmu_stop(struct perf_event *event) | 1097 | static void x86_pmu_stop(struct perf_event *event, int flags) |
1082 | { | 1098 | { |
1083 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1099 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1084 | struct hw_perf_event *hwc = &event->hw; | 1100 | struct hw_perf_event *hwc = &event->hw; |
1085 | int idx = hwc->idx; | ||
1086 | 1101 | ||
1087 | if (!__test_and_clear_bit(idx, cpuc->active_mask)) | 1102 | if (__test_and_clear_bit(hwc->idx, cpuc->active_mask)) { |
1088 | return; | 1103 | x86_pmu.disable(event); |
1089 | 1104 | cpuc->events[hwc->idx] = NULL; | |
1090 | x86_pmu.disable(event); | 1105 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); |
1091 | 1106 | hwc->state |= PERF_HES_STOPPED; | |
1092 | /* | 1107 | } |
1093 | * Drain the remaining delta count out of a event | ||
1094 | * that we are disabling: | ||
1095 | */ | ||
1096 | x86_perf_event_update(event); | ||
1097 | 1108 | ||
1098 | cpuc->events[idx] = NULL; | 1109 | if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { |
1110 | /* | ||
1111 | * Drain the remaining delta count out of a event | ||
1112 | * that we are disabling: | ||
1113 | */ | ||
1114 | x86_perf_event_update(event); | ||
1115 | hwc->state |= PERF_HES_UPTODATE; | ||
1116 | } | ||
1099 | } | 1117 | } |
1100 | 1118 | ||
1101 | static void x86_pmu_disable(struct perf_event *event) | 1119 | static void x86_pmu_del(struct perf_event *event, int flags) |
1102 | { | 1120 | { |
1103 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1121 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1104 | int i; | 1122 | int i; |
@@ -1111,7 +1129,7 @@ static void x86_pmu_disable(struct perf_event *event) | |||
1111 | if (cpuc->group_flag & PERF_EVENT_TXN) | 1129 | if (cpuc->group_flag & PERF_EVENT_TXN) |
1112 | return; | 1130 | return; |
1113 | 1131 | ||
1114 | x86_pmu_stop(event); | 1132 | x86_pmu_stop(event, PERF_EF_UPDATE); |
1115 | 1133 | ||
1116 | for (i = 0; i < cpuc->n_events; i++) { | 1134 | for (i = 0; i < cpuc->n_events; i++) { |
1117 | if (event == cpuc->event_list[i]) { | 1135 | if (event == cpuc->event_list[i]) { |
@@ -1134,7 +1152,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1134 | struct perf_sample_data data; | 1152 | struct perf_sample_data data; |
1135 | struct cpu_hw_events *cpuc; | 1153 | struct cpu_hw_events *cpuc; |
1136 | struct perf_event *event; | 1154 | struct perf_event *event; |
1137 | struct hw_perf_event *hwc; | ||
1138 | int idx, handled = 0; | 1155 | int idx, handled = 0; |
1139 | u64 val; | 1156 | u64 val; |
1140 | 1157 | ||
@@ -1155,7 +1172,6 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1155 | } | 1172 | } |
1156 | 1173 | ||
1157 | event = cpuc->events[idx]; | 1174 | event = cpuc->events[idx]; |
1158 | hwc = &event->hw; | ||
1159 | 1175 | ||
1160 | val = x86_perf_event_update(event); | 1176 | val = x86_perf_event_update(event); |
1161 | if (val & (1ULL << (x86_pmu.cntval_bits - 1))) | 1177 | if (val & (1ULL << (x86_pmu.cntval_bits - 1))) |
@@ -1171,7 +1187,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1171 | continue; | 1187 | continue; |
1172 | 1188 | ||
1173 | if (perf_event_overflow(event, 1, &data, regs)) | 1189 | if (perf_event_overflow(event, 1, &data, regs)) |
1174 | x86_pmu_stop(event); | 1190 | x86_pmu_stop(event, 0); |
1175 | } | 1191 | } |
1176 | 1192 | ||
1177 | if (handled) | 1193 | if (handled) |
@@ -1388,7 +1404,6 @@ void __init init_hw_perf_events(void) | |||
1388 | x86_pmu.num_counters = X86_PMC_MAX_GENERIC; | 1404 | x86_pmu.num_counters = X86_PMC_MAX_GENERIC; |
1389 | } | 1405 | } |
1390 | x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; | 1406 | x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; |
1391 | perf_max_events = x86_pmu.num_counters; | ||
1392 | 1407 | ||
1393 | if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { | 1408 | if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { |
1394 | WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", | 1409 | WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", |
@@ -1424,6 +1439,7 @@ void __init init_hw_perf_events(void) | |||
1424 | pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed); | 1439 | pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed); |
1425 | pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); | 1440 | pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); |
1426 | 1441 | ||
1442 | perf_pmu_register(&pmu); | ||
1427 | perf_cpu_notifier(x86_pmu_notifier); | 1443 | perf_cpu_notifier(x86_pmu_notifier); |
1428 | } | 1444 | } |
1429 | 1445 | ||
@@ -1437,10 +1453,11 @@ static inline void x86_pmu_read(struct perf_event *event) | |||
1437 | * Set the flag to make pmu::enable() not perform the | 1453 | * Set the flag to make pmu::enable() not perform the |
1438 | * schedulability test, it will be performed at commit time | 1454 | * schedulability test, it will be performed at commit time |
1439 | */ | 1455 | */ |
1440 | static void x86_pmu_start_txn(const struct pmu *pmu) | 1456 | static void x86_pmu_start_txn(struct pmu *pmu) |
1441 | { | 1457 | { |
1442 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1458 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1443 | 1459 | ||
1460 | perf_pmu_disable(pmu); | ||
1444 | cpuc->group_flag |= PERF_EVENT_TXN; | 1461 | cpuc->group_flag |= PERF_EVENT_TXN; |
1445 | cpuc->n_txn = 0; | 1462 | cpuc->n_txn = 0; |
1446 | } | 1463 | } |
@@ -1450,7 +1467,7 @@ static void x86_pmu_start_txn(const struct pmu *pmu) | |||
1450 | * Clear the flag and pmu::enable() will perform the | 1467 | * Clear the flag and pmu::enable() will perform the |
1451 | * schedulability test. | 1468 | * schedulability test. |
1452 | */ | 1469 | */ |
1453 | static void x86_pmu_cancel_txn(const struct pmu *pmu) | 1470 | static void x86_pmu_cancel_txn(struct pmu *pmu) |
1454 | { | 1471 | { |
1455 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1472 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1456 | 1473 | ||
@@ -1460,6 +1477,7 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu) | |||
1460 | */ | 1477 | */ |
1461 | cpuc->n_added -= cpuc->n_txn; | 1478 | cpuc->n_added -= cpuc->n_txn; |
1462 | cpuc->n_events -= cpuc->n_txn; | 1479 | cpuc->n_events -= cpuc->n_txn; |
1480 | perf_pmu_enable(pmu); | ||
1463 | } | 1481 | } |
1464 | 1482 | ||
1465 | /* | 1483 | /* |
@@ -1467,7 +1485,7 @@ static void x86_pmu_cancel_txn(const struct pmu *pmu) | |||
1467 | * Perform the group schedulability test as a whole | 1485 | * Perform the group schedulability test as a whole |
1468 | * Return 0 if success | 1486 | * Return 0 if success |
1469 | */ | 1487 | */ |
1470 | static int x86_pmu_commit_txn(const struct pmu *pmu) | 1488 | static int x86_pmu_commit_txn(struct pmu *pmu) |
1471 | { | 1489 | { |
1472 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 1490 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
1473 | int assign[X86_PMC_IDX_MAX]; | 1491 | int assign[X86_PMC_IDX_MAX]; |
@@ -1489,22 +1507,10 @@ static int x86_pmu_commit_txn(const struct pmu *pmu) | |||
1489 | memcpy(cpuc->assign, assign, n*sizeof(int)); | 1507 | memcpy(cpuc->assign, assign, n*sizeof(int)); |
1490 | 1508 | ||
1491 | cpuc->group_flag &= ~PERF_EVENT_TXN; | 1509 | cpuc->group_flag &= ~PERF_EVENT_TXN; |
1492 | 1510 | perf_pmu_enable(pmu); | |
1493 | return 0; | 1511 | return 0; |
1494 | } | 1512 | } |
1495 | 1513 | ||
1496 | static const struct pmu pmu = { | ||
1497 | .enable = x86_pmu_enable, | ||
1498 | .disable = x86_pmu_disable, | ||
1499 | .start = x86_pmu_start, | ||
1500 | .stop = x86_pmu_stop, | ||
1501 | .read = x86_pmu_read, | ||
1502 | .unthrottle = x86_pmu_unthrottle, | ||
1503 | .start_txn = x86_pmu_start_txn, | ||
1504 | .cancel_txn = x86_pmu_cancel_txn, | ||
1505 | .commit_txn = x86_pmu_commit_txn, | ||
1506 | }; | ||
1507 | |||
1508 | /* | 1514 | /* |
1509 | * validate that we can schedule this event | 1515 | * validate that we can schedule this event |
1510 | */ | 1516 | */ |
@@ -1579,12 +1585,22 @@ out: | |||
1579 | return ret; | 1585 | return ret; |
1580 | } | 1586 | } |
1581 | 1587 | ||
1582 | const struct pmu *hw_perf_event_init(struct perf_event *event) | 1588 | int x86_pmu_event_init(struct perf_event *event) |
1583 | { | 1589 | { |
1584 | const struct pmu *tmp; | 1590 | struct pmu *tmp; |
1585 | int err; | 1591 | int err; |
1586 | 1592 | ||
1587 | err = __hw_perf_event_init(event); | 1593 | switch (event->attr.type) { |
1594 | case PERF_TYPE_RAW: | ||
1595 | case PERF_TYPE_HARDWARE: | ||
1596 | case PERF_TYPE_HW_CACHE: | ||
1597 | break; | ||
1598 | |||
1599 | default: | ||
1600 | return -ENOENT; | ||
1601 | } | ||
1602 | |||
1603 | err = __x86_pmu_event_init(event); | ||
1588 | if (!err) { | 1604 | if (!err) { |
1589 | /* | 1605 | /* |
1590 | * we temporarily connect event to its pmu | 1606 | * we temporarily connect event to its pmu |
@@ -1604,26 +1620,31 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) | |||
1604 | if (err) { | 1620 | if (err) { |
1605 | if (event->destroy) | 1621 | if (event->destroy) |
1606 | event->destroy(event); | 1622 | event->destroy(event); |
1607 | return ERR_PTR(err); | ||
1608 | } | 1623 | } |
1609 | 1624 | ||
1610 | return &pmu; | 1625 | return err; |
1611 | } | 1626 | } |
1612 | 1627 | ||
1613 | /* | 1628 | static struct pmu pmu = { |
1614 | * callchain support | 1629 | .pmu_enable = x86_pmu_enable, |
1615 | */ | 1630 | .pmu_disable = x86_pmu_disable, |
1616 | 1631 | ||
1617 | static inline | 1632 | .event_init = x86_pmu_event_init, |
1618 | void callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
1619 | { | ||
1620 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
1621 | entry->ip[entry->nr++] = ip; | ||
1622 | } | ||
1623 | 1633 | ||
1624 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); | 1634 | .add = x86_pmu_add, |
1625 | static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry); | 1635 | .del = x86_pmu_del, |
1636 | .start = x86_pmu_start, | ||
1637 | .stop = x86_pmu_stop, | ||
1638 | .read = x86_pmu_read, | ||
1626 | 1639 | ||
1640 | .start_txn = x86_pmu_start_txn, | ||
1641 | .cancel_txn = x86_pmu_cancel_txn, | ||
1642 | .commit_txn = x86_pmu_commit_txn, | ||
1643 | }; | ||
1644 | |||
1645 | /* | ||
1646 | * callchain support | ||
1647 | */ | ||
1627 | 1648 | ||
1628 | static void | 1649 | static void |
1629 | backtrace_warning_symbol(void *data, char *msg, unsigned long symbol) | 1650 | backtrace_warning_symbol(void *data, char *msg, unsigned long symbol) |
@@ -1645,7 +1666,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
1645 | { | 1666 | { |
1646 | struct perf_callchain_entry *entry = data; | 1667 | struct perf_callchain_entry *entry = data; |
1647 | 1668 | ||
1648 | callchain_store(entry, addr); | 1669 | perf_callchain_store(entry, addr); |
1649 | } | 1670 | } |
1650 | 1671 | ||
1651 | static const struct stacktrace_ops backtrace_ops = { | 1672 | static const struct stacktrace_ops backtrace_ops = { |
@@ -1656,11 +1677,15 @@ static const struct stacktrace_ops backtrace_ops = { | |||
1656 | .walk_stack = print_context_stack_bp, | 1677 | .walk_stack = print_context_stack_bp, |
1657 | }; | 1678 | }; |
1658 | 1679 | ||
1659 | static void | 1680 | void |
1660 | perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1681 | perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) |
1661 | { | 1682 | { |
1662 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 1683 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
1663 | callchain_store(entry, regs->ip); | 1684 | /* TODO: We don't support guest os callchain now */ |
1685 | return; | ||
1686 | } | ||
1687 | |||
1688 | perf_callchain_store(entry, regs->ip); | ||
1664 | 1689 | ||
1665 | dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); | 1690 | dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry); |
1666 | } | 1691 | } |
@@ -1689,7 +1714,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1689 | if (fp < compat_ptr(regs->sp)) | 1714 | if (fp < compat_ptr(regs->sp)) |
1690 | break; | 1715 | break; |
1691 | 1716 | ||
1692 | callchain_store(entry, frame.return_address); | 1717 | perf_callchain_store(entry, frame.return_address); |
1693 | fp = compat_ptr(frame.next_frame); | 1718 | fp = compat_ptr(frame.next_frame); |
1694 | } | 1719 | } |
1695 | return 1; | 1720 | return 1; |
@@ -1702,19 +1727,20 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1702 | } | 1727 | } |
1703 | #endif | 1728 | #endif |
1704 | 1729 | ||
1705 | static void | 1730 | void |
1706 | perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1731 | perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) |
1707 | { | 1732 | { |
1708 | struct stack_frame frame; | 1733 | struct stack_frame frame; |
1709 | const void __user *fp; | 1734 | const void __user *fp; |
1710 | 1735 | ||
1711 | if (!user_mode(regs)) | 1736 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
1712 | regs = task_pt_regs(current); | 1737 | /* TODO: We don't support guest os callchain now */ |
1738 | return; | ||
1739 | } | ||
1713 | 1740 | ||
1714 | fp = (void __user *)regs->bp; | 1741 | fp = (void __user *)regs->bp; |
1715 | 1742 | ||
1716 | callchain_store(entry, PERF_CONTEXT_USER); | 1743 | perf_callchain_store(entry, regs->ip); |
1717 | callchain_store(entry, regs->ip); | ||
1718 | 1744 | ||
1719 | if (perf_callchain_user32(regs, entry)) | 1745 | if (perf_callchain_user32(regs, entry)) |
1720 | return; | 1746 | return; |
@@ -1731,52 +1757,11 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1731 | if ((unsigned long)fp < regs->sp) | 1757 | if ((unsigned long)fp < regs->sp) |
1732 | break; | 1758 | break; |
1733 | 1759 | ||
1734 | callchain_store(entry, frame.return_address); | 1760 | perf_callchain_store(entry, frame.return_address); |
1735 | fp = frame.next_frame; | 1761 | fp = frame.next_frame; |
1736 | } | 1762 | } |
1737 | } | 1763 | } |
1738 | 1764 | ||
1739 | static void | ||
1740 | perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
1741 | { | ||
1742 | int is_user; | ||
1743 | |||
1744 | if (!regs) | ||
1745 | return; | ||
1746 | |||
1747 | is_user = user_mode(regs); | ||
1748 | |||
1749 | if (is_user && current->state != TASK_RUNNING) | ||
1750 | return; | ||
1751 | |||
1752 | if (!is_user) | ||
1753 | perf_callchain_kernel(regs, entry); | ||
1754 | |||
1755 | if (current->mm) | ||
1756 | perf_callchain_user(regs, entry); | ||
1757 | } | ||
1758 | |||
1759 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
1760 | { | ||
1761 | struct perf_callchain_entry *entry; | ||
1762 | |||
1763 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { | ||
1764 | /* TODO: We don't support guest os callchain now */ | ||
1765 | return NULL; | ||
1766 | } | ||
1767 | |||
1768 | if (in_nmi()) | ||
1769 | entry = &__get_cpu_var(pmc_nmi_entry); | ||
1770 | else | ||
1771 | entry = &__get_cpu_var(pmc_irq_entry); | ||
1772 | |||
1773 | entry->nr = 0; | ||
1774 | |||
1775 | perf_do_callchain(regs, entry); | ||
1776 | |||
1777 | return entry; | ||
1778 | } | ||
1779 | |||
1780 | unsigned long perf_instruction_pointer(struct pt_regs *regs) | 1765 | unsigned long perf_instruction_pointer(struct pt_regs *regs) |
1781 | { | 1766 | { |
1782 | unsigned long ip; | 1767 | unsigned long ip; |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index ee05c90012d2..c8f5c088cad1 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -713,18 +713,18 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
713 | struct cpu_hw_events *cpuc; | 713 | struct cpu_hw_events *cpuc; |
714 | int bit, loops; | 714 | int bit, loops; |
715 | u64 status; | 715 | u64 status; |
716 | int handled = 0; | 716 | int handled; |
717 | 717 | ||
718 | perf_sample_data_init(&data, 0); | 718 | perf_sample_data_init(&data, 0); |
719 | 719 | ||
720 | cpuc = &__get_cpu_var(cpu_hw_events); | 720 | cpuc = &__get_cpu_var(cpu_hw_events); |
721 | 721 | ||
722 | intel_pmu_disable_all(); | 722 | intel_pmu_disable_all(); |
723 | intel_pmu_drain_bts_buffer(); | 723 | handled = intel_pmu_drain_bts_buffer(); |
724 | status = intel_pmu_get_status(); | 724 | status = intel_pmu_get_status(); |
725 | if (!status) { | 725 | if (!status) { |
726 | intel_pmu_enable_all(0); | 726 | intel_pmu_enable_all(0); |
727 | return 0; | 727 | return handled; |
728 | } | 728 | } |
729 | 729 | ||
730 | loops = 0; | 730 | loops = 0; |
@@ -763,7 +763,7 @@ again: | |||
763 | data.period = event->hw.last_period; | 763 | data.period = event->hw.last_period; |
764 | 764 | ||
765 | if (perf_event_overflow(event, 1, &data, regs)) | 765 | if (perf_event_overflow(event, 1, &data, regs)) |
766 | x86_pmu_stop(event); | 766 | x86_pmu_stop(event, 0); |
767 | } | 767 | } |
768 | 768 | ||
769 | /* | 769 | /* |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 18018d1311cd..4977f9c400e5 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -214,7 +214,7 @@ static void intel_pmu_disable_bts(void) | |||
214 | update_debugctlmsr(debugctlmsr); | 214 | update_debugctlmsr(debugctlmsr); |
215 | } | 215 | } |
216 | 216 | ||
217 | static void intel_pmu_drain_bts_buffer(void) | 217 | static int intel_pmu_drain_bts_buffer(void) |
218 | { | 218 | { |
219 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 219 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
220 | struct debug_store *ds = cpuc->ds; | 220 | struct debug_store *ds = cpuc->ds; |
@@ -231,16 +231,16 @@ static void intel_pmu_drain_bts_buffer(void) | |||
231 | struct pt_regs regs; | 231 | struct pt_regs regs; |
232 | 232 | ||
233 | if (!event) | 233 | if (!event) |
234 | return; | 234 | return 0; |
235 | 235 | ||
236 | if (!ds) | 236 | if (!ds) |
237 | return; | 237 | return 0; |
238 | 238 | ||
239 | at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; | 239 | at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; |
240 | top = (struct bts_record *)(unsigned long)ds->bts_index; | 240 | top = (struct bts_record *)(unsigned long)ds->bts_index; |
241 | 241 | ||
242 | if (top <= at) | 242 | if (top <= at) |
243 | return; | 243 | return 0; |
244 | 244 | ||
245 | ds->bts_index = ds->bts_buffer_base; | 245 | ds->bts_index = ds->bts_buffer_base; |
246 | 246 | ||
@@ -256,7 +256,7 @@ static void intel_pmu_drain_bts_buffer(void) | |||
256 | perf_prepare_sample(&header, &data, event, ®s); | 256 | perf_prepare_sample(&header, &data, event, ®s); |
257 | 257 | ||
258 | if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1)) | 258 | if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1)) |
259 | return; | 259 | return 1; |
260 | 260 | ||
261 | for (; at < top; at++) { | 261 | for (; at < top; at++) { |
262 | data.ip = at->from; | 262 | data.ip = at->from; |
@@ -270,6 +270,7 @@ static void intel_pmu_drain_bts_buffer(void) | |||
270 | /* There's new data available. */ | 270 | /* There's new data available. */ |
271 | event->hw.interrupts++; | 271 | event->hw.interrupts++; |
272 | event->pending_kill = POLL_IN; | 272 | event->pending_kill = POLL_IN; |
273 | return 1; | ||
273 | } | 274 | } |
274 | 275 | ||
275 | /* | 276 | /* |
@@ -491,7 +492,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event, | |||
491 | regs.flags &= ~PERF_EFLAGS_EXACT; | 492 | regs.flags &= ~PERF_EFLAGS_EXACT; |
492 | 493 | ||
493 | if (perf_event_overflow(event, 1, &data, ®s)) | 494 | if (perf_event_overflow(event, 1, &data, ®s)) |
494 | x86_pmu_stop(event); | 495 | x86_pmu_stop(event, 0); |
495 | } | 496 | } |
496 | 497 | ||
497 | static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) | 498 | static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b560db3305be..81400b93e694 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -18,6 +18,8 @@ | |||
18 | struct p4_event_bind { | 18 | struct p4_event_bind { |
19 | unsigned int opcode; /* Event code and ESCR selector */ | 19 | unsigned int opcode; /* Event code and ESCR selector */ |
20 | unsigned int escr_msr[2]; /* ESCR MSR for this event */ | 20 | unsigned int escr_msr[2]; /* ESCR MSR for this event */ |
21 | unsigned int escr_emask; /* valid ESCR EventMask bits */ | ||
22 | unsigned int shared; /* event is shared across threads */ | ||
21 | char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ | 23 | char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */ |
22 | }; | 24 | }; |
23 | 25 | ||
@@ -66,231 +68,435 @@ static struct p4_event_bind p4_event_bind_map[] = { | |||
66 | [P4_EVENT_TC_DELIVER_MODE] = { | 68 | [P4_EVENT_TC_DELIVER_MODE] = { |
67 | .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE), | 69 | .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE), |
68 | .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, | 70 | .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, |
71 | .escr_emask = | ||
72 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DD) | | ||
73 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DB) | | ||
74 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, DI) | | ||
75 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BD) | | ||
76 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BB) | | ||
77 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, BI) | | ||
78 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_DELIVER_MODE, ID), | ||
79 | .shared = 1, | ||
69 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 80 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
70 | }, | 81 | }, |
71 | [P4_EVENT_BPU_FETCH_REQUEST] = { | 82 | [P4_EVENT_BPU_FETCH_REQUEST] = { |
72 | .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST), | 83 | .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST), |
73 | .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 }, | 84 | .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 }, |
85 | .escr_emask = | ||
86 | P4_ESCR_EMASK_BIT(P4_EVENT_BPU_FETCH_REQUEST, TCMISS), | ||
74 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 87 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
75 | }, | 88 | }, |
76 | [P4_EVENT_ITLB_REFERENCE] = { | 89 | [P4_EVENT_ITLB_REFERENCE] = { |
77 | .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE), | 90 | .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE), |
78 | .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, | 91 | .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 }, |
92 | .escr_emask = | ||
93 | P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT) | | ||
94 | P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, MISS) | | ||
95 | P4_ESCR_EMASK_BIT(P4_EVENT_ITLB_REFERENCE, HIT_UK), | ||
79 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 96 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
80 | }, | 97 | }, |
81 | [P4_EVENT_MEMORY_CANCEL] = { | 98 | [P4_EVENT_MEMORY_CANCEL] = { |
82 | .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL), | 99 | .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL), |
83 | .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, | 100 | .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, |
101 | .escr_emask = | ||
102 | P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL) | | ||
103 | P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_CANCEL, 64K_CONF), | ||
84 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 104 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
85 | }, | 105 | }, |
86 | [P4_EVENT_MEMORY_COMPLETE] = { | 106 | [P4_EVENT_MEMORY_COMPLETE] = { |
87 | .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE), | 107 | .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE), |
88 | .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, | 108 | .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, |
109 | .escr_emask = | ||
110 | P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, LSC) | | ||
111 | P4_ESCR_EMASK_BIT(P4_EVENT_MEMORY_COMPLETE, SSC), | ||
89 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 112 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
90 | }, | 113 | }, |
91 | [P4_EVENT_LOAD_PORT_REPLAY] = { | 114 | [P4_EVENT_LOAD_PORT_REPLAY] = { |
92 | .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY), | 115 | .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY), |
93 | .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 }, | 116 | .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 }, |
117 | .escr_emask = | ||
118 | P4_ESCR_EMASK_BIT(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD), | ||
94 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 119 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
95 | }, | 120 | }, |
96 | [P4_EVENT_STORE_PORT_REPLAY] = { | 121 | [P4_EVENT_STORE_PORT_REPLAY] = { |
97 | .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY), | 122 | .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY), |
98 | .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, | 123 | .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 }, |
124 | .escr_emask = | ||
125 | P4_ESCR_EMASK_BIT(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST), | ||
99 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 126 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
100 | }, | 127 | }, |
101 | [P4_EVENT_MOB_LOAD_REPLAY] = { | 128 | [P4_EVENT_MOB_LOAD_REPLAY] = { |
102 | .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY), | 129 | .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY), |
103 | .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 }, | 130 | .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 }, |
131 | .escr_emask = | ||
132 | P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STA) | | ||
133 | P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, NO_STD) | | ||
134 | P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA) | | ||
135 | P4_ESCR_EMASK_BIT(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR), | ||
104 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 136 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
105 | }, | 137 | }, |
106 | [P4_EVENT_PAGE_WALK_TYPE] = { | 138 | [P4_EVENT_PAGE_WALK_TYPE] = { |
107 | .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE), | 139 | .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE), |
108 | .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 }, | 140 | .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 }, |
141 | .escr_emask = | ||
142 | P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, DTMISS) | | ||
143 | P4_ESCR_EMASK_BIT(P4_EVENT_PAGE_WALK_TYPE, ITMISS), | ||
144 | .shared = 1, | ||
109 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 145 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
110 | }, | 146 | }, |
111 | [P4_EVENT_BSQ_CACHE_REFERENCE] = { | 147 | [P4_EVENT_BSQ_CACHE_REFERENCE] = { |
112 | .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE), | 148 | .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE), |
113 | .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, | 149 | .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 }, |
150 | .escr_emask = | ||
151 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) | | ||
152 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) | | ||
153 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) | | ||
154 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) | | ||
155 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) | | ||
156 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM) | | ||
157 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) | | ||
158 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) | | ||
159 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS), | ||
114 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 160 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
115 | }, | 161 | }, |
116 | [P4_EVENT_IOQ_ALLOCATION] = { | 162 | [P4_EVENT_IOQ_ALLOCATION] = { |
117 | .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION), | 163 | .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION), |
118 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 164 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
165 | .escr_emask = | ||
166 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, DEFAULT) | | ||
167 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_READ) | | ||
168 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE) | | ||
169 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_UC) | | ||
170 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WC) | | ||
171 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WT) | | ||
172 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WP) | | ||
173 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, MEM_WB) | | ||
174 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OWN) | | ||
175 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, OTHER) | | ||
176 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ALLOCATION, PREFETCH), | ||
119 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 177 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
120 | }, | 178 | }, |
121 | [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */ | 179 | [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */ |
122 | .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES), | 180 | .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES), |
123 | .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 }, | 181 | .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 }, |
182 | .escr_emask = | ||
183 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT) | | ||
184 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ) | | ||
185 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE) | | ||
186 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC) | | ||
187 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC) | | ||
188 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT) | | ||
189 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP) | | ||
190 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB) | | ||
191 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN) | | ||
192 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER) | | ||
193 | P4_ESCR_EMASK_BIT(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH), | ||
124 | .cntr = { {2, -1, -1}, {3, -1, -1} }, | 194 | .cntr = { {2, -1, -1}, {3, -1, -1} }, |
125 | }, | 195 | }, |
126 | [P4_EVENT_FSB_DATA_ACTIVITY] = { | 196 | [P4_EVENT_FSB_DATA_ACTIVITY] = { |
127 | .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY), | 197 | .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY), |
128 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 198 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
199 | .escr_emask = | ||
200 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) | | ||
201 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN) | | ||
202 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER) | | ||
203 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV) | | ||
204 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN) | | ||
205 | P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER), | ||
206 | .shared = 1, | ||
129 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 207 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
130 | }, | 208 | }, |
131 | [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */ | 209 | [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */ |
132 | .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION), | 210 | .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION), |
133 | .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 }, | 211 | .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 }, |
212 | .escr_emask = | ||
213 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0) | | ||
214 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1) | | ||
215 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0) | | ||
216 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1) | | ||
217 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE) | | ||
218 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE) | | ||
219 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE) | | ||
220 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE) | | ||
221 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE) | | ||
222 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE) | | ||
223 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0) | | ||
224 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1) | | ||
225 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2), | ||
134 | .cntr = { {0, -1, -1}, {1, -1, -1} }, | 226 | .cntr = { {0, -1, -1}, {1, -1, -1} }, |
135 | }, | 227 | }, |
136 | [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */ | 228 | [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */ |
137 | .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES), | 229 | .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES), |
138 | .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 }, | 230 | .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 }, |
231 | .escr_emask = | ||
232 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0) | | ||
233 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1) | | ||
234 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0) | | ||
235 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1) | | ||
236 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE) | | ||
237 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE) | | ||
238 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE) | | ||
239 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE) | | ||
240 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE) | | ||
241 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE) | | ||
242 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0) | | ||
243 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1) | | ||
244 | P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2), | ||
139 | .cntr = { {2, -1, -1}, {3, -1, -1} }, | 245 | .cntr = { {2, -1, -1}, {3, -1, -1} }, |
140 | }, | 246 | }, |
141 | [P4_EVENT_SSE_INPUT_ASSIST] = { | 247 | [P4_EVENT_SSE_INPUT_ASSIST] = { |
142 | .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST), | 248 | .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST), |
143 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 249 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
250 | .escr_emask = | ||
251 | P4_ESCR_EMASK_BIT(P4_EVENT_SSE_INPUT_ASSIST, ALL), | ||
252 | .shared = 1, | ||
144 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 253 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
145 | }, | 254 | }, |
146 | [P4_EVENT_PACKED_SP_UOP] = { | 255 | [P4_EVENT_PACKED_SP_UOP] = { |
147 | .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP), | 256 | .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP), |
148 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 257 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
258 | .escr_emask = | ||
259 | P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_SP_UOP, ALL), | ||
260 | .shared = 1, | ||
149 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 261 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
150 | }, | 262 | }, |
151 | [P4_EVENT_PACKED_DP_UOP] = { | 263 | [P4_EVENT_PACKED_DP_UOP] = { |
152 | .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP), | 264 | .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP), |
153 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 265 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
266 | .escr_emask = | ||
267 | P4_ESCR_EMASK_BIT(P4_EVENT_PACKED_DP_UOP, ALL), | ||
268 | .shared = 1, | ||
154 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 269 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
155 | }, | 270 | }, |
156 | [P4_EVENT_SCALAR_SP_UOP] = { | 271 | [P4_EVENT_SCALAR_SP_UOP] = { |
157 | .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP), | 272 | .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP), |
158 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 273 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
274 | .escr_emask = | ||
275 | P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_SP_UOP, ALL), | ||
276 | .shared = 1, | ||
159 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 277 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
160 | }, | 278 | }, |
161 | [P4_EVENT_SCALAR_DP_UOP] = { | 279 | [P4_EVENT_SCALAR_DP_UOP] = { |
162 | .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP), | 280 | .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP), |
163 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 281 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
282 | .escr_emask = | ||
283 | P4_ESCR_EMASK_BIT(P4_EVENT_SCALAR_DP_UOP, ALL), | ||
284 | .shared = 1, | ||
164 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 285 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
165 | }, | 286 | }, |
166 | [P4_EVENT_64BIT_MMX_UOP] = { | 287 | [P4_EVENT_64BIT_MMX_UOP] = { |
167 | .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP), | 288 | .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP), |
168 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 289 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
290 | .escr_emask = | ||
291 | P4_ESCR_EMASK_BIT(P4_EVENT_64BIT_MMX_UOP, ALL), | ||
292 | .shared = 1, | ||
169 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 293 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
170 | }, | 294 | }, |
171 | [P4_EVENT_128BIT_MMX_UOP] = { | 295 | [P4_EVENT_128BIT_MMX_UOP] = { |
172 | .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP), | 296 | .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP), |
173 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 297 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
298 | .escr_emask = | ||
299 | P4_ESCR_EMASK_BIT(P4_EVENT_128BIT_MMX_UOP, ALL), | ||
300 | .shared = 1, | ||
174 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 301 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
175 | }, | 302 | }, |
176 | [P4_EVENT_X87_FP_UOP] = { | 303 | [P4_EVENT_X87_FP_UOP] = { |
177 | .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP), | 304 | .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP), |
178 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, | 305 | .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 }, |
306 | .escr_emask = | ||
307 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_FP_UOP, ALL), | ||
308 | .shared = 1, | ||
179 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 309 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
180 | }, | 310 | }, |
181 | [P4_EVENT_TC_MISC] = { | 311 | [P4_EVENT_TC_MISC] = { |
182 | .opcode = P4_OPCODE(P4_EVENT_TC_MISC), | 312 | .opcode = P4_OPCODE(P4_EVENT_TC_MISC), |
183 | .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, | 313 | .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 }, |
314 | .escr_emask = | ||
315 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_MISC, FLUSH), | ||
184 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 316 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
185 | }, | 317 | }, |
186 | [P4_EVENT_GLOBAL_POWER_EVENTS] = { | 318 | [P4_EVENT_GLOBAL_POWER_EVENTS] = { |
187 | .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS), | 319 | .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS), |
188 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 320 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
321 | .escr_emask = | ||
322 | P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING), | ||
189 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 323 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
190 | }, | 324 | }, |
191 | [P4_EVENT_TC_MS_XFER] = { | 325 | [P4_EVENT_TC_MS_XFER] = { |
192 | .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER), | 326 | .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER), |
193 | .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, | 327 | .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, |
328 | .escr_emask = | ||
329 | P4_ESCR_EMASK_BIT(P4_EVENT_TC_MS_XFER, CISC), | ||
194 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 330 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
195 | }, | 331 | }, |
196 | [P4_EVENT_UOP_QUEUE_WRITES] = { | 332 | [P4_EVENT_UOP_QUEUE_WRITES] = { |
197 | .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES), | 333 | .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES), |
198 | .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, | 334 | .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 }, |
335 | .escr_emask = | ||
336 | P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD) | | ||
337 | P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER) | | ||
338 | P4_ESCR_EMASK_BIT(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM), | ||
199 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 339 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
200 | }, | 340 | }, |
201 | [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = { | 341 | [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = { |
202 | .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE), | 342 | .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE), |
203 | .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 }, | 343 | .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 }, |
344 | .escr_emask = | ||
345 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL) | | ||
346 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL) | | ||
347 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN) | | ||
348 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT), | ||
204 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 349 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
205 | }, | 350 | }, |
206 | [P4_EVENT_RETIRED_BRANCH_TYPE] = { | 351 | [P4_EVENT_RETIRED_BRANCH_TYPE] = { |
207 | .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE), | 352 | .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE), |
208 | .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 }, | 353 | .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 }, |
354 | .escr_emask = | ||
355 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) | | ||
356 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) | | ||
357 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) | | ||
358 | P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT), | ||
209 | .cntr = { {4, 5, -1}, {6, 7, -1} }, | 359 | .cntr = { {4, 5, -1}, {6, 7, -1} }, |
210 | }, | 360 | }, |
211 | [P4_EVENT_RESOURCE_STALL] = { | 361 | [P4_EVENT_RESOURCE_STALL] = { |
212 | .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL), | 362 | .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL), |
213 | .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 }, | 363 | .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 }, |
364 | .escr_emask = | ||
365 | P4_ESCR_EMASK_BIT(P4_EVENT_RESOURCE_STALL, SBFULL), | ||
214 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 366 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
215 | }, | 367 | }, |
216 | [P4_EVENT_WC_BUFFER] = { | 368 | [P4_EVENT_WC_BUFFER] = { |
217 | .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER), | 369 | .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER), |
218 | .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, | 370 | .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 }, |
371 | .escr_emask = | ||
372 | P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_EVICTS) | | ||
373 | P4_ESCR_EMASK_BIT(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS), | ||
374 | .shared = 1, | ||
219 | .cntr = { {8, 9, -1}, {10, 11, -1} }, | 375 | .cntr = { {8, 9, -1}, {10, 11, -1} }, |
220 | }, | 376 | }, |
221 | [P4_EVENT_B2B_CYCLES] = { | 377 | [P4_EVENT_B2B_CYCLES] = { |
222 | .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES), | 378 | .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES), |
223 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 379 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
380 | .escr_emask = 0, | ||
224 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 381 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
225 | }, | 382 | }, |
226 | [P4_EVENT_BNR] = { | 383 | [P4_EVENT_BNR] = { |
227 | .opcode = P4_OPCODE(P4_EVENT_BNR), | 384 | .opcode = P4_OPCODE(P4_EVENT_BNR), |
228 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 385 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
386 | .escr_emask = 0, | ||
229 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 387 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
230 | }, | 388 | }, |
231 | [P4_EVENT_SNOOP] = { | 389 | [P4_EVENT_SNOOP] = { |
232 | .opcode = P4_OPCODE(P4_EVENT_SNOOP), | 390 | .opcode = P4_OPCODE(P4_EVENT_SNOOP), |
233 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 391 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
392 | .escr_emask = 0, | ||
234 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 393 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
235 | }, | 394 | }, |
236 | [P4_EVENT_RESPONSE] = { | 395 | [P4_EVENT_RESPONSE] = { |
237 | .opcode = P4_OPCODE(P4_EVENT_RESPONSE), | 396 | .opcode = P4_OPCODE(P4_EVENT_RESPONSE), |
238 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, | 397 | .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 }, |
398 | .escr_emask = 0, | ||
239 | .cntr = { {0, -1, -1}, {2, -1, -1} }, | 399 | .cntr = { {0, -1, -1}, {2, -1, -1} }, |
240 | }, | 400 | }, |
241 | [P4_EVENT_FRONT_END_EVENT] = { | 401 | [P4_EVENT_FRONT_END_EVENT] = { |
242 | .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT), | 402 | .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT), |
243 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 403 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
404 | .escr_emask = | ||
405 | P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, NBOGUS) | | ||
406 | P4_ESCR_EMASK_BIT(P4_EVENT_FRONT_END_EVENT, BOGUS), | ||
244 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 407 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
245 | }, | 408 | }, |
246 | [P4_EVENT_EXECUTION_EVENT] = { | 409 | [P4_EVENT_EXECUTION_EVENT] = { |
247 | .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT), | 410 | .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT), |
248 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 411 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
412 | .escr_emask = | ||
413 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS0) | | ||
414 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS1) | | ||
415 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS2) | | ||
416 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, NBOGUS3) | | ||
417 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS0) | | ||
418 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS1) | | ||
419 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS2) | | ||
420 | P4_ESCR_EMASK_BIT(P4_EVENT_EXECUTION_EVENT, BOGUS3), | ||
249 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 421 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
250 | }, | 422 | }, |
251 | [P4_EVENT_REPLAY_EVENT] = { | 423 | [P4_EVENT_REPLAY_EVENT] = { |
252 | .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT), | 424 | .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT), |
253 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 425 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
426 | .escr_emask = | ||
427 | P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, NBOGUS) | | ||
428 | P4_ESCR_EMASK_BIT(P4_EVENT_REPLAY_EVENT, BOGUS), | ||
254 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 429 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
255 | }, | 430 | }, |
256 | [P4_EVENT_INSTR_RETIRED] = { | 431 | [P4_EVENT_INSTR_RETIRED] = { |
257 | .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED), | 432 | .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED), |
258 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, | 433 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, |
434 | .escr_emask = | ||
435 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) | | ||
436 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSTAG) | | ||
437 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG) | | ||
438 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSTAG), | ||
259 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 439 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
260 | }, | 440 | }, |
261 | [P4_EVENT_UOPS_RETIRED] = { | 441 | [P4_EVENT_UOPS_RETIRED] = { |
262 | .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED), | 442 | .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED), |
263 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, | 443 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, |
444 | .escr_emask = | ||
445 | P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, NBOGUS) | | ||
446 | P4_ESCR_EMASK_BIT(P4_EVENT_UOPS_RETIRED, BOGUS), | ||
264 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 447 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
265 | }, | 448 | }, |
266 | [P4_EVENT_UOP_TYPE] = { | 449 | [P4_EVENT_UOP_TYPE] = { |
267 | .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE), | 450 | .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE), |
268 | .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, | 451 | .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 }, |
452 | .escr_emask = | ||
453 | P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGLOADS) | | ||
454 | P4_ESCR_EMASK_BIT(P4_EVENT_UOP_TYPE, TAGSTORES), | ||
269 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 455 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
270 | }, | 456 | }, |
271 | [P4_EVENT_BRANCH_RETIRED] = { | 457 | [P4_EVENT_BRANCH_RETIRED] = { |
272 | .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED), | 458 | .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED), |
273 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 459 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
460 | .escr_emask = | ||
461 | P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNP) | | ||
462 | P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMNM) | | ||
463 | P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTP) | | ||
464 | P4_ESCR_EMASK_BIT(P4_EVENT_BRANCH_RETIRED, MMTM), | ||
274 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 465 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
275 | }, | 466 | }, |
276 | [P4_EVENT_MISPRED_BRANCH_RETIRED] = { | 467 | [P4_EVENT_MISPRED_BRANCH_RETIRED] = { |
277 | .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED), | 468 | .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED), |
278 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, | 469 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, |
470 | .escr_emask = | ||
471 | P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS), | ||
279 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 472 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
280 | }, | 473 | }, |
281 | [P4_EVENT_X87_ASSIST] = { | 474 | [P4_EVENT_X87_ASSIST] = { |
282 | .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST), | 475 | .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST), |
283 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 476 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
477 | .escr_emask = | ||
478 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSU) | | ||
479 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, FPSO) | | ||
480 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAO) | | ||
481 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, POAU) | | ||
482 | P4_ESCR_EMASK_BIT(P4_EVENT_X87_ASSIST, PREA), | ||
284 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 483 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
285 | }, | 484 | }, |
286 | [P4_EVENT_MACHINE_CLEAR] = { | 485 | [P4_EVENT_MACHINE_CLEAR] = { |
287 | .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR), | 486 | .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR), |
288 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, | 487 | .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 }, |
488 | .escr_emask = | ||
489 | P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, CLEAR) | | ||
490 | P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, MOCLEAR) | | ||
491 | P4_ESCR_EMASK_BIT(P4_EVENT_MACHINE_CLEAR, SMCLEAR), | ||
289 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 492 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
290 | }, | 493 | }, |
291 | [P4_EVENT_INSTR_COMPLETED] = { | 494 | [P4_EVENT_INSTR_COMPLETED] = { |
292 | .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED), | 495 | .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED), |
293 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, | 496 | .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 }, |
497 | .escr_emask = | ||
498 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, NBOGUS) | | ||
499 | P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_COMPLETED, BOGUS), | ||
294 | .cntr = { {12, 13, 16}, {14, 15, 17} }, | 500 | .cntr = { {12, 13, 16}, {14, 15, 17} }, |
295 | }, | 501 | }, |
296 | }; | 502 | }; |
@@ -428,29 +634,73 @@ static u64 p4_pmu_event_map(int hw_event) | |||
428 | return config; | 634 | return config; |
429 | } | 635 | } |
430 | 636 | ||
637 | /* check cpu model specifics */ | ||
638 | static bool p4_event_match_cpu_model(unsigned int event_idx) | ||
639 | { | ||
640 | /* INSTR_COMPLETED event only exist for model 3, 4, 6 (Prescott) */ | ||
641 | if (event_idx == P4_EVENT_INSTR_COMPLETED) { | ||
642 | if (boot_cpu_data.x86_model != 3 && | ||
643 | boot_cpu_data.x86_model != 4 && | ||
644 | boot_cpu_data.x86_model != 6) | ||
645 | return false; | ||
646 | } | ||
647 | |||
648 | /* | ||
649 | * For info | ||
650 | * - IQ_ESCR0, IQ_ESCR1 only for models 1 and 2 | ||
651 | */ | ||
652 | |||
653 | return true; | ||
654 | } | ||
655 | |||
431 | static int p4_validate_raw_event(struct perf_event *event) | 656 | static int p4_validate_raw_event(struct perf_event *event) |
432 | { | 657 | { |
433 | unsigned int v; | 658 | unsigned int v, emask; |
434 | 659 | ||
435 | /* user data may have out-of-bound event index */ | 660 | /* User data may have out-of-bound event index */ |
436 | v = p4_config_unpack_event(event->attr.config); | 661 | v = p4_config_unpack_event(event->attr.config); |
437 | if (v >= ARRAY_SIZE(p4_event_bind_map)) { | 662 | if (v >= ARRAY_SIZE(p4_event_bind_map)) |
438 | pr_warning("P4 PMU: Unknown event code: %d\n", v); | 663 | return -EINVAL; |
664 | |||
665 | /* It may be unsupported: */ | ||
666 | if (!p4_event_match_cpu_model(v)) | ||
439 | return -EINVAL; | 667 | return -EINVAL; |
668 | |||
669 | /* | ||
670 | * NOTE: P4_CCCR_THREAD_ANY has not the same meaning as | ||
671 | * in Architectural Performance Monitoring, it means not | ||
672 | * on _which_ logical cpu to count but rather _when_, ie it | ||
673 | * depends on logical cpu state -- count event if one cpu active, | ||
674 | * none, both or any, so we just allow user to pass any value | ||
675 | * desired. | ||
676 | * | ||
677 | * In turn we always set Tx_OS/Tx_USR bits bound to logical | ||
678 | * cpu without their propagation to another cpu | ||
679 | */ | ||
680 | |||
681 | /* | ||
682 | * if an event is shared accross the logical threads | ||
683 | * the user needs special permissions to be able to use it | ||
684 | */ | ||
685 | if (p4_event_bind_map[v].shared) { | ||
686 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) | ||
687 | return -EACCES; | ||
440 | } | 688 | } |
441 | 689 | ||
690 | /* ESCR EventMask bits may be invalid */ | ||
691 | emask = p4_config_unpack_escr(event->attr.config) & P4_ESCR_EVENTMASK_MASK; | ||
692 | if (emask & ~p4_event_bind_map[v].escr_emask) | ||
693 | return -EINVAL; | ||
694 | |||
442 | /* | 695 | /* |
443 | * it may have some screwed PEBS bits | 696 | * it may have some invalid PEBS bits |
444 | */ | 697 | */ |
445 | if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE)) { | 698 | if (p4_config_pebs_has(event->attr.config, P4_PEBS_CONFIG_ENABLE)) |
446 | pr_warning("P4 PMU: PEBS are not supported yet\n"); | ||
447 | return -EINVAL; | 699 | return -EINVAL; |
448 | } | 700 | |
449 | v = p4_config_unpack_metric(event->attr.config); | 701 | v = p4_config_unpack_metric(event->attr.config); |
450 | if (v >= ARRAY_SIZE(p4_pebs_bind_map)) { | 702 | if (v >= ARRAY_SIZE(p4_pebs_bind_map)) |
451 | pr_warning("P4 PMU: Unknown metric code: %d\n", v); | ||
452 | return -EINVAL; | 703 | return -EINVAL; |
453 | } | ||
454 | 704 | ||
455 | return 0; | 705 | return 0; |
456 | } | 706 | } |
@@ -478,27 +728,21 @@ static int p4_hw_config(struct perf_event *event) | |||
478 | 728 | ||
479 | if (event->attr.type == PERF_TYPE_RAW) { | 729 | if (event->attr.type == PERF_TYPE_RAW) { |
480 | 730 | ||
731 | /* | ||
732 | * Clear bits we reserve to be managed by kernel itself | ||
733 | * and never allowed from a user space | ||
734 | */ | ||
735 | event->attr.config &= P4_CONFIG_MASK; | ||
736 | |||
481 | rc = p4_validate_raw_event(event); | 737 | rc = p4_validate_raw_event(event); |
482 | if (rc) | 738 | if (rc) |
483 | goto out; | 739 | goto out; |
484 | 740 | ||
485 | /* | 741 | /* |
486 | * We don't control raw events so it's up to the caller | ||
487 | * to pass sane values (and we don't count the thread number | ||
488 | * on HT machine but allow HT-compatible specifics to be | ||
489 | * passed on) | ||
490 | * | ||
491 | * Note that for RAW events we allow user to use P4_CCCR_RESERVED | 742 | * Note that for RAW events we allow user to use P4_CCCR_RESERVED |
492 | * bits since we keep additional info here (for cache events and etc) | 743 | * bits since we keep additional info here (for cache events and etc) |
493 | * | ||
494 | * XXX: HT wide things should check perf_paranoid_cpu() && | ||
495 | * CAP_SYS_ADMIN | ||
496 | */ | 744 | */ |
497 | event->hw.config |= event->attr.config & | 745 | event->hw.config |= event->attr.config; |
498 | (p4_config_pack_escr(P4_ESCR_MASK_HT) | | ||
499 | p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); | ||
500 | |||
501 | event->hw.config &= ~P4_CCCR_FORCE_OVF; | ||
502 | } | 746 | } |
503 | 747 | ||
504 | rc = x86_setup_perfctr(event); | 748 | rc = x86_setup_perfctr(event); |
@@ -660,8 +904,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) | |||
660 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 904 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
661 | int overflow; | 905 | int overflow; |
662 | 906 | ||
663 | if (!test_bit(idx, cpuc->active_mask)) | 907 | if (!test_bit(idx, cpuc->active_mask)) { |
908 | /* catch in-flight IRQs */ | ||
909 | if (__test_and_clear_bit(idx, cpuc->running)) | ||
910 | handled++; | ||
664 | continue; | 911 | continue; |
912 | } | ||
665 | 913 | ||
666 | event = cpuc->events[idx]; | 914 | event = cpuc->events[idx]; |
667 | hwc = &event->hw; | 915 | hwc = &event->hw; |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 34b4dad6f0b8..d49079515122 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
31 | const struct cpuid_bit *cb; | 31 | const struct cpuid_bit *cb; |
32 | 32 | ||
33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | 33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { |
34 | { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, | ||
34 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, | 35 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, |
35 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | 36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, |
36 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, | 37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index cd37469b54ee..3afb33f14d2d 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -257,14 +257,9 @@ do_ftrace_mod_code(unsigned long ip, void *new_code) | |||
257 | return mod_code_status; | 257 | return mod_code_status; |
258 | } | 258 | } |
259 | 259 | ||
260 | |||
261 | |||
262 | |||
263 | static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; | ||
264 | |||
265 | static unsigned char *ftrace_nop_replace(void) | 260 | static unsigned char *ftrace_nop_replace(void) |
266 | { | 261 | { |
267 | return ftrace_nop; | 262 | return ideal_nop5; |
268 | } | 263 | } |
269 | 264 | ||
270 | static int | 265 | static int |
@@ -338,62 +333,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func) | |||
338 | 333 | ||
339 | int __init ftrace_dyn_arch_init(void *data) | 334 | int __init ftrace_dyn_arch_init(void *data) |
340 | { | 335 | { |
341 | extern const unsigned char ftrace_test_p6nop[]; | ||
342 | extern const unsigned char ftrace_test_nop5[]; | ||
343 | extern const unsigned char ftrace_test_jmp[]; | ||
344 | int faulted = 0; | ||
345 | |||
346 | /* | ||
347 | * There is no good nop for all x86 archs. | ||
348 | * We will default to using the P6_NOP5, but first we | ||
349 | * will test to make sure that the nop will actually | ||
350 | * work on this CPU. If it faults, we will then | ||
351 | * go to a lesser efficient 5 byte nop. If that fails | ||
352 | * we then just use a jmp as our nop. This isn't the most | ||
353 | * efficient nop, but we can not use a multi part nop | ||
354 | * since we would then risk being preempted in the middle | ||
355 | * of that nop, and if we enabled tracing then, it might | ||
356 | * cause a system crash. | ||
357 | * | ||
358 | * TODO: check the cpuid to determine the best nop. | ||
359 | */ | ||
360 | asm volatile ( | ||
361 | "ftrace_test_jmp:" | ||
362 | "jmp ftrace_test_p6nop\n" | ||
363 | "nop\n" | ||
364 | "nop\n" | ||
365 | "nop\n" /* 2 byte jmp + 3 bytes */ | ||
366 | "ftrace_test_p6nop:" | ||
367 | P6_NOP5 | ||
368 | "jmp 1f\n" | ||
369 | "ftrace_test_nop5:" | ||
370 | ".byte 0x66,0x66,0x66,0x66,0x90\n" | ||
371 | "1:" | ||
372 | ".section .fixup, \"ax\"\n" | ||
373 | "2: movl $1, %0\n" | ||
374 | " jmp ftrace_test_nop5\n" | ||
375 | "3: movl $2, %0\n" | ||
376 | " jmp 1b\n" | ||
377 | ".previous\n" | ||
378 | _ASM_EXTABLE(ftrace_test_p6nop, 2b) | ||
379 | _ASM_EXTABLE(ftrace_test_nop5, 3b) | ||
380 | : "=r"(faulted) : "0" (faulted)); | ||
381 | |||
382 | switch (faulted) { | ||
383 | case 0: | ||
384 | pr_info("converting mcount calls to 0f 1f 44 00 00\n"); | ||
385 | memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); | ||
386 | break; | ||
387 | case 1: | ||
388 | pr_info("converting mcount calls to 66 66 66 66 90\n"); | ||
389 | memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); | ||
390 | break; | ||
391 | case 2: | ||
392 | pr_info("converting mcount calls to jmp . + 5\n"); | ||
393 | memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); | ||
394 | break; | ||
395 | } | ||
396 | |||
397 | /* The return code is retured via data */ | 336 | /* The return code is retured via data */ |
398 | *(unsigned long *)data = 0; | 337 | *(unsigned long *)data = 0; |
399 | 338 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 410fdb3f1939..7494999141b3 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -506,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) | |||
506 | { | 506 | { |
507 | unsigned int irq; | 507 | unsigned int irq; |
508 | 508 | ||
509 | irq = create_irq(); | 509 | irq = create_irq_nr(0, -1); |
510 | if (!irq) | 510 | if (!irq) |
511 | return -EINVAL; | 511 | return -EINVAL; |
512 | 512 | ||
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c new file mode 100644 index 000000000000..961b6b30ba90 --- /dev/null +++ b/arch/x86/kernel/jump_label.c | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * jump label x86 support | ||
3 | * | ||
4 | * Copyright (C) 2009 Jason Baron <jbaron@redhat.com> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/jump_label.h> | ||
8 | #include <linux/memory.h> | ||
9 | #include <linux/uaccess.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/jhash.h> | ||
13 | #include <linux/cpu.h> | ||
14 | #include <asm/kprobes.h> | ||
15 | #include <asm/alternative.h> | ||
16 | |||
17 | #ifdef HAVE_JUMP_LABEL | ||
18 | |||
19 | union jump_code_union { | ||
20 | char code[JUMP_LABEL_NOP_SIZE]; | ||
21 | struct { | ||
22 | char jump; | ||
23 | int offset; | ||
24 | } __attribute__((packed)); | ||
25 | }; | ||
26 | |||
27 | void arch_jump_label_transform(struct jump_entry *entry, | ||
28 | enum jump_label_type type) | ||
29 | { | ||
30 | union jump_code_union code; | ||
31 | |||
32 | if (type == JUMP_LABEL_ENABLE) { | ||
33 | code.jump = 0xe9; | ||
34 | code.offset = entry->target - | ||
35 | (entry->code + JUMP_LABEL_NOP_SIZE); | ||
36 | } else | ||
37 | memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE); | ||
38 | get_online_cpus(); | ||
39 | mutex_lock(&text_mutex); | ||
40 | text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); | ||
41 | mutex_unlock(&text_mutex); | ||
42 | put_online_cpus(); | ||
43 | } | ||
44 | |||
45 | void arch_jump_label_text_poke_early(jump_label_t addr) | ||
46 | { | ||
47 | text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE); | ||
48 | } | ||
49 | |||
50 | #endif | ||
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 770ebfb349e9..1cbd54c0df99 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -230,9 +230,6 @@ static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) | |||
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | 232 | ||
233 | /* Dummy buffers for kallsyms_lookup */ | ||
234 | static char __dummy_buf[KSYM_NAME_LEN]; | ||
235 | |||
236 | /* Check if paddr is at an instruction boundary */ | 233 | /* Check if paddr is at an instruction boundary */ |
237 | static int __kprobes can_probe(unsigned long paddr) | 234 | static int __kprobes can_probe(unsigned long paddr) |
238 | { | 235 | { |
@@ -241,7 +238,7 @@ static int __kprobes can_probe(unsigned long paddr) | |||
241 | struct insn insn; | 238 | struct insn insn; |
242 | kprobe_opcode_t buf[MAX_INSN_SIZE]; | 239 | kprobe_opcode_t buf[MAX_INSN_SIZE]; |
243 | 240 | ||
244 | if (!kallsyms_lookup(paddr, NULL, &offset, NULL, __dummy_buf)) | 241 | if (!kallsyms_lookup_size_offset(paddr, NULL, &offset)) |
245 | return 0; | 242 | return 0; |
246 | 243 | ||
247 | /* Decode instructions */ | 244 | /* Decode instructions */ |
@@ -1129,7 +1126,7 @@ static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr, | |||
1129 | *(unsigned long *)addr = val; | 1126 | *(unsigned long *)addr = val; |
1130 | } | 1127 | } |
1131 | 1128 | ||
1132 | void __kprobes kprobes_optinsn_template_holder(void) | 1129 | static void __used __kprobes kprobes_optinsn_template_holder(void) |
1133 | { | 1130 | { |
1134 | asm volatile ( | 1131 | asm volatile ( |
1135 | ".global optprobe_template_entry\n" | 1132 | ".global optprobe_template_entry\n" |
@@ -1221,7 +1218,8 @@ static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src) | |||
1221 | } | 1218 | } |
1222 | /* Check whether the address range is reserved */ | 1219 | /* Check whether the address range is reserved */ |
1223 | if (ftrace_text_reserved(src, src + len - 1) || | 1220 | if (ftrace_text_reserved(src, src + len - 1) || |
1224 | alternatives_text_reserved(src, src + len - 1)) | 1221 | alternatives_text_reserved(src, src + len - 1) || |
1222 | jump_label_text_reserved(src, src + len - 1)) | ||
1225 | return -EBUSY; | 1223 | return -EBUSY; |
1226 | 1224 | ||
1227 | return len; | 1225 | return len; |
@@ -1269,11 +1267,9 @@ static int __kprobes can_optimize(unsigned long paddr) | |||
1269 | unsigned long addr, size = 0, offset = 0; | 1267 | unsigned long addr, size = 0, offset = 0; |
1270 | struct insn insn; | 1268 | struct insn insn; |
1271 | kprobe_opcode_t buf[MAX_INSN_SIZE]; | 1269 | kprobe_opcode_t buf[MAX_INSN_SIZE]; |
1272 | /* Dummy buffers for lookup_symbol_attrs */ | ||
1273 | static char __dummy_buf[KSYM_NAME_LEN]; | ||
1274 | 1270 | ||
1275 | /* Lookup symbol including addr */ | 1271 | /* Lookup symbol including addr */ |
1276 | if (!kallsyms_lookup(paddr, &size, &offset, NULL, __dummy_buf)) | 1272 | if (!kallsyms_lookup_size_offset(paddr, &size, &offset)) |
1277 | return 0; | 1273 | return 0; |
1278 | 1274 | ||
1279 | /* Check there is enough space for a relative jump. */ | 1275 | /* Check there is enough space for a relative jump. */ |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index e0bc186d7501..8f2956091735 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -239,11 +239,13 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
239 | apply_paravirt(pseg, pseg + para->sh_size); | 239 | apply_paravirt(pseg, pseg + para->sh_size); |
240 | } | 240 | } |
241 | 241 | ||
242 | return module_bug_finalize(hdr, sechdrs, me); | 242 | /* make jump label nops */ |
243 | jump_label_apply_nops(me); | ||
244 | |||
245 | return 0; | ||
243 | } | 246 | } |
244 | 247 | ||
245 | void module_arch_cleanup(struct module *mod) | 248 | void module_arch_cleanup(struct module *mod) |
246 | { | 249 | { |
247 | alternatives_smp_module_del(mod); | 250 | alternatives_smp_module_del(mod); |
248 | module_bug_cleanup(mod); | ||
249 | } | 251 | } |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c3a4fbb2b996..00e167870f71 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -112,6 +112,7 @@ | |||
112 | #include <asm/numa_64.h> | 112 | #include <asm/numa_64.h> |
113 | #endif | 113 | #endif |
114 | #include <asm/mce.h> | 114 | #include <asm/mce.h> |
115 | #include <asm/alternative.h> | ||
115 | 116 | ||
116 | /* | 117 | /* |
117 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | 118 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. |
@@ -726,6 +727,7 @@ void __init setup_arch(char **cmdline_p) | |||
726 | { | 727 | { |
727 | int acpi = 0; | 728 | int acpi = 0; |
728 | int k8 = 0; | 729 | int k8 = 0; |
730 | unsigned long flags; | ||
729 | 731 | ||
730 | #ifdef CONFIG_X86_32 | 732 | #ifdef CONFIG_X86_32 |
731 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 733 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
@@ -1071,6 +1073,10 @@ void __init setup_arch(char **cmdline_p) | |||
1071 | x86_init.oem.banner(); | 1073 | x86_init.oem.banner(); |
1072 | 1074 | ||
1073 | mcheck_init(); | 1075 | mcheck_init(); |
1076 | |||
1077 | local_irq_save(flags); | ||
1078 | arch_init_ideal_nop5(); | ||
1079 | local_irq_restore(flags); | ||
1074 | } | 1080 | } |
1075 | 1081 | ||
1076 | #ifdef CONFIG_X86_32 | 1082 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 4c4508e8a204..a24c6cfdccc4 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -251,6 +251,8 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
251 | if (!(address >= VMALLOC_START && address < VMALLOC_END)) | 251 | if (!(address >= VMALLOC_START && address < VMALLOC_END)) |
252 | return -1; | 252 | return -1; |
253 | 253 | ||
254 | WARN_ON_ONCE(in_nmi()); | ||
255 | |||
254 | /* | 256 | /* |
255 | * Synchronize this task's top level page-table | 257 | * Synchronize this task's top level page-table |
256 | * with the 'reference' page table. | 258 | * with the 'reference' page table. |
@@ -369,6 +371,8 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
369 | if (!(address >= VMALLOC_START && address < VMALLOC_END)) | 371 | if (!(address >= VMALLOC_START && address < VMALLOC_END)) |
370 | return -1; | 372 | return -1; |
371 | 373 | ||
374 | WARN_ON_ONCE(in_nmi()); | ||
375 | |||
372 | /* | 376 | /* |
373 | * Copy kernel mappings over when needed. This can also | 377 | * Copy kernel mappings over when needed. This can also |
374 | * happen within a race in page table update. In the later | 378 | * happen within a race in page table update. In the later |
diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c index b3b531a4f8e5..d87dd6d042d6 100644 --- a/arch/x86/mm/kmemcheck/kmemcheck.c +++ b/arch/x86/mm/kmemcheck/kmemcheck.c | |||
@@ -631,6 +631,8 @@ bool kmemcheck_fault(struct pt_regs *regs, unsigned long address, | |||
631 | if (!pte) | 631 | if (!pte) |
632 | return false; | 632 | return false; |
633 | 633 | ||
634 | WARN_ON_ONCE(in_nmi()); | ||
635 | |||
634 | if (error_code & 2) | 636 | if (error_code & 2) |
635 | kmemcheck_access(regs, address, KMEMCHECK_WRITE); | 637 | kmemcheck_access(regs, address, KMEMCHECK_WRITE); |
636 | else | 638 | else |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 1a5353a753fc..b2bb5aa3b054 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -489,8 +489,9 @@ static void xen_hvm_setup_cpu_clockevents(void) | |||
489 | __init void xen_hvm_init_time_ops(void) | 489 | __init void xen_hvm_init_time_ops(void) |
490 | { | 490 | { |
491 | /* vector callback is needed otherwise we cannot receive interrupts | 491 | /* vector callback is needed otherwise we cannot receive interrupts |
492 | * on cpu > 0 */ | 492 | * on cpu > 0 and at this point we don't know how many cpus are |
493 | if (!xen_have_vector_callback && num_present_cpus() > 1) | 493 | * available */ |
494 | if (!xen_have_vector_callback) | ||
494 | return; | 495 | return; |
495 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { | 496 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { |
496 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," | 497 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 3b0cd4249671..eafc94f68d79 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -362,6 +362,18 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
362 | return 0; | 362 | return 0; |
363 | 363 | ||
364 | /* | 364 | /* |
365 | * Don't merge file system requests and discard requests | ||
366 | */ | ||
367 | if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD)) | ||
368 | return 0; | ||
369 | |||
370 | /* | ||
371 | * Don't merge discard requests and secure discard requests | ||
372 | */ | ||
373 | if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE)) | ||
374 | return 0; | ||
375 | |||
376 | /* | ||
365 | * not contiguous | 377 | * not contiguous |
366 | */ | 378 | */ |
367 | if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next)) | 379 | if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next)) |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b811f2173f6f..88681aca88c5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -105,7 +105,7 @@ config ACPI_EC_DEBUGFS | |||
105 | 105 | ||
106 | Be aware that using this interface can confuse your Embedded | 106 | Be aware that using this interface can confuse your Embedded |
107 | Controller in a way that a normal reboot is not enough. You then | 107 | Controller in a way that a normal reboot is not enough. You then |
108 | have to power of your system, and remove the laptop battery for | 108 | have to power off your system, and remove the laptop battery for |
109 | some seconds. | 109 | some seconds. |
110 | An Embedded Controller typically is available on laptops and reads | 110 | An Embedded Controller typically is available on laptops and reads |
111 | sensor values like battery state and temperature. | 111 | sensor values like battery state and temperature. |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b76848c80be3..6b115f6c4313 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device) | |||
382 | device_remove_file(&device->dev, &dev_attr_rrtime); | 382 | device_remove_file(&device->dev, &dev_attr_rrtime); |
383 | } | 383 | } |
384 | 384 | ||
385 | /* Query firmware how many CPUs should be idle */ | 385 | /* |
386 | static int acpi_pad_pur(acpi_handle handle, int *num_cpus) | 386 | * Query firmware how many CPUs should be idle |
387 | * return -1 on failure | ||
388 | */ | ||
389 | static int acpi_pad_pur(acpi_handle handle) | ||
387 | { | 390 | { |
388 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 391 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
389 | union acpi_object *package; | 392 | union acpi_object *package; |
390 | int rev, num, ret = -EINVAL; | 393 | int num = -1; |
391 | 394 | ||
392 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) | 395 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) |
393 | return -EINVAL; | 396 | return num; |
394 | 397 | ||
395 | if (!buffer.length || !buffer.pointer) | 398 | if (!buffer.length || !buffer.pointer) |
396 | return -EINVAL; | 399 | return num; |
397 | 400 | ||
398 | package = buffer.pointer; | 401 | package = buffer.pointer; |
399 | if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) | 402 | |
400 | goto out; | 403 | if (package->type == ACPI_TYPE_PACKAGE && |
401 | rev = package->package.elements[0].integer.value; | 404 | package->package.count == 2 && |
402 | num = package->package.elements[1].integer.value; | 405 | package->package.elements[0].integer.value == 1) /* rev 1 */ |
403 | if (rev != 1 || num < 0) | 406 | |
404 | goto out; | 407 | num = package->package.elements[1].integer.value; |
405 | *num_cpus = num; | 408 | |
406 | ret = 0; | ||
407 | out: | ||
408 | kfree(buffer.pointer); | 409 | kfree(buffer.pointer); |
409 | return ret; | 410 | return num; |
410 | } | 411 | } |
411 | 412 | ||
412 | /* Notify firmware how many CPUs are idle */ | 413 | /* Notify firmware how many CPUs are idle */ |
@@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) | |||
433 | uint32_t idle_cpus; | 434 | uint32_t idle_cpus; |
434 | 435 | ||
435 | mutex_lock(&isolated_cpus_lock); | 436 | mutex_lock(&isolated_cpus_lock); |
436 | if (acpi_pad_pur(handle, &num_cpus)) { | 437 | num_cpus = acpi_pad_pur(handle); |
438 | if (num_cpus < 0) { | ||
437 | mutex_unlock(&isolated_cpus_lock); | 439 | mutex_unlock(&isolated_cpus_lock); |
438 | return; | 440 | return; |
439 | } | 441 | } |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53a674f..7dad9160f209 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -854,6 +854,7 @@ struct acpi_bit_register_info { | |||
854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ | 854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ |
855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ | 855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ |
856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ | 856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ |
857 | ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ | ||
857 | ACPI_BITMASK_WAKE_STATUS) | 858 | ACPI_BITMASK_WAKE_STATUS) |
858 | 859 | ||
859 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 | 860 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 74c24d517f81..4093522eed45 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void) | |||
109 | * | 109 | * |
110 | * DESCRIPTION: Reacquire the interpreter execution region from within the | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | 111 | * interpreter code. Failure to enter the interpreter region is a |
112 | * fatal system error. Used in conjuction with | 112 | * fatal system error. Used in conjunction with |
113 | * relinquish_interpreter | 113 | * relinquish_interpreter |
114 | * | 114 | * |
115 | ******************************************************************************/ | 115 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 22cfcfbd9fff..491191e6cf69 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | |||
149 | 149 | ||
150 | /* | 150 | /* |
151 | * 16-, 32-, and 64-bit cases must use the move macros that perform | 151 | * 16-, 32-, and 64-bit cases must use the move macros that perform |
152 | * endian conversion and/or accomodate hardware that cannot perform | 152 | * endian conversion and/or accommodate hardware that cannot perform |
153 | * misaligned memory transfers | 153 | * misaligned memory transfers |
154 | */ | 154 | */ |
155 | case ACPI_RSC_MOVE16: | 155 | case ACPI_RSC_MOVE16: |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 907e350f1c7d..fca34ccfd294 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG | |||
34 | depends on ACPI_APEI | 34 | depends on ACPI_APEI |
35 | help | 35 | help |
36 | ERST is a way provided by APEI to save and retrieve hardware | 36 | ERST is a way provided by APEI to save and retrieve hardware |
37 | error infomation to and from a persistent store. Enable this | 37 | error information to and from a persistent store. Enable this |
38 | if you want to debugging and testing the ERST kernel support | 38 | if you want to debugging and testing the ERST kernel support |
39 | and firmware implementation. | 39 | and firmware implementation. |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 73fd0c7487c1..4a904a4bf05f 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub); | |||
445 | int apei_resources_request(struct apei_resources *resources, | 445 | int apei_resources_request(struct apei_resources *resources, |
446 | const char *desc) | 446 | const char *desc) |
447 | { | 447 | { |
448 | struct apei_res *res, *res_bak; | 448 | struct apei_res *res, *res_bak = NULL; |
449 | struct resource *r; | 449 | struct resource *r; |
450 | int rc; | ||
450 | 451 | ||
451 | apei_resources_sub(resources, &apei_resources_all); | 452 | rc = apei_resources_sub(resources, &apei_resources_all); |
453 | if (rc) | ||
454 | return rc; | ||
452 | 455 | ||
456 | rc = -EINVAL; | ||
453 | list_for_each_entry(res, &resources->iomem, list) { | 457 | list_for_each_entry(res, &resources->iomem, list) { |
454 | r = request_mem_region(res->start, res->end - res->start, | 458 | r = request_mem_region(res->start, res->end - res->start, |
455 | desc); | 459 | desc); |
@@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources, | |||
475 | } | 479 | } |
476 | } | 480 | } |
477 | 481 | ||
478 | apei_resources_merge(&apei_resources_all, resources); | 482 | rc = apei_resources_merge(&apei_resources_all, resources); |
483 | if (rc) { | ||
484 | pr_err(APEI_PFX "Fail to merge resources!\n"); | ||
485 | goto err_unmap_ioport; | ||
486 | } | ||
479 | 487 | ||
480 | return 0; | 488 | return 0; |
481 | err_unmap_ioport: | 489 | err_unmap_ioport: |
@@ -491,12 +499,13 @@ err_unmap_iomem: | |||
491 | break; | 499 | break; |
492 | release_mem_region(res->start, res->end - res->start); | 500 | release_mem_region(res->start, res->end - res->start); |
493 | } | 501 | } |
494 | return -EINVAL; | 502 | return rc; |
495 | } | 503 | } |
496 | EXPORT_SYMBOL_GPL(apei_resources_request); | 504 | EXPORT_SYMBOL_GPL(apei_resources_request); |
497 | 505 | ||
498 | void apei_resources_release(struct apei_resources *resources) | 506 | void apei_resources_release(struct apei_resources *resources) |
499 | { | 507 | { |
508 | int rc; | ||
500 | struct apei_res *res; | 509 | struct apei_res *res; |
501 | 510 | ||
502 | list_for_each_entry(res, &resources->iomem, list) | 511 | list_for_each_entry(res, &resources->iomem, list) |
@@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources) | |||
504 | list_for_each_entry(res, &resources->ioport, list) | 513 | list_for_each_entry(res, &resources->ioport, list) |
505 | release_region(res->start, res->end - res->start); | 514 | release_region(res->start, res->end - res->start); |
506 | 515 | ||
507 | apei_resources_sub(&apei_resources_all, resources); | 516 | rc = apei_resources_sub(&apei_resources_all, resources); |
517 | if (rc) | ||
518 | pr_err(APEI_PFX "Fail to sub resources!\n"); | ||
508 | } | 519 | } |
509 | EXPORT_SYMBOL_GPL(apei_resources_release); | 520 | EXPORT_SYMBOL_GPL(apei_resources_release); |
510 | 521 | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 465c885938ee..cf29df69380b 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, | |||
426 | 426 | ||
427 | static int einj_check_table(struct acpi_table_einj *einj_tab) | 427 | static int einj_check_table(struct acpi_table_einj *einj_tab) |
428 | { | 428 | { |
429 | if (einj_tab->header_length != sizeof(struct acpi_table_einj)) | 429 | if ((einj_tab->header_length != |
430 | (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) | ||
431 | && (einj_tab->header_length != sizeof(struct acpi_table_einj))) | ||
430 | return -EINVAL; | 432 | return -EINVAL; |
431 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) | 433 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) |
432 | return -EINVAL; | 434 | return -EINVAL; |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 5281ddda2777..da1228a9a544 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table debug support | 2 | * APEI Error Record Serialization Table debug support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. This file provide the | 5 | * information to and from a persistent store. This file provide the |
6 | * debugging/testing support for ERST kernel support and firmware | 6 | * debugging/testing support for ERST kernel support and firmware |
7 | * implementation. | 7 | * implementation. |
8 | * | 8 | * |
@@ -111,11 +111,13 @@ retry: | |||
111 | goto out; | 111 | goto out; |
112 | } | 112 | } |
113 | if (len > erst_dbg_buf_len) { | 113 | if (len > erst_dbg_buf_len) { |
114 | kfree(erst_dbg_buf); | 114 | void *p; |
115 | rc = -ENOMEM; | 115 | rc = -ENOMEM; |
116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | 116 | p = kmalloc(len, GFP_KERNEL); |
117 | if (!erst_dbg_buf) | 117 | if (!p) |
118 | goto out; | 118 | goto out; |
119 | kfree(erst_dbg_buf); | ||
120 | erst_dbg_buf = p; | ||
119 | erst_dbg_buf_len = len; | 121 | erst_dbg_buf_len = len; |
120 | goto retry; | 122 | goto retry; |
121 | } | 123 | } |
@@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | |||
150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | 152 | if (mutex_lock_interruptible(&erst_dbg_mutex)) |
151 | return -EINTR; | 153 | return -EINTR; |
152 | if (usize > erst_dbg_buf_len) { | 154 | if (usize > erst_dbg_buf_len) { |
153 | kfree(erst_dbg_buf); | 155 | void *p; |
154 | rc = -ENOMEM; | 156 | rc = -ENOMEM; |
155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | 157 | p = kmalloc(usize, GFP_KERNEL); |
156 | if (!erst_dbg_buf) | 158 | if (!p) |
157 | goto out; | 159 | goto out; |
160 | kfree(erst_dbg_buf); | ||
161 | erst_dbg_buf = p; | ||
158 | erst_dbg_buf_len = usize; | 162 | erst_dbg_buf_len = usize; |
159 | } | 163 | } |
160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | 164 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 18645f4e83cd..1211c03149e8 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table support | 2 | * APEI Error Record Serialization Table support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. | 5 | * information to and from a persistent store. |
6 | * | 6 | * |
7 | * For more information about ERST, please refer to ACPI Specification | 7 | * For more information about ERST, please refer to ACPI Specification |
8 | * version 4.0, section 17.4. | 8 | * version 4.0, section 17.4. |
@@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, | |||
266 | { | 266 | { |
267 | int rc; | 267 | int rc; |
268 | u64 offset; | 268 | u64 offset; |
269 | void *src, *dst; | ||
270 | |||
271 | /* ioremap does not work in interrupt context */ | ||
272 | if (in_interrupt()) { | ||
273 | pr_warning(ERST_PFX | ||
274 | "MOVE_DATA can not be used in interrupt context"); | ||
275 | return -EBUSY; | ||
276 | } | ||
269 | 277 | ||
270 | rc = __apei_exec_read_register(entry, &offset); | 278 | rc = __apei_exec_read_register(entry, &offset); |
271 | if (rc) | 279 | if (rc) |
272 | return rc; | 280 | return rc; |
273 | memmove((void *)ctx->dst_base + offset, | 281 | |
274 | (void *)ctx->src_base + offset, | 282 | src = ioremap(ctx->src_base + offset, ctx->var2); |
275 | ctx->var2); | 283 | if (!src) |
284 | return -ENOMEM; | ||
285 | dst = ioremap(ctx->dst_base + offset, ctx->var2); | ||
286 | if (!dst) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | memmove(dst, src, ctx->var2); | ||
290 | |||
291 | iounmap(src); | ||
292 | iounmap(dst); | ||
276 | 293 | ||
277 | return 0; | 294 | return 0; |
278 | } | 295 | } |
@@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable); | |||
750 | 767 | ||
751 | static int erst_check_table(struct acpi_table_erst *erst_tab) | 768 | static int erst_check_table(struct acpi_table_erst *erst_tab) |
752 | { | 769 | { |
753 | if (erst_tab->header_length != sizeof(struct acpi_table_erst)) | 770 | if ((erst_tab->header_length != |
771 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | ||
772 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | ||
754 | return -EINVAL; | 773 | return -EINVAL; |
755 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 774 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
756 | return -EINVAL; | 775 | return -EINVAL; |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 385a6059714a..0d505e59214d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
302 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
303 | int rc = -EINVAL; | 303 | int rc = -EINVAL; |
304 | 304 | ||
305 | generic = ghes_dev->dev.platform_data; | 305 | generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; |
306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
307 | return -ENODEV; | 307 | return -ENODEV; |
308 | 308 | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 343168d18266..1a3508a7fe03 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct acpi_hest_generic *generic; | ||
141 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
142 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
143 | int rc; | 142 | int rc; |
144 | 143 | ||
145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
146 | return 0; | 145 | return 0; |
147 | generic = (struct acpi_hest_generic *)hest_hdr; | 146 | |
148 | if (!generic->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
149 | return 0; | 148 | return 0; |
150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
151 | if (!ghes_dev) | 150 | if (!ghes_dev) |
152 | return -ENOMEM; | 151 | return -ENOMEM; |
153 | ghes_dev->dev.platform_data = generic; | 152 | |
153 | rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *)); | ||
154 | if (rc) | ||
155 | goto err; | ||
156 | |||
154 | rc = platform_device_add(ghes_dev); | 157 | rc = platform_device_add(ghes_dev); |
155 | if (rc) | 158 | if (rc) |
156 | goto err; | 159 | goto err; |
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 8f8bd736d4ff..542e53903891 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c | |||
@@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr, | |||
142 | list_add_tail_rcu(&map->list, &acpi_iomaps); | 142 | list_add_tail_rcu(&map->list, &acpi_iomaps); |
143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | 143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); |
144 | 144 | ||
145 | return vaddr + (paddr - pg_off); | 145 | return map->vaddr + (paddr - map->paddr); |
146 | err_unmap: | 146 | err_unmap: |
147 | iounmap(vaddr); | 147 | iounmap(vaddr); |
148 | return NULL; | 148 | return NULL; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dc58402b0a17..98417201e9ce 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
273 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 273 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
276 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
277 | POWER_SUPPLY_PROP_POWER_NOW, | 276 | POWER_SUPPLY_PROP_POWER_NOW, |
278 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 277 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
279 | POWER_SUPPLY_PROP_ENERGY_FULL, | 278 | POWER_SUPPLY_PROP_ENERGY_FULL, |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c4..f7619600270a 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
183 | { | 183 | { |
184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
185 | acpi_osi_setup("!Windows 2006"); | 185 | acpi_osi_setup("!Windows 2006"); |
186 | acpi_osi_setup("!Windows 2006 SP1"); | ||
187 | acpi_osi_setup("!Windows 2006 SP2"); | ||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | 190 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) |
@@ -226,6 +228,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
226 | }, | 228 | }, |
227 | }, | 229 | }, |
228 | { | 230 | { |
231 | .callback = dmi_disable_osi_vista, | ||
232 | .ident = "Toshiba Satellite L355", | ||
233 | .matches = { | ||
234 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
235 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
236 | }, | ||
237 | }, | ||
238 | { | ||
229 | .callback = dmi_disable_osi_win7, | 239 | .callback = dmi_disable_osi_win7, |
230 | .ident = "ASUS K50IJ", | 240 | .ident = "ASUS K50IJ", |
231 | .matches = { | 241 | .matches = { |
@@ -233,6 +243,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
233 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | 243 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), |
234 | }, | 244 | }, |
235 | }, | 245 | }, |
246 | { | ||
247 | .callback = dmi_disable_osi_vista, | ||
248 | .ident = "Toshiba P305D", | ||
249 | .matches = { | ||
250 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
251 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
252 | }, | ||
253 | }, | ||
236 | 254 | ||
237 | /* | 255 | /* |
238 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 256 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 5c221ab535d5..310e3b9749cb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | 55 | static int set_power_nocheck(const struct dmi_system_id *id) |
56 | { | 56 | { |
57 | printk(KERN_NOTICE PREFIX "%s detected - " | 57 | printk(KERN_NOTICE PREFIX "%s detected - " |
58 | "disable power check in power transistion\n", id->ident); | 58 | "disable power check in power transition\n", id->ident); |
59 | acpi_power_nocheck = 1; | 59 | acpi_power_nocheck = 1; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
@@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id) | |||
80 | 80 | ||
81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { | 81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { |
82 | /* | 82 | /* |
83 | * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. | 83 | * Invoke DSDT corruption work-around on all Toshiba Satellite. |
84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 | 84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 |
85 | */ | 85 | */ |
86 | { | 86 | { |
87 | .callback = set_copy_dsdt, | 87 | .callback = set_copy_dsdt, |
88 | .ident = "TOSHIBA Satellite A505", | 88 | .ident = "TOSHIBA Satellite", |
89 | .matches = { | 89 | .matches = { |
90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), | 91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
92 | }, | ||
93 | }, | ||
94 | { | ||
95 | .callback = set_copy_dsdt, | ||
96 | .ident = "TOSHIBA Satellite L505D", | ||
97 | .matches = { | ||
98 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), | ||
100 | }, | 92 | }, |
101 | }, | 93 | }, |
102 | {} | 94 | {} |
@@ -1027,7 +1019,7 @@ static int __init acpi_init(void) | |||
1027 | 1019 | ||
1028 | /* | 1020 | /* |
1029 | * If the laptop falls into the DMI check table, the power state check | 1021 | * If the laptop falls into the DMI check table, the power state check |
1030 | * will be disabled in the course of device power transistion. | 1022 | * will be disabled in the course of device power transition. |
1031 | */ | 1023 | */ |
1032 | dmi_check_system(power_nocheck_dmi_table); | 1024 | dmi_check_system(power_nocheck_dmi_table); |
1033 | 1025 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8a3b840c0bb2..d94d2953c974 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -369,7 +369,9 @@ static void __exit acpi_fan_exit(void) | |||
369 | 369 | ||
370 | acpi_bus_unregister_driver(&acpi_fan_driver); | 370 | acpi_bus_unregister_driver(&acpi_fan_driver); |
371 | 371 | ||
372 | #ifdef CONFIG_ACPI_PROCFS | ||
372 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | 373 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); |
374 | #endif | ||
373 | 375 | ||
374 | return; | 376 | return; |
375 | } | 377 | } |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9699aaed109..b618f888d66b 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -29,12 +29,6 @@ static int set_no_mwait(const struct dmi_system_id *id) | |||
29 | 29 | ||
30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | 30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { |
31 | { | 31 | { |
32 | set_no_mwait, "IFL91 board", { | ||
33 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
34 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
35 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
36 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
37 | { | ||
38 | set_no_mwait, "Extensa 5220", { | 32 | set_no_mwait, "Extensa 5220", { |
39 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
40 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 34 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 156021892389..347eb21b2353 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -850,7 +850,7 @@ static int __init acpi_processor_init(void) | |||
850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
851 | acpi_idle_driver.name); | 851 | acpi_idle_driver.name); |
852 | } else { | 852 | } else { |
853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | 853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", |
854 | cpuidle_get_driver()->name); | 854 | cpuidle_get_driver()->name); |
855 | } | 855 | } |
856 | 856 | ||
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ba1bd263d903..3a73a93596e8 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
447 | if (!try_module_get(calling_module)) | 447 | if (!try_module_get(calling_module)) |
448 | return -EINVAL; | 448 | return -EINVAL; |
449 | 449 | ||
450 | /* is_done is set to negative if an error occured, | 450 | /* is_done is set to negative if an error occurred, |
451 | * and to postitive if _no_ error occured, but SMM | 451 | * and to postitive if _no_ error occurred, but SMM |
452 | * was already notified. This avoids double notification | 452 | * was already notified. This avoids double notification |
453 | * which might lead to unexpected results... | 453 | * which might lead to unexpected results... |
454 | */ | 454 | */ |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cf82989ae756..4754ff6e70e6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
367 | { | ||
368 | acpi_nvs_nosave(); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
366 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 372 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
367 | { | 373 | { |
368 | .callback = init_old_suspend_ordering, | 374 | .callback = init_old_suspend_ordering, |
@@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
397 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | 403 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), |
398 | }, | 404 | }, |
399 | }, | 405 | }, |
406 | { | ||
407 | .callback = init_nvs_nosave, | ||
408 | .ident = "Sony Vaio VGN-SR11M", | ||
409 | .matches = { | ||
410 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
411 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
412 | }, | ||
413 | }, | ||
414 | { | ||
415 | .callback = init_nvs_nosave, | ||
416 | .ident = "Everex StepNote Series", | ||
417 | .matches = { | ||
418 | DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
419 | DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
420 | }, | ||
421 | }, | ||
400 | {}, | 422 | {}, |
401 | }; | 423 | }; |
402 | #endif /* CONFIG_SUSPEND */ | 424 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 68e2e4582fa2..f8588f81048a 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { | |||
100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | 100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | 103 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) |
104 | { | 104 | { |
105 | int result = 0; | 105 | int result = 0; |
106 | int i; | 106 | int i; |
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | |||
128 | return result; | 128 | return result; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | 131 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) |
132 | { | 132 | { |
133 | int result = 0; | 133 | int result = 0; |
134 | int i; | 134 | int i; |
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) | |||
149 | return result; | 149 | return result; |
150 | } | 150 | } |
151 | 151 | ||
152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | 152 | static struct kernel_param_ops param_ops_debug_layer = { |
153 | &acpi_dbg_layer, 0644); | 153 | .set = param_set_uint, |
154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | 154 | .get = param_get_debug_layer, |
155 | &acpi_dbg_level, 0644); | 155 | }; |
156 | |||
157 | static struct kernel_param_ops param_ops_debug_level = { | ||
158 | .set = param_set_uint, | ||
159 | .get = param_get_debug_level, | ||
160 | }; | ||
161 | |||
162 | module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); | ||
163 | module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); | ||
156 | 164 | ||
157 | static char trace_method_name[6]; | 165 | static char trace_method_name[6]; |
158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | 166 | module_param_string(trace_method_name, trace_method_name, 6, 0644); |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c5fef01b3c95..b83676126598 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
59 | "support\n")); | 59 | "support\n")); |
60 | *cap |= ACPI_VIDEO_BACKLIGHT; | 60 | *cap |= ACPI_VIDEO_BACKLIGHT; |
61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | 61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) |
62 | printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " | 62 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " |
63 | "control misses _BQC function\n"); | 63 | "cannot determine initial brightness\n"); |
64 | /* We have backlight support, no need to scan further */ | 64 | /* We have backlight support, no need to scan further */ |
65 | return AE_CTRL_TERMINATE; | 65 | return AE_CTRL_TERMINATE; |
66 | } | 66 | } |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ff1c945fba98..99d0e5a51148 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -90,6 +90,10 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | |||
90 | static int ahci_pci_device_resume(struct pci_dev *pdev); | 90 | static int ahci_pci_device_resume(struct pci_dev *pdev); |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | static struct scsi_host_template ahci_sht = { | ||
94 | AHCI_SHT("ahci"), | ||
95 | }; | ||
96 | |||
93 | static struct ata_port_operations ahci_vt8251_ops = { | 97 | static struct ata_port_operations ahci_vt8251_ops = { |
94 | .inherits = &ahci_ops, | 98 | .inherits = &ahci_ops, |
95 | .hardreset = ahci_vt8251_hardreset, | 99 | .hardreset = ahci_vt8251_hardreset, |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 474427b6f99f..e5fdeebf9ef0 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -298,7 +298,17 @@ struct ahci_host_priv { | |||
298 | 298 | ||
299 | extern int ahci_ignore_sss; | 299 | extern int ahci_ignore_sss; |
300 | 300 | ||
301 | extern struct scsi_host_template ahci_sht; | 301 | extern struct device_attribute *ahci_shost_attrs[]; |
302 | extern struct device_attribute *ahci_sdev_attrs[]; | ||
303 | |||
304 | #define AHCI_SHT(drv_name) \ | ||
305 | ATA_NCQ_SHT(drv_name), \ | ||
306 | .can_queue = AHCI_MAX_CMDS - 1, \ | ||
307 | .sg_tablesize = AHCI_MAX_SG, \ | ||
308 | .dma_boundary = AHCI_DMA_BOUNDARY, \ | ||
309 | .shost_attrs = ahci_shost_attrs, \ | ||
310 | .sdev_attrs = ahci_sdev_attrs | ||
311 | |||
302 | extern struct ata_port_operations ahci_ops; | 312 | extern struct ata_port_operations ahci_ops; |
303 | 313 | ||
304 | void ahci_save_initial_config(struct device *dev, | 314 | void ahci_save_initial_config(struct device *dev, |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 4e97f33cca44..84b643270e7a 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -23,6 +23,10 @@ | |||
23 | #include <linux/ahci_platform.h> | 23 | #include <linux/ahci_platform.h> |
24 | #include "ahci.h" | 24 | #include "ahci.h" |
25 | 25 | ||
26 | static struct scsi_host_template ahci_platform_sht = { | ||
27 | AHCI_SHT("ahci_platform"), | ||
28 | }; | ||
29 | |||
26 | static int __init ahci_probe(struct platform_device *pdev) | 30 | static int __init ahci_probe(struct platform_device *pdev) |
27 | { | 31 | { |
28 | struct device *dev = &pdev->dev; | 32 | struct device *dev = &pdev->dev; |
@@ -145,7 +149,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
145 | ahci_print_info(host, "platform"); | 149 | ahci_print_info(host, "platform"); |
146 | 150 | ||
147 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, | 151 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, |
148 | &ahci_sht); | 152 | &ahci_platform_sht); |
149 | if (rc) | 153 | if (rc) |
150 | goto err0; | 154 | goto err0; |
151 | 155 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 68dc6785472f..8eea309ea212 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -121,7 +121,7 @@ static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | |||
121 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, | 121 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
122 | ahci_read_em_buffer, ahci_store_em_buffer); | 122 | ahci_read_em_buffer, ahci_store_em_buffer); |
123 | 123 | ||
124 | static struct device_attribute *ahci_shost_attrs[] = { | 124 | struct device_attribute *ahci_shost_attrs[] = { |
125 | &dev_attr_link_power_management_policy, | 125 | &dev_attr_link_power_management_policy, |
126 | &dev_attr_em_message_type, | 126 | &dev_attr_em_message_type, |
127 | &dev_attr_em_message, | 127 | &dev_attr_em_message, |
@@ -132,22 +132,14 @@ static struct device_attribute *ahci_shost_attrs[] = { | |||
132 | &dev_attr_em_buffer, | 132 | &dev_attr_em_buffer, |
133 | NULL | 133 | NULL |
134 | }; | 134 | }; |
135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); | ||
135 | 136 | ||
136 | static struct device_attribute *ahci_sdev_attrs[] = { | 137 | struct device_attribute *ahci_sdev_attrs[] = { |
137 | &dev_attr_sw_activity, | 138 | &dev_attr_sw_activity, |
138 | &dev_attr_unload_heads, | 139 | &dev_attr_unload_heads, |
139 | NULL | 140 | NULL |
140 | }; | 141 | }; |
141 | 142 | EXPORT_SYMBOL_GPL(ahci_sdev_attrs); | |
142 | struct scsi_host_template ahci_sht = { | ||
143 | ATA_NCQ_SHT("ahci"), | ||
144 | .can_queue = AHCI_MAX_CMDS - 1, | ||
145 | .sg_tablesize = AHCI_MAX_SG, | ||
146 | .dma_boundary = AHCI_DMA_BOUNDARY, | ||
147 | .shost_attrs = ahci_shost_attrs, | ||
148 | .sdev_attrs = ahci_sdev_attrs, | ||
149 | }; | ||
150 | EXPORT_SYMBOL_GPL(ahci_sht); | ||
151 | 143 | ||
152 | struct ata_port_operations ahci_ops = { | 144 | struct ata_port_operations ahci_ops = { |
153 | .inherits = &sata_pmp_port_ops, | 145 | .inherits = &sata_pmp_port_ops, |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index b1cbeb59bb76..37a2bb595076 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2369,7 +2369,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | |||
2369 | pkt_shrink_pktlist(pd); | 2369 | pkt_shrink_pktlist(pd); |
2370 | } | 2370 | } |
2371 | 2371 | ||
2372 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) | 2372 | static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor) |
2373 | { | 2373 | { |
2374 | if (dev_minor >= MAX_WRITERS) | 2374 | if (dev_minor >= MAX_WRITERS) |
2375 | return NULL; | 2375 | return NULL; |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3822b4f49c84..7bd7c45b53ef 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -305,6 +305,9 @@ static int num_force_kipmid; | |||
305 | #ifdef CONFIG_PCI | 305 | #ifdef CONFIG_PCI |
306 | static int pci_registered; | 306 | static int pci_registered; |
307 | #endif | 307 | #endif |
308 | #ifdef CONFIG_ACPI | ||
309 | static int pnp_registered; | ||
310 | #endif | ||
308 | #ifdef CONFIG_PPC_OF | 311 | #ifdef CONFIG_PPC_OF |
309 | static int of_registered; | 312 | static int of_registered; |
310 | #endif | 313 | #endif |
@@ -2126,7 +2129,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2126 | { | 2129 | { |
2127 | struct acpi_device *acpi_dev; | 2130 | struct acpi_device *acpi_dev; |
2128 | struct smi_info *info; | 2131 | struct smi_info *info; |
2129 | struct resource *res; | 2132 | struct resource *res, *res_second; |
2130 | acpi_handle handle; | 2133 | acpi_handle handle; |
2131 | acpi_status status; | 2134 | acpi_status status; |
2132 | unsigned long long tmp; | 2135 | unsigned long long tmp; |
@@ -2182,13 +2185,13 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2182 | info->io.addr_data = res->start; | 2185 | info->io.addr_data = res->start; |
2183 | 2186 | ||
2184 | info->io.regspacing = DEFAULT_REGSPACING; | 2187 | info->io.regspacing = DEFAULT_REGSPACING; |
2185 | res = pnp_get_resource(dev, | 2188 | res_second = pnp_get_resource(dev, |
2186 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? | 2189 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? |
2187 | IORESOURCE_IO : IORESOURCE_MEM, | 2190 | IORESOURCE_IO : IORESOURCE_MEM, |
2188 | 1); | 2191 | 1); |
2189 | if (res) { | 2192 | if (res_second) { |
2190 | if (res->start > info->io.addr_data) | 2193 | if (res_second->start > info->io.addr_data) |
2191 | info->io.regspacing = res->start - info->io.addr_data; | 2194 | info->io.regspacing = res_second->start - info->io.addr_data; |
2192 | } | 2195 | } |
2193 | info->io.regsize = DEFAULT_REGSPACING; | 2196 | info->io.regsize = DEFAULT_REGSPACING; |
2194 | info->io.regshift = 0; | 2197 | info->io.regshift = 0; |
@@ -3359,6 +3362,7 @@ static __devinit int init_ipmi_si(void) | |||
3359 | 3362 | ||
3360 | #ifdef CONFIG_ACPI | 3363 | #ifdef CONFIG_ACPI |
3361 | pnp_register_driver(&ipmi_pnp_driver); | 3364 | pnp_register_driver(&ipmi_pnp_driver); |
3365 | pnp_registered = 1; | ||
3362 | #endif | 3366 | #endif |
3363 | 3367 | ||
3364 | #ifdef CONFIG_DMI | 3368 | #ifdef CONFIG_DMI |
@@ -3526,7 +3530,8 @@ static __exit void cleanup_ipmi_si(void) | |||
3526 | pci_unregister_driver(&ipmi_pci_driver); | 3530 | pci_unregister_driver(&ipmi_pci_driver); |
3527 | #endif | 3531 | #endif |
3528 | #ifdef CONFIG_ACPI | 3532 | #ifdef CONFIG_ACPI |
3529 | pnp_unregister_driver(&ipmi_pnp_driver); | 3533 | if (pnp_registered) |
3534 | pnp_unregister_driver(&ipmi_pnp_driver); | ||
3530 | #endif | 3535 | #endif |
3531 | 3536 | ||
3532 | #ifdef CONFIG_PPC_OF | 3537 | #ifdef CONFIG_PPC_OF |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c2408bbe9c2e..f508690eb958 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -80,7 +80,7 @@ | |||
80 | * Limiting Performance Impact | 80 | * Limiting Performance Impact |
81 | * --------------------------- | 81 | * --------------------------- |
82 | * C states, especially those with large exit latencies, can have a real | 82 | * C states, especially those with large exit latencies, can have a real |
83 | * noticable impact on workloads, which is not acceptable for most sysadmins, | 83 | * noticeable impact on workloads, which is not acceptable for most sysadmins, |
84 | * and in addition, less performance has a power price of its own. | 84 | * and in addition, less performance has a power price of its own. |
85 | * | 85 | * |
86 | * As a general rule of thumb, menu assumes that the following heuristic | 86 | * As a general rule of thumb, menu assumes that the following heuristic |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 86c5ae9fde34..411d5bf50fc4 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -162,7 +162,7 @@ static int mv_is_err_intr(u32 intr_cause) | |||
162 | 162 | ||
163 | static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) | 163 | static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) |
164 | { | 164 | { |
165 | u32 val = (1 << (1 + (chan->idx * 16))); | 165 | u32 val = ~(1 << (chan->idx * 16)); |
166 | dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); | 166 | dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); |
167 | __raw_writel(val, XOR_INTR_CAUSE(chan)); | 167 | __raw_writel(val, XOR_INTR_CAUSE(chan)); |
168 | } | 168 | } |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index fb64cf36ba61..eb6b54dbb806 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
580 | 580 | ||
581 | sh_chan = to_sh_chan(chan); | 581 | sh_chan = to_sh_chan(chan); |
582 | param = chan->private; | 582 | param = chan->private; |
583 | slave_addr = param->config->addr; | ||
584 | 583 | ||
585 | /* Someone calling slave DMA on a public channel? */ | 584 | /* Someone calling slave DMA on a public channel? */ |
586 | if (!param || !sg_len) { | 585 | if (!param || !sg_len) { |
@@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
589 | return NULL; | 588 | return NULL; |
590 | } | 589 | } |
591 | 590 | ||
591 | slave_addr = param->config->addr; | ||
592 | |||
592 | /* | 593 | /* |
593 | * if (param != NULL), this is a successfully requested slave channel, | 594 | * if (param != NULL), this is a successfully requested slave channel, |
594 | * therefore param->config != NULL too. | 595 | * therefore param->config != NULL too. |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 3630308e7b81..6b21e25f7a84 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -339,6 +339,9 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci) | |||
339 | { | 339 | { |
340 | int status; | 340 | int status; |
341 | 341 | ||
342 | if (mci->op_state != OP_RUNNING_POLL) | ||
343 | return; | ||
344 | |||
342 | status = cancel_delayed_work(&mci->work); | 345 | status = cancel_delayed_work(&mci->work); |
343 | if (status == 0) { | 346 | if (status == 0) { |
344 | debugf0("%s() not canceled, flush the queue\n", | 347 | debugf0("%s() not canceled, flush the queue\n", |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0187d16dd7c..0fd5b85a0f75 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1140,6 +1140,7 @@ static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { | |||
1140 | ATTR_COUNTER(0), | 1140 | ATTR_COUNTER(0), |
1141 | ATTR_COUNTER(1), | 1141 | ATTR_COUNTER(1), |
1142 | ATTR_COUNTER(2), | 1142 | ATTR_COUNTER(2), |
1143 | { .attr = { .name = NULL } } | ||
1143 | }; | 1144 | }; |
1144 | 1145 | ||
1145 | static struct mcidev_sysfs_group i7core_udimm_counters = { | 1146 | static struct mcidev_sysfs_group i7core_udimm_counters = { |
diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c index 55d03ed05000..529a0dbe9fc6 100644 --- a/drivers/gpu/drm/drm_buffer.c +++ b/drivers/gpu/drm/drm_buffer.c | |||
@@ -98,8 +98,8 @@ EXPORT_SYMBOL(drm_buffer_alloc); | |||
98 | * user_data: A pointer the data that is copied to the buffer. | 98 | * user_data: A pointer the data that is copied to the buffer. |
99 | * size: The Number of bytes to copy. | 99 | * size: The Number of bytes to copy. |
100 | */ | 100 | */ |
101 | extern int drm_buffer_copy_from_user(struct drm_buffer *buf, | 101 | int drm_buffer_copy_from_user(struct drm_buffer *buf, |
102 | void __user *user_data, int size) | 102 | void __user *user_data, int size) |
103 | { | 103 | { |
104 | int nr_pages = size / PAGE_SIZE + 1; | 104 | int nr_pages = size / PAGE_SIZE + 1; |
105 | int idx; | 105 | int idx; |
@@ -163,7 +163,7 @@ void *drm_buffer_read_object(struct drm_buffer *buf, | |||
163 | { | 163 | { |
164 | int idx = drm_buffer_index(buf); | 164 | int idx = drm_buffer_index(buf); |
165 | int page = drm_buffer_page(buf); | 165 | int page = drm_buffer_page(buf); |
166 | void *obj = 0; | 166 | void *obj = NULL; |
167 | 167 | ||
168 | if (idx + objsize <= PAGE_SIZE) { | 168 | if (idx + objsize <= PAGE_SIZE) { |
169 | obj = &buf->data[page][idx]; | 169 | obj = &buf->data[page][idx]; |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510df..5663d2719063 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | 149 | ||
150 | kref_init(&obj->refcount); | 150 | kref_init(&obj->refcount); |
151 | kref_init(&obj->handlecount); | 151 | atomic_set(&obj->handle_count, 0); |
152 | obj->size = size; | 152 | obj->size = size; |
153 | 153 | ||
154 | atomic_inc(&dev->object_count); | 154 | atomic_inc(&dev->object_count); |
@@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref) | |||
462 | } | 462 | } |
463 | EXPORT_SYMBOL(drm_gem_object_free); | 463 | EXPORT_SYMBOL(drm_gem_object_free); |
464 | 464 | ||
465 | /** | ||
466 | * Called after the last reference to the object has been lost. | ||
467 | * Must be called without holding struct_mutex | ||
468 | * | ||
469 | * Frees the object | ||
470 | */ | ||
471 | void | ||
472 | drm_gem_object_free_unlocked(struct kref *kref) | ||
473 | { | ||
474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
475 | struct drm_device *dev = obj->dev; | ||
476 | |||
477 | if (dev->driver->gem_free_object_unlocked != NULL) | ||
478 | dev->driver->gem_free_object_unlocked(obj); | ||
479 | else if (dev->driver->gem_free_object != NULL) { | ||
480 | mutex_lock(&dev->struct_mutex); | ||
481 | dev->driver->gem_free_object(obj); | ||
482 | mutex_unlock(&dev->struct_mutex); | ||
483 | } | ||
484 | } | ||
485 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
486 | |||
487 | static void drm_gem_object_ref_bug(struct kref *list_kref) | 465 | static void drm_gem_object_ref_bug(struct kref *list_kref) |
488 | { | 466 | { |
489 | BUG(); | 467 | BUG(); |
@@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref) | |||
496 | * called before drm_gem_object_free or we'll be touching | 474 | * called before drm_gem_object_free or we'll be touching |
497 | * freed memory | 475 | * freed memory |
498 | */ | 476 | */ |
499 | void | 477 | void drm_gem_object_handle_free(struct drm_gem_object *obj) |
500 | drm_gem_object_handle_free(struct kref *kref) | ||
501 | { | 478 | { |
502 | struct drm_gem_object *obj = container_of(kref, | ||
503 | struct drm_gem_object, | ||
504 | handlecount); | ||
505 | struct drm_device *dev = obj->dev; | 479 | struct drm_device *dev = obj->dev; |
506 | 480 | ||
507 | /* Remove any name for this object */ | 481 | /* Remove any name for this object */ |
@@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma) | |||
528 | struct drm_gem_object *obj = vma->vm_private_data; | 502 | struct drm_gem_object *obj = vma->vm_private_data; |
529 | 503 | ||
530 | drm_gem_object_reference(obj); | 504 | drm_gem_object_reference(obj); |
505 | |||
506 | mutex_lock(&obj->dev->struct_mutex); | ||
507 | drm_vm_open_locked(vma); | ||
508 | mutex_unlock(&obj->dev->struct_mutex); | ||
531 | } | 509 | } |
532 | EXPORT_SYMBOL(drm_gem_vm_open); | 510 | EXPORT_SYMBOL(drm_gem_vm_open); |
533 | 511 | ||
@@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma) | |||
535 | { | 513 | { |
536 | struct drm_gem_object *obj = vma->vm_private_data; | 514 | struct drm_gem_object *obj = vma->vm_private_data; |
537 | 515 | ||
538 | drm_gem_object_unreference_unlocked(obj); | 516 | mutex_lock(&obj->dev->struct_mutex); |
517 | drm_vm_close_locked(vma); | ||
518 | drm_gem_object_unreference(obj); | ||
519 | mutex_unlock(&obj->dev->struct_mutex); | ||
539 | } | 520 | } |
540 | EXPORT_SYMBOL(drm_gem_vm_close); | 521 | EXPORT_SYMBOL(drm_gem_vm_close); |
541 | 522 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c7827243..974e970ce3f8 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
255 | 255 | ||
256 | seq_printf(m, "%6d %8zd %7d %8d\n", | 256 | seq_printf(m, "%6d %8zd %7d %8d\n", |
257 | obj->name, obj->size, | 257 | obj->name, obj->size, |
258 | atomic_read(&obj->handlecount.refcount), | 258 | atomic_read(&obj->handle_count), |
259 | atomic_read(&obj->refcount.refcount)); | 259 | atomic_read(&obj->refcount.refcount)); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index fda67468e603..5df450683aab 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
433 | mutex_unlock(&dev->struct_mutex); | 433 | mutex_unlock(&dev->struct_mutex); |
434 | } | 434 | } |
435 | 435 | ||
436 | /** | 436 | void drm_vm_close_locked(struct vm_area_struct *vma) |
437 | * \c close method for all virtual memory types. | ||
438 | * | ||
439 | * \param vma virtual memory area. | ||
440 | * | ||
441 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
442 | * free it. | ||
443 | */ | ||
444 | static void drm_vm_close(struct vm_area_struct *vma) | ||
445 | { | 437 | { |
446 | struct drm_file *priv = vma->vm_file->private_data; | 438 | struct drm_file *priv = vma->vm_file->private_data; |
447 | struct drm_device *dev = priv->minor->dev; | 439 | struct drm_device *dev = priv->minor->dev; |
@@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
451 | vma->vm_start, vma->vm_end - vma->vm_start); | 443 | vma->vm_start, vma->vm_end - vma->vm_start); |
452 | atomic_dec(&dev->vma_count); | 444 | atomic_dec(&dev->vma_count); |
453 | 445 | ||
454 | mutex_lock(&dev->struct_mutex); | ||
455 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { | 446 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { |
456 | if (pt->vma == vma) { | 447 | if (pt->vma == vma) { |
457 | list_del(&pt->head); | 448 | list_del(&pt->head); |
@@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
459 | break; | 450 | break; |
460 | } | 451 | } |
461 | } | 452 | } |
453 | } | ||
454 | |||
455 | /** | ||
456 | * \c close method for all virtual memory types. | ||
457 | * | ||
458 | * \param vma virtual memory area. | ||
459 | * | ||
460 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
461 | * free it. | ||
462 | */ | ||
463 | static void drm_vm_close(struct vm_area_struct *vma) | ||
464 | { | ||
465 | struct drm_file *priv = vma->vm_file->private_data; | ||
466 | struct drm_device *dev = priv->minor->dev; | ||
467 | |||
468 | mutex_lock(&dev->struct_mutex); | ||
469 | drm_vm_close_locked(vma); | ||
462 | mutex_unlock(&dev->struct_mutex); | 470 | mutex_unlock(&dev->struct_mutex); |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 61b4caf220fa..fb07e73581e8 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
116 | static const struct file_operations i810_buffer_fops = { | 116 | static const struct file_operations i810_buffer_fops = { |
117 | .open = drm_open, | 117 | .open = drm_open, |
118 | .release = drm_release, | 118 | .release = drm_release, |
119 | .unlocked_ioctl = drm_ioctl, | 119 | .unlocked_ioctl = i810_ioctl, |
120 | .mmap = i810_mmap_buffers, | 120 | .mmap = i810_mmap_buffers, |
121 | .fasync = drm_fasync, | 121 | .fasync = drm_fasync, |
122 | }; | 122 | }; |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 671aa18415ac..cc92c7e6236f 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
118 | static const struct file_operations i830_buffer_fops = { | 118 | static const struct file_operations i830_buffer_fops = { |
119 | .open = drm_open, | 119 | .open = drm_open, |
120 | .release = drm_release, | 120 | .release = drm_release, |
121 | .unlocked_ioctl = drm_ioctl, | 121 | .unlocked_ioctl = i830_ioctl, |
122 | .mmap = i830_mmap_buffers, | 122 | .mmap = i830_mmap_buffers, |
123 | .fasync = drm_fasync, | 123 | .fasync = drm_fasync, |
124 | }; | 124 | }; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9d67b4853030..c74e4e8006d4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1787,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
1787 | } | 1787 | } |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | div_u64(diff, diff1); | 1790 | diff = div_u64(diff, diff1); |
1791 | ret = ((m * diff) + c); | 1791 | ret = ((m * diff) + c); |
1792 | div_u64(ret, 10); | 1792 | ret = div_u64(ret, 10); |
1793 | 1793 | ||
1794 | dev_priv->last_count1 = total_count; | 1794 | dev_priv->last_count1 = total_count; |
1795 | dev_priv->last_time1 = now; | 1795 | dev_priv->last_time1 = now; |
@@ -1858,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |||
1858 | 1858 | ||
1859 | /* More magic constants... */ | 1859 | /* More magic constants... */ |
1860 | diff = diff * 1181; | 1860 | diff = diff * 1181; |
1861 | div_u64(diff, diffms * 10); | 1861 | diff = div_u64(diff, diffms * 10); |
1862 | dev_priv->gfx_power = diff; | 1862 | dev_priv->gfx_power = diff; |
1863 | } | 1863 | } |
1864 | 1864 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4ffbee1c00..90b1d6753b9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
139 | /* drop reference from allocate - handle holds it now */ | ||
140 | drm_gem_object_unreference_unlocked(obj); | ||
139 | if (ret) { | 141 | if (ret) { |
140 | drm_gem_object_unreference_unlocked(obj); | ||
141 | return ret; | 142 | return ret; |
142 | } | 143 | } |
143 | 144 | ||
144 | /* Sink the floating reference from kref_init(handlecount) */ | ||
145 | drm_gem_object_handle_unreference_unlocked(obj); | ||
146 | |||
147 | args->handle = handle; | 145 | args->handle = handle; |
148 | return 0; | 146 | return 0; |
149 | } | 147 | } |
@@ -471,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
471 | return -ENOENT; | 469 | return -ENOENT; |
472 | obj_priv = to_intel_bo(obj); | 470 | obj_priv = to_intel_bo(obj); |
473 | 471 | ||
474 | /* Bounds check source. | 472 | /* Bounds check source. */ |
475 | * | 473 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
476 | * XXX: This could use review for overflow issues... | 474 | ret = -EINVAL; |
477 | */ | 475 | goto err; |
478 | if (args->offset > obj->size || args->size > obj->size || | 476 | } |
479 | args->offset + args->size > obj->size) { | 477 | |
480 | drm_gem_object_unreference_unlocked(obj); | 478 | if (!access_ok(VERIFY_WRITE, |
481 | return -EINVAL; | 479 | (char __user *)(uintptr_t)args->data_ptr, |
480 | args->size)) { | ||
481 | ret = -EFAULT; | ||
482 | goto err; | ||
482 | } | 483 | } |
483 | 484 | ||
484 | if (i915_gem_object_needs_bit17_swizzle(obj)) { | 485 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
@@ -490,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
490 | file_priv); | 491 | file_priv); |
491 | } | 492 | } |
492 | 493 | ||
494 | err: | ||
493 | drm_gem_object_unreference_unlocked(obj); | 495 | drm_gem_object_unreference_unlocked(obj); |
494 | |||
495 | return ret; | 496 | return ret; |
496 | } | 497 | } |
497 | 498 | ||
@@ -580,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
580 | 581 | ||
581 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 582 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
582 | remain = args->size; | 583 | remain = args->size; |
583 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
584 | return -EFAULT; | ||
585 | 584 | ||
586 | 585 | ||
587 | mutex_lock(&dev->struct_mutex); | 586 | mutex_lock(&dev->struct_mutex); |
@@ -934,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
934 | return -ENOENT; | 933 | return -ENOENT; |
935 | obj_priv = to_intel_bo(obj); | 934 | obj_priv = to_intel_bo(obj); |
936 | 935 | ||
937 | /* Bounds check destination. | 936 | /* Bounds check destination. */ |
938 | * | 937 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
939 | * XXX: This could use review for overflow issues... | 938 | ret = -EINVAL; |
940 | */ | 939 | goto err; |
941 | if (args->offset > obj->size || args->size > obj->size || | 940 | } |
942 | args->offset + args->size > obj->size) { | 941 | |
943 | drm_gem_object_unreference_unlocked(obj); | 942 | if (!access_ok(VERIFY_READ, |
944 | return -EINVAL; | 943 | (char __user *)(uintptr_t)args->data_ptr, |
944 | args->size)) { | ||
945 | ret = -EFAULT; | ||
946 | goto err; | ||
945 | } | 947 | } |
946 | 948 | ||
947 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | 949 | /* We can only do the GTT pwrite on untiled buffers, as otherwise |
@@ -975,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
975 | DRM_INFO("pwrite failed %d\n", ret); | 977 | DRM_INFO("pwrite failed %d\n", ret); |
976 | #endif | 978 | #endif |
977 | 979 | ||
980 | err: | ||
978 | drm_gem_object_unreference_unlocked(obj); | 981 | drm_gem_object_unreference_unlocked(obj); |
979 | |||
980 | return ret; | 982 | return ret; |
981 | } | 983 | } |
982 | 984 | ||
@@ -2400,7 +2402,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2400 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2402 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); |
2401 | break; | 2403 | break; |
2402 | case 3: | 2404 | case 3: |
2403 | if (obj_priv->fence_reg > 8) | 2405 | if (obj_priv->fence_reg >= 8) |
2404 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; | 2406 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; |
2405 | else | 2407 | else |
2406 | case 2: | 2408 | case 2: |
@@ -3258,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3258 | (int) reloc->offset, | 3260 | (int) reloc->offset, |
3259 | reloc->read_domains, | 3261 | reloc->read_domains, |
3260 | reloc->write_domain); | 3262 | reloc->write_domain); |
3263 | drm_gem_object_unreference(target_obj); | ||
3264 | i915_gem_object_unpin(obj); | ||
3261 | return -EINVAL; | 3265 | return -EINVAL; |
3262 | } | 3266 | } |
3263 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || | 3267 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index e85246ef691c..5c428fa3e0b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -93,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
93 | { | 93 | { |
94 | drm_i915_private_t *dev_priv = dev->dev_private; | 94 | drm_i915_private_t *dev_priv = dev->dev_private; |
95 | struct list_head eviction_list, unwind_list; | 95 | struct list_head eviction_list, unwind_list; |
96 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | 96 | struct drm_i915_gem_object *obj_priv; |
97 | struct list_head *render_iter, *bsd_iter; | 97 | struct list_head *render_iter, *bsd_iter; |
98 | int ret = 0; | 98 | int ret = 0; |
99 | 99 | ||
@@ -175,39 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
175 | return -ENOSPC; | 175 | return -ENOSPC; |
176 | 176 | ||
177 | found: | 177 | found: |
178 | /* drm_mm doesn't allow any other other operations while | ||
179 | * scanning, therefore store to be evicted objects on a | ||
180 | * temporary list. */ | ||
178 | INIT_LIST_HEAD(&eviction_list); | 181 | INIT_LIST_HEAD(&eviction_list); |
179 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 182 | while (!list_empty(&unwind_list)) { |
180 | &unwind_list, evict_list) { | 183 | obj_priv = list_first_entry(&unwind_list, |
184 | struct drm_i915_gem_object, | ||
185 | evict_list); | ||
181 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | 186 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { |
182 | /* drm_mm doesn't allow any other other operations while | ||
183 | * scanning, therefore store to be evicted objects on a | ||
184 | * temporary list. */ | ||
185 | list_move(&obj_priv->evict_list, &eviction_list); | 187 | list_move(&obj_priv->evict_list, &eviction_list); |
186 | } else | 188 | continue; |
187 | drm_gem_object_unreference(&obj_priv->base); | 189 | } |
190 | list_del(&obj_priv->evict_list); | ||
191 | drm_gem_object_unreference(&obj_priv->base); | ||
188 | } | 192 | } |
189 | 193 | ||
190 | /* Unbinding will emit any required flushes */ | 194 | /* Unbinding will emit any required flushes */ |
191 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 195 | while (!list_empty(&eviction_list)) { |
192 | &eviction_list, evict_list) { | 196 | obj_priv = list_first_entry(&eviction_list, |
193 | #if WATCH_LRU | 197 | struct drm_i915_gem_object, |
194 | DRM_INFO("%s: evicting %p\n", __func__, &obj_priv->base); | 198 | evict_list); |
195 | #endif | 199 | if (ret == 0) |
196 | ret = i915_gem_object_unbind(&obj_priv->base); | 200 | ret = i915_gem_object_unbind(&obj_priv->base); |
197 | if (ret) | 201 | list_del(&obj_priv->evict_list); |
198 | return ret; | ||
199 | |||
200 | drm_gem_object_unreference(&obj_priv->base); | 202 | drm_gem_object_unreference(&obj_priv->base); |
201 | } | 203 | } |
202 | 204 | ||
203 | /* The just created free hole should be on the top of the free stack | 205 | return ret; |
204 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
205 | * Furthermore all accessed data has just recently been used, so it | ||
206 | * should be really fast, too. */ | ||
207 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
208 | alignment, 0)); | ||
209 | |||
210 | return 0; | ||
211 | } | 206 | } |
212 | 207 | ||
213 | int | 208 | int |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b5bf51a4502d..979228594599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1013,8 +1013,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | /** | 1016 | /* |
1017 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | 1017 | * intel_wait_for_pipe_off - wait for pipe to turn off |
1018 | * @dev: drm device | 1018 | * @dev: drm device |
1019 | * @pipe: pipe to wait for | 1019 | * @pipe: pipe to wait for |
1020 | * | 1020 | * |
@@ -1022,25 +1022,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1022 | * spinning on the vblank interrupt status bit, since we won't actually | 1022 | * spinning on the vblank interrupt status bit, since we won't actually |
1023 | * see an interrupt when the pipe is disabled. | 1023 | * see an interrupt when the pipe is disabled. |
1024 | * | 1024 | * |
1025 | * So this function waits for the display line value to settle (it | 1025 | * On Gen4 and above: |
1026 | * usually ends up stopping at the start of the next frame). | 1026 | * wait for the pipe register state bit to turn off |
1027 | * | ||
1028 | * Otherwise: | ||
1029 | * wait for the display line value to settle (it usually | ||
1030 | * ends up stopping at the start of the next frame). | ||
1031 | * | ||
1027 | */ | 1032 | */ |
1028 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | 1033 | static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) |
1029 | { | 1034 | { |
1030 | struct drm_i915_private *dev_priv = dev->dev_private; | 1035 | struct drm_i915_private *dev_priv = dev->dev_private; |
1031 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | 1036 | |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | 1037 | if (INTEL_INFO(dev)->gen >= 4) { |
1033 | u32 last_line; | 1038 | int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); |
1034 | 1039 | ||
1035 | /* Wait for the display line to settle */ | 1040 | /* Wait for the Pipe State to go off */ |
1036 | do { | 1041 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, |
1037 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | 1042 | 100, 0)) |
1038 | mdelay(5); | 1043 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); |
1039 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | 1044 | } else { |
1040 | time_after(timeout, jiffies)); | 1045 | u32 last_line; |
1041 | 1046 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | |
1042 | if (time_after(jiffies, timeout)) | 1047 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1043 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1048 | |
1049 | /* Wait for the display line to settle */ | ||
1050 | do { | ||
1051 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1052 | mdelay(5); | ||
1053 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1054 | time_after(timeout, jiffies)); | ||
1055 | if (time_after(jiffies, timeout)) | ||
1056 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | ||
1057 | } | ||
1044 | } | 1058 | } |
1045 | 1059 | ||
1046 | /* Parameters have changed, update FBC info */ | 1060 | /* Parameters have changed, update FBC info */ |
@@ -2328,13 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2328 | I915_READ(dspbase_reg); | 2342 | I915_READ(dspbase_reg); |
2329 | } | 2343 | } |
2330 | 2344 | ||
2331 | /* Wait for vblank for the disable to take effect */ | ||
2332 | intel_wait_for_vblank_off(dev, pipe); | ||
2333 | |||
2334 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2345 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2335 | if (pipeconf_reg == PIPEACONF && | 2346 | if (pipeconf_reg == PIPEACONF && |
2336 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | 2347 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { |
2348 | /* Wait for vblank for the disable to take effect */ | ||
2349 | intel_wait_for_vblank(dev, pipe); | ||
2337 | goto skip_pipe_off; | 2350 | goto skip_pipe_off; |
2351 | } | ||
2338 | 2352 | ||
2339 | /* Next, disable display pipes */ | 2353 | /* Next, disable display pipes */ |
2340 | temp = I915_READ(pipeconf_reg); | 2354 | temp = I915_READ(pipeconf_reg); |
@@ -2343,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2343 | I915_READ(pipeconf_reg); | 2357 | I915_READ(pipeconf_reg); |
2344 | } | 2358 | } |
2345 | 2359 | ||
2346 | /* Wait for vblank for the disable to take effect. */ | 2360 | /* Wait for the pipe to turn off */ |
2347 | intel_wait_for_vblank_off(dev, pipe); | 2361 | intel_wait_for_pipe_off(dev, pipe); |
2348 | 2362 | ||
2349 | temp = I915_READ(dpll_reg); | 2363 | temp = I915_READ(dpll_reg); |
2350 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2364 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1a51ee07de3e..9ab8708ac6ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1138,18 +1138,14 @@ static bool | |||
1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1139 | uint32_t dp_reg_value, | 1139 | uint32_t dp_reg_value, |
1140 | uint8_t dp_train_pat, | 1140 | uint8_t dp_train_pat, |
1141 | uint8_t train_set[4], | 1141 | uint8_t train_set[4]) |
1142 | bool first) | ||
1143 | { | 1142 | { |
1144 | struct drm_device *dev = intel_dp->base.enc.dev; | 1143 | struct drm_device *dev = intel_dp->base.enc.dev; |
1145 | struct drm_i915_private *dev_priv = dev->dev_private; | 1144 | struct drm_i915_private *dev_priv = dev->dev_private; |
1146 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1147 | int ret; | 1145 | int ret; |
1148 | 1146 | ||
1149 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1147 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1150 | POSTING_READ(intel_dp->output_reg); | 1148 | POSTING_READ(intel_dp->output_reg); |
1151 | if (first) | ||
1152 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1153 | 1149 | ||
1154 | intel_dp_aux_native_write_1(intel_dp, | 1150 | intel_dp_aux_native_write_1(intel_dp, |
1155 | DP_TRAINING_PATTERN_SET, | 1151 | DP_TRAINING_PATTERN_SET, |
@@ -1174,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1174 | uint8_t voltage; | 1170 | uint8_t voltage; |
1175 | bool clock_recovery = false; | 1171 | bool clock_recovery = false; |
1176 | bool channel_eq = false; | 1172 | bool channel_eq = false; |
1177 | bool first = true; | ||
1178 | int tries; | 1173 | int tries; |
1179 | u32 reg; | 1174 | u32 reg; |
1180 | uint32_t DP = intel_dp->DP; | 1175 | uint32_t DP = intel_dp->DP; |
1176 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1177 | |||
1178 | /* Enable output, wait for it to become active */ | ||
1179 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
1180 | POSTING_READ(intel_dp->output_reg); | ||
1181 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1181 | 1182 | ||
1182 | /* Write the link configuration data */ | 1183 | /* Write the link configuration data */ |
1183 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1184 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
@@ -1210,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1210 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1211 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1211 | 1212 | ||
1212 | if (!intel_dp_set_link_train(intel_dp, reg, | 1213 | if (!intel_dp_set_link_train(intel_dp, reg, |
1213 | DP_TRAINING_PATTERN_1, train_set, first)) | 1214 | DP_TRAINING_PATTERN_1, train_set)) |
1214 | break; | 1215 | break; |
1215 | first = false; | ||
1216 | /* Set training pattern 1 */ | 1216 | /* Set training pattern 1 */ |
1217 | 1217 | ||
1218 | udelay(100); | 1218 | udelay(100); |
@@ -1266,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1266 | 1266 | ||
1267 | /* channel eq pattern */ | 1267 | /* channel eq pattern */ |
1268 | if (!intel_dp_set_link_train(intel_dp, reg, | 1268 | if (!intel_dp_set_link_train(intel_dp, reg, |
1269 | DP_TRAINING_PATTERN_2, train_set, | 1269 | DP_TRAINING_PATTERN_2, train_set)) |
1270 | false)) | ||
1271 | break; | 1270 | break; |
1272 | 1271 | ||
1273 | udelay(400); | 1272 | udelay(400); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ad312ca6b3e5..8828b3ac6414 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -229,7 +229,6 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
229 | struct drm_crtc *crtc); | 229 | struct drm_crtc *crtc); |
230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
231 | struct drm_file *file_priv); | 231 | struct drm_file *file_priv); |
232 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); | ||
233 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | 232 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); |
234 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 233 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
235 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 234 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf5..56ad9df2ccb5 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev, | |||
237 | drm_fb_helper_fini(&ifbdev->helper); | 237 | drm_fb_helper_fini(&ifbdev->helper); |
238 | 238 | ||
239 | drm_framebuffer_cleanup(&ifb->base); | 239 | drm_framebuffer_cleanup(&ifb->base); |
240 | if (ifb->obj) | 240 | if (ifb->obj) { |
241 | drm_gem_object_handle_unreference(ifb->obj); | ||
241 | drm_gem_object_unreference(ifb->obj); | 242 | drm_gem_object_unreference(ifb->obj); |
243 | } | ||
242 | 244 | ||
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e8e902d614ed..ee73e428a84a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2170,8 +2170,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
2170 | return true; | 2170 | return true; |
2171 | 2171 | ||
2172 | err: | 2172 | err: |
2173 | intel_sdvo_destroy_enhance_property(connector); | 2173 | intel_sdvo_destroy(connector); |
2174 | kfree(intel_sdvo_connector); | ||
2175 | return false; | 2174 | return false; |
2176 | } | 2175 | } |
2177 | 2176 | ||
@@ -2243,8 +2242,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2243 | return true; | 2242 | return true; |
2244 | 2243 | ||
2245 | err: | 2244 | err: |
2246 | intel_sdvo_destroy_enhance_property(connector); | 2245 | intel_sdvo_destroy(connector); |
2247 | kfree(intel_sdvo_connector); | ||
2248 | return false; | 2246 | return false; |
2249 | } | 2247 | } |
2250 | 2248 | ||
@@ -2522,11 +2520,10 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | |||
2522 | uint16_t response; | 2520 | uint16_t response; |
2523 | } enhancements; | 2521 | } enhancements; |
2524 | 2522 | ||
2525 | if (!intel_sdvo_get_value(intel_sdvo, | 2523 | enhancements.response = 0; |
2526 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2524 | intel_sdvo_get_value(intel_sdvo, |
2527 | &enhancements, sizeof(enhancements))) | 2525 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2528 | return false; | 2526 | &enhancements, sizeof(enhancements)); |
2529 | |||
2530 | if (enhancements.response == 0) { | 2527 | if (enhancements.response == 0) { |
2531 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2528 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2532 | return true; | 2529 | return true; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 87186a4bbf03..fc737037f751 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -558,8 +558,10 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
558 | if (nv_encoder->dcb->type == OUTPUT_LVDS && | 558 | if (nv_encoder->dcb->type == OUTPUT_LVDS && |
559 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | 559 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || |
560 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { | 560 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { |
561 | nv_connector->native_mode = drm_mode_create(dev); | 561 | struct drm_display_mode mode; |
562 | nouveau_bios_fp_mode(dev, nv_connector->native_mode); | 562 | |
563 | nouveau_bios_fp_mode(dev, &mode); | ||
564 | nv_connector->native_mode = drm_mode_duplicate(dev, &mode); | ||
563 | } | 565 | } |
564 | 566 | ||
565 | /* Find the native mode if this is a digital panel, if we didn't | 567 | /* Find the native mode if this is a digital panel, if we didn't |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index dbd30b2e43fd..d2047713dc59 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -352,6 +352,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) | |||
352 | 352 | ||
353 | if (nouveau_fb->nvbo) { | 353 | if (nouveau_fb->nvbo) { |
354 | nouveau_bo_unmap(nouveau_fb->nvbo); | 354 | nouveau_bo_unmap(nouveau_fb->nvbo); |
355 | drm_gem_object_handle_unreference_unlocked(nouveau_fb->nvbo->gem); | ||
355 | drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); | 356 | drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); |
356 | nouveau_fb->nvbo = NULL; | 357 | nouveau_fb->nvbo = NULL; |
357 | } | 358 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index ead7b8fc53fc..19620a6709f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
167 | goto out; | 167 | goto out; |
168 | 168 | ||
169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); | 169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); |
170 | /* drop reference from allocate - handle holds it now */ | ||
171 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
170 | out: | 172 | out: |
171 | drm_gem_object_handle_unreference_unlocked(nvbo->gem); | ||
172 | |||
173 | if (ret) | ||
174 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
175 | return ret; | 173 | return ret; |
176 | } | 174 | } |
177 | 175 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 3ec181ff50ce..3c9964a8fbad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -79,6 +79,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) | |||
79 | mutex_lock(&dev->struct_mutex); | 79 | mutex_lock(&dev->struct_mutex); |
80 | nouveau_bo_unpin(chan->notifier_bo); | 80 | nouveau_bo_unpin(chan->notifier_bo); |
81 | mutex_unlock(&dev->struct_mutex); | 81 | mutex_unlock(&dev->struct_mutex); |
82 | drm_gem_object_handle_unreference_unlocked(chan->notifier_bo->gem); | ||
82 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); | 83 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); |
83 | drm_mm_takedown(&chan->notifier_heap); | 84 | drm_mm_takedown(&chan->notifier_heap); |
84 | } | 85 | } |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 1bc72c3190a9..fe359a239df3 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -4999,7 +4999,7 @@ typedef struct _SW_I2C_IO_DATA_PARAMETERS | |||
4999 | #define SW_I2C_CNTL_WRITE1BIT 6 | 4999 | #define SW_I2C_CNTL_WRITE1BIT 6 |
5000 | 5000 | ||
5001 | //==============================VESA definition Portion=============================== | 5001 | //==============================VESA definition Portion=============================== |
5002 | #define VESA_OEM_PRODUCT_REV '01.00' | 5002 | #define VESA_OEM_PRODUCT_REV "01.00" |
5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support | 5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support |
5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 | 5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 |
5005 | #define VESA_WIN_SIZE 64 | 5005 | #define VESA_WIN_SIZE 64 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index afc18d87fdca..7a04959ba0ee 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2729,7 +2729,7 @@ int r600_ib_test(struct radeon_device *rdev) | |||
2729 | if (i < rdev->usec_timeout) { | 2729 | if (i < rdev->usec_timeout) { |
2730 | DRM_INFO("ib test succeeded in %u usecs\n", i); | 2730 | DRM_INFO("ib test succeeded in %u usecs\n", i); |
2731 | } else { | 2731 | } else { |
2732 | DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", | 2732 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
2733 | scratch, tmp); | 2733 | scratch, tmp); |
2734 | r = -EINVAL; | 2734 | r = -EINVAL; |
2735 | } | 2735 | } |
@@ -3528,7 +3528,8 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3528 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3528 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
3530 | */ | 3530 | */ |
3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3532 | rdev->vram_scratch.ptr) { | ||
3532 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3533 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3533 | u32 tmp; | 3534 | u32 tmp; |
3534 | 3535 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index ebae14c4b768..68932ba7b8a4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -317,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
317 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 317 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
318 | } | 318 | } |
319 | 319 | ||
320 | /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ | ||
321 | if ((dev->pdev->device == 0x796e) && | ||
322 | (dev->pdev->subsystem_vendor == 0x1462) && | ||
323 | (dev->pdev->subsystem_device == 0x7302)) { | ||
324 | if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || | ||
325 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
326 | return false; | ||
327 | } | ||
328 | |||
320 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 329 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
321 | if ((dev->pdev->device == 0x7941) && | 330 | if ((dev->pdev->device == 0x7941) && |
322 | (dev->pdev->subsystem_vendor == 0x147b) && | 331 | (dev->pdev->subsystem_vendor == 0x147b) && |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 127a395f70fb..b92d2f2fcbed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); | 349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); |
350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) | 350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) |
351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); | 351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); |
352 | if (devices & ATOM_DEVICE_DFP6_SUPPORT) | ||
353 | DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); | ||
352 | if (devices & ATOM_DEVICE_TV1_SUPPORT) | 354 | if (devices & ATOM_DEVICE_TV1_SUPPORT) |
353 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); | 355 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); |
354 | if (devices & ATOM_DEVICE_CV_SUPPORT) | 356 | if (devices & ATOM_DEVICE_CV_SUPPORT) |
@@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
841 | { | 843 | { |
842 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
843 | 845 | ||
844 | if (radeon_fb->obj) | 846 | if (radeon_fb->obj) { |
845 | drm_gem_object_unreference_unlocked(radeon_fb->obj); | 847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
848 | } | ||
846 | drm_framebuffer_cleanup(fb); | 849 | drm_framebuffer_cleanup(fb); |
847 | kfree(radeon_fb); | 850 | kfree(radeon_fb); |
848 | } | 851 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index c74a8b20d941..9cdf6a35bc2c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -94,8 +94,10 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | |||
94 | ret = radeon_bo_reserve(rbo, false); | 94 | ret = radeon_bo_reserve(rbo, false); |
95 | if (likely(ret == 0)) { | 95 | if (likely(ret == 0)) { |
96 | radeon_bo_kunmap(rbo); | 96 | radeon_bo_kunmap(rbo); |
97 | radeon_bo_unpin(rbo); | ||
97 | radeon_bo_unreserve(rbo); | 98 | radeon_bo_unreserve(rbo); |
98 | } | 99 | } |
100 | drm_gem_object_handle_unreference(gobj); | ||
99 | drm_gem_object_unreference_unlocked(gobj); | 101 | drm_gem_object_unreference_unlocked(gobj); |
100 | } | 102 | } |
101 | 103 | ||
@@ -325,8 +327,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
325 | { | 327 | { |
326 | struct fb_info *info; | 328 | struct fb_info *info; |
327 | struct radeon_framebuffer *rfb = &rfbdev->rfb; | 329 | struct radeon_framebuffer *rfb = &rfbdev->rfb; |
328 | struct radeon_bo *rbo; | ||
329 | int r; | ||
330 | 330 | ||
331 | if (rfbdev->helper.fbdev) { | 331 | if (rfbdev->helper.fbdev) { |
332 | info = rfbdev->helper.fbdev; | 332 | info = rfbdev->helper.fbdev; |
@@ -338,14 +338,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
338 | } | 338 | } |
339 | 339 | ||
340 | if (rfb->obj) { | 340 | if (rfb->obj) { |
341 | rbo = rfb->obj->driver_private; | 341 | radeonfb_destroy_pinned_object(rfb->obj); |
342 | r = radeon_bo_reserve(rbo, false); | 342 | rfb->obj = NULL; |
343 | if (likely(r == 0)) { | ||
344 | radeon_bo_kunmap(rbo); | ||
345 | radeon_bo_unpin(rbo); | ||
346 | radeon_bo_unreserve(rbo); | ||
347 | } | ||
348 | drm_gem_object_unreference_unlocked(rfb->obj); | ||
349 | } | 343 | } |
350 | drm_fb_helper_fini(&rfbdev->helper); | 344 | drm_fb_helper_fini(&rfbdev->helper); |
351 | drm_framebuffer_cleanup(&rfb->base); | 345 | drm_framebuffer_cleanup(&rfb->base); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24c..d1e595d91723 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
201 | return r; | 201 | return r; |
202 | } | 202 | } |
203 | r = drm_gem_handle_create(filp, gobj, &handle); | 203 | r = drm_gem_handle_create(filp, gobj, &handle); |
204 | /* drop reference from allocate - handle holds it now */ | ||
205 | drm_gem_object_unreference_unlocked(gobj); | ||
204 | if (r) { | 206 | if (r) { |
205 | drm_gem_object_unreference_unlocked(gobj); | ||
206 | return r; | 207 | return r; |
207 | } | 208 | } |
208 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
209 | args->handle = handle; | 209 | args->handle = handle; |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 5eee3c41d124..8fbbe1c6ebbd 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -203,6 +203,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
203 | */ | 203 | */ |
204 | int radeon_driver_firstopen_kms(struct drm_device *dev) | 204 | int radeon_driver_firstopen_kms(struct drm_device *dev) |
205 | { | 205 | { |
206 | struct radeon_device *rdev = dev->dev_private; | ||
207 | |||
208 | if (rdev->powered_down) | ||
209 | return -EINVAL; | ||
206 | return 0; | 210 | return 0; |
207 | } | 211 | } |
208 | 212 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 7cffb3e04232..3451a82adba7 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
351 | INIT_LIST_HEAD(&fbo->lru); | 351 | INIT_LIST_HEAD(&fbo->lru); |
352 | INIT_LIST_HEAD(&fbo->swap); | 352 | INIT_LIST_HEAD(&fbo->swap); |
353 | fbo->vm_node = NULL; | 353 | fbo->vm_node = NULL; |
354 | atomic_set(&fbo->cpu_writers, 0); | ||
354 | 355 | ||
355 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | 356 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); |
356 | kref_init(&fbo->list_kref); | 357 | kref_init(&fbo->list_kref); |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index ca904799f018..b1e02fffd3cc 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -69,7 +69,7 @@ struct ttm_page_pool { | |||
69 | spinlock_t lock; | 69 | spinlock_t lock; |
70 | bool fill_lock; | 70 | bool fill_lock; |
71 | struct list_head list; | 71 | struct list_head list; |
72 | int gfp_flags; | 72 | gfp_t gfp_flags; |
73 | unsigned npages; | 73 | unsigned npages; |
74 | char *name; | 74 | char *name; |
75 | unsigned long nfrees; | 75 | unsigned long nfrees; |
@@ -475,7 +475,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages, | |||
475 | * This function is reentrant if caller updates count depending on number of | 475 | * This function is reentrant if caller updates count depending on number of |
476 | * pages returned in pages array. | 476 | * pages returned in pages array. |
477 | */ | 477 | */ |
478 | static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags, | 478 | static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, |
479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) | 479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) |
480 | { | 480 | { |
481 | struct page **caching_array; | 481 | struct page **caching_array; |
@@ -666,7 +666,7 @@ int ttm_get_pages(struct list_head *pages, int flags, | |||
666 | { | 666 | { |
667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); | 667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); |
668 | struct page *p = NULL; | 668 | struct page *p = NULL; |
669 | int gfp_flags = GFP_USER; | 669 | gfp_t gfp_flags = GFP_USER; |
670 | int r; | 670 | int r; |
671 | 671 | ||
672 | /* set zero flag for page allocation if required */ | 672 | /* set zero flag for page allocation if required */ |
@@ -818,7 +818,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | void ttm_page_alloc_fini() | 821 | void ttm_page_alloc_fini(void) |
822 | { | 822 | { |
823 | int i; | 823 | int i; |
824 | 824 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 72ec2e2b6e97..a96ed6d9d010 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
148 | {0, 0, 0} | 148 | {0, 0, 0} |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static char *vmw_devname = "vmwgfx"; | 151 | static int enable_fbdev; |
152 | 152 | ||
153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
154 | static void vmw_master_init(struct vmw_master *); | 154 | static void vmw_master_init(struct vmw_master *); |
155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | 155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
156 | void *ptr); | 156 | void *ptr); |
157 | 157 | ||
158 | MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); | ||
159 | module_param_named(enable_fbdev, enable_fbdev, int, 0600); | ||
160 | |||
158 | static void vmw_print_capabilities(uint32_t capabilities) | 161 | static void vmw_print_capabilities(uint32_t capabilities) |
159 | { | 162 | { |
160 | DRM_INFO("Capabilities:\n"); | 163 | DRM_INFO("Capabilities:\n"); |
@@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
192 | { | 195 | { |
193 | int ret; | 196 | int ret; |
194 | 197 | ||
195 | vmw_kms_save_vga(dev_priv); | ||
196 | |||
197 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); | 198 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); |
198 | if (unlikely(ret != 0)) { | 199 | if (unlikely(ret != 0)) { |
199 | DRM_ERROR("Unable to initialize FIFO.\n"); | 200 | DRM_ERROR("Unable to initialize FIFO.\n"); |
@@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
206 | static void vmw_release_device(struct vmw_private *dev_priv) | 207 | static void vmw_release_device(struct vmw_private *dev_priv) |
207 | { | 208 | { |
208 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | 209 | vmw_fifo_release(dev_priv, &dev_priv->fifo); |
209 | vmw_kms_restore_vga(dev_priv); | ||
210 | } | 210 | } |
211 | 211 | ||
212 | int vmw_3d_resource_inc(struct vmw_private *dev_priv) | ||
213 | { | ||
214 | int ret = 0; | ||
215 | |||
216 | mutex_lock(&dev_priv->release_mutex); | ||
217 | if (unlikely(dev_priv->num_3d_resources++ == 0)) { | ||
218 | ret = vmw_request_device(dev_priv); | ||
219 | if (unlikely(ret != 0)) | ||
220 | --dev_priv->num_3d_resources; | ||
221 | } | ||
222 | mutex_unlock(&dev_priv->release_mutex); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | |||
227 | void vmw_3d_resource_dec(struct vmw_private *dev_priv) | ||
228 | { | ||
229 | int32_t n3d; | ||
230 | |||
231 | mutex_lock(&dev_priv->release_mutex); | ||
232 | if (unlikely(--dev_priv->num_3d_resources == 0)) | ||
233 | vmw_release_device(dev_priv); | ||
234 | n3d = (int32_t) dev_priv->num_3d_resources; | ||
235 | mutex_unlock(&dev_priv->release_mutex); | ||
236 | |||
237 | BUG_ON(n3d < 0); | ||
238 | } | ||
212 | 239 | ||
213 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | 240 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
214 | { | 241 | { |
@@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
228 | dev_priv->last_read_sequence = (uint32_t) -100; | 255 | dev_priv->last_read_sequence = (uint32_t) -100; |
229 | mutex_init(&dev_priv->hw_mutex); | 256 | mutex_init(&dev_priv->hw_mutex); |
230 | mutex_init(&dev_priv->cmdbuf_mutex); | 257 | mutex_init(&dev_priv->cmdbuf_mutex); |
258 | mutex_init(&dev_priv->release_mutex); | ||
231 | rwlock_init(&dev_priv->resource_lock); | 259 | rwlock_init(&dev_priv->resource_lock); |
232 | idr_init(&dev_priv->context_idr); | 260 | idr_init(&dev_priv->context_idr); |
233 | idr_init(&dev_priv->surface_idr); | 261 | idr_init(&dev_priv->surface_idr); |
@@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
244 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 272 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
245 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); | 273 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); |
246 | 274 | ||
275 | dev_priv->enable_fb = enable_fbdev; | ||
276 | |||
247 | mutex_lock(&dev_priv->hw_mutex); | 277 | mutex_lock(&dev_priv->hw_mutex); |
248 | 278 | ||
249 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 279 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
@@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
343 | 373 | ||
344 | dev->dev_private = dev_priv; | 374 | dev->dev_private = dev_priv; |
345 | 375 | ||
346 | if (!dev->devname) | ||
347 | dev->devname = vmw_devname; | ||
348 | |||
349 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
350 | ret = drm_irq_install(dev); | ||
351 | if (unlikely(ret != 0)) { | ||
352 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
353 | goto out_no_irq; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); | 376 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); |
358 | dev_priv->stealth = (ret != 0); | 377 | dev_priv->stealth = (ret != 0); |
359 | if (dev_priv->stealth) { | 378 | if (dev_priv->stealth) { |
@@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
369 | goto out_no_device; | 388 | goto out_no_device; |
370 | } | 389 | } |
371 | } | 390 | } |
372 | ret = vmw_request_device(dev_priv); | 391 | ret = vmw_kms_init(dev_priv); |
373 | if (unlikely(ret != 0)) | 392 | if (unlikely(ret != 0)) |
374 | goto out_no_device; | 393 | goto out_no_kms; |
375 | vmw_kms_init(dev_priv); | ||
376 | vmw_overlay_init(dev_priv); | 394 | vmw_overlay_init(dev_priv); |
377 | vmw_fb_init(dev_priv); | 395 | if (dev_priv->enable_fb) { |
396 | ret = vmw_3d_resource_inc(dev_priv); | ||
397 | if (unlikely(ret != 0)) | ||
398 | goto out_no_fifo; | ||
399 | vmw_kms_save_vga(dev_priv); | ||
400 | vmw_fb_init(dev_priv); | ||
401 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? | ||
402 | "Detected device 3D availability.\n" : | ||
403 | "Detected no device 3D availability.\n"); | ||
404 | } else { | ||
405 | DRM_INFO("Delayed 3D detection since we're not " | ||
406 | "running the device in SVGA mode yet.\n"); | ||
407 | } | ||
408 | |||
409 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
410 | ret = drm_irq_install(dev); | ||
411 | if (unlikely(ret != 0)) { | ||
412 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
413 | goto out_no_irq; | ||
414 | } | ||
415 | } | ||
378 | 416 | ||
379 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 417 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
380 | register_pm_notifier(&dev_priv->pm_nb); | 418 | register_pm_notifier(&dev_priv->pm_nb); |
381 | 419 | ||
382 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n"); | ||
383 | |||
384 | return 0; | 420 | return 0; |
385 | 421 | ||
386 | out_no_device: | ||
387 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
388 | drm_irq_uninstall(dev_priv->dev); | ||
389 | if (dev->devname == vmw_devname) | ||
390 | dev->devname = NULL; | ||
391 | out_no_irq: | 422 | out_no_irq: |
423 | if (dev_priv->enable_fb) { | ||
424 | vmw_fb_close(dev_priv); | ||
425 | vmw_kms_restore_vga(dev_priv); | ||
426 | vmw_3d_resource_dec(dev_priv); | ||
427 | } | ||
428 | out_no_fifo: | ||
429 | vmw_overlay_close(dev_priv); | ||
430 | vmw_kms_close(dev_priv); | ||
431 | out_no_kms: | ||
432 | if (dev_priv->stealth) | ||
433 | pci_release_region(dev->pdev, 2); | ||
434 | else | ||
435 | pci_release_regions(dev->pdev); | ||
436 | out_no_device: | ||
392 | ttm_object_device_release(&dev_priv->tdev); | 437 | ttm_object_device_release(&dev_priv->tdev); |
393 | out_err4: | 438 | out_err4: |
394 | iounmap(dev_priv->mmio_virt); | 439 | iounmap(dev_priv->mmio_virt); |
@@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
415 | 460 | ||
416 | unregister_pm_notifier(&dev_priv->pm_nb); | 461 | unregister_pm_notifier(&dev_priv->pm_nb); |
417 | 462 | ||
418 | vmw_fb_close(dev_priv); | 463 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
464 | drm_irq_uninstall(dev_priv->dev); | ||
465 | if (dev_priv->enable_fb) { | ||
466 | vmw_fb_close(dev_priv); | ||
467 | vmw_kms_restore_vga(dev_priv); | ||
468 | vmw_3d_resource_dec(dev_priv); | ||
469 | } | ||
419 | vmw_kms_close(dev_priv); | 470 | vmw_kms_close(dev_priv); |
420 | vmw_overlay_close(dev_priv); | 471 | vmw_overlay_close(dev_priv); |
421 | vmw_release_device(dev_priv); | ||
422 | if (dev_priv->stealth) | 472 | if (dev_priv->stealth) |
423 | pci_release_region(dev->pdev, 2); | 473 | pci_release_region(dev->pdev, 2); |
424 | else | 474 | else |
425 | pci_release_regions(dev->pdev); | 475 | pci_release_regions(dev->pdev); |
426 | 476 | ||
427 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
428 | drm_irq_uninstall(dev_priv->dev); | ||
429 | if (dev->devname == vmw_devname) | ||
430 | dev->devname = NULL; | ||
431 | ttm_object_device_release(&dev_priv->tdev); | 477 | ttm_object_device_release(&dev_priv->tdev); |
432 | iounmap(dev_priv->mmio_virt); | 478 | iounmap(dev_priv->mmio_virt); |
433 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 479 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
@@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
500 | struct drm_ioctl_desc *ioctl = | 546 | struct drm_ioctl_desc *ioctl = |
501 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; | 547 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; |
502 | 548 | ||
503 | if (unlikely(ioctl->cmd != cmd)) { | 549 | if (unlikely(ioctl->cmd_drv != cmd)) { |
504 | DRM_ERROR("Invalid command format, ioctl %d\n", | 550 | DRM_ERROR("Invalid command format, ioctl %d\n", |
505 | nr - DRM_COMMAND_BASE); | 551 | nr - DRM_COMMAND_BASE); |
506 | return -EINVAL; | 552 | return -EINVAL; |
@@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev, | |||
589 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 635 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
590 | int ret = 0; | 636 | int ret = 0; |
591 | 637 | ||
638 | if (!dev_priv->enable_fb) { | ||
639 | ret = vmw_3d_resource_inc(dev_priv); | ||
640 | if (unlikely(ret != 0)) | ||
641 | return ret; | ||
642 | vmw_kms_save_vga(dev_priv); | ||
643 | mutex_lock(&dev_priv->hw_mutex); | ||
644 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | ||
645 | mutex_unlock(&dev_priv->hw_mutex); | ||
646 | } | ||
647 | |||
592 | if (active) { | 648 | if (active) { |
593 | BUG_ON(active != &dev_priv->fbdev_master); | 649 | BUG_ON(active != &dev_priv->fbdev_master); |
594 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); | 650 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); |
@@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev, | |||
617 | return 0; | 673 | return 0; |
618 | 674 | ||
619 | out_no_active_lock: | 675 | out_no_active_lock: |
620 | vmw_release_device(dev_priv); | 676 | if (!dev_priv->enable_fb) { |
677 | mutex_lock(&dev_priv->hw_mutex); | ||
678 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
679 | mutex_unlock(&dev_priv->hw_mutex); | ||
680 | vmw_kms_restore_vga(dev_priv); | ||
681 | vmw_3d_resource_dec(dev_priv); | ||
682 | } | ||
621 | return ret; | 683 | return ret; |
622 | } | 684 | } |
623 | 685 | ||
@@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev, | |||
645 | 707 | ||
646 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 708 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
647 | 709 | ||
710 | if (!dev_priv->enable_fb) { | ||
711 | ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); | ||
712 | if (unlikely(ret != 0)) | ||
713 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | ||
714 | mutex_lock(&dev_priv->hw_mutex); | ||
715 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
716 | mutex_unlock(&dev_priv->hw_mutex); | ||
717 | vmw_kms_restore_vga(dev_priv); | ||
718 | vmw_3d_resource_dec(dev_priv); | ||
719 | } | ||
720 | |||
648 | dev_priv->active_master = &dev_priv->fbdev_master; | 721 | dev_priv->active_master = &dev_priv->fbdev_master; |
649 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 722 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
650 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 723 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
651 | 724 | ||
652 | vmw_fb_on(dev_priv); | 725 | if (dev_priv->enable_fb) |
726 | vmw_fb_on(dev_priv); | ||
653 | } | 727 | } |
654 | 728 | ||
655 | 729 | ||
@@ -722,6 +796,7 @@ static struct drm_driver driver = { | |||
722 | .irq_postinstall = vmw_irq_postinstall, | 796 | .irq_postinstall = vmw_irq_postinstall, |
723 | .irq_uninstall = vmw_irq_uninstall, | 797 | .irq_uninstall = vmw_irq_uninstall, |
724 | .irq_handler = vmw_irq_handler, | 798 | .irq_handler = vmw_irq_handler, |
799 | .get_vblank_counter = vmw_get_vblank_counter, | ||
725 | .reclaim_buffers_locked = NULL, | 800 | .reclaim_buffers_locked = NULL, |
726 | .get_map_ofs = drm_core_get_map_ofs, | 801 | .get_map_ofs = drm_core_get_map_ofs, |
727 | .get_reg_ofs = drm_core_get_reg_ofs, | 802 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 429f917b60bf..58de6393f611 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -277,6 +277,7 @@ struct vmw_private { | |||
277 | 277 | ||
278 | bool stealth; | 278 | bool stealth; |
279 | bool is_opened; | 279 | bool is_opened; |
280 | bool enable_fb; | ||
280 | 281 | ||
281 | /** | 282 | /** |
282 | * Master management. | 283 | * Master management. |
@@ -285,6 +286,9 @@ struct vmw_private { | |||
285 | struct vmw_master *active_master; | 286 | struct vmw_master *active_master; |
286 | struct vmw_master fbdev_master; | 287 | struct vmw_master fbdev_master; |
287 | struct notifier_block pm_nb; | 288 | struct notifier_block pm_nb; |
289 | |||
290 | struct mutex release_mutex; | ||
291 | uint32_t num_3d_resources; | ||
288 | }; | 292 | }; |
289 | 293 | ||
290 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) | 294 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) |
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, | |||
319 | return val; | 323 | return val; |
320 | } | 324 | } |
321 | 325 | ||
326 | int vmw_3d_resource_inc(struct vmw_private *dev_priv); | ||
327 | void vmw_3d_resource_dec(struct vmw_private *dev_priv); | ||
328 | |||
322 | /** | 329 | /** |
323 | * GMR utilities - vmwgfx_gmr.c | 330 | * GMR utilities - vmwgfx_gmr.c |
324 | */ | 331 | */ |
@@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
511 | unsigned bbp, unsigned depth); | 518 | unsigned bbp, unsigned depth); |
512 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
513 | struct drm_file *file_priv); | 520 | struct drm_file *file_priv); |
521 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | ||
514 | 522 | ||
515 | /** | 523 | /** |
516 | * Overlay control - vmwgfx_overlay.c | 524 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 870967a97c15..409e172f4abf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | |||
615 | if (unlikely(ret != 0)) | 615 | if (unlikely(ret != 0)) |
616 | goto err_unlock; | 616 | goto err_unlock; |
617 | 617 | ||
618 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
619 | bo->mem.mm_node->start < bo->num_pages) | ||
620 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
621 | false, false); | ||
622 | |||
618 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | 623 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); |
619 | 624 | ||
620 | /* Could probably bug on */ | 625 | /* Could probably bug on */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index e6a1eb7ea954..0fe31766e4cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
106 | mutex_lock(&dev_priv->hw_mutex); | 106 | mutex_lock(&dev_priv->hw_mutex); |
107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
109 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | ||
109 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); | 110 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); |
110 | 111 | ||
111 | min = 4; | 112 | min = 4; |
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
175 | dev_priv->config_done_state); | 176 | dev_priv->config_done_state); |
176 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 177 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
177 | dev_priv->enable_state); | 178 | dev_priv->enable_state); |
179 | vmw_write(dev_priv, SVGA_REG_TRACES, | ||
180 | dev_priv->traces_state); | ||
178 | 181 | ||
179 | mutex_unlock(&dev_priv->hw_mutex); | 182 | mutex_unlock(&dev_priv->hw_mutex); |
180 | vmw_fence_queue_takedown(&fifo->fence_queue); | 183 | vmw_fence_queue_takedown(&fifo->fence_queue); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 64d7f47df868..e882ba099f0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) | |||
898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); | 898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); |
899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); | 899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); |
900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | 900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); |
901 | if (i == 0 && vmw_priv->num_displays == 1 && | ||
902 | save->width == 0 && save->height == 0) { | ||
903 | |||
904 | /* | ||
905 | * It should be fairly safe to assume that these | ||
906 | * values are uninitialized. | ||
907 | */ | ||
908 | |||
909 | save->width = vmw_priv->vga_width - save->pos_x; | ||
910 | save->height = vmw_priv->vga_height - save->pos_y; | ||
911 | } | ||
901 | } | 912 | } |
913 | |||
902 | return 0; | 914 | return 0; |
903 | } | 915 | } |
904 | 916 | ||
@@ -984,3 +996,8 @@ out_unlock: | |||
984 | ttm_read_unlock(&vmaster->lock); | 996 | ttm_read_unlock(&vmaster->lock); |
985 | return ret; | 997 | return ret; |
986 | } | 998 | } |
999 | |||
1000 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) | ||
1001 | { | ||
1002 | return 0; | ||
1003 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 7083b1a24df3..11cb39e3accb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include "vmwgfx_kms.h" | 28 | #include "vmwgfx_kms.h" |
29 | 29 | ||
30 | #define VMWGFX_LDU_NUM_DU 8 | ||
31 | |||
30 | #define vmw_crtc_to_ldu(x) \ | 32 | #define vmw_crtc_to_ldu(x) \ |
31 | container_of(x, struct vmw_legacy_display_unit, base.crtc) | 33 | container_of(x, struct vmw_legacy_display_unit, base.crtc) |
32 | #define vmw_encoder_to_ldu(x) \ | 34 | #define vmw_encoder_to_ldu(x) \ |
@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
536 | 538 | ||
537 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | 539 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) |
538 | { | 540 | { |
541 | struct drm_device *dev = dev_priv->dev; | ||
542 | int i; | ||
543 | int ret; | ||
544 | |||
539 | if (dev_priv->ldu_priv) { | 545 | if (dev_priv->ldu_priv) { |
540 | DRM_INFO("ldu system already on\n"); | 546 | DRM_INFO("ldu system already on\n"); |
541 | return -EINVAL; | 547 | return -EINVAL; |
@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
553 | 559 | ||
554 | drm_mode_create_dirty_info_property(dev_priv->dev); | 560 | drm_mode_create_dirty_info_property(dev_priv->dev); |
555 | 561 | ||
556 | vmw_ldu_init(dev_priv, 0); | ||
557 | /* for old hardware without multimon only enable one display */ | ||
558 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { | 562 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { |
559 | vmw_ldu_init(dev_priv, 1); | 563 | for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) |
560 | vmw_ldu_init(dev_priv, 2); | 564 | vmw_ldu_init(dev_priv, i); |
561 | vmw_ldu_init(dev_priv, 3); | 565 | ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); |
562 | vmw_ldu_init(dev_priv, 4); | 566 | } else { |
563 | vmw_ldu_init(dev_priv, 5); | 567 | /* for old hardware without multimon only enable one display */ |
564 | vmw_ldu_init(dev_priv, 6); | 568 | vmw_ldu_init(dev_priv, 0); |
565 | vmw_ldu_init(dev_priv, 7); | 569 | ret = drm_vblank_init(dev, 1); |
566 | } | 570 | } |
567 | 571 | ||
568 | return 0; | 572 | return ret; |
569 | } | 573 | } |
570 | 574 | ||
571 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | 575 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) |
572 | { | 576 | { |
577 | struct drm_device *dev = dev_priv->dev; | ||
578 | |||
579 | drm_vblank_cleanup(dev); | ||
573 | if (!dev_priv->ldu_priv) | 580 | if (!dev_priv->ldu_priv) |
574 | return -ENOSYS; | 581 | return -ENOSYS; |
575 | 582 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5f2d5df01e5c..c8c40e9979db 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
211 | cmd->body.cid = cpu_to_le32(res->id); | 211 | cmd->body.cid = cpu_to_le32(res->id); |
212 | 212 | ||
213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
214 | vmw_3d_resource_dec(dev_priv); | ||
214 | } | 215 | } |
215 | 216 | ||
216 | static int vmw_context_init(struct vmw_private *dev_priv, | 217 | static int vmw_context_init(struct vmw_private *dev_priv, |
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, | |||
247 | cmd->body.cid = cpu_to_le32(res->id); | 248 | cmd->body.cid = cpu_to_le32(res->id); |
248 | 249 | ||
249 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 250 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
251 | (void) vmw_3d_resource_inc(dev_priv); | ||
250 | vmw_resource_activate(res, vmw_hw_context_destroy); | 252 | vmw_resource_activate(res, vmw_hw_context_destroy); |
251 | return 0; | 253 | return 0; |
252 | } | 254 | } |
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) | |||
406 | cmd->body.sid = cpu_to_le32(res->id); | 408 | cmd->body.sid = cpu_to_le32(res->id); |
407 | 409 | ||
408 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 410 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
411 | vmw_3d_resource_dec(dev_priv); | ||
409 | } | 412 | } |
410 | 413 | ||
411 | void vmw_surface_res_free(struct vmw_resource *res) | 414 | void vmw_surface_res_free(struct vmw_resource *res) |
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv, | |||
473 | } | 476 | } |
474 | 477 | ||
475 | vmw_fifo_commit(dev_priv, submit_size); | 478 | vmw_fifo_commit(dev_priv, submit_size); |
479 | (void) vmw_3d_resource_inc(dev_priv); | ||
476 | vmw_resource_activate(res, vmw_hw_surface_destroy); | 480 | vmw_resource_activate(res, vmw_hw_surface_destroy); |
477 | return 0; | 481 | return 0; |
478 | } | 482 | } |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index b87569e96b16..f366f968155a 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -598,7 +598,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, | |||
598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); | 598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); |
599 | } | 599 | } |
600 | 600 | ||
601 | void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) | 601 | static void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) |
602 | { | 602 | { |
603 | struct vga_device *vgadev; | 603 | struct vga_device *vgadev; |
604 | unsigned long flags; | 604 | unsigned long flags; |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4d4d09bdec0a..97499d00615a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -409,7 +409,7 @@ config SENSORS_CORETEMP | |||
409 | 409 | ||
410 | config SENSORS_PKGTEMP | 410 | config SENSORS_PKGTEMP |
411 | tristate "Intel processor package temperature sensor" | 411 | tristate "Intel processor package temperature sensor" |
412 | depends on X86 && PCI && EXPERIMENTAL | 412 | depends on X86 && EXPERIMENTAL |
413 | help | 413 | help |
414 | If you say yes here you get support for the package level temperature | 414 | If you say yes here you get support for the package level temperature |
415 | sensor inside your CPU. Check documentation/driver for details. | 415 | sensor inside your CPU. Check documentation/driver for details. |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index de8111114f46..a23b17a78ace 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <asm/msr.h> | 37 | #include <asm/msr.h> |
38 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
39 | #include <asm/smp.h> | ||
39 | 40 | ||
40 | #define DRVNAME "coretemp" | 41 | #define DRVNAME "coretemp" |
41 | 42 | ||
@@ -423,9 +424,18 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) | |||
423 | int err; | 424 | int err; |
424 | struct platform_device *pdev; | 425 | struct platform_device *pdev; |
425 | struct pdev_entry *pdev_entry; | 426 | struct pdev_entry *pdev_entry; |
426 | #ifdef CONFIG_SMP | ||
427 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 427 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
428 | #endif | 428 | |
429 | /* | ||
430 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | ||
431 | * sensors. We check this bit only, all the early CPUs | ||
432 | * without thermal sensors will be filtered out. | ||
433 | */ | ||
434 | if (!cpu_has(c, X86_FEATURE_DTS)) { | ||
435 | printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" | ||
436 | " has no thermal sensor.\n", c->x86_model); | ||
437 | return 0; | ||
438 | } | ||
429 | 439 | ||
430 | mutex_lock(&pdev_list_mutex); | 440 | mutex_lock(&pdev_list_mutex); |
431 | 441 | ||
@@ -482,14 +492,22 @@ exit: | |||
482 | 492 | ||
483 | static void coretemp_device_remove(unsigned int cpu) | 493 | static void coretemp_device_remove(unsigned int cpu) |
484 | { | 494 | { |
485 | struct pdev_entry *p, *n; | 495 | struct pdev_entry *p; |
496 | unsigned int i; | ||
497 | |||
486 | mutex_lock(&pdev_list_mutex); | 498 | mutex_lock(&pdev_list_mutex); |
487 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 499 | list_for_each_entry(p, &pdev_list, list) { |
488 | if (p->cpu == cpu) { | 500 | if (p->cpu != cpu) |
489 | platform_device_unregister(p->pdev); | 501 | continue; |
490 | list_del(&p->list); | 502 | |
491 | kfree(p); | 503 | platform_device_unregister(p->pdev); |
492 | } | 504 | list_del(&p->list); |
505 | mutex_unlock(&pdev_list_mutex); | ||
506 | kfree(p); | ||
507 | for_each_cpu(i, cpu_sibling_mask(cpu)) | ||
508 | if (i != cpu && !coretemp_device_add(i)) | ||
509 | break; | ||
510 | return; | ||
493 | } | 511 | } |
494 | mutex_unlock(&pdev_list_mutex); | 512 | mutex_unlock(&pdev_list_mutex); |
495 | } | 513 | } |
@@ -527,30 +545,21 @@ static int __init coretemp_init(void) | |||
527 | if (err) | 545 | if (err) |
528 | goto exit; | 546 | goto exit; |
529 | 547 | ||
530 | for_each_online_cpu(i) { | 548 | for_each_online_cpu(i) |
531 | struct cpuinfo_x86 *c = &cpu_data(i); | 549 | coretemp_device_add(i); |
532 | /* | 550 | |
533 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | 551 | #ifndef CONFIG_HOTPLUG_CPU |
534 | * sensors. We check this bit only, all the early CPUs | ||
535 | * without thermal sensors will be filtered out. | ||
536 | */ | ||
537 | if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) | ||
538 | coretemp_device_add(i); | ||
539 | else { | ||
540 | printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" | ||
541 | " has no thermal sensor.\n", c->x86_model); | ||
542 | } | ||
543 | } | ||
544 | if (list_empty(&pdev_list)) { | 552 | if (list_empty(&pdev_list)) { |
545 | err = -ENODEV; | 553 | err = -ENODEV; |
546 | goto exit_driver_unreg; | 554 | goto exit_driver_unreg; |
547 | } | 555 | } |
556 | #endif | ||
548 | 557 | ||
549 | register_hotcpu_notifier(&coretemp_cpu_notifier); | 558 | register_hotcpu_notifier(&coretemp_cpu_notifier); |
550 | return 0; | 559 | return 0; |
551 | 560 | ||
552 | exit_driver_unreg: | ||
553 | #ifndef CONFIG_HOTPLUG_CPU | 561 | #ifndef CONFIG_HOTPLUG_CPU |
562 | exit_driver_unreg: | ||
554 | platform_driver_unregister(&coretemp_driver); | 563 | platform_driver_unregister(&coretemp_driver); |
555 | #endif | 564 | #endif |
556 | exit: | 565 | exit: |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b9..75afb3b0e076 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; | |||
111 | /* Super-I/O Function prototypes */ | 111 | /* Super-I/O Function prototypes */ |
112 | static inline int superio_inb(int base, int reg); | 112 | static inline int superio_inb(int base, int reg); |
113 | static inline int superio_inw(int base, int reg); | 113 | static inline int superio_inw(int base, int reg); |
114 | static inline void superio_enter(int base); | 114 | static inline int superio_enter(int base); |
115 | static inline void superio_select(int base, int ld); | 115 | static inline void superio_select(int base, int ld); |
116 | static inline void superio_exit(int base); | 116 | static inline void superio_exit(int base); |
117 | 117 | ||
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) | |||
861 | return val; | 861 | return val; |
862 | } | 862 | } |
863 | 863 | ||
864 | static inline void superio_enter(int base) | 864 | static inline int superio_enter(int base) |
865 | { | 865 | { |
866 | /* Don't step on other drivers' I/O space by accident */ | ||
867 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
868 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
869 | base); | ||
870 | return -EBUSY; | ||
871 | } | ||
872 | |||
866 | /* according to the datasheet the key must be send twice! */ | 873 | /* according to the datasheet the key must be send twice! */ |
867 | outb(SIO_UNLOCK_KEY, base); | 874 | outb(SIO_UNLOCK_KEY, base); |
868 | outb(SIO_UNLOCK_KEY, base); | 875 | outb(SIO_UNLOCK_KEY, base); |
876 | |||
877 | return 0; | ||
869 | } | 878 | } |
870 | 879 | ||
871 | static inline void superio_select(int base, int ld) | 880 | static inline void superio_select(int base, int ld) |
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) | |||
877 | static inline void superio_exit(int base) | 886 | static inline void superio_exit(int base) |
878 | { | 887 | { |
879 | outb(SIO_LOCK_KEY, base); | 888 | outb(SIO_LOCK_KEY, base); |
889 | release_region(base, 2); | ||
880 | } | 890 | } |
881 | 891 | ||
882 | static inline int fan_from_reg(u16 reg) | 892 | static inline int fan_from_reg(u16 reg) |
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2175 | static int __init f71882fg_find(int sioaddr, unsigned short *address, | 2185 | static int __init f71882fg_find(int sioaddr, unsigned short *address, |
2176 | struct f71882fg_sio_data *sio_data) | 2186 | struct f71882fg_sio_data *sio_data) |
2177 | { | 2187 | { |
2178 | int err = -ENODEV; | ||
2179 | u16 devid; | 2188 | u16 devid; |
2180 | 2189 | int err = superio_enter(sioaddr); | |
2181 | /* Don't step on other drivers' I/O space by accident */ | 2190 | if (err) |
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | 2191 | return err; |
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2188 | superio_enter(sioaddr); | ||
2189 | 2192 | ||
2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2193 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
2191 | if (devid != SIO_FINTEK_ID) { | 2194 | if (devid != SIO_FINTEK_ID) { |
2192 | pr_debug(DRVNAME ": Not a Fintek device\n"); | 2195 | pr_debug(DRVNAME ": Not a Fintek device\n"); |
2196 | err = -ENODEV; | ||
2193 | goto exit; | 2197 | goto exit; |
2194 | } | 2198 | } |
2195 | 2199 | ||
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2213 | default: | 2217 | default: |
2214 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", | 2218 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", |
2215 | (unsigned int)devid); | 2219 | (unsigned int)devid); |
2220 | err = -ENODEV; | ||
2216 | goto exit; | 2221 | goto exit; |
2217 | } | 2222 | } |
2218 | 2223 | ||
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2223 | 2228 | ||
2224 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2229 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
2225 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2230 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
2231 | err = -ENODEV; | ||
2226 | goto exit; | 2232 | goto exit; |
2227 | } | 2233 | } |
2228 | 2234 | ||
2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2235 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2230 | if (*address == 0) { | 2236 | if (*address == 0) { |
2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2237 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2238 | err = -ENODEV; | ||
2232 | goto exit; | 2239 | goto exit; |
2233 | } | 2240 | } |
2234 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | 2241 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ |
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2246 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2240 | exit: | 2247 | exit: |
2241 | superio_exit(sioaddr); | 2248 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2243 | return err; | 2249 | return err; |
2244 | } | 2250 | } |
2245 | 2251 | ||
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 6138f036b159..fc591ae53107 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -277,7 +277,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
277 | wake_up_interruptible(&lis3_dev.misc_wait); | 277 | wake_up_interruptible(&lis3_dev.misc_wait); |
278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); | 278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); |
279 | out: | 279 | out: |
280 | if (lis3_dev.whoami == WAI_8B && lis3_dev.idev && | 280 | if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev && |
281 | lis3_dev.idev->input->users) | 281 | lis3_dev.idev->input->users) |
282 | return IRQ_WAKE_THREAD; | 282 | return IRQ_WAKE_THREAD; |
283 | return IRQ_HANDLED; | 283 | return IRQ_HANDLED; |
@@ -718,7 +718,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
718 | * io-apic is not configurable (and generates a warning) but I keep it | 718 | * io-apic is not configurable (and generates a warning) but I keep it |
719 | * in case of support for other hardware. | 719 | * in case of support for other hardware. |
720 | */ | 720 | */ |
721 | if (dev->whoami == WAI_8B) | 721 | if (dev->pdata && dev->whoami == WAI_8B) |
722 | thread_fn = lis302dl_interrupt_thread1_8b; | 722 | thread_fn = lis302dl_interrupt_thread1_8b; |
723 | else | 723 | else |
724 | thread_fn = NULL; | 724 | thread_fn = NULL; |
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c index 74157fcda6ed..f11903936c8b 100644 --- a/drivers/hwmon/pkgtemp.c +++ b/drivers/hwmon/pkgtemp.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/cpu.h> | 35 | #include <linux/cpu.h> |
36 | #include <linux/pci.h> | ||
37 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
38 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
39 | 38 | ||
@@ -224,7 +223,7 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
224 | 223 | ||
225 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); | 224 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); |
226 | if (err) | 225 | if (err) |
227 | goto exit_free; | 226 | goto exit_dev; |
228 | 227 | ||
229 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 228 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
230 | if (IS_ERR(data->hwmon_dev)) { | 229 | if (IS_ERR(data->hwmon_dev)) { |
@@ -238,6 +237,8 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
238 | 237 | ||
239 | exit_class: | 238 | exit_class: |
240 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 239 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
240 | exit_dev: | ||
241 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
241 | exit_free: | 242 | exit_free: |
242 | kfree(data); | 243 | kfree(data); |
243 | exit: | 244 | exit: |
@@ -250,6 +251,7 @@ static int __devexit pkgtemp_remove(struct platform_device *pdev) | |||
250 | 251 | ||
251 | hwmon_device_unregister(data->hwmon_dev); | 252 | hwmon_device_unregister(data->hwmon_dev); |
252 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 253 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
254 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
253 | platform_set_drvdata(pdev, NULL); | 255 | platform_set_drvdata(pdev, NULL); |
254 | kfree(data); | 256 | kfree(data); |
255 | return 0; | 257 | return 0; |
@@ -281,9 +283,10 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu) | |||
281 | int err; | 283 | int err; |
282 | struct platform_device *pdev; | 284 | struct platform_device *pdev; |
283 | struct pdev_entry *pdev_entry; | 285 | struct pdev_entry *pdev_entry; |
284 | #ifdef CONFIG_SMP | ||
285 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 286 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
286 | #endif | 287 | |
288 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
289 | return 0; | ||
287 | 290 | ||
288 | mutex_lock(&pdev_list_mutex); | 291 | mutex_lock(&pdev_list_mutex); |
289 | 292 | ||
@@ -339,17 +342,18 @@ exit: | |||
339 | #ifdef CONFIG_HOTPLUG_CPU | 342 | #ifdef CONFIG_HOTPLUG_CPU |
340 | static void pkgtemp_device_remove(unsigned int cpu) | 343 | static void pkgtemp_device_remove(unsigned int cpu) |
341 | { | 344 | { |
342 | struct pdev_entry *p, *n; | 345 | struct pdev_entry *p; |
343 | unsigned int i; | 346 | unsigned int i; |
344 | int err; | 347 | int err; |
345 | 348 | ||
346 | mutex_lock(&pdev_list_mutex); | 349 | mutex_lock(&pdev_list_mutex); |
347 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 350 | list_for_each_entry(p, &pdev_list, list) { |
348 | if (p->cpu != cpu) | 351 | if (p->cpu != cpu) |
349 | continue; | 352 | continue; |
350 | 353 | ||
351 | platform_device_unregister(p->pdev); | 354 | platform_device_unregister(p->pdev); |
352 | list_del(&p->list); | 355 | list_del(&p->list); |
356 | mutex_unlock(&pdev_list_mutex); | ||
353 | kfree(p); | 357 | kfree(p); |
354 | for_each_cpu(i, cpu_core_mask(cpu)) { | 358 | for_each_cpu(i, cpu_core_mask(cpu)) { |
355 | if (i != cpu) { | 359 | if (i != cpu) { |
@@ -358,7 +362,7 @@ static void pkgtemp_device_remove(unsigned int cpu) | |||
358 | break; | 362 | break; |
359 | } | 363 | } |
360 | } | 364 | } |
361 | break; | 365 | return; |
362 | } | 366 | } |
363 | mutex_unlock(&pdev_list_mutex); | 367 | mutex_unlock(&pdev_list_mutex); |
364 | } | 368 | } |
@@ -399,11 +403,6 @@ static int __init pkgtemp_init(void) | |||
399 | goto exit; | 403 | goto exit; |
400 | 404 | ||
401 | for_each_online_cpu(i) { | 405 | for_each_online_cpu(i) { |
402 | struct cpuinfo_x86 *c = &cpu_data(i); | ||
403 | |||
404 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
405 | continue; | ||
406 | |||
407 | err = pkgtemp_device_add(i); | 406 | err = pkgtemp_device_add(i); |
408 | if (err) | 407 | if (err) |
409 | goto exit_devices_unreg; | 408 | goto exit_devices_unreg; |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 2222c87876b9..b8feac5f2ef4 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
357 | 357 | ||
358 | dev->terminate = 0; | 358 | dev->terminate = 0; |
359 | 359 | ||
360 | /* write the data into mode register */ | ||
361 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
362 | |||
363 | /* | 360 | /* |
364 | * First byte should be set here, not after interrupt, | 361 | * First byte should be set here, not after interrupt, |
365 | * because transmit-data-ready interrupt can come before | 362 | * because transmit-data-ready interrupt can come before |
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
371 | dev->buf_len--; | 368 | dev->buf_len--; |
372 | } | 369 | } |
373 | 370 | ||
371 | /* write the data into mode register; start transmitting */ | ||
372 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
373 | |||
374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |
375 | dev->adapter.timeout); | 375 | dev->adapter.timeout); |
376 | if (r == 0) { | 376 | if (r == 0) { |
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 0e9f85d0a835..56dbe54e8811 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c | |||
@@ -218,7 +218,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) | |||
218 | return result; | 218 | return result; |
219 | } else if (result == 0) { | 219 | } else if (result == 0) { |
220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); | 220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); |
221 | result = -ETIMEDOUT; | 221 | return -ETIMEDOUT; |
222 | } | 222 | } |
223 | 223 | ||
224 | return 0; | 224 | return 0; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 72902e0bbfa7..bf831bf81587 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -662,8 +662,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got) | |||
662 | unsigned long sda_delay; | 662 | unsigned long sda_delay; |
663 | 663 | ||
664 | if (pdata->sda_delay) { | 664 | if (pdata->sda_delay) { |
665 | sda_delay = (freq / 1000) * pdata->sda_delay; | 665 | sda_delay = clkin * pdata->sda_delay; |
666 | sda_delay /= 1000000; | 666 | sda_delay = DIV_ROUND_UP(sda_delay, 1000000); |
667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); | 667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); |
668 | if (sda_delay > 3) | 668 | if (sda_delay > 3) |
669 | sda_delay = 3; | 669 | sda_delay = 3; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a10152bb1427..0906fc5b69b9 100755..100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -83,7 +83,7 @@ static unsigned int mwait_substates; | |||
83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | 83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ |
84 | static unsigned int lapic_timer_reliable_states; | 84 | static unsigned int lapic_timer_reliable_states; |
85 | 85 | ||
86 | static struct cpuidle_device *intel_idle_cpuidle_devices; | 86 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); |
88 | 88 | ||
89 | static struct cpuidle_state *cpuidle_state_table; | 89 | static struct cpuidle_state *cpuidle_state_table; |
@@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
108 | .name = "NHM-C3", | 108 | .name = "NHM-C3", |
109 | .desc = "MWAIT 0x10", | 109 | .desc = "MWAIT 0x10", |
110 | .driver_data = (void *) 0x10, | 110 | .driver_data = (void *) 0x10, |
111 | .flags = CPUIDLE_FLAG_TIME_VALID, | 111 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
112 | .exit_latency = 20, | 112 | .exit_latency = 20, |
113 | .power_usage = 500, | 113 | .power_usage = 500, |
114 | .target_residency = 80, | 114 | .target_residency = 80, |
@@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
117 | .name = "NHM-C6", | 117 | .name = "NHM-C6", |
118 | .desc = "MWAIT 0x20", | 118 | .desc = "MWAIT 0x20", |
119 | .driver_data = (void *) 0x20, | 119 | .driver_data = (void *) 0x20, |
120 | .flags = CPUIDLE_FLAG_TIME_VALID, | 120 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
121 | .exit_latency = 200, | 121 | .exit_latency = 200, |
122 | .power_usage = 350, | 122 | .power_usage = 350, |
123 | .target_residency = 800, | 123 | .target_residency = 800, |
@@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
149 | .name = "ATM-C4", | 149 | .name = "ATM-C4", |
150 | .desc = "MWAIT 0x30", | 150 | .desc = "MWAIT 0x30", |
151 | .driver_data = (void *) 0x30, | 151 | .driver_data = (void *) 0x30, |
152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 152 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
153 | .exit_latency = 100, | 153 | .exit_latency = 100, |
154 | .power_usage = 250, | 154 | .power_usage = 250, |
155 | .target_residency = 400, | 155 | .target_residency = 400, |
@@ -159,7 +159,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
159 | .name = "ATM-C6", | 159 | .name = "ATM-C6", |
160 | .desc = "MWAIT 0x40", | 160 | .desc = "MWAIT 0x40", |
161 | .driver_data = (void *) 0x40, | 161 | .driver_data = (void *) 0x40, |
162 | .flags = CPUIDLE_FLAG_TIME_VALID, | 162 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
163 | .exit_latency = 200, | 163 | .exit_latency = 200, |
164 | .power_usage = 150, | 164 | .power_usage = 150, |
165 | .target_residency = 800, | 165 | .target_residency = 800, |
@@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
185 | 185 | ||
186 | local_irq_disable(); | 186 | local_irq_disable(); |
187 | 187 | ||
188 | /* | ||
189 | * If the state flag indicates that the TLB will be flushed or if this | ||
190 | * is the deepest c-state supported, do a voluntary leave mm to avoid | ||
191 | * costly and mostly unnecessary wakeups for flushing the user TLB's | ||
192 | * associated with the active mm. | ||
193 | */ | ||
194 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || | ||
195 | (&dev->states[dev->state_count - 1] == state)) | ||
196 | leave_mm(cpu); | ||
197 | |||
188 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 198 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
189 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 199 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
190 | 200 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index d88077a21994..13c88871dc3b 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -463,7 +463,8 @@ static int send_connect(struct iwch_ep *ep) | |||
463 | V_MSS_IDX(mtu_idx) | | 463 | V_MSS_IDX(mtu_idx) | |
464 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); | 464 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); |
465 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); | 465 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); |
466 | opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); | 466 | opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | |
467 | V_CONG_CONTROL_FLAVOR(cong_flavor); | ||
467 | skb->priority = CPL_PRIORITY_SETUP; | 468 | skb->priority = CPL_PRIORITY_SETUP; |
468 | set_arp_failure_handler(skb, act_open_req_arp_failure); | 469 | set_arp_failure_handler(skb, act_open_req_arp_failure); |
469 | 470 | ||
@@ -1280,7 +1281,8 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) | |||
1280 | V_MSS_IDX(mtu_idx) | | 1281 | V_MSS_IDX(mtu_idx) | |
1281 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); | 1282 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); |
1282 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); | 1283 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); |
1283 | opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); | 1284 | opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | |
1285 | V_CONG_CONTROL_FLAVOR(cong_flavor); | ||
1284 | 1286 | ||
1285 | rpl = cplhdr(skb); | 1287 | rpl = cplhdr(skb); |
1286 | rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 1288 | rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 74dce4ba0262..350eb34f049c 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c | |||
@@ -81,7 +81,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat, | |||
81 | int cmd_level; | 81 | int cmd_level; |
82 | int slow_level; | 82 | int slow_level; |
83 | 83 | ||
84 | read_lock(&led_dat->rw_lock); | 84 | read_lock_irq(&led_dat->rw_lock); |
85 | 85 | ||
86 | cmd_level = gpio_get_value(led_dat->cmd); | 86 | cmd_level = gpio_get_value(led_dat->cmd); |
87 | slow_level = gpio_get_value(led_dat->slow); | 87 | slow_level = gpio_get_value(led_dat->slow); |
@@ -95,7 +95,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat, | |||
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | read_unlock(&led_dat->rw_lock); | 98 | read_unlock_irq(&led_dat->rw_lock); |
99 | 99 | ||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
@@ -104,8 +104,9 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat, | |||
104 | enum ns2_led_modes mode) | 104 | enum ns2_led_modes mode) |
105 | { | 105 | { |
106 | int i; | 106 | int i; |
107 | unsigned long flags; | ||
107 | 108 | ||
108 | write_lock(&led_dat->rw_lock); | 109 | write_lock_irqsave(&led_dat->rw_lock, flags); |
109 | 110 | ||
110 | for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { | 111 | for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { |
111 | if (mode == ns2_led_modval[i].mode) { | 112 | if (mode == ns2_led_modval[i].mode) { |
@@ -116,7 +117,7 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat, | |||
116 | } | 117 | } |
117 | } | 118 | } |
118 | 119 | ||
119 | write_unlock(&led_dat->rw_lock); | 120 | write_unlock_irqrestore(&led_dat->rw_lock, flags); |
120 | } | 121 | } |
121 | 122 | ||
122 | static void ns2_led_set(struct led_classdev *led_cdev, | 123 | static void ns2_led_set(struct led_classdev *led_cdev, |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 04028a9ee082..428377a5a6f5 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) | |||
429 | irq_tsc = cache_tsc; | 429 | irq_tsc = cache_tsc; |
430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { |
431 | irq_data = &max8925_irqs[i]; | 431 | irq_data = &max8925_irqs[i]; |
432 | /* 1 -- disable, 0 -- enable */ | ||
432 | switch (irq_data->mask_reg) { | 433 | switch (irq_data->mask_reg) { |
433 | case MAX8925_CHG_IRQ1_MASK: | 434 | case MAX8925_CHG_IRQ1_MASK: |
434 | irq_chg[0] &= irq_data->enable; | 435 | irq_chg[0] &= ~irq_data->enable; |
435 | break; | 436 | break; |
436 | case MAX8925_CHG_IRQ2_MASK: | 437 | case MAX8925_CHG_IRQ2_MASK: |
437 | irq_chg[1] &= irq_data->enable; | 438 | irq_chg[1] &= ~irq_data->enable; |
438 | break; | 439 | break; |
439 | case MAX8925_ON_OFF_IRQ1_MASK: | 440 | case MAX8925_ON_OFF_IRQ1_MASK: |
440 | irq_on[0] &= irq_data->enable; | 441 | irq_on[0] &= ~irq_data->enable; |
441 | break; | 442 | break; |
442 | case MAX8925_ON_OFF_IRQ2_MASK: | 443 | case MAX8925_ON_OFF_IRQ2_MASK: |
443 | irq_on[1] &= irq_data->enable; | 444 | irq_on[1] &= ~irq_data->enable; |
444 | break; | 445 | break; |
445 | case MAX8925_RTC_IRQ_MASK: | 446 | case MAX8925_RTC_IRQ_MASK: |
446 | irq_rtc &= irq_data->enable; | 447 | irq_rtc &= ~irq_data->enable; |
447 | break; | 448 | break; |
448 | case MAX8925_TSC_IRQ_MASK: | 449 | case MAX8925_TSC_IRQ_MASK: |
449 | irq_tsc &= irq_data->enable; | 450 | irq_tsc &= ~irq_data->enable; |
450 | break; | 451 | break; |
451 | default: | 452 | default: |
452 | dev_err(chip->dev, "wrong IRQ\n"); | 453 | dev_err(chip->dev, "wrong IRQ\n"); |
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 7dabe4dbd373..294183b6260b 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | |||
394 | 394 | ||
395 | irq = irq - wm831x->irq_base; | 395 | irq = irq - wm831x->irq_base; |
396 | 396 | ||
397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) | 397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
398 | return -EINVAL; | 398 | /* Ignore internal-only IRQs */ |
399 | if (irq >= 0 && irq < WM831X_NUM_IRQS) | ||
400 | return 0; | ||
401 | else | ||
402 | return -EINVAL; | ||
403 | } | ||
399 | 404 | ||
400 | switch (type) { | 405 | switch (type) { |
401 | case IRQ_TYPE_EDGE_BOTH: | 406 | case IRQ_TYPE_EDGE_BOTH: |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0b591b658243..b74331260744 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -368,7 +368,7 @@ config VMWARE_BALLOON | |||
368 | If unsure, say N. | 368 | If unsure, say N. |
369 | 369 | ||
370 | To compile this driver as a module, choose M here: the | 370 | To compile this driver as a module, choose M here: the |
371 | module will be called vmware_balloon. | 371 | module will be called vmw_balloon. |
372 | 372 | ||
373 | config ARM_CHARLCD | 373 | config ARM_CHARLCD |
374 | bool "ARM Ltd. Character LCD Driver" | 374 | bool "ARM Ltd. Character LCD Driver" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 255a80dc9d73..42eab95cde2a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -33,5 +33,5 @@ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ | |||
33 | obj-$(CONFIG_HMC6352) += hmc6352.o | 33 | obj-$(CONFIG_HMC6352) += hmc6352.o |
34 | obj-y += eeprom/ | 34 | obj-y += eeprom/ |
35 | obj-y += cb710/ | 35 | obj-y += cb710/ |
36 | obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o | 36 | obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o |
37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o | 37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o |
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmw_balloon.c index 2a1e804a71aa..2a1e804a71aa 100644 --- a/drivers/misc/vmware_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 71ad4163b95e..aacb862ecc8a 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -241,8 +241,10 @@ static struct sdhci_ops sdhci_s3c_ops = { | |||
241 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | 241 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) |
242 | { | 242 | { |
243 | struct sdhci_host *host = platform_get_drvdata(dev); | 243 | struct sdhci_host *host = platform_get_drvdata(dev); |
244 | unsigned long flags; | ||
245 | |||
244 | if (host) { | 246 | if (host) { |
245 | spin_lock(&host->lock); | 247 | spin_lock_irqsave(&host->lock, flags); |
246 | if (state) { | 248 | if (state) { |
247 | dev_dbg(&dev->dev, "card inserted.\n"); | 249 | dev_dbg(&dev->dev, "card inserted.\n"); |
248 | host->flags &= ~SDHCI_DEVICE_DEAD; | 250 | host->flags &= ~SDHCI_DEVICE_DEAD; |
@@ -253,7 +255,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 255 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
254 | } | 256 | } |
255 | tasklet_schedule(&host->card_tasklet); | 257 | tasklet_schedule(&host->card_tasklet); |
256 | spin_unlock(&host->lock); | 258 | spin_unlock_irqrestore(&host->lock, flags); |
257 | } | 259 | } |
258 | } | 260 | } |
259 | 261 | ||
@@ -481,8 +483,10 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
481 | sdhci_remove_host(host, 1); | 483 | sdhci_remove_host(host, 1); |
482 | 484 | ||
483 | for (ptr = 0; ptr < 3; ptr++) { | 485 | for (ptr = 0; ptr < 3; ptr++) { |
484 | clk_disable(sc->clk_bus[ptr]); | 486 | if (sc->clk_bus[ptr]) { |
485 | clk_put(sc->clk_bus[ptr]); | 487 | clk_disable(sc->clk_bus[ptr]); |
488 | clk_put(sc->clk_bus[ptr]); | ||
489 | } | ||
486 | } | 490 | } |
487 | clk_disable(sc->clk_io); | 491 | clk_disable(sc->clk_io); |
488 | clk_put(sc->clk_io); | 492 | clk_put(sc->clk_io); |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d51528f8d..513e0a76a4a7 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); | 413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); |
414 | } while (prefetch_status); | 414 | } while (prefetch_status); |
415 | /* disable and stop the PFPW engine */ | 415 | /* disable and stop the PFPW engine */ |
416 | gpmc_prefetch_reset(); | 416 | gpmc_prefetch_reset(info->gpmc_cs); |
417 | 417 | ||
418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); | 418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); |
419 | return 0; | 419 | return 0; |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index fa42103b2874..179871d9e71f 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -2942,6 +2942,9 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2942 | { | 2942 | { |
2943 | struct vortex_private *vp = netdev_priv(dev); | 2943 | struct vortex_private *vp = netdev_priv(dev); |
2944 | 2944 | ||
2945 | if (!VORTEX_PCI(vp)) | ||
2946 | return; | ||
2947 | |||
2945 | wol->supported = WAKE_MAGIC; | 2948 | wol->supported = WAKE_MAGIC; |
2946 | 2949 | ||
2947 | wol->wolopts = 0; | 2950 | wol->wolopts = 0; |
@@ -2952,6 +2955,10 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2952 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2955 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2953 | { | 2956 | { |
2954 | struct vortex_private *vp = netdev_priv(dev); | 2957 | struct vortex_private *vp = netdev_priv(dev); |
2958 | |||
2959 | if (!VORTEX_PCI(vp)) | ||
2960 | return -EOPNOTSUPP; | ||
2961 | |||
2955 | if (wol->wolopts & ~WAKE_MAGIC) | 2962 | if (wol->wolopts & ~WAKE_MAGIC) |
2956 | return -EINVAL; | 2963 | return -EINVAL; |
2957 | 2964 | ||
@@ -3201,6 +3208,9 @@ static void acpi_set_WOL(struct net_device *dev) | |||
3201 | return; | 3208 | return; |
3202 | } | 3209 | } |
3203 | 3210 | ||
3211 | if (VORTEX_PCI(vp)->current_state < PCI_D3hot) | ||
3212 | return; | ||
3213 | |||
3204 | /* Change the power state to D3; RxEnable doesn't take effect. */ | 3214 | /* Change the power state to D3; RxEnable doesn't take effect. */ |
3205 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | 3215 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); |
3206 | } | 3216 | } |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 63b9ba0cc67e..c73be2848319 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -1251,6 +1251,12 @@ static void atl1_free_ring_resources(struct atl1_adapter *adapter) | |||
1251 | 1251 | ||
1252 | rrd_ring->desc = NULL; | 1252 | rrd_ring->desc = NULL; |
1253 | rrd_ring->dma = 0; | 1253 | rrd_ring->dma = 0; |
1254 | |||
1255 | adapter->cmb.dma = 0; | ||
1256 | adapter->cmb.cmb = NULL; | ||
1257 | |||
1258 | adapter->smb.dma = 0; | ||
1259 | adapter->smb.smb = NULL; | ||
1254 | } | 1260 | } |
1255 | 1261 | ||
1256 | static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) | 1262 | static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) |
@@ -2847,10 +2853,11 @@ static int atl1_resume(struct pci_dev *pdev) | |||
2847 | pci_enable_wake(pdev, PCI_D3cold, 0); | 2853 | pci_enable_wake(pdev, PCI_D3cold, 0); |
2848 | 2854 | ||
2849 | atl1_reset_hw(&adapter->hw); | 2855 | atl1_reset_hw(&adapter->hw); |
2850 | adapter->cmb.cmb->int_stats = 0; | ||
2851 | 2856 | ||
2852 | if (netif_running(netdev)) | 2857 | if (netif_running(netdev)) { |
2858 | adapter->cmb.cmb->int_stats = 0; | ||
2853 | atl1_up(adapter); | 2859 | atl1_up(adapter); |
2860 | } | ||
2854 | netif_device_attach(netdev); | 2861 | netif_device_attach(netdev); |
2855 | 2862 | ||
2856 | return 0; | 2863 | return 0; |
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 66ed08f726fb..ba302a5c2c30 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -57,6 +57,7 @@ enum e1e_registers { | |||
57 | E1000_SCTL = 0x00024, /* SerDes Control - RW */ | 57 | E1000_SCTL = 0x00024, /* SerDes Control - RW */ |
58 | E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ | 58 | E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ |
59 | E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ | 59 | E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ |
60 | E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */ | ||
60 | E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ | 61 | E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ |
61 | E1000_FCT = 0x00030, /* Flow Control Type - RW */ | 62 | E1000_FCT = 0x00030, /* Flow Control Type - RW */ |
62 | E1000_VET = 0x00038, /* VLAN Ether Type - RW */ | 63 | E1000_VET = 0x00038, /* VLAN Ether Type - RW */ |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 63930d12711c..57b5435599ab 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -105,6 +105,10 @@ | |||
105 | #define E1000_FEXTNVM_SW_CONFIG 1 | 105 | #define E1000_FEXTNVM_SW_CONFIG 1 |
106 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ | 106 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ |
107 | 107 | ||
108 | #define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7 | ||
109 | #define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 | ||
110 | #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 | ||
111 | |||
108 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL | 112 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL |
109 | 113 | ||
110 | #define E1000_ICH_RAR_ENTRIES 7 | 114 | #define E1000_ICH_RAR_ENTRIES 7 |
@@ -125,6 +129,7 @@ | |||
125 | 129 | ||
126 | /* SMBus Address Phy Register */ | 130 | /* SMBus Address Phy Register */ |
127 | #define HV_SMB_ADDR PHY_REG(768, 26) | 131 | #define HV_SMB_ADDR PHY_REG(768, 26) |
132 | #define HV_SMB_ADDR_MASK 0x007F | ||
128 | #define HV_SMB_ADDR_PEC_EN 0x0200 | 133 | #define HV_SMB_ADDR_PEC_EN 0x0200 |
129 | #define HV_SMB_ADDR_VALID 0x0080 | 134 | #define HV_SMB_ADDR_VALID 0x0080 |
130 | 135 | ||
@@ -237,6 +242,8 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); | |||
237 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); | 242 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); |
238 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); | 243 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); |
239 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); | 244 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); |
245 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); | ||
246 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); | ||
240 | 247 | ||
241 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 248 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
242 | { | 249 | { |
@@ -272,7 +279,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) | |||
272 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | 279 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) |
273 | { | 280 | { |
274 | struct e1000_phy_info *phy = &hw->phy; | 281 | struct e1000_phy_info *phy = &hw->phy; |
275 | u32 ctrl; | 282 | u32 ctrl, fwsm; |
276 | s32 ret_val = 0; | 283 | s32 ret_val = 0; |
277 | 284 | ||
278 | phy->addr = 1; | 285 | phy->addr = 1; |
@@ -294,7 +301,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
294 | * disabled, then toggle the LANPHYPC Value bit to force | 301 | * disabled, then toggle the LANPHYPC Value bit to force |
295 | * the interconnect to PCIe mode. | 302 | * the interconnect to PCIe mode. |
296 | */ | 303 | */ |
297 | if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | 304 | fwsm = er32(FWSM); |
305 | if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
298 | ctrl = er32(CTRL); | 306 | ctrl = er32(CTRL); |
299 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; | 307 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; |
300 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; | 308 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; |
@@ -303,6 +311,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
303 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | 311 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; |
304 | ew32(CTRL, ctrl); | 312 | ew32(CTRL, ctrl); |
305 | msleep(50); | 313 | msleep(50); |
314 | |||
315 | /* | ||
316 | * Gate automatic PHY configuration by hardware on | ||
317 | * non-managed 82579 | ||
318 | */ | ||
319 | if (hw->mac.type == e1000_pch2lan) | ||
320 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
306 | } | 321 | } |
307 | 322 | ||
308 | /* | 323 | /* |
@@ -315,6 +330,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
315 | if (ret_val) | 330 | if (ret_val) |
316 | goto out; | 331 | goto out; |
317 | 332 | ||
333 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
334 | if ((hw->mac.type == e1000_pch2lan) && | ||
335 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
336 | msleep(10); | ||
337 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
338 | } | ||
339 | |||
318 | phy->id = e1000_phy_unknown; | 340 | phy->id = e1000_phy_unknown; |
319 | ret_val = e1000e_get_phy_id(hw); | 341 | ret_val = e1000e_get_phy_id(hw); |
320 | if (ret_val) | 342 | if (ret_val) |
@@ -561,13 +583,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) | |||
561 | if (mac->type == e1000_ich8lan) | 583 | if (mac->type == e1000_ich8lan) |
562 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); | 584 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); |
563 | 585 | ||
564 | /* Disable PHY configuration by hardware, config by software */ | 586 | /* Gate automatic PHY configuration by hardware on managed 82579 */ |
565 | if (mac->type == e1000_pch2lan) { | 587 | if ((mac->type == e1000_pch2lan) && |
566 | u32 extcnf_ctrl = er32(EXTCNF_CTRL); | 588 | (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) |
567 | 589 | e1000_gate_hw_phy_config_ich8lan(hw, true); | |
568 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
569 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
570 | } | ||
571 | 590 | ||
572 | return 0; | 591 | return 0; |
573 | } | 592 | } |
@@ -652,6 +671,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
652 | goto out; | 671 | goto out; |
653 | } | 672 | } |
654 | 673 | ||
674 | if (hw->mac.type == e1000_pch2lan) { | ||
675 | ret_val = e1000_k1_workaround_lv(hw); | ||
676 | if (ret_val) | ||
677 | goto out; | ||
678 | } | ||
679 | |||
655 | /* | 680 | /* |
656 | * Check if there was DownShift, must be checked | 681 | * Check if there was DownShift, must be checked |
657 | * immediately after link-up | 682 | * immediately after link-up |
@@ -895,6 +920,34 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
895 | } | 920 | } |
896 | 921 | ||
897 | /** | 922 | /** |
923 | * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states | ||
924 | * @hw: pointer to the HW structure | ||
925 | * | ||
926 | * Assumes semaphore already acquired. | ||
927 | * | ||
928 | **/ | ||
929 | static s32 e1000_write_smbus_addr(struct e1000_hw *hw) | ||
930 | { | ||
931 | u16 phy_data; | ||
932 | u32 strap = er32(STRAP); | ||
933 | s32 ret_val = 0; | ||
934 | |||
935 | strap &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
936 | |||
937 | ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data); | ||
938 | if (ret_val) | ||
939 | goto out; | ||
940 | |||
941 | phy_data &= ~HV_SMB_ADDR_MASK; | ||
942 | phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT); | ||
943 | phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
944 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); | ||
945 | |||
946 | out: | ||
947 | return ret_val; | ||
948 | } | ||
949 | |||
950 | /** | ||
898 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration | 951 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration |
899 | * @hw: pointer to the HW structure | 952 | * @hw: pointer to the HW structure |
900 | * | 953 | * |
@@ -903,7 +956,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
903 | **/ | 956 | **/ |
904 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | 957 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) |
905 | { | 958 | { |
906 | struct e1000_adapter *adapter = hw->adapter; | ||
907 | struct e1000_phy_info *phy = &hw->phy; | 959 | struct e1000_phy_info *phy = &hw->phy; |
908 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; | 960 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; |
909 | s32 ret_val = 0; | 961 | s32 ret_val = 0; |
@@ -921,7 +973,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
921 | if (phy->type != e1000_phy_igp_3) | 973 | if (phy->type != e1000_phy_igp_3) |
922 | return ret_val; | 974 | return ret_val; |
923 | 975 | ||
924 | if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) { | 976 | if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) || |
977 | (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) { | ||
925 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; | 978 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; |
926 | break; | 979 | break; |
927 | } | 980 | } |
@@ -961,21 +1014,16 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
961 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | 1014 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; |
962 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | 1015 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; |
963 | 1016 | ||
964 | if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && | 1017 | if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && |
965 | ((hw->mac.type == e1000_pchlan) || | 1018 | (hw->mac.type == e1000_pchlan)) || |
966 | (hw->mac.type == e1000_pch2lan))) { | 1019 | (hw->mac.type == e1000_pch2lan)) { |
967 | /* | 1020 | /* |
968 | * HW configures the SMBus address and LEDs when the | 1021 | * HW configures the SMBus address and LEDs when the |
969 | * OEM and LCD Write Enable bits are set in the NVM. | 1022 | * OEM and LCD Write Enable bits are set in the NVM. |
970 | * When both NVM bits are cleared, SW will configure | 1023 | * When both NVM bits are cleared, SW will configure |
971 | * them instead. | 1024 | * them instead. |
972 | */ | 1025 | */ |
973 | data = er32(STRAP); | 1026 | ret_val = e1000_write_smbus_addr(hw); |
974 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
975 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
976 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
977 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
978 | reg_data); | ||
979 | if (ret_val) | 1027 | if (ret_val) |
980 | goto out; | 1028 | goto out; |
981 | 1029 | ||
@@ -1440,10 +1488,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1440 | goto out; | 1488 | goto out; |
1441 | 1489 | ||
1442 | /* Enable jumbo frame workaround in the PHY */ | 1490 | /* Enable jumbo frame workaround in the PHY */ |
1443 | e1e_rphy(hw, PHY_REG(769, 20), &data); | ||
1444 | ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14)); | ||
1445 | if (ret_val) | ||
1446 | goto out; | ||
1447 | e1e_rphy(hw, PHY_REG(769, 23), &data); | 1491 | e1e_rphy(hw, PHY_REG(769, 23), &data); |
1448 | data &= ~(0x7F << 5); | 1492 | data &= ~(0x7F << 5); |
1449 | data |= (0x37 << 5); | 1493 | data |= (0x37 << 5); |
@@ -1452,7 +1496,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1452 | goto out; | 1496 | goto out; |
1453 | e1e_rphy(hw, PHY_REG(769, 16), &data); | 1497 | e1e_rphy(hw, PHY_REG(769, 16), &data); |
1454 | data &= ~(1 << 13); | 1498 | data &= ~(1 << 13); |
1455 | data |= (1 << 12); | ||
1456 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); | 1499 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); |
1457 | if (ret_val) | 1500 | if (ret_val) |
1458 | goto out; | 1501 | goto out; |
@@ -1477,7 +1520,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1477 | 1520 | ||
1478 | mac_reg = er32(RCTL); | 1521 | mac_reg = er32(RCTL); |
1479 | mac_reg &= ~E1000_RCTL_SECRC; | 1522 | mac_reg &= ~E1000_RCTL_SECRC; |
1480 | ew32(FFLT_DBG, mac_reg); | 1523 | ew32(RCTL, mac_reg); |
1481 | 1524 | ||
1482 | ret_val = e1000e_read_kmrn_reg(hw, | 1525 | ret_val = e1000e_read_kmrn_reg(hw, |
1483 | E1000_KMRNCTRLSTA_CTRL_OFFSET, | 1526 | E1000_KMRNCTRLSTA_CTRL_OFFSET, |
@@ -1503,17 +1546,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1503 | goto out; | 1546 | goto out; |
1504 | 1547 | ||
1505 | /* Write PHY register values back to h/w defaults */ | 1548 | /* Write PHY register values back to h/w defaults */ |
1506 | e1e_rphy(hw, PHY_REG(769, 20), &data); | ||
1507 | ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14)); | ||
1508 | if (ret_val) | ||
1509 | goto out; | ||
1510 | e1e_rphy(hw, PHY_REG(769, 23), &data); | 1549 | e1e_rphy(hw, PHY_REG(769, 23), &data); |
1511 | data &= ~(0x7F << 5); | 1550 | data &= ~(0x7F << 5); |
1512 | ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); | 1551 | ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); |
1513 | if (ret_val) | 1552 | if (ret_val) |
1514 | goto out; | 1553 | goto out; |
1515 | e1e_rphy(hw, PHY_REG(769, 16), &data); | 1554 | e1e_rphy(hw, PHY_REG(769, 16), &data); |
1516 | data &= ~(1 << 12); | ||
1517 | data |= (1 << 13); | 1555 | data |= (1 << 13); |
1518 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); | 1556 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); |
1519 | if (ret_val) | 1557 | if (ret_val) |
@@ -1559,6 +1597,69 @@ out: | |||
1559 | } | 1597 | } |
1560 | 1598 | ||
1561 | /** | 1599 | /** |
1600 | * e1000_k1_gig_workaround_lv - K1 Si workaround | ||
1601 | * @hw: pointer to the HW structure | ||
1602 | * | ||
1603 | * Workaround to set the K1 beacon duration for 82579 parts | ||
1604 | **/ | ||
1605 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) | ||
1606 | { | ||
1607 | s32 ret_val = 0; | ||
1608 | u16 status_reg = 0; | ||
1609 | u32 mac_reg; | ||
1610 | |||
1611 | if (hw->mac.type != e1000_pch2lan) | ||
1612 | goto out; | ||
1613 | |||
1614 | /* Set K1 beacon duration based on 1Gbps speed or otherwise */ | ||
1615 | ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); | ||
1616 | if (ret_val) | ||
1617 | goto out; | ||
1618 | |||
1619 | if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) | ||
1620 | == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { | ||
1621 | mac_reg = er32(FEXTNVM4); | ||
1622 | mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; | ||
1623 | |||
1624 | if (status_reg & HV_M_STATUS_SPEED_1000) | ||
1625 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; | ||
1626 | else | ||
1627 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; | ||
1628 | |||
1629 | ew32(FEXTNVM4, mac_reg); | ||
1630 | } | ||
1631 | |||
1632 | out: | ||
1633 | return ret_val; | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
1637 | * e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware | ||
1638 | * @hw: pointer to the HW structure | ||
1639 | * @gate: boolean set to true to gate, false to ungate | ||
1640 | * | ||
1641 | * Gate/ungate the automatic PHY configuration via hardware; perform | ||
1642 | * the configuration via software instead. | ||
1643 | **/ | ||
1644 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) | ||
1645 | { | ||
1646 | u32 extcnf_ctrl; | ||
1647 | |||
1648 | if (hw->mac.type != e1000_pch2lan) | ||
1649 | return; | ||
1650 | |||
1651 | extcnf_ctrl = er32(EXTCNF_CTRL); | ||
1652 | |||
1653 | if (gate) | ||
1654 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
1655 | else | ||
1656 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
1657 | |||
1658 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
1659 | return; | ||
1660 | } | ||
1661 | |||
1662 | /** | ||
1562 | * e1000_lan_init_done_ich8lan - Check for PHY config completion | 1663 | * e1000_lan_init_done_ich8lan - Check for PHY config completion |
1563 | * @hw: pointer to the HW structure | 1664 | * @hw: pointer to the HW structure |
1564 | * | 1665 | * |
@@ -1602,6 +1703,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
1602 | if (e1000_check_reset_block(hw)) | 1703 | if (e1000_check_reset_block(hw)) |
1603 | goto out; | 1704 | goto out; |
1604 | 1705 | ||
1706 | /* Allow time for h/w to get to quiescent state after reset */ | ||
1707 | msleep(10); | ||
1708 | |||
1605 | /* Perform any necessary post-reset workarounds */ | 1709 | /* Perform any necessary post-reset workarounds */ |
1606 | switch (hw->mac.type) { | 1710 | switch (hw->mac.type) { |
1607 | case e1000_pchlan: | 1711 | case e1000_pchlan: |
@@ -1630,6 +1734,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
1630 | /* Configure the LCD with the OEM bits in NVM */ | 1734 | /* Configure the LCD with the OEM bits in NVM */ |
1631 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); | 1735 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); |
1632 | 1736 | ||
1737 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
1738 | if ((hw->mac.type == e1000_pch2lan) && | ||
1739 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | ||
1740 | msleep(10); | ||
1741 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
1742 | } | ||
1743 | |||
1633 | out: | 1744 | out: |
1634 | return ret_val; | 1745 | return ret_val; |
1635 | } | 1746 | } |
@@ -1646,6 +1757,11 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
1646 | { | 1757 | { |
1647 | s32 ret_val = 0; | 1758 | s32 ret_val = 0; |
1648 | 1759 | ||
1760 | /* Gate automatic PHY configuration by hardware on non-managed 82579 */ | ||
1761 | if ((hw->mac.type == e1000_pch2lan) && | ||
1762 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
1763 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
1764 | |||
1649 | ret_val = e1000e_phy_hw_reset_generic(hw); | 1765 | ret_val = e1000e_phy_hw_reset_generic(hw); |
1650 | if (ret_val) | 1766 | if (ret_val) |
1651 | goto out; | 1767 | goto out; |
@@ -2910,6 +3026,14 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2910 | * external PHY is reset. | 3026 | * external PHY is reset. |
2911 | */ | 3027 | */ |
2912 | ctrl |= E1000_CTRL_PHY_RST; | 3028 | ctrl |= E1000_CTRL_PHY_RST; |
3029 | |||
3030 | /* | ||
3031 | * Gate automatic PHY configuration by hardware on | ||
3032 | * non-managed 82579 | ||
3033 | */ | ||
3034 | if ((hw->mac.type == e1000_pch2lan) && | ||
3035 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
3036 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
2913 | } | 3037 | } |
2914 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 3038 | ret_val = e1000_acquire_swflag_ich8lan(hw); |
2915 | e_dbg("Issuing a global reset to ich8lan\n"); | 3039 | e_dbg("Issuing a global reset to ich8lan\n"); |
@@ -3460,13 +3584,20 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) | |||
3460 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) | 3584 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) |
3461 | { | 3585 | { |
3462 | u32 phy_ctrl; | 3586 | u32 phy_ctrl; |
3587 | s32 ret_val; | ||
3463 | 3588 | ||
3464 | phy_ctrl = er32(PHY_CTRL); | 3589 | phy_ctrl = er32(PHY_CTRL); |
3465 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; | 3590 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; |
3466 | ew32(PHY_CTRL, phy_ctrl); | 3591 | ew32(PHY_CTRL, phy_ctrl); |
3467 | 3592 | ||
3468 | if (hw->mac.type >= e1000_pchlan) | 3593 | if (hw->mac.type >= e1000_pchlan) { |
3469 | e1000_phy_hw_reset_ich8lan(hw); | 3594 | e1000_oem_bits_config_ich8lan(hw, true); |
3595 | ret_val = hw->phy.ops.acquire(hw); | ||
3596 | if (ret_val) | ||
3597 | return; | ||
3598 | e1000_write_smbus_addr(hw); | ||
3599 | hw->phy.ops.release(hw); | ||
3600 | } | ||
3470 | } | 3601 | } |
3471 | 3602 | ||
3472 | /** | 3603 | /** |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2b8ef44bd2b1..e561d15c3eb1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2704,6 +2704,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2704 | u32 psrctl = 0; | 2704 | u32 psrctl = 0; |
2705 | u32 pages = 0; | 2705 | u32 pages = 0; |
2706 | 2706 | ||
2707 | /* Workaround Si errata on 82579 - configure jumbo frame flow */ | ||
2708 | if (hw->mac.type == e1000_pch2lan) { | ||
2709 | s32 ret_val; | ||
2710 | |||
2711 | if (adapter->netdev->mtu > ETH_DATA_LEN) | ||
2712 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); | ||
2713 | else | ||
2714 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); | ||
2715 | } | ||
2716 | |||
2707 | /* Program MC offset vector base */ | 2717 | /* Program MC offset vector base */ |
2708 | rctl = er32(RCTL); | 2718 | rctl = er32(RCTL); |
2709 | rctl &= ~(3 << E1000_RCTL_MO_SHIFT); | 2719 | rctl &= ~(3 << E1000_RCTL_MO_SHIFT); |
@@ -2744,16 +2754,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2744 | e1e_wphy(hw, 22, phy_data); | 2754 | e1e_wphy(hw, 22, phy_data); |
2745 | } | 2755 | } |
2746 | 2756 | ||
2747 | /* Workaround Si errata on 82579 - configure jumbo frame flow */ | ||
2748 | if (hw->mac.type == e1000_pch2lan) { | ||
2749 | s32 ret_val; | ||
2750 | |||
2751 | if (rctl & E1000_RCTL_LPE) | ||
2752 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); | ||
2753 | else | ||
2754 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); | ||
2755 | } | ||
2756 | |||
2757 | /* Setup buffer sizes */ | 2757 | /* Setup buffer sizes */ |
2758 | rctl &= ~E1000_RCTL_SZ_4096; | 2758 | rctl &= ~E1000_RCTL_SZ_4096; |
2759 | rctl |= E1000_RCTL_BSEX; | 2759 | rctl |= E1000_RCTL_BSEX; |
@@ -4833,6 +4833,15 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4833 | return -EINVAL; | 4833 | return -EINVAL; |
4834 | } | 4834 | } |
4835 | 4835 | ||
4836 | /* Jumbo frame workaround on 82579 requires CRC be stripped */ | ||
4837 | if ((adapter->hw.mac.type == e1000_pch2lan) && | ||
4838 | !(adapter->flags2 & FLAG2_CRC_STRIPPING) && | ||
4839 | (new_mtu > ETH_DATA_LEN)) { | ||
4840 | e_err("Jumbo Frames not supported on 82579 when CRC " | ||
4841 | "stripping is disabled.\n"); | ||
4842 | return -EINVAL; | ||
4843 | } | ||
4844 | |||
4836 | /* 82573 Errata 17 */ | 4845 | /* 82573 Errata 17 */ |
4837 | if (((adapter->hw.mac.type == e1000_82573) || | 4846 | if (((adapter->hw.mac.type == e1000_82573) || |
4838 | (adapter->hw.mac.type == e1000_82574)) && | 4847 | (adapter->hw.mac.type == e1000_82574)) && |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 3506fd6ad726..519e19e23955 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -2928,7 +2928,7 @@ static int __devinit emac_probe(struct platform_device *ofdev, | |||
2928 | if (dev->emac_irq != NO_IRQ) | 2928 | if (dev->emac_irq != NO_IRQ) |
2929 | irq_dispose_mapping(dev->emac_irq); | 2929 | irq_dispose_mapping(dev->emac_irq); |
2930 | err_free: | 2930 | err_free: |
2931 | kfree(ndev); | 2931 | free_netdev(ndev); |
2932 | err_gone: | 2932 | err_gone: |
2933 | /* if we were on the bootlist, remove us as we won't show up and | 2933 | /* if we were on the bootlist, remove us as we won't show up and |
2934 | * wake up all waiters to notify them in case they were waiting | 2934 | * wake up all waiters to notify them in case they were waiting |
@@ -2971,7 +2971,7 @@ static int __devexit emac_remove(struct platform_device *ofdev) | |||
2971 | if (dev->emac_irq != NO_IRQ) | 2971 | if (dev->emac_irq != NO_IRQ) |
2972 | irq_dispose_mapping(dev->emac_irq); | 2972 | irq_dispose_mapping(dev->emac_irq); |
2973 | 2973 | ||
2974 | kfree(dev->ndev); | 2974 | free_netdev(dev->ndev); |
2975 | 2975 | ||
2976 | return 0; | 2976 | return 0; |
2977 | } | 2977 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index cabae7bb1fc6..b075a35b85d4 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1540,7 +1540,6 @@ netxen_process_rcv(struct netxen_adapter *adapter, | |||
1540 | if (pkt_offset) | 1540 | if (pkt_offset) |
1541 | skb_pull(skb, pkt_offset); | 1541 | skb_pull(skb, pkt_offset); |
1542 | 1542 | ||
1543 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1544 | skb->protocol = eth_type_trans(skb, netdev); | 1543 | skb->protocol = eth_type_trans(skb, netdev); |
1545 | 1544 | ||
1546 | napi_gro_receive(&sds_ring->napi, skb); | 1545 | napi_gro_receive(&sds_ring->napi, skb); |
@@ -1602,8 +1601,6 @@ netxen_process_lro(struct netxen_adapter *adapter, | |||
1602 | 1601 | ||
1603 | skb_put(skb, lro_length + data_offset); | 1602 | skb_put(skb, lro_length + data_offset); |
1604 | 1603 | ||
1605 | skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); | ||
1606 | |||
1607 | skb_pull(skb, l2_hdr_offset); | 1604 | skb_pull(skb, l2_hdr_offset); |
1608 | skb->protocol = eth_type_trans(skb, netdev); | 1605 | skb->protocol = eth_type_trans(skb, netdev); |
1609 | 1606 | ||
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 75ba744b173c..2c7cf0b64811 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -1316,7 +1316,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, | |||
1316 | return -ENOMEM; | 1316 | return -ENOMEM; |
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | skb_reserve(skb, 2); | 1319 | skb_reserve(skb, NET_IP_ALIGN); |
1320 | 1320 | ||
1321 | dma = pci_map_single(pdev, skb->data, | 1321 | dma = pci_map_single(pdev, skb->data, |
1322 | rds_ring->dma_size, PCI_DMA_FROMDEVICE); | 1322 | rds_ring->dma_size, PCI_DMA_FROMDEVICE); |
@@ -1404,7 +1404,6 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, | |||
1404 | if (pkt_offset) | 1404 | if (pkt_offset) |
1405 | skb_pull(skb, pkt_offset); | 1405 | skb_pull(skb, pkt_offset); |
1406 | 1406 | ||
1407 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1408 | skb->protocol = eth_type_trans(skb, netdev); | 1407 | skb->protocol = eth_type_trans(skb, netdev); |
1409 | 1408 | ||
1410 | napi_gro_receive(&sds_ring->napi, skb); | 1409 | napi_gro_receive(&sds_ring->napi, skb); |
@@ -1466,8 +1465,6 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1466 | 1465 | ||
1467 | skb_put(skb, lro_length + data_offset); | 1466 | skb_put(skb, lro_length + data_offset); |
1468 | 1467 | ||
1469 | skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); | ||
1470 | |||
1471 | skb_pull(skb, l2_hdr_offset); | 1468 | skb_pull(skb, l2_hdr_offset); |
1472 | skb->protocol = eth_type_trans(skb, netdev); | 1469 | skb->protocol = eth_type_trans(skb, netdev); |
1473 | 1470 | ||
@@ -1700,8 +1697,6 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, | |||
1700 | if (pkt_offset) | 1697 | if (pkt_offset) |
1701 | skb_pull(skb, pkt_offset); | 1698 | skb_pull(skb, pkt_offset); |
1702 | 1699 | ||
1703 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1704 | |||
1705 | if (!qlcnic_check_loopback_buff(skb->data)) | 1700 | if (!qlcnic_check_loopback_buff(skb->data)) |
1706 | adapter->diag_cnt++; | 1701 | adapter->diag_cnt++; |
1707 | 1702 | ||
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 07eb884ff982..44150f2f7bfd 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c | |||
@@ -384,7 +384,7 @@ static void rionet_remove(struct rio_dev *rdev) | |||
384 | free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? | 384 | free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? |
385 | __ilog2(sizeof(void *)) + 4 : 0); | 385 | __ilog2(sizeof(void *)) + 4 : 0); |
386 | unregister_netdev(ndev); | 386 | unregister_netdev(ndev); |
387 | kfree(ndev); | 387 | free_netdev(ndev); |
388 | 388 | ||
389 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { | 389 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { |
390 | list_del(&peer->node); | 390 | list_del(&peer->node); |
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index cc4bd8c65f8b..9265315baa0b 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c | |||
@@ -804,7 +804,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
804 | err_out_free_page: | 804 | err_out_free_page: |
805 | free_page((unsigned long) sp->srings); | 805 | free_page((unsigned long) sp->srings); |
806 | err_out_free_dev: | 806 | err_out_free_dev: |
807 | kfree(dev); | 807 | free_netdev(dev); |
808 | 808 | ||
809 | err_out: | 809 | err_out: |
810 | return err; | 810 | return err; |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 0909ae934ad0..8150ba154116 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -58,6 +58,7 @@ | |||
58 | 58 | ||
59 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
60 | MODULE_VERSION(SMSC_DRV_VERSION); | 60 | MODULE_VERSION(SMSC_DRV_VERSION); |
61 | MODULE_ALIAS("platform:smsc911x"); | ||
61 | 62 | ||
62 | #if USE_DEBUG > 0 | 63 | #if USE_DEBUG > 0 |
63 | static int debug = 16; | 64 | static int debug = 16; |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5efa57757a2c..6888e3d41462 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -243,6 +243,7 @@ enum { | |||
243 | NWayState = (1 << 14) | (1 << 13) | (1 << 12), | 243 | NWayState = (1 << 14) | (1 << 13) | (1 << 12), |
244 | NWayRestart = (1 << 12), | 244 | NWayRestart = (1 << 12), |
245 | NonselPortActive = (1 << 9), | 245 | NonselPortActive = (1 << 9), |
246 | SelPortActive = (1 << 8), | ||
246 | LinkFailStatus = (1 << 2), | 247 | LinkFailStatus = (1 << 2), |
247 | NetCxnErr = (1 << 1), | 248 | NetCxnErr = (1 << 1), |
248 | }; | 249 | }; |
@@ -363,7 +364,9 @@ static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, }; | |||
363 | 364 | ||
364 | /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ | 365 | /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ |
365 | static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; | 366 | static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; |
366 | static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; | 367 | static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; |
368 | /* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */ | ||
369 | static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; | ||
367 | static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; | 370 | static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; |
368 | 371 | ||
369 | 372 | ||
@@ -1064,6 +1067,9 @@ static void de21041_media_timer (unsigned long data) | |||
1064 | unsigned int carrier; | 1067 | unsigned int carrier; |
1065 | unsigned long flags; | 1068 | unsigned long flags; |
1066 | 1069 | ||
1070 | /* clear port active bits */ | ||
1071 | dw32(SIAStatus, NonselPortActive | SelPortActive); | ||
1072 | |||
1067 | carrier = (status & NetCxnErr) ? 0 : 1; | 1073 | carrier = (status & NetCxnErr) ? 0 : 1; |
1068 | 1074 | ||
1069 | if (carrier) { | 1075 | if (carrier) { |
@@ -1158,14 +1164,29 @@ no_link_yet: | |||
1158 | static void de_media_interrupt (struct de_private *de, u32 status) | 1164 | static void de_media_interrupt (struct de_private *de, u32 status) |
1159 | { | 1165 | { |
1160 | if (status & LinkPass) { | 1166 | if (status & LinkPass) { |
1167 | /* Ignore if current media is AUI or BNC and we can't use TP */ | ||
1168 | if ((de->media_type == DE_MEDIA_AUI || | ||
1169 | de->media_type == DE_MEDIA_BNC) && | ||
1170 | (de->media_lock || | ||
1171 | !de_ok_to_advertise(de, DE_MEDIA_TP_AUTO))) | ||
1172 | return; | ||
1173 | /* If current media is not TP, change it to TP */ | ||
1174 | if ((de->media_type == DE_MEDIA_AUI || | ||
1175 | de->media_type == DE_MEDIA_BNC)) { | ||
1176 | de->media_type = DE_MEDIA_TP_AUTO; | ||
1177 | de_stop_rxtx(de); | ||
1178 | de_set_media(de); | ||
1179 | de_start_rxtx(de); | ||
1180 | } | ||
1161 | de_link_up(de); | 1181 | de_link_up(de); |
1162 | mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK); | 1182 | mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK); |
1163 | return; | 1183 | return; |
1164 | } | 1184 | } |
1165 | 1185 | ||
1166 | BUG_ON(!(status & LinkFail)); | 1186 | BUG_ON(!(status & LinkFail)); |
1167 | 1187 | /* Mark the link as down only if current media is TP */ | |
1168 | if (netif_carrier_ok(de->dev)) { | 1188 | if (netif_carrier_ok(de->dev) && de->media_type != DE_MEDIA_AUI && |
1189 | de->media_type != DE_MEDIA_BNC) { | ||
1169 | de_link_down(de); | 1190 | de_link_down(de); |
1170 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); | 1191 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); |
1171 | } | 1192 | } |
@@ -1229,6 +1250,7 @@ static void de_adapter_sleep (struct de_private *de) | |||
1229 | if (de->de21040) | 1250 | if (de->de21040) |
1230 | return; | 1251 | return; |
1231 | 1252 | ||
1253 | dw32(CSR13, 0); /* Reset phy */ | ||
1232 | pci_read_config_dword(de->pdev, PCIPM, &pmctl); | 1254 | pci_read_config_dword(de->pdev, PCIPM, &pmctl); |
1233 | pmctl |= PM_Sleep; | 1255 | pmctl |= PM_Sleep; |
1234 | pci_write_config_dword(de->pdev, PCIPM, pmctl); | 1256 | pci_write_config_dword(de->pdev, PCIPM, pmctl); |
@@ -1574,12 +1596,15 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd) | |||
1574 | return 0; /* nothing to change */ | 1596 | return 0; /* nothing to change */ |
1575 | 1597 | ||
1576 | de_link_down(de); | 1598 | de_link_down(de); |
1599 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); | ||
1577 | de_stop_rxtx(de); | 1600 | de_stop_rxtx(de); |
1578 | 1601 | ||
1579 | de->media_type = new_media; | 1602 | de->media_type = new_media; |
1580 | de->media_lock = media_lock; | 1603 | de->media_lock = media_lock; |
1581 | de->media_advertise = ecmd->advertising; | 1604 | de->media_advertise = ecmd->advertising; |
1582 | de_set_media(de); | 1605 | de_set_media(de); |
1606 | if (netif_running(de->dev)) | ||
1607 | de_start_rxtx(de); | ||
1583 | 1608 | ||
1584 | return 0; | 1609 | return 0; |
1585 | } | 1610 | } |
@@ -1911,8 +1936,14 @@ fill_defaults: | |||
1911 | for (i = 0; i < DE_MAX_MEDIA; i++) { | 1936 | for (i = 0; i < DE_MAX_MEDIA; i++) { |
1912 | if (de->media[i].csr13 == 0xffff) | 1937 | if (de->media[i].csr13 == 0xffff) |
1913 | de->media[i].csr13 = t21041_csr13[i]; | 1938 | de->media[i].csr13 = t21041_csr13[i]; |
1914 | if (de->media[i].csr14 == 0xffff) | 1939 | if (de->media[i].csr14 == 0xffff) { |
1915 | de->media[i].csr14 = t21041_csr14[i]; | 1940 | /* autonegotiation is broken at least on some chip |
1941 | revisions - rev. 0x21 works, 0x11 does not */ | ||
1942 | if (de->pdev->revision < 0x20) | ||
1943 | de->media[i].csr14 = t21041_csr14_brk[i]; | ||
1944 | else | ||
1945 | de->media[i].csr14 = t21041_csr14[i]; | ||
1946 | } | ||
1916 | if (de->media[i].csr15 == 0xffff) | 1947 | if (de->media[i].csr15 == 0xffff) |
1917 | de->media[i].csr15 = t21041_csr15[i]; | 1948 | de->media[i].csr15 = t21041_csr15[i]; |
1918 | } | 1949 | } |
@@ -2158,6 +2189,8 @@ static int de_resume (struct pci_dev *pdev) | |||
2158 | dev_err(&dev->dev, "pci_enable_device failed in resume\n"); | 2189 | dev_err(&dev->dev, "pci_enable_device failed in resume\n"); |
2159 | goto out; | 2190 | goto out; |
2160 | } | 2191 | } |
2192 | pci_set_master(pdev); | ||
2193 | de_init_rings(de); | ||
2161 | de_init_hw(de); | 2194 | de_init_hw(de); |
2162 | out_attach: | 2195 | out_attach: |
2163 | netif_device_attach(dev); | 2196 | netif_device_attach(dev); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9dd9e64c2b0b..8fd00a6e5120 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1411 | clear_bit(STATUS_SCAN_HW, &priv->status); | 1411 | clear_bit(STATUS_SCAN_HW, &priv->status); |
1412 | clear_bit(STATUS_SCANNING, &priv->status); | 1412 | clear_bit(STATUS_SCANNING, &priv->status); |
1413 | /* inform mac80211 scan aborted */ | 1413 | /* inform mac80211 scan aborted */ |
1414 | queue_work(priv->workqueue, &priv->scan_completed); | 1414 | queue_work(priv->workqueue, &priv->abort_scan); |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, | 1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 07dbc2796448..e23c4060a0f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2613,6 +2613,11 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
2613 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2613 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2614 | return -EINVAL; | 2614 | return -EINVAL; |
2615 | 2615 | ||
2616 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
2617 | IWL_DEBUG_INFO(priv, "scan in progress.\n"); | ||
2618 | return -EINVAL; | ||
2619 | } | ||
2620 | |||
2616 | if (mode >= IWL_MAX_FORCE_RESET) { | 2621 | if (mode >= IWL_MAX_FORCE_RESET) { |
2617 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); | 2622 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); |
2618 | return -EINVAL; | 2623 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 59a308b02f95..d31661c1ce77 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3018 | clear_bit(STATUS_SCANNING, &priv->status); | 3018 | clear_bit(STATUS_SCANNING, &priv->status); |
3019 | 3019 | ||
3020 | /* inform mac80211 scan aborted */ | 3020 | /* inform mac80211 scan aborted */ |
3021 | queue_work(priv->workqueue, &priv->scan_completed); | 3021 | queue_work(priv->workqueue, &priv->abort_scan); |
3022 | } | 3022 | } |
3023 | 3023 | ||
3024 | static void iwl3945_bg_restart(struct work_struct *data) | 3024 | static void iwl3945_bg_restart(struct work_struct *data) |
diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index b17235a24a4d..79c0005134a1 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c | |||
@@ -77,7 +77,7 @@ static int op_create_counter(int cpu, int event) | |||
77 | return 0; | 77 | return 0; |
78 | 78 | ||
79 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, | 79 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, |
80 | cpu, -1, | 80 | cpu, NULL, |
81 | op_overflow_handler); | 81 | op_overflow_handler); |
82 | 82 | ||
83 | if (IS_ERR(pevent)) | 83 | if (IS_ERR(pevent)) |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index c3ceebb5be84..4789f8e8bf7a 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -71,6 +71,49 @@ | |||
71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) | 71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) |
72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) | 72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) |
73 | 73 | ||
74 | /* page table handling */ | ||
75 | #define LEVEL_STRIDE (9) | ||
76 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
77 | |||
78 | static inline int agaw_to_level(int agaw) | ||
79 | { | ||
80 | return agaw + 2; | ||
81 | } | ||
82 | |||
83 | static inline int agaw_to_width(int agaw) | ||
84 | { | ||
85 | return 30 + agaw * LEVEL_STRIDE; | ||
86 | } | ||
87 | |||
88 | static inline int width_to_agaw(int width) | ||
89 | { | ||
90 | return (width - 30) / LEVEL_STRIDE; | ||
91 | } | ||
92 | |||
93 | static inline unsigned int level_to_offset_bits(int level) | ||
94 | { | ||
95 | return (level - 1) * LEVEL_STRIDE; | ||
96 | } | ||
97 | |||
98 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
99 | { | ||
100 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
101 | } | ||
102 | |||
103 | static inline unsigned long level_mask(int level) | ||
104 | { | ||
105 | return -1UL << level_to_offset_bits(level); | ||
106 | } | ||
107 | |||
108 | static inline unsigned long level_size(int level) | ||
109 | { | ||
110 | return 1UL << level_to_offset_bits(level); | ||
111 | } | ||
112 | |||
113 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
114 | { | ||
115 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
116 | } | ||
74 | 117 | ||
75 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things | 118 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
76 | are never going to work. */ | 119 | are never going to work. */ |
@@ -434,8 +477,6 @@ void free_iova_mem(struct iova *iova) | |||
434 | } | 477 | } |
435 | 478 | ||
436 | 479 | ||
437 | static inline int width_to_agaw(int width); | ||
438 | |||
439 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) | 480 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) |
440 | { | 481 | { |
441 | unsigned long sagaw; | 482 | unsigned long sagaw; |
@@ -646,51 +687,6 @@ out: | |||
646 | spin_unlock_irqrestore(&iommu->lock, flags); | 687 | spin_unlock_irqrestore(&iommu->lock, flags); |
647 | } | 688 | } |
648 | 689 | ||
649 | /* page table handling */ | ||
650 | #define LEVEL_STRIDE (9) | ||
651 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
652 | |||
653 | static inline int agaw_to_level(int agaw) | ||
654 | { | ||
655 | return agaw + 2; | ||
656 | } | ||
657 | |||
658 | static inline int agaw_to_width(int agaw) | ||
659 | { | ||
660 | return 30 + agaw * LEVEL_STRIDE; | ||
661 | |||
662 | } | ||
663 | |||
664 | static inline int width_to_agaw(int width) | ||
665 | { | ||
666 | return (width - 30) / LEVEL_STRIDE; | ||
667 | } | ||
668 | |||
669 | static inline unsigned int level_to_offset_bits(int level) | ||
670 | { | ||
671 | return (level - 1) * LEVEL_STRIDE; | ||
672 | } | ||
673 | |||
674 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
675 | { | ||
676 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
677 | } | ||
678 | |||
679 | static inline unsigned long level_mask(int level) | ||
680 | { | ||
681 | return -1UL << level_to_offset_bits(level); | ||
682 | } | ||
683 | |||
684 | static inline unsigned long level_size(int level) | ||
685 | { | ||
686 | return 1UL << level_to_offset_bits(level); | ||
687 | } | ||
688 | |||
689 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
690 | { | ||
691 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
692 | } | ||
693 | |||
694 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | 690 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
695 | unsigned long pfn) | 691 | unsigned long pfn) |
696 | { | 692 | { |
@@ -3761,6 +3757,33 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | |||
3761 | 3757 | ||
3762 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); | 3758 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); |
3763 | 3759 | ||
3760 | #define GGC 0x52 | ||
3761 | #define GGC_MEMORY_SIZE_MASK (0xf << 8) | ||
3762 | #define GGC_MEMORY_SIZE_NONE (0x0 << 8) | ||
3763 | #define GGC_MEMORY_SIZE_1M (0x1 << 8) | ||
3764 | #define GGC_MEMORY_SIZE_2M (0x3 << 8) | ||
3765 | #define GGC_MEMORY_VT_ENABLED (0x8 << 8) | ||
3766 | #define GGC_MEMORY_SIZE_2M_VT (0x9 << 8) | ||
3767 | #define GGC_MEMORY_SIZE_3M_VT (0xa << 8) | ||
3768 | #define GGC_MEMORY_SIZE_4M_VT (0xb << 8) | ||
3769 | |||
3770 | static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev) | ||
3771 | { | ||
3772 | unsigned short ggc; | ||
3773 | |||
3774 | if (pci_read_config_word(dev, GGC, &ggc)) | ||
3775 | return; | ||
3776 | |||
3777 | if (!(ggc & GGC_MEMORY_VT_ENABLED)) { | ||
3778 | printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n"); | ||
3779 | dmar_map_gfx = 0; | ||
3780 | } | ||
3781 | } | ||
3782 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); | ||
3783 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt); | ||
3784 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt); | ||
3785 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt); | ||
3786 | |||
3764 | /* On Tylersburg chipsets, some BIOSes have been known to enable the | 3787 | /* On Tylersburg chipsets, some BIOSes have been known to enable the |
3765 | ISOCH DMAR unit for the Azalia sound device, but not give it any | 3788 | ISOCH DMAR unit for the Azalia sound device, but not give it any |
3766 | TLB entries, which causes it to deadlock. Check for that. We do | 3789 | TLB entries, which causes it to deadlock. Check for that. We do |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index ce6a3666b3d9..553d8ee55c1c 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -608,7 +608,7 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, | |||
608 | * the VF BAR size multiplied by the number of VFs. The alignment | 608 | * the VF BAR size multiplied by the number of VFs. The alignment |
609 | * is just the VF BAR size. | 609 | * is just the VF BAR size. |
610 | */ | 610 | */ |
611 | int pci_sriov_resource_alignment(struct pci_dev *dev, int resno) | 611 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) |
612 | { | 612 | { |
613 | struct resource tmp; | 613 | struct resource tmp; |
614 | enum pci_bar_type type; | 614 | enum pci_bar_type type; |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7754a678ab15..6beb11b617a9 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -264,7 +264,8 @@ extern int pci_iov_init(struct pci_dev *dev); | |||
264 | extern void pci_iov_release(struct pci_dev *dev); | 264 | extern void pci_iov_release(struct pci_dev *dev); |
265 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 265 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, |
266 | enum pci_bar_type *type); | 266 | enum pci_bar_type *type); |
267 | extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno); | 267 | extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, |
268 | int resno); | ||
268 | extern void pci_restore_iov_state(struct pci_dev *dev); | 269 | extern void pci_restore_iov_state(struct pci_dev *dev); |
269 | extern int pci_iov_bus_range(struct pci_bus *bus); | 270 | extern int pci_iov_bus_range(struct pci_bus *bus); |
270 | 271 | ||
@@ -320,7 +321,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) | |||
320 | } | 321 | } |
321 | #endif /* CONFIG_PCI_IOV */ | 322 | #endif /* CONFIG_PCI_IOV */ |
322 | 323 | ||
323 | static inline int pci_resource_alignment(struct pci_dev *dev, | 324 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
324 | struct resource *res) | 325 | struct resource *res) |
325 | { | 326 | { |
326 | #ifdef CONFIG_PCI_IOV | 327 | #ifdef CONFIG_PCI_IOV |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 89ed181cd90c..857ae01734a6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -163,6 +163,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d | |||
163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); | 163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear | ||
167 | * for some HT machines to use C4 w/o hanging. | ||
168 | */ | ||
169 | static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) | ||
170 | { | ||
171 | u32 pmbase; | ||
172 | u16 pm1a; | ||
173 | |||
174 | pci_read_config_dword(dev, 0x40, &pmbase); | ||
175 | pmbase = pmbase & 0xff80; | ||
176 | pm1a = inw(pmbase); | ||
177 | |||
178 | if (pm1a & 0x10) { | ||
179 | dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); | ||
180 | outw(0x10, pmbase); | ||
181 | } | ||
182 | } | ||
183 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); | ||
184 | |||
185 | /* | ||
166 | * Chipsets where PCI->PCI transfers vanish or hang | 186 | * Chipsets where PCI->PCI transfers vanish or hang |
167 | */ | 187 | */ |
168 | static void __devinit quirk_nopcipci(struct pci_dev *dev) | 188 | static void __devinit quirk_nopcipci(struct pci_dev *dev) |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index a5c176598d95..9ba4dade69a4 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -595,7 +595,13 @@ int pcmcia_request_io(struct pcmcia_device *p_dev) | |||
595 | if (c->io[1].end) { | 595 | if (c->io[1].end) { |
596 | ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); | 596 | ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); |
597 | if (ret) { | 597 | if (ret) { |
598 | struct resource tmp = c->io[0]; | ||
599 | /* release the previously allocated resource */ | ||
598 | release_io_space(s, &c->io[0]); | 600 | release_io_space(s, &c->io[0]); |
601 | /* but preserve the settings, for they worked... */ | ||
602 | c->io[0].end = resource_size(&tmp); | ||
603 | c->io[0].start = tmp.start; | ||
604 | c->io[0].flags = tmp.flags; | ||
599 | goto out; | 605 | goto out; |
600 | } | 606 | } |
601 | } else | 607 | } else |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b8a869af0f44..deef6656ab7b 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -646,7 +646,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
646 | if (!pci_resource_start(dev, 0)) { | 646 | if (!pci_resource_start(dev, 0)) { |
647 | dev_warn(&dev->dev, "refusing to load the driver as the " | 647 | dev_warn(&dev->dev, "refusing to load the driver as the " |
648 | "io_base is NULL.\n"); | 648 | "io_base is NULL.\n"); |
649 | goto err_out_free_mem; | 649 | goto err_out_disable; |
650 | } | 650 | } |
651 | 651 | ||
652 | dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " | 652 | dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e35ed128bdef..2d61186ad5a2 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -3093,7 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { | |||
3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ | 3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ |
3094 | }; | 3094 | }; |
3095 | 3095 | ||
3096 | typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | 3096 | typedef u16 tpacpi_keymap_entry_t; |
3097 | typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | ||
3097 | 3098 | ||
3098 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 3099 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
3099 | { | 3100 | { |
@@ -3230,7 +3231,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3230 | }; | 3231 | }; |
3231 | 3232 | ||
3232 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) | 3233 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) |
3233 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0]) | 3234 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t) |
3234 | 3235 | ||
3235 | int res, i; | 3236 | int res, i; |
3236 | int status; | 3237 | int status; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 422a709d271d..cc8b337b9119 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -700,7 +700,7 @@ static void print_constraints(struct regulator_dev *rdev) | |||
700 | constraints->min_uA != constraints->max_uA) { | 700 | constraints->min_uA != constraints->max_uA) { |
701 | ret = _regulator_get_current_limit(rdev); | 701 | ret = _regulator_get_current_limit(rdev); |
702 | if (ret > 0) | 702 | if (ret > 0) |
703 | count += sprintf(buf + count, "at %d uA ", ret / 1000); | 703 | count += sprintf(buf + count, "at %d mA ", ret / 1000); |
704 | } | 704 | } |
705 | 705 | ||
706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) | 706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) |
@@ -2302,8 +2302,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2302 | dev_set_name(&rdev->dev, "regulator.%d", | 2302 | dev_set_name(&rdev->dev, "regulator.%d", |
2303 | atomic_inc_return(®ulator_no) - 1); | 2303 | atomic_inc_return(®ulator_no) - 1); |
2304 | ret = device_register(&rdev->dev); | 2304 | ret = device_register(&rdev->dev); |
2305 | if (ret != 0) | 2305 | if (ret != 0) { |
2306 | put_device(&rdev->dev); | ||
2306 | goto clean; | 2307 | goto clean; |
2308 | } | ||
2307 | 2309 | ||
2308 | dev_set_drvdata(&rdev->dev, rdev); | 2310 | dev_set_drvdata(&rdev->dev, rdev); |
2309 | 2311 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 4520ace3f7e7..6b60a9c0366b 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -330,7 +330,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, | |||
330 | /* set external clock frequency */ | 330 | /* set external clock frequency */ |
331 | info->extclk_freq = pdata->extclk_freq; | 331 | info->extclk_freq = pdata->extclk_freq; |
332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, | 332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, |
333 | info->extclk_freq); | 333 | info->extclk_freq << 6); |
334 | } | 334 | } |
335 | 335 | ||
336 | if (pdata->ramp_timing) { | 336 | if (pdata->ramp_timing) { |
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index d26780ea254b..261a07e0fb24 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c | |||
@@ -235,6 +235,7 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) | |||
235 | err = PTR_ERR(rtc); | 235 | err = PTR_ERR(rtc); |
236 | return err; | 236 | return err; |
237 | } | 237 | } |
238 | platform_set_drvdata(pdev, rtc); | ||
238 | 239 | ||
239 | return 0; | 240 | return 0; |
240 | } | 241 | } |
@@ -244,6 +245,7 @@ static int __exit ab3100_rtc_remove(struct platform_device *pdev) | |||
244 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 245 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
245 | 246 | ||
246 | rtc_device_unregister(rtc); | 247 | rtc_device_unregister(rtc); |
248 | platform_set_drvdata(pdev, NULL); | ||
247 | return 0; | 249 | return 0; |
248 | } | 250 | } |
249 | 251 | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a0d3ec89d412..f57a87f4ae96 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -310,11 +310,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
310 | 310 | ||
311 | s3c_rtc_setaie(alrm->enabled); | 311 | s3c_rtc_setaie(alrm->enabled); |
312 | 312 | ||
313 | if (alrm->enabled) | ||
314 | enable_irq_wake(s3c_rtc_alarmno); | ||
315 | else | ||
316 | disable_irq_wake(s3c_rtc_alarmno); | ||
317 | |||
318 | return 0; | 313 | return 0; |
319 | } | 314 | } |
320 | 315 | ||
@@ -587,6 +582,10 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
587 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 582 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; |
588 | } | 583 | } |
589 | s3c_rtc_enable(pdev, 0); | 584 | s3c_rtc_enable(pdev, 0); |
585 | |||
586 | if (device_may_wakeup(&pdev->dev)) | ||
587 | enable_irq_wake(s3c_rtc_alarmno); | ||
588 | |||
590 | return 0; | 589 | return 0; |
591 | } | 590 | } |
592 | 591 | ||
@@ -600,6 +599,10 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
600 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | 599 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); |
601 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | 600 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); |
602 | } | 601 | } |
602 | |||
603 | if (device_may_wakeup(&pdev->dev)) | ||
604 | disable_irq_wake(s3c_rtc_alarmno); | ||
605 | |||
603 | return 0; | 606 | return 0; |
604 | } | 607 | } |
605 | #else | 608 | #else |
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 6edf20b62de5..2c7d2d9be4d0 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c | |||
@@ -1154,7 +1154,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) | |||
1154 | dev_fsm, dev_fsm_len, GFP_KERNEL); | 1154 | dev_fsm, dev_fsm_len, GFP_KERNEL); |
1155 | if (priv->fsm == NULL) { | 1155 | if (priv->fsm == NULL) { |
1156 | CTCMY_DBF_DEV(SETUP, dev, "init_fsm error"); | 1156 | CTCMY_DBF_DEV(SETUP, dev, "init_fsm error"); |
1157 | kfree(dev); | 1157 | free_netdev(dev); |
1158 | return NULL; | 1158 | return NULL; |
1159 | } | 1159 | } |
1160 | fsm_newstate(priv->fsm, DEV_STATE_STOPPED); | 1160 | fsm_newstate(priv->fsm, DEV_STATE_STOPPED); |
@@ -1165,7 +1165,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) | |||
1165 | grp = ctcmpc_init_mpc_group(priv); | 1165 | grp = ctcmpc_init_mpc_group(priv); |
1166 | if (grp == NULL) { | 1166 | if (grp == NULL) { |
1167 | MPC_DBF_DEV(SETUP, dev, "init_mpc_group error"); | 1167 | MPC_DBF_DEV(SETUP, dev, "init_mpc_group error"); |
1168 | kfree(dev); | 1168 | free_netdev(dev); |
1169 | return NULL; | 1169 | return NULL; |
1170 | } | 1170 | } |
1171 | tasklet_init(&grp->mpc_tasklet2, | 1171 | tasklet_init(&grp->mpc_tasklet2, |
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c index 324c385a653d..5dff45c76d32 100644 --- a/drivers/serial/mfd.c +++ b/drivers/serial/mfd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/sysrq.h> | 29 | #include <linux/sysrq.h> |
30 | #include <linux/slab.h> | ||
30 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
31 | #include <linux/circ_buf.h> | 32 | #include <linux/circ_buf.h> |
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c index f6ad1ecbff79..51c15f58e01e 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/serial/mrst_max3110.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/irq.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/console.h> | 34 | #include <linux/console.h> |
34 | #include <linux/sysrq.h> | 35 | #include <linux/sysrq.h> |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0bcf4c1601a2..b5a78a1f4421 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/cache.h> | 24 | #include <linux/cache.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/of_device.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <linux/mod_devicetable.h> | 28 | #include <linux/mod_devicetable.h> |
28 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
@@ -86,6 +87,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
86 | const struct spi_device *spi = to_spi_device(dev); | 87 | const struct spi_device *spi = to_spi_device(dev); |
87 | const struct spi_driver *sdrv = to_spi_driver(drv); | 88 | const struct spi_driver *sdrv = to_spi_driver(drv); |
88 | 89 | ||
90 | /* Attempt an OF style match */ | ||
91 | if (of_driver_match_device(dev, drv)) | ||
92 | return 1; | ||
93 | |||
89 | if (sdrv->id_table) | 94 | if (sdrv->id_table) |
90 | return !!spi_match_id(sdrv->id_table, spi); | 95 | return !!spi_match_id(sdrv->id_table, spi); |
91 | 96 | ||
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index e24a63498acb..63e51b011d50 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c | |||
@@ -350,7 +350,7 @@ static int __init spi_gpio_probe(struct platform_device *pdev) | |||
350 | spi_gpio->bitbang.master = spi_master_get(master); | 350 | spi_gpio->bitbang.master = spi_master_get(master); |
351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
352 | 352 | ||
353 | if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) { | 353 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { |
354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | 354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; |
355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; | 355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; |
356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; | 356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; |
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index d31b57f7baaf..1dd86b835cd8 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c | |||
@@ -408,11 +408,17 @@ static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) | |||
408 | 408 | ||
409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; | 409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; |
410 | 410 | ||
411 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | 411 | if (mspi->rx_dma == mspi->dma_dummy_rx) |
412 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma); | ||
413 | else | ||
414 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | ||
412 | out_be16(&rx_bd->cbd_datlen, 0); | 415 | out_be16(&rx_bd->cbd_datlen, 0); |
413 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); | 416 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); |
414 | 417 | ||
415 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | 418 | if (mspi->tx_dma == mspi->dma_dummy_tx) |
419 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma); | ||
420 | else | ||
421 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | ||
416 | out_be16(&tx_bd->cbd_datlen, xfer_len); | 422 | out_be16(&tx_bd->cbd_datlen, xfer_len); |
417 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | | 423 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | |
418 | BD_SC_LAST); | 424 | BD_SC_LAST); |
diff --git a/drivers/staging/ti-st/st.h b/drivers/staging/ti-st/st.h index 9952579425b9..1b3060eb2921 100644 --- a/drivers/staging/ti-st/st.h +++ b/drivers/staging/ti-st/st.h | |||
@@ -80,5 +80,4 @@ struct st_proto_s { | |||
80 | extern long st_register(struct st_proto_s *); | 80 | extern long st_register(struct st_proto_s *); |
81 | extern long st_unregister(enum proto_type); | 81 | extern long st_unregister(enum proto_type); |
82 | 82 | ||
83 | extern struct platform_device *st_get_plat_device(void); | ||
84 | #endif /* ST_H */ | 83 | #endif /* ST_H */ |
diff --git a/drivers/staging/ti-st/st_core.c b/drivers/staging/ti-st/st_core.c index 063c9b1db1ab..b85d8bfdf600 100644 --- a/drivers/staging/ti-st/st_core.c +++ b/drivers/staging/ti-st/st_core.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include "st_ll.h" | 38 | #include "st_ll.h" |
39 | #include "st.h" | 39 | #include "st.h" |
40 | 40 | ||
41 | #define VERBOSE | ||
42 | /* strings to be used for rfkill entries and by | 41 | /* strings to be used for rfkill entries and by |
43 | * ST Core to be used for sysfs debug entry | 42 | * ST Core to be used for sysfs debug entry |
44 | */ | 43 | */ |
@@ -581,7 +580,7 @@ long st_register(struct st_proto_s *new_proto) | |||
581 | long err = 0; | 580 | long err = 0; |
582 | unsigned long flags = 0; | 581 | unsigned long flags = 0; |
583 | 582 | ||
584 | st_kim_ref(&st_gdata); | 583 | st_kim_ref(&st_gdata, 0); |
585 | pr_info("%s(%d) ", __func__, new_proto->type); | 584 | pr_info("%s(%d) ", __func__, new_proto->type); |
586 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL | 585 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL |
587 | || new_proto->reg_complete_cb == NULL) { | 586 | || new_proto->reg_complete_cb == NULL) { |
@@ -713,7 +712,7 @@ long st_unregister(enum proto_type type) | |||
713 | 712 | ||
714 | pr_debug("%s: %d ", __func__, type); | 713 | pr_debug("%s: %d ", __func__, type); |
715 | 714 | ||
716 | st_kim_ref(&st_gdata); | 715 | st_kim_ref(&st_gdata, 0); |
717 | if (type < ST_BT || type >= ST_MAX) { | 716 | if (type < ST_BT || type >= ST_MAX) { |
718 | pr_err(" protocol %d not supported", type); | 717 | pr_err(" protocol %d not supported", type); |
719 | return -EPROTONOSUPPORT; | 718 | return -EPROTONOSUPPORT; |
@@ -767,7 +766,7 @@ long st_write(struct sk_buff *skb) | |||
767 | #endif | 766 | #endif |
768 | long len; | 767 | long len; |
769 | 768 | ||
770 | st_kim_ref(&st_gdata); | 769 | st_kim_ref(&st_gdata, 0); |
771 | if (unlikely(skb == NULL || st_gdata == NULL | 770 | if (unlikely(skb == NULL || st_gdata == NULL |
772 | || st_gdata->tty == NULL)) { | 771 | || st_gdata->tty == NULL)) { |
773 | pr_err("data/tty unavailable to perform write"); | 772 | pr_err("data/tty unavailable to perform write"); |
@@ -818,7 +817,7 @@ static int st_tty_open(struct tty_struct *tty) | |||
818 | struct st_data_s *st_gdata; | 817 | struct st_data_s *st_gdata; |
819 | pr_info("%s ", __func__); | 818 | pr_info("%s ", __func__); |
820 | 819 | ||
821 | st_kim_ref(&st_gdata); | 820 | st_kim_ref(&st_gdata, 0); |
822 | st_gdata->tty = tty; | 821 | st_gdata->tty = tty; |
823 | tty->disc_data = st_gdata; | 822 | tty->disc_data = st_gdata; |
824 | 823 | ||
diff --git a/drivers/staging/ti-st/st_core.h b/drivers/staging/ti-st/st_core.h index e0c32d149f5f..8601320a679e 100644 --- a/drivers/staging/ti-st/st_core.h +++ b/drivers/staging/ti-st/st_core.h | |||
@@ -117,7 +117,7 @@ int st_core_init(struct st_data_s **); | |||
117 | void st_core_exit(struct st_data_s *); | 117 | void st_core_exit(struct st_data_s *); |
118 | 118 | ||
119 | /* ask for reference from KIM */ | 119 | /* ask for reference from KIM */ |
120 | void st_kim_ref(struct st_data_s **); | 120 | void st_kim_ref(struct st_data_s **, int); |
121 | 121 | ||
122 | #define GPS_STUB_TEST | 122 | #define GPS_STUB_TEST |
123 | #ifdef GPS_STUB_TEST | 123 | #ifdef GPS_STUB_TEST |
diff --git a/drivers/staging/ti-st/st_kim.c b/drivers/staging/ti-st/st_kim.c index b4a6c7fdc4e6..9e99463f76e8 100644 --- a/drivers/staging/ti-st/st_kim.c +++ b/drivers/staging/ti-st/st_kim.c | |||
@@ -72,11 +72,26 @@ const unsigned char *protocol_names[] = { | |||
72 | PROTO_ENTRY(ST_GPS, "GPS"), | 72 | PROTO_ENTRY(ST_GPS, "GPS"), |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */ | ||
76 | struct platform_device *st_kim_devices[MAX_ST_DEVICES]; | ||
75 | 77 | ||
76 | /**********************************************************************/ | 78 | /**********************************************************************/ |
77 | /* internal functions */ | 79 | /* internal functions */ |
78 | 80 | ||
79 | /** | 81 | /** |
82 | * st_get_plat_device - | ||
83 | * function which returns the reference to the platform device | ||
84 | * requested by id. As of now only 1 such device exists (id=0) | ||
85 | * the context requesting for reference can get the id to be | ||
86 | * requested by a. The protocol driver which is registering or | ||
87 | * b. the tty device which is opened. | ||
88 | */ | ||
89 | static struct platform_device *st_get_plat_device(int id) | ||
90 | { | ||
91 | return st_kim_devices[id]; | ||
92 | } | ||
93 | |||
94 | /** | ||
80 | * validate_firmware_response - | 95 | * validate_firmware_response - |
81 | * function to return whether the firmware response was proper | 96 | * function to return whether the firmware response was proper |
82 | * in case of error don't complete so that waiting for proper | 97 | * in case of error don't complete so that waiting for proper |
@@ -353,7 +368,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) | |||
353 | struct kim_data_s *kim_gdata; | 368 | struct kim_data_s *kim_gdata; |
354 | pr_info(" %s ", __func__); | 369 | pr_info(" %s ", __func__); |
355 | 370 | ||
356 | kim_pdev = st_get_plat_device(); | 371 | kim_pdev = st_get_plat_device(0); |
357 | kim_gdata = dev_get_drvdata(&kim_pdev->dev); | 372 | kim_gdata = dev_get_drvdata(&kim_pdev->dev); |
358 | 373 | ||
359 | if (kim_gdata->gpios[type] == -1) { | 374 | if (kim_gdata->gpios[type] == -1) { |
@@ -574,12 +589,12 @@ static int kim_toggle_radio(void *data, bool blocked) | |||
574 | * This would enable multiple such platform devices to exist | 589 | * This would enable multiple such platform devices to exist |
575 | * on a given platform | 590 | * on a given platform |
576 | */ | 591 | */ |
577 | void st_kim_ref(struct st_data_s **core_data) | 592 | void st_kim_ref(struct st_data_s **core_data, int id) |
578 | { | 593 | { |
579 | struct platform_device *pdev; | 594 | struct platform_device *pdev; |
580 | struct kim_data_s *kim_gdata; | 595 | struct kim_data_s *kim_gdata; |
581 | /* get kim_gdata reference from platform device */ | 596 | /* get kim_gdata reference from platform device */ |
582 | pdev = st_get_plat_device(); | 597 | pdev = st_get_plat_device(id); |
583 | kim_gdata = dev_get_drvdata(&pdev->dev); | 598 | kim_gdata = dev_get_drvdata(&pdev->dev); |
584 | *core_data = kim_gdata->core_data; | 599 | *core_data = kim_gdata->core_data; |
585 | } | 600 | } |
@@ -623,6 +638,7 @@ static int kim_probe(struct platform_device *pdev) | |||
623 | long *gpios = pdev->dev.platform_data; | 638 | long *gpios = pdev->dev.platform_data; |
624 | struct kim_data_s *kim_gdata; | 639 | struct kim_data_s *kim_gdata; |
625 | 640 | ||
641 | st_kim_devices[pdev->id] = pdev; | ||
626 | kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC); | 642 | kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC); |
627 | if (!kim_gdata) { | 643 | if (!kim_gdata) { |
628 | pr_err("no mem to allocate"); | 644 | pr_err("no mem to allocate"); |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 7e594449600e..9eed5b52d9de 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -91,12 +91,12 @@ config USB_DYNAMIC_MINORS | |||
91 | If you are unsure about this, say N here. | 91 | If you are unsure about this, say N here. |
92 | 92 | ||
93 | config USB_SUSPEND | 93 | config USB_SUSPEND |
94 | bool "USB runtime power management (suspend/resume and wakeup)" | 94 | bool "USB runtime power management (autosuspend) and wakeup" |
95 | depends on USB && PM_RUNTIME | 95 | depends on USB && PM_RUNTIME |
96 | help | 96 | help |
97 | If you say Y here, you can use driver calls or the sysfs | 97 | If you say Y here, you can use driver calls or the sysfs |
98 | "power/level" file to suspend or resume individual USB | 98 | "power/control" file to enable or disable autosuspend for |
99 | peripherals and to enable or disable autosuspend (see | 99 | individual USB peripherals (see |
100 | Documentation/usb/power-management.txt for more details). | 100 | Documentation/usb/power-management.txt for more details). |
101 | 101 | ||
102 | Also, USB "remote wakeup" signaling is supported, whereby some | 102 | Also, USB "remote wakeup" signaling is supported, whereby some |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index f06f5dbc8cdc..1e6ccef2cf0c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -159,9 +159,9 @@ void usb_major_cleanup(void) | |||
159 | int usb_register_dev(struct usb_interface *intf, | 159 | int usb_register_dev(struct usb_interface *intf, |
160 | struct usb_class_driver *class_driver) | 160 | struct usb_class_driver *class_driver) |
161 | { | 161 | { |
162 | int retval = -EINVAL; | 162 | int retval; |
163 | int minor_base = class_driver->minor_base; | 163 | int minor_base = class_driver->minor_base; |
164 | int minor = 0; | 164 | int minor; |
165 | char name[20]; | 165 | char name[20]; |
166 | char *temp; | 166 | char *temp; |
167 | 167 | ||
@@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf, | |||
173 | */ | 173 | */ |
174 | minor_base = 0; | 174 | minor_base = 0; |
175 | #endif | 175 | #endif |
176 | intf->minor = -1; | ||
177 | |||
178 | dbg ("looking for a minor, starting at %d", minor_base); | ||
179 | 176 | ||
180 | if (class_driver->fops == NULL) | 177 | if (class_driver->fops == NULL) |
181 | goto exit; | 178 | return -EINVAL; |
179 | if (intf->minor >= 0) | ||
180 | return -EADDRINUSE; | ||
181 | |||
182 | retval = init_usb_class(); | ||
183 | if (retval) | ||
184 | return retval; | ||
185 | |||
186 | dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base); | ||
182 | 187 | ||
183 | down_write(&minor_rwsem); | 188 | down_write(&minor_rwsem); |
184 | for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { | 189 | for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { |
@@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf, | |||
186 | continue; | 191 | continue; |
187 | 192 | ||
188 | usb_minors[minor] = class_driver->fops; | 193 | usb_minors[minor] = class_driver->fops; |
189 | 194 | intf->minor = minor; | |
190 | retval = 0; | ||
191 | break; | 195 | break; |
192 | } | 196 | } |
193 | up_write(&minor_rwsem); | 197 | up_write(&minor_rwsem); |
194 | 198 | if (intf->minor < 0) | |
195 | if (retval) | 199 | return -EXFULL; |
196 | goto exit; | ||
197 | |||
198 | retval = init_usb_class(); | ||
199 | if (retval) | ||
200 | goto exit; | ||
201 | |||
202 | intf->minor = minor; | ||
203 | 200 | ||
204 | /* create a usb class device for this usb interface */ | 201 | /* create a usb class device for this usb interface */ |
205 | snprintf(name, sizeof(name), class_driver->name, minor - minor_base); | 202 | snprintf(name, sizeof(name), class_driver->name, minor - minor_base); |
@@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf, | |||
213 | "%s", temp); | 210 | "%s", temp); |
214 | if (IS_ERR(intf->usb_dev)) { | 211 | if (IS_ERR(intf->usb_dev)) { |
215 | down_write(&minor_rwsem); | 212 | down_write(&minor_rwsem); |
216 | usb_minors[intf->minor] = NULL; | 213 | usb_minors[minor] = NULL; |
214 | intf->minor = -1; | ||
217 | up_write(&minor_rwsem); | 215 | up_write(&minor_rwsem); |
218 | retval = PTR_ERR(intf->usb_dev); | 216 | retval = PTR_ERR(intf->usb_dev); |
219 | } | 217 | } |
220 | exit: | ||
221 | return retval; | 218 | return retval; |
222 | } | 219 | } |
223 | EXPORT_SYMBOL_GPL(usb_register_dev); | 220 | EXPORT_SYMBOL_GPL(usb_register_dev); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 844683e50383..9f0ce7de0e36 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1802,6 +1802,7 @@ free_interfaces: | |||
1802 | intf->dev.groups = usb_interface_groups; | 1802 | intf->dev.groups = usb_interface_groups; |
1803 | intf->dev.dma_mask = dev->dev.dma_mask; | 1803 | intf->dev.dma_mask = dev->dev.dma_mask; |
1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
1805 | intf->minor = -1; | ||
1805 | device_initialize(&intf->dev); | 1806 | device_initialize(&intf->dev); |
1806 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1807 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
1807 | dev->bus->busnum, dev->devpath, | 1808 | dev->bus->busnum, dev->devpath, |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 59dc3d351b60..5ab5bb89bae3 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -322,6 +322,7 @@ cppi_channel_allocate(struct dma_controller *c, | |||
322 | index, transmit ? 'T' : 'R', cppi_ch); | 322 | index, transmit ? 'T' : 'R', cppi_ch); |
323 | cppi_ch->hw_ep = ep; | 323 | cppi_ch->hw_ep = ep; |
324 | cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; | 324 | cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; |
325 | cppi_ch->channel.max_len = 0x7fffffff; | ||
325 | 326 | ||
326 | DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); | 327 | DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); |
327 | return &cppi_ch->channel; | 328 | return &cppi_ch->channel; |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6fca870e957e..d065e23f123e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -300,6 +300,11 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
300 | #ifndef CONFIG_MUSB_PIO_ONLY | 300 | #ifndef CONFIG_MUSB_PIO_ONLY |
301 | if (is_dma_capable() && musb_ep->dma) { | 301 | if (is_dma_capable() && musb_ep->dma) { |
302 | struct dma_controller *c = musb->dma_controller; | 302 | struct dma_controller *c = musb->dma_controller; |
303 | size_t request_size; | ||
304 | |||
305 | /* setup DMA, then program endpoint CSR */ | ||
306 | request_size = min_t(size_t, request->length - request->actual, | ||
307 | musb_ep->dma->max_len); | ||
303 | 308 | ||
304 | use_dma = (request->dma != DMA_ADDR_INVALID); | 309 | use_dma = (request->dma != DMA_ADDR_INVALID); |
305 | 310 | ||
@@ -307,11 +312,6 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
307 | 312 | ||
308 | #ifdef CONFIG_USB_INVENTRA_DMA | 313 | #ifdef CONFIG_USB_INVENTRA_DMA |
309 | { | 314 | { |
310 | size_t request_size; | ||
311 | |||
312 | /* setup DMA, then program endpoint CSR */ | ||
313 | request_size = min_t(size_t, request->length, | ||
314 | musb_ep->dma->max_len); | ||
315 | if (request_size < musb_ep->packet_sz) | 315 | if (request_size < musb_ep->packet_sz) |
316 | musb_ep->dma->desired_mode = 0; | 316 | musb_ep->dma->desired_mode = 0; |
317 | else | 317 | else |
@@ -373,8 +373,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
373 | use_dma = use_dma && c->channel_program( | 373 | use_dma = use_dma && c->channel_program( |
374 | musb_ep->dma, musb_ep->packet_sz, | 374 | musb_ep->dma, musb_ep->packet_sz, |
375 | 0, | 375 | 0, |
376 | request->dma, | 376 | request->dma + request->actual, |
377 | request->length); | 377 | request_size); |
378 | if (!use_dma) { | 378 | if (!use_dma) { |
379 | c->channel_release(musb_ep->dma); | 379 | c->channel_release(musb_ep->dma); |
380 | musb_ep->dma = NULL; | 380 | musb_ep->dma = NULL; |
@@ -386,8 +386,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
386 | use_dma = use_dma && c->channel_program( | 386 | use_dma = use_dma && c->channel_program( |
387 | musb_ep->dma, musb_ep->packet_sz, | 387 | musb_ep->dma, musb_ep->packet_sz, |
388 | request->zero, | 388 | request->zero, |
389 | request->dma, | 389 | request->dma + request->actual, |
390 | request->length); | 390 | request_size); |
391 | #endif | 391 | #endif |
392 | } | 392 | } |
393 | #endif | 393 | #endif |
@@ -501,26 +501,14 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
501 | request->zero = 0; | 501 | request->zero = 0; |
502 | } | 502 | } |
503 | 503 | ||
504 | /* ... or if not, then complete it. */ | 504 | if (request->actual == request->length) { |
505 | musb_g_giveback(musb_ep, request, 0); | 505 | musb_g_giveback(musb_ep, request, 0); |
506 | 506 | request = musb_ep->desc ? next_request(musb_ep) : NULL; | |
507 | /* | 507 | if (!request) { |
508 | * Kickstart next transfer if appropriate; | 508 | DBG(4, "%s idle now\n", |
509 | * the packet that just completed might not | 509 | musb_ep->end_point.name); |
510 | * be transmitted for hours or days. | 510 | return; |
511 | * REVISIT for double buffering... | 511 | } |
512 | * FIXME revisit for stalls too... | ||
513 | */ | ||
514 | musb_ep_select(mbase, epnum); | ||
515 | csr = musb_readw(epio, MUSB_TXCSR); | ||
516 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) | ||
517 | return; | ||
518 | |||
519 | request = musb_ep->desc ? next_request(musb_ep) : NULL; | ||
520 | if (!request) { | ||
521 | DBG(4, "%s idle now\n", | ||
522 | musb_ep->end_point.name); | ||
523 | return; | ||
524 | } | 512 | } |
525 | } | 513 | } |
526 | 514 | ||
@@ -568,11 +556,19 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
568 | { | 556 | { |
569 | const u8 epnum = req->epnum; | 557 | const u8 epnum = req->epnum; |
570 | struct usb_request *request = &req->request; | 558 | struct usb_request *request = &req->request; |
571 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 559 | struct musb_ep *musb_ep; |
572 | void __iomem *epio = musb->endpoints[epnum].regs; | 560 | void __iomem *epio = musb->endpoints[epnum].regs; |
573 | unsigned fifo_count = 0; | 561 | unsigned fifo_count = 0; |
574 | u16 len = musb_ep->packet_sz; | 562 | u16 len; |
575 | u16 csr = musb_readw(epio, MUSB_RXCSR); | 563 | u16 csr = musb_readw(epio, MUSB_RXCSR); |
564 | struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; | ||
565 | |||
566 | if (hw_ep->is_shared_fifo) | ||
567 | musb_ep = &hw_ep->ep_in; | ||
568 | else | ||
569 | musb_ep = &hw_ep->ep_out; | ||
570 | |||
571 | len = musb_ep->packet_sz; | ||
576 | 572 | ||
577 | /* We shouldn't get here while DMA is active, but we do... */ | 573 | /* We shouldn't get here while DMA is active, but we do... */ |
578 | if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { | 574 | if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { |
@@ -647,8 +643,8 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
647 | */ | 643 | */ |
648 | 644 | ||
649 | csr |= MUSB_RXCSR_DMAENAB; | 645 | csr |= MUSB_RXCSR_DMAENAB; |
650 | #ifdef USE_MODE1 | ||
651 | csr |= MUSB_RXCSR_AUTOCLEAR; | 646 | csr |= MUSB_RXCSR_AUTOCLEAR; |
647 | #ifdef USE_MODE1 | ||
652 | /* csr |= MUSB_RXCSR_DMAMODE; */ | 648 | /* csr |= MUSB_RXCSR_DMAMODE; */ |
653 | 649 | ||
654 | /* this special sequence (enabling and then | 650 | /* this special sequence (enabling and then |
@@ -663,10 +659,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
663 | if (request->actual < request->length) { | 659 | if (request->actual < request->length) { |
664 | int transfer_size = 0; | 660 | int transfer_size = 0; |
665 | #ifdef USE_MODE1 | 661 | #ifdef USE_MODE1 |
666 | transfer_size = min(request->length, | 662 | transfer_size = min(request->length - request->actual, |
667 | channel->max_len); | 663 | channel->max_len); |
668 | #else | 664 | #else |
669 | transfer_size = len; | 665 | transfer_size = min(request->length - request->actual, |
666 | (unsigned)len); | ||
670 | #endif | 667 | #endif |
671 | if (transfer_size <= musb_ep->packet_sz) | 668 | if (transfer_size <= musb_ep->packet_sz) |
672 | musb_ep->dma->desired_mode = 0; | 669 | musb_ep->dma->desired_mode = 0; |
@@ -740,9 +737,15 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
740 | u16 csr; | 737 | u16 csr; |
741 | struct usb_request *request; | 738 | struct usb_request *request; |
742 | void __iomem *mbase = musb->mregs; | 739 | void __iomem *mbase = musb->mregs; |
743 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 740 | struct musb_ep *musb_ep; |
744 | void __iomem *epio = musb->endpoints[epnum].regs; | 741 | void __iomem *epio = musb->endpoints[epnum].regs; |
745 | struct dma_channel *dma; | 742 | struct dma_channel *dma; |
743 | struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; | ||
744 | |||
745 | if (hw_ep->is_shared_fifo) | ||
746 | musb_ep = &hw_ep->ep_in; | ||
747 | else | ||
748 | musb_ep = &hw_ep->ep_out; | ||
746 | 749 | ||
747 | musb_ep_select(mbase, epnum); | 750 | musb_ep_select(mbase, epnum); |
748 | 751 | ||
@@ -1081,7 +1084,7 @@ struct free_record { | |||
1081 | /* | 1084 | /* |
1082 | * Context: controller locked, IRQs blocked. | 1085 | * Context: controller locked, IRQs blocked. |
1083 | */ | 1086 | */ |
1084 | static void musb_ep_restart(struct musb *musb, struct musb_request *req) | 1087 | void musb_ep_restart(struct musb *musb, struct musb_request *req) |
1085 | { | 1088 | { |
1086 | DBG(3, "<== %s request %p len %u on hw_ep%d\n", | 1089 | DBG(3, "<== %s request %p len %u on hw_ep%d\n", |
1087 | req->tx ? "TX/IN" : "RX/OUT", | 1090 | req->tx ? "TX/IN" : "RX/OUT", |
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index c8b140325d82..572b1da7f2dc 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h | |||
@@ -105,4 +105,6 @@ extern void musb_gadget_cleanup(struct musb *); | |||
105 | 105 | ||
106 | extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); | 106 | extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); |
107 | 107 | ||
108 | extern void musb_ep_restart(struct musb *, struct musb_request *); | ||
109 | |||
108 | #endif /* __MUSB_GADGET_H */ | 110 | #endif /* __MUSB_GADGET_H */ |
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 59bef8f3a358..6dd03f4c5f49 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -261,6 +261,7 @@ __acquires(musb->lock) | |||
261 | ctrlrequest->wIndex & 0x0f; | 261 | ctrlrequest->wIndex & 0x0f; |
262 | struct musb_ep *musb_ep; | 262 | struct musb_ep *musb_ep; |
263 | struct musb_hw_ep *ep; | 263 | struct musb_hw_ep *ep; |
264 | struct musb_request *request; | ||
264 | void __iomem *regs; | 265 | void __iomem *regs; |
265 | int is_in; | 266 | int is_in; |
266 | u16 csr; | 267 | u16 csr; |
@@ -302,6 +303,14 @@ __acquires(musb->lock) | |||
302 | musb_writew(regs, MUSB_RXCSR, csr); | 303 | musb_writew(regs, MUSB_RXCSR, csr); |
303 | } | 304 | } |
304 | 305 | ||
306 | /* Maybe start the first request in the queue */ | ||
307 | request = to_musb_request( | ||
308 | next_request(musb_ep)); | ||
309 | if (!musb_ep->busy && request) { | ||
310 | DBG(3, "restarting the request\n"); | ||
311 | musb_ep_restart(musb, request); | ||
312 | } | ||
313 | |||
305 | /* select ep0 again */ | 314 | /* select ep0 again */ |
306 | musb_ep_select(mbase, 0); | 315 | musb_ep_select(mbase, 0); |
307 | } break; | 316 | } break; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 877d20b1dff9..9e65c47cc98b 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -660,6 +660,12 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
660 | 660 | ||
661 | qh->segsize = length; | 661 | qh->segsize = length; |
662 | 662 | ||
663 | /* | ||
664 | * Ensure the data reaches to main memory before starting | ||
665 | * DMA transfer | ||
666 | */ | ||
667 | wmb(); | ||
668 | |||
663 | if (!dma->channel_program(channel, pkt_size, mode, | 669 | if (!dma->channel_program(channel, pkt_size, mode, |
664 | urb->transfer_dma + offset, length)) { | 670 | urb->transfer_dma + offset, length)) { |
665 | dma->channel_release(channel); | 671 | dma->channel_release(channel); |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 29e850a7a2f9..7c8008225ee3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -243,7 +243,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, | |||
243 | int r, nlogs = 0; | 243 | int r, nlogs = 0; |
244 | 244 | ||
245 | while (datalen > 0) { | 245 | while (datalen > 0) { |
246 | if (unlikely(headcount >= VHOST_NET_MAX_SG)) { | 246 | if (unlikely(seg >= VHOST_NET_MAX_SG)) { |
247 | r = -ENOBUFS; | 247 | r = -ENOBUFS; |
248 | goto err; | 248 | goto err; |
249 | } | 249 | } |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c579dcc9200c..dd3d6f7406f8 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -858,11 +858,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | |||
858 | if (r < 0) | 858 | if (r < 0) |
859 | return r; | 859 | return r; |
860 | len -= l; | 860 | len -= l; |
861 | if (!len) | 861 | if (!len) { |
862 | if (vq->log_ctx) | ||
863 | eventfd_signal(vq->log_ctx, 1); | ||
862 | return 0; | 864 | return 0; |
865 | } | ||
863 | } | 866 | } |
864 | if (vq->log_ctx) | ||
865 | eventfd_signal(vq->log_ctx, 1); | ||
866 | /* Length written exceeds what we have stored. This is a bug. */ | 867 | /* Length written exceeds what we have stored. This is a bug. */ |
867 | BUG(); | 868 | BUG(); |
868 | return 0; | 869 | return 0; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 84f842331dfa..7ccc967831f0 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -3508,7 +3508,7 @@ static void fbcon_exit(void) | |||
3508 | softback_buf = 0UL; | 3508 | softback_buf = 0UL; |
3509 | 3509 | ||
3510 | for (i = 0; i < FB_MAX; i++) { | 3510 | for (i = 0; i < FB_MAX; i++) { |
3511 | int pending; | 3511 | int pending = 0; |
3512 | 3512 | ||
3513 | mapped = 0; | 3513 | mapped = 0; |
3514 | info = registered_fb[i]; | 3514 | info = registered_fb[i]; |
@@ -3516,7 +3516,8 @@ static void fbcon_exit(void) | |||
3516 | if (info == NULL) | 3516 | if (info == NULL) |
3517 | continue; | 3517 | continue; |
3518 | 3518 | ||
3519 | pending = cancel_work_sync(&info->queue); | 3519 | if (info->queue.func) |
3520 | pending = cancel_work_sync(&info->queue); | ||
3520 | DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : | 3521 | DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : |
3521 | "no")); | 3522 | "no")); |
3522 | 3523 | ||
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 815f84b07933..70477c2e4b61 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/screen_info.h> | 14 | #include <linux/screen_info.h> |
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | 16 | #include <linux/pci.h> | |
17 | #include <video/vga.h> | 17 | #include <video/vga.h> |
18 | 18 | ||
19 | static struct fb_var_screeninfo efifb_defined __devinitdata = { | 19 | static struct fb_var_screeninfo efifb_defined __devinitdata = { |
@@ -39,17 +39,31 @@ enum { | |||
39 | M_I20, /* 20-Inch iMac */ | 39 | M_I20, /* 20-Inch iMac */ |
40 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | 40 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ |
41 | M_I24, /* 24-Inch iMac */ | 41 | M_I24, /* 24-Inch iMac */ |
42 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
43 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
44 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
42 | M_MINI, /* Mac Mini */ | 45 | M_MINI, /* Mac Mini */ |
46 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
47 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
43 | M_MB, /* MacBook */ | 48 | M_MB, /* MacBook */ |
44 | M_MB_2, /* MacBook, 2nd rev. */ | 49 | M_MB_2, /* MacBook, 2nd rev. */ |
45 | M_MB_3, /* MacBook, 3rd rev. */ | 50 | M_MB_3, /* MacBook, 3rd rev. */ |
51 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
52 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
53 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
46 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | 54 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ |
47 | M_MBA, /* MacBook Air */ | 55 | M_MBA, /* MacBook Air */ |
48 | M_MBP, /* MacBook Pro */ | 56 | M_MBP, /* MacBook Pro */ |
49 | M_MBP_2, /* MacBook Pro 2nd gen */ | 57 | M_MBP_2, /* MacBook Pro 2nd gen */ |
58 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
50 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | 59 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ |
51 | M_MBP_4, /* MacBook Pro, 4th gen */ | 60 | M_MBP_4, /* MacBook Pro, 4th gen */ |
52 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | 61 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ |
62 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
63 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
64 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
65 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
66 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
53 | M_UNKNOWN /* placeholder */ | 67 | M_UNKNOWN /* placeholder */ |
54 | }; | 68 | }; |
55 | 69 | ||
@@ -64,14 +78,28 @@ static struct efifb_dmi_info { | |||
64 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ | 78 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ |
65 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, | 79 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, |
66 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ | 80 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ |
81 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 }, | ||
82 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 }, | ||
83 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 }, | ||
67 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, | 84 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, |
85 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 }, | ||
86 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 }, | ||
68 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, | 87 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, |
88 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 }, | ||
89 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 }, | ||
90 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 }, | ||
69 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, | 91 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, |
70 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, | 92 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, |
71 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ | 93 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ |
94 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 }, | ||
72 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, | 95 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, |
73 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, | 96 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, |
74 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, | 97 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, |
98 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 }, | ||
99 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 }, | ||
100 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 }, | ||
101 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 }, | ||
102 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 }, | ||
75 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } | 103 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } |
76 | }; | 104 | }; |
77 | 105 | ||
@@ -92,7 +120,12 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { | |||
92 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | 120 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), |
93 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | 121 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), |
94 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | 122 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), |
123 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
124 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
125 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
95 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | 126 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), |
127 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
128 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
96 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | 129 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), |
97 | /* At least one of these two will be right; maybe both? */ | 130 | /* At least one of these two will be right; maybe both? */ |
98 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | 131 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), |
@@ -101,14 +134,23 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { | |||
101 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | 134 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), |
102 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | 135 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), |
103 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | 136 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), |
137 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
138 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
139 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
104 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | 140 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), |
105 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | 141 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), |
106 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | 142 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), |
143 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
107 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | 144 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), |
108 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | 145 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), |
109 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | 146 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), |
110 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | 147 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), |
111 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | 148 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), |
149 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
150 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
151 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
152 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
153 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
112 | {}, | 154 | {}, |
113 | }; | 155 | }; |
114 | 156 | ||
@@ -116,7 +158,7 @@ static int set_system(const struct dmi_system_id *id) | |||
116 | { | 158 | { |
117 | struct efifb_dmi_info *info = id->driver_data; | 159 | struct efifb_dmi_info *info = id->driver_data; |
118 | if (info->base == 0) | 160 | if (info->base == 0) |
119 | return -ENODEV; | 161 | return 0; |
120 | 162 | ||
121 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " | 163 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " |
122 | "(%dx%d, stride %d)\n", id->ident, | 164 | "(%dx%d, stride %d)\n", id->ident, |
@@ -124,18 +166,55 @@ static int set_system(const struct dmi_system_id *id) | |||
124 | info->stride); | 166 | info->stride); |
125 | 167 | ||
126 | /* Trust the bootloader over the DMI tables */ | 168 | /* Trust the bootloader over the DMI tables */ |
127 | if (screen_info.lfb_base == 0) | 169 | if (screen_info.lfb_base == 0) { |
170 | #if defined(CONFIG_PCI) | ||
171 | struct pci_dev *dev = NULL; | ||
172 | int found_bar = 0; | ||
173 | #endif | ||
128 | screen_info.lfb_base = info->base; | 174 | screen_info.lfb_base = info->base; |
129 | if (screen_info.lfb_linelength == 0) | ||
130 | screen_info.lfb_linelength = info->stride; | ||
131 | if (screen_info.lfb_width == 0) | ||
132 | screen_info.lfb_width = info->width; | ||
133 | if (screen_info.lfb_height == 0) | ||
134 | screen_info.lfb_height = info->height; | ||
135 | if (screen_info.orig_video_isVGA == 0) | ||
136 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
137 | 175 | ||
138 | return 0; | 176 | #if defined(CONFIG_PCI) |
177 | /* make sure that the address in the table is actually on a | ||
178 | * VGA device's PCI BAR */ | ||
179 | |||
180 | for_each_pci_dev(dev) { | ||
181 | int i; | ||
182 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
183 | continue; | ||
184 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
185 | resource_size_t start, end; | ||
186 | |||
187 | start = pci_resource_start(dev, i); | ||
188 | if (start == 0) | ||
189 | break; | ||
190 | end = pci_resource_end(dev, i); | ||
191 | if (screen_info.lfb_base >= start && | ||
192 | screen_info.lfb_base < end) { | ||
193 | found_bar = 1; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | if (!found_bar) | ||
198 | screen_info.lfb_base = 0; | ||
199 | #endif | ||
200 | } | ||
201 | if (screen_info.lfb_base) { | ||
202 | if (screen_info.lfb_linelength == 0) | ||
203 | screen_info.lfb_linelength = info->stride; | ||
204 | if (screen_info.lfb_width == 0) | ||
205 | screen_info.lfb_width = info->width; | ||
206 | if (screen_info.lfb_height == 0) | ||
207 | screen_info.lfb_height = info->height; | ||
208 | if (screen_info.orig_video_isVGA == 0) | ||
209 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
210 | } else { | ||
211 | screen_info.lfb_linelength = 0; | ||
212 | screen_info.lfb_width = 0; | ||
213 | screen_info.lfb_height = 0; | ||
214 | screen_info.orig_video_isVGA = 0; | ||
215 | return 0; | ||
216 | } | ||
217 | return 1; | ||
139 | } | 218 | } |
140 | 219 | ||
141 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | 220 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, |
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c index 5d786bd3e304..a31a77ff6f3d 100644 --- a/drivers/video/pxa168fb.c +++ b/drivers/video/pxa168fb.c | |||
@@ -298,8 +298,8 @@ static void set_dma_control0(struct pxa168fb_info *fbi) | |||
298 | * Set bit to enable graphics DMA. | 298 | * Set bit to enable graphics DMA. |
299 | */ | 299 | */ |
300 | x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0); | 300 | x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0); |
301 | x |= fbi->active ? 0x00000100 : 0; | 301 | x &= ~CFG_GRA_ENA_MASK; |
302 | fbi->active = 0; | 302 | x |= fbi->active ? CFG_GRA_ENA(1) : CFG_GRA_ENA(0); |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * If we are in a pseudo-color mode, we need to enable | 305 | * If we are in a pseudo-color mode, we need to enable |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 559bf1727a2b..b52f8e4ef1fd 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -1701,6 +1701,9 @@ static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, | |||
1701 | break; | 1701 | break; |
1702 | 1702 | ||
1703 | case FBIOGET_VBLANK: | 1703 | case FBIOGET_VBLANK: |
1704 | |||
1705 | memset(&sisvbblank, 0, sizeof(struct fb_vblank)); | ||
1706 | |||
1704 | sisvbblank.count = 0; | 1707 | sisvbblank.count = 0; |
1705 | sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); | 1708 | sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); |
1706 | 1709 | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 29bac5118877..d409495876f1 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -755,7 +755,10 @@ int register_xenstore_notifier(struct notifier_block *nb) | |||
755 | { | 755 | { |
756 | int ret = 0; | 756 | int ret = 0; |
757 | 757 | ||
758 | blocking_notifier_chain_register(&xenstore_chain, nb); | 758 | if (xenstored_ready > 0) |
759 | ret = nb->notifier_call(nb, 0, NULL); | ||
760 | else | ||
761 | blocking_notifier_chain_register(&xenstore_chain, nb); | ||
759 | 762 | ||
760 | return ret; | 763 | return ret; |
761 | } | 764 | } |
@@ -769,7 +772,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); | |||
769 | 772 | ||
770 | void xenbus_probe(struct work_struct *unused) | 773 | void xenbus_probe(struct work_struct *unused) |
771 | { | 774 | { |
772 | BUG_ON((xenstored_ready <= 0)); | 775 | xenstored_ready = 1; |
773 | 776 | ||
774 | /* Enumerate devices in xenstore and watch for changes. */ | 777 | /* Enumerate devices in xenstore and watch for changes. */ |
775 | xenbus_probe_devices(&xenbus_frontend); | 778 | xenbus_probe_devices(&xenbus_frontend); |
@@ -835,8 +838,8 @@ static int __init xenbus_init(void) | |||
835 | xen_store_evtchn = xen_start_info->store_evtchn; | 838 | xen_store_evtchn = xen_start_info->store_evtchn; |
836 | xen_store_mfn = xen_start_info->store_mfn; | 839 | xen_store_mfn = xen_start_info->store_mfn; |
837 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 840 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
841 | xenstored_ready = 1; | ||
838 | } | 842 | } |
839 | xenstored_ready = 1; | ||
840 | } | 843 | } |
841 | 844 | ||
842 | /* Initialize the interface to xenstore. */ | 845 | /* Initialize the interface to xenstore. */ |
@@ -712,8 +712,16 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
712 | */ | 712 | */ |
713 | ret = retry(iocb); | 713 | ret = retry(iocb); |
714 | 714 | ||
715 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) | 715 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) { |
716 | /* | ||
717 | * There's no easy way to restart the syscall since other AIO's | ||
718 | * may be already running. Just fail this IO with EINTR. | ||
719 | */ | ||
720 | if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR || | ||
721 | ret == -ERESTARTNOHAND || ret == -ERESTART_RESTARTBLOCK)) | ||
722 | ret = -EINTR; | ||
716 | aio_complete(iocb, ret, 0); | 723 | aio_complete(iocb, ret, 0); |
724 | } | ||
717 | out: | 725 | out: |
718 | spin_lock_irq(&ctx->ctx_lock); | 726 | spin_lock_irq(&ctx->ctx_lock); |
719 | 727 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c65c3419dd37..7e83b356cc9e 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -232,7 +232,7 @@ static int | |||
232 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | 232 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
233 | void **request_buf) | 233 | void **request_buf) |
234 | { | 234 | { |
235 | int rc = 0; | 235 | int rc; |
236 | 236 | ||
237 | rc = cifs_reconnect_tcon(tcon, smb_command); | 237 | rc = cifs_reconnect_tcon(tcon, smb_command); |
238 | if (rc) | 238 | if (rc) |
@@ -250,7 +250,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
250 | if (tcon != NULL) | 250 | if (tcon != NULL) |
251 | cifs_stats_inc(&tcon->num_smbs_sent); | 251 | cifs_stats_inc(&tcon->num_smbs_sent); |
252 | 252 | ||
253 | return rc; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | int | 256 | int |
@@ -281,16 +281,9 @@ small_smb_init_no_tc(const int smb_command, const int wct, | |||
281 | 281 | ||
282 | /* If the return code is zero, this function must fill in request_buf pointer */ | 282 | /* If the return code is zero, this function must fill in request_buf pointer */ |
283 | static int | 283 | static int |
284 | smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | 284 | __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
285 | void **request_buf /* returned */ , | 285 | void **request_buf, void **response_buf) |
286 | void **response_buf /* returned */ ) | ||
287 | { | 286 | { |
288 | int rc = 0; | ||
289 | |||
290 | rc = cifs_reconnect_tcon(tcon, smb_command); | ||
291 | if (rc) | ||
292 | return rc; | ||
293 | |||
294 | *request_buf = cifs_buf_get(); | 287 | *request_buf = cifs_buf_get(); |
295 | if (*request_buf == NULL) { | 288 | if (*request_buf == NULL) { |
296 | /* BB should we add a retry in here if not a writepage? */ | 289 | /* BB should we add a retry in here if not a writepage? */ |
@@ -309,7 +302,31 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
309 | if (tcon != NULL) | 302 | if (tcon != NULL) |
310 | cifs_stats_inc(&tcon->num_smbs_sent); | 303 | cifs_stats_inc(&tcon->num_smbs_sent); |
311 | 304 | ||
312 | return rc; | 305 | return 0; |
306 | } | ||
307 | |||
308 | /* If the return code is zero, this function must fill in request_buf pointer */ | ||
309 | static int | ||
310 | smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | ||
311 | void **request_buf, void **response_buf) | ||
312 | { | ||
313 | int rc; | ||
314 | |||
315 | rc = cifs_reconnect_tcon(tcon, smb_command); | ||
316 | if (rc) | ||
317 | return rc; | ||
318 | |||
319 | return __smb_init(smb_command, wct, tcon, request_buf, response_buf); | ||
320 | } | ||
321 | |||
322 | static int | ||
323 | smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, | ||
324 | void **request_buf, void **response_buf) | ||
325 | { | ||
326 | if (tcon->ses->need_reconnect || tcon->need_reconnect) | ||
327 | return -EHOSTDOWN; | ||
328 | |||
329 | return __smb_init(smb_command, wct, tcon, request_buf, response_buf); | ||
313 | } | 330 | } |
314 | 331 | ||
315 | static int validate_t2(struct smb_t2_rsp *pSMB) | 332 | static int validate_t2(struct smb_t2_rsp *pSMB) |
@@ -4534,8 +4551,8 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) | |||
4534 | 4551 | ||
4535 | cFYI(1, "In QFSUnixInfo"); | 4552 | cFYI(1, "In QFSUnixInfo"); |
4536 | QFSUnixRetry: | 4553 | QFSUnixRetry: |
4537 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 4554 | rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, |
4538 | (void **) &pSMBr); | 4555 | (void **) &pSMB, (void **) &pSMBr); |
4539 | if (rc) | 4556 | if (rc) |
4540 | return rc; | 4557 | return rc; |
4541 | 4558 | ||
@@ -4604,8 +4621,8 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) | |||
4604 | cFYI(1, "In SETFSUnixInfo"); | 4621 | cFYI(1, "In SETFSUnixInfo"); |
4605 | SETFSUnixRetry: | 4622 | SETFSUnixRetry: |
4606 | /* BB switch to small buf init to save memory */ | 4623 | /* BB switch to small buf init to save memory */ |
4607 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 4624 | rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, |
4608 | (void **) &pSMBr); | 4625 | (void **) &pSMB, (void **) &pSMBr); |
4609 | if (rc) | 4626 | if (rc) |
4610 | return rc; | 4627 | return rc; |
4611 | 4628 | ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 93f77d438d3c..53cce8cc2224 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -801,6 +801,8 @@ retry_iget5_locked: | |||
801 | inode->i_flags |= S_NOATIME | S_NOCMTIME; | 801 | inode->i_flags |= S_NOATIME | S_NOCMTIME; |
802 | if (inode->i_state & I_NEW) { | 802 | if (inode->i_state & I_NEW) { |
803 | inode->i_ino = hash; | 803 | inode->i_ino = hash; |
804 | if (S_ISREG(inode->i_mode)) | ||
805 | inode->i_data.backing_dev_info = sb->s_bdi; | ||
804 | #ifdef CONFIG_CIFS_FSCACHE | 806 | #ifdef CONFIG_CIFS_FSCACHE |
805 | /* initialize per-inode cache cookie pointer */ | 807 | /* initialize per-inode cache cookie pointer */ |
806 | CIFS_I(inode)->fscache = NULL; | 808 | CIFS_I(inode)->fscache = NULL; |
diff --git a/fs/compat.c b/fs/compat.c index 718c7062aec1..0644a154672b 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1153,7 +1153,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1153 | { | 1153 | { |
1154 | compat_ssize_t tot_len; | 1154 | compat_ssize_t tot_len; |
1155 | struct iovec iovstack[UIO_FASTIOV]; | 1155 | struct iovec iovstack[UIO_FASTIOV]; |
1156 | struct iovec *iov; | 1156 | struct iovec *iov = iovstack; |
1157 | ssize_t ret; | 1157 | ssize_t ret; |
1158 | io_fn_t fn; | 1158 | io_fn_t fn; |
1159 | iov_fn_t fnv; | 1159 | iov_fn_t fnv; |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 5581122bd2c0..ab38fef1c9a1 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -72,22 +72,11 @@ int writeback_in_progress(struct backing_dev_info *bdi) | |||
72 | static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) | 72 | static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) |
73 | { | 73 | { |
74 | struct super_block *sb = inode->i_sb; | 74 | struct super_block *sb = inode->i_sb; |
75 | struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info; | ||
76 | 75 | ||
77 | /* | 76 | if (strcmp(sb->s_type->name, "bdev") == 0) |
78 | * For inodes on standard filesystems, we use superblock's bdi. For | 77 | return inode->i_mapping->backing_dev_info; |
79 | * inodes on virtual filesystems, we want to use inode mapping's bdi | 78 | |
80 | * because they can possibly point to something useful (think about | 79 | return sb->s_bdi; |
81 | * block_dev filesystem). | ||
82 | */ | ||
83 | if (sb->s_bdi && sb->s_bdi != &noop_backing_dev_info) { | ||
84 | /* Some device inodes could play dirty tricks. Catch them... */ | ||
85 | WARN(bdi != sb->s_bdi && bdi_cap_writeback_dirty(bdi), | ||
86 | "Dirtiable inode bdi %s != sb bdi %s\n", | ||
87 | bdi->name, sb->s_bdi->name); | ||
88 | return sb->s_bdi; | ||
89 | } | ||
90 | return bdi; | ||
91 | } | 80 | } |
92 | 81 | ||
93 | static void bdi_queue_work(struct backing_dev_info *bdi, | 82 | static void bdi_queue_work(struct backing_dev_info *bdi, |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d367af1514ef..cde755cca564 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1354,7 +1354,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | |||
1354 | loff_t file_size; | 1354 | loff_t file_size; |
1355 | unsigned int num; | 1355 | unsigned int num; |
1356 | unsigned int offset; | 1356 | unsigned int offset; |
1357 | size_t total_len; | 1357 | size_t total_len = 0; |
1358 | 1358 | ||
1359 | req = fuse_get_req(fc); | 1359 | req = fuse_get_req(fc); |
1360 | if (IS_ERR(req)) | 1360 | if (IS_ERR(req)) |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index a76e0aa5cd3f..391915093fe1 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -209,7 +209,10 @@ static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | inode->i_mode = new_mode; | 211 | inode->i_mode = new_mode; |
212 | inode->i_ctime = CURRENT_TIME; | ||
212 | di->i_mode = cpu_to_le16(inode->i_mode); | 213 | di->i_mode = cpu_to_le16(inode->i_mode); |
214 | di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); | ||
215 | di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | ||
213 | 216 | ||
214 | ocfs2_journal_dirty(handle, di_bh); | 217 | ocfs2_journal_dirty(handle, di_bh); |
215 | 218 | ||
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1361997cf205..cbe2f057cc28 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -977,7 +977,7 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, | |||
977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, | 977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, |
978 | size_t caller_veclen, u8 target_node, int *status) | 978 | size_t caller_veclen, u8 target_node, int *status) |
979 | { | 979 | { |
980 | int ret; | 980 | int ret = 0; |
981 | struct o2net_msg *msg = NULL; | 981 | struct o2net_msg *msg = NULL; |
982 | size_t veclen, caller_bytes = 0; | 982 | size_t veclen, caller_bytes = 0; |
983 | struct kvec *vec = NULL; | 983 | struct kvec *vec = NULL; |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index f04ebcfffc4a..c49f6de0e7ab 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -3931,6 +3931,15 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
3931 | goto out_commit; | 3931 | goto out_commit; |
3932 | } | 3932 | } |
3933 | 3933 | ||
3934 | cpos = split_hash; | ||
3935 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | ||
3936 | data_ac, meta_ac, new_dx_leaves, | ||
3937 | num_dx_leaves); | ||
3938 | if (ret) { | ||
3939 | mlog_errno(ret); | ||
3940 | goto out_commit; | ||
3941 | } | ||
3942 | |||
3934 | for (i = 0; i < num_dx_leaves; i++) { | 3943 | for (i = 0; i < num_dx_leaves; i++) { |
3935 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), | 3944 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
3936 | orig_dx_leaves[i], | 3945 | orig_dx_leaves[i], |
@@ -3939,15 +3948,14 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
3939 | mlog_errno(ret); | 3948 | mlog_errno(ret); |
3940 | goto out_commit; | 3949 | goto out_commit; |
3941 | } | 3950 | } |
3942 | } | ||
3943 | 3951 | ||
3944 | cpos = split_hash; | 3952 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
3945 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | 3953 | new_dx_leaves[i], |
3946 | data_ac, meta_ac, new_dx_leaves, | 3954 | OCFS2_JOURNAL_ACCESS_WRITE); |
3947 | num_dx_leaves); | 3955 | if (ret) { |
3948 | if (ret) { | 3956 | mlog_errno(ret); |
3949 | mlog_errno(ret); | 3957 | goto out_commit; |
3950 | goto out_commit; | 3958 | } |
3951 | } | 3959 | } |
3952 | 3960 | ||
3953 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, | 3961 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 4b6ae2c13b47..765298908f1d 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -1030,6 +1030,7 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, | |||
1030 | struct dlm_lock_resource *res); | 1030 | struct dlm_lock_resource *res); |
1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, | 1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, |
1032 | u8 dead_node); | 1032 | u8 dead_node); |
1033 | void dlm_force_free_mles(struct dlm_ctxt *dlm); | ||
1033 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 1034 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
1034 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); | 1035 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); |
1035 | int __dlm_lockres_unused(struct dlm_lock_resource *res); | 1036 | int __dlm_lockres_unused(struct dlm_lock_resource *res); |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 5efdd37dfe48..901ca52bf86b 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
@@ -636,8 +636,14 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
636 | spin_lock(&dlm->track_lock); | 636 | spin_lock(&dlm->track_lock); |
637 | if (oldres) | 637 | if (oldres) |
638 | track_list = &oldres->tracking; | 638 | track_list = &oldres->tracking; |
639 | else | 639 | else { |
640 | track_list = &dlm->tracking_list; | 640 | track_list = &dlm->tracking_list; |
641 | if (list_empty(track_list)) { | ||
642 | dl = NULL; | ||
643 | spin_unlock(&dlm->track_lock); | ||
644 | goto bail; | ||
645 | } | ||
646 | } | ||
641 | 647 | ||
642 | list_for_each_entry(res, track_list, tracking) { | 648 | list_for_each_entry(res, track_list, tracking) { |
643 | if (&res->tracking == &dlm->tracking_list) | 649 | if (&res->tracking == &dlm->tracking_list) |
@@ -660,6 +666,7 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
660 | } else | 666 | } else |
661 | dl = NULL; | 667 | dl = NULL; |
662 | 668 | ||
669 | bail: | ||
663 | /* passed to seq_show */ | 670 | /* passed to seq_show */ |
664 | return dl; | 671 | return dl; |
665 | } | 672 | } |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 153abb5abef0..11a5c87fd7f7 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -693,6 +693,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) | |||
693 | 693 | ||
694 | dlm_mark_domain_leaving(dlm); | 694 | dlm_mark_domain_leaving(dlm); |
695 | dlm_leave_domain(dlm); | 695 | dlm_leave_domain(dlm); |
696 | dlm_force_free_mles(dlm); | ||
696 | dlm_complete_dlm_shutdown(dlm); | 697 | dlm_complete_dlm_shutdown(dlm); |
697 | } | 698 | } |
698 | dlm_put(dlm); | 699 | dlm_put(dlm); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index ffb4c68dafa4..f564b0e5f80d 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -3433,3 +3433,43 @@ void dlm_lockres_release_ast(struct dlm_ctxt *dlm, | |||
3433 | wake_up(&res->wq); | 3433 | wake_up(&res->wq); |
3434 | wake_up(&dlm->migration_wq); | 3434 | wake_up(&dlm->migration_wq); |
3435 | } | 3435 | } |
3436 | |||
3437 | void dlm_force_free_mles(struct dlm_ctxt *dlm) | ||
3438 | { | ||
3439 | int i; | ||
3440 | struct hlist_head *bucket; | ||
3441 | struct dlm_master_list_entry *mle; | ||
3442 | struct hlist_node *tmp, *list; | ||
3443 | |||
3444 | /* | ||
3445 | * We notified all other nodes that we are exiting the domain and | ||
3446 | * marked the dlm state to DLM_CTXT_LEAVING. If any mles are still | ||
3447 | * around we force free them and wake any processes that are waiting | ||
3448 | * on the mles | ||
3449 | */ | ||
3450 | spin_lock(&dlm->spinlock); | ||
3451 | spin_lock(&dlm->master_lock); | ||
3452 | |||
3453 | BUG_ON(dlm->dlm_state != DLM_CTXT_LEAVING); | ||
3454 | BUG_ON((find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 0) < O2NM_MAX_NODES)); | ||
3455 | |||
3456 | for (i = 0; i < DLM_HASH_BUCKETS; i++) { | ||
3457 | bucket = dlm_master_hash(dlm, i); | ||
3458 | hlist_for_each_safe(list, tmp, bucket) { | ||
3459 | mle = hlist_entry(list, struct dlm_master_list_entry, | ||
3460 | master_hash_node); | ||
3461 | if (mle->type != DLM_MLE_BLOCK) { | ||
3462 | mlog(ML_ERROR, "bad mle: %p\n", mle); | ||
3463 | dlm_print_one_mle(mle); | ||
3464 | } | ||
3465 | atomic_set(&mle->woken, 1); | ||
3466 | wake_up(&mle->wq); | ||
3467 | |||
3468 | __dlm_unlink_mle(dlm, mle); | ||
3469 | __dlm_mle_detach_hb_events(dlm, mle); | ||
3470 | __dlm_put_mle(mle); | ||
3471 | } | ||
3472 | } | ||
3473 | spin_unlock(&dlm->master_lock); | ||
3474 | spin_unlock(&dlm->spinlock); | ||
3475 | } | ||
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index d1ce48e1b3d6..1d596d8c4a4a 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -84,6 +84,7 @@ enum { | |||
84 | OI_LS_PARENT, | 84 | OI_LS_PARENT, |
85 | OI_LS_RENAME1, | 85 | OI_LS_RENAME1, |
86 | OI_LS_RENAME2, | 86 | OI_LS_RENAME2, |
87 | OI_LS_REFLINK_TARGET, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | int ocfs2_dlm_init(struct ocfs2_super *osb); | 90 | int ocfs2_dlm_init(struct ocfs2_super *osb); |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 33f1c9a8258d..fa31d05e41b7 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -235,18 +235,31 @@ | |||
235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) | 235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) |
236 | 236 | ||
237 | /* Inode attributes, keep in sync with EXT2 */ | 237 | /* Inode attributes, keep in sync with EXT2 */ |
238 | #define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ | 238 | #define OCFS2_SECRM_FL FS_SECRM_FL /* Secure deletion */ |
239 | #define OCFS2_UNRM_FL (0x00000002) /* Undelete */ | 239 | #define OCFS2_UNRM_FL FS_UNRM_FL /* Undelete */ |
240 | #define OCFS2_COMPR_FL (0x00000004) /* Compress file */ | 240 | #define OCFS2_COMPR_FL FS_COMPR_FL /* Compress file */ |
241 | #define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */ | 241 | #define OCFS2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ |
242 | #define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */ | 242 | #define OCFS2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ |
243 | #define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */ | 243 | #define OCFS2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ |
244 | #define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */ | 244 | #define OCFS2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ |
245 | #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */ | 245 | #define OCFS2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ |
246 | #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */ | 246 | /* Reserved for compression usage... */ |
247 | 247 | #define OCFS2_DIRTY_FL FS_DIRTY_FL | |
248 | #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */ | 248 | #define OCFS2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */ |
249 | #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */ | 249 | #define OCFS2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */ |
250 | #define OCFS2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */ | ||
251 | /* End compression flags --- maybe not all used */ | ||
252 | #define OCFS2_BTREE_FL FS_BTREE_FL /* btree format dir */ | ||
253 | #define OCFS2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */ | ||
254 | #define OCFS2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */ | ||
255 | #define OCFS2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */ | ||
256 | #define OCFS2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ | ||
257 | #define OCFS2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ | ||
258 | #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ | ||
259 | #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ | ||
260 | |||
261 | #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ | ||
262 | #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ | ||
250 | 263 | ||
251 | /* | 264 | /* |
252 | * Extent record flags (e_node.leaf.flags) | 265 | * Extent record flags (e_node.leaf.flags) |
diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h index 2d3420af1a83..5d241505690b 100644 --- a/fs/ocfs2/ocfs2_ioctl.h +++ b/fs/ocfs2/ocfs2_ioctl.h | |||
@@ -23,10 +23,10 @@ | |||
23 | /* | 23 | /* |
24 | * ioctl commands | 24 | * ioctl commands |
25 | */ | 25 | */ |
26 | #define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) | 26 | #define OCFS2_IOC_GETFLAGS FS_IOC_GETFLAGS |
27 | #define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) | 27 | #define OCFS2_IOC_SETFLAGS FS_IOC_SETFLAGS |
28 | #define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) | 28 | #define OCFS2_IOC32_GETFLAGS FS_IOC32_GETFLAGS |
29 | #define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) | 29 | #define OCFS2_IOC32_SETFLAGS FS_IOC32_SETFLAGS |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Space reservation / allocation / free ioctls and argument structure | 32 | * Space reservation / allocation / free ioctls and argument structure |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 0afeda83120f..efdd75607406 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -4201,8 +4201,9 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
4201 | goto out; | 4201 | goto out; |
4202 | } | 4202 | } |
4203 | 4203 | ||
4204 | mutex_lock(&new_inode->i_mutex); | 4204 | mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD); |
4205 | ret = ocfs2_inode_lock(new_inode, &new_bh, 1); | 4205 | ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1, |
4206 | OI_LS_REFLINK_TARGET); | ||
4206 | if (ret) { | 4207 | if (ret) { |
4207 | mlog_errno(ret); | 4208 | mlog_errno(ret); |
4208 | goto out_unlock; | 4209 | goto out_unlock; |
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index d8b6e4259b80..3e78db361bc7 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c | |||
@@ -732,25 +732,23 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap, | |||
732 | struct ocfs2_alloc_reservation *resv, | 732 | struct ocfs2_alloc_reservation *resv, |
733 | int *cstart, int *clen) | 733 | int *cstart, int *clen) |
734 | { | 734 | { |
735 | unsigned int wanted = *clen; | ||
736 | |||
737 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) | 735 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) |
738 | return -ENOSPC; | 736 | return -ENOSPC; |
739 | 737 | ||
740 | spin_lock(&resv_lock); | 738 | spin_lock(&resv_lock); |
741 | 739 | ||
742 | /* | ||
743 | * We don't want to over-allocate for temporary | ||
744 | * windows. Otherwise, we run the risk of fragmenting the | ||
745 | * allocation space. | ||
746 | */ | ||
747 | wanted = ocfs2_resv_window_bits(resmap, resv); | ||
748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
749 | wanted = *clen; | ||
750 | |||
751 | if (ocfs2_resv_empty(resv)) { | 740 | if (ocfs2_resv_empty(resv)) { |
752 | mlog(0, "empty reservation, find new window\n"); | 741 | /* |
742 | * We don't want to over-allocate for temporary | ||
743 | * windows. Otherwise, we run the risk of fragmenting the | ||
744 | * allocation space. | ||
745 | */ | ||
746 | unsigned int wanted = ocfs2_resv_window_bits(resmap, resv); | ||
753 | 747 | ||
748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
749 | wanted = *clen; | ||
750 | |||
751 | mlog(0, "empty reservation, find new window\n"); | ||
754 | /* | 752 | /* |
755 | * Try to get a window here. If it works, we must fall | 753 | * Try to get a window here. If it works, we must fall |
756 | * through and test the bitmap . This avoids some | 754 | * through and test the bitmap . This avoids some |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 8a286f54dca1..849c2f0e0a0e 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -357,7 +357,7 @@ out: | |||
357 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | 357 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, |
358 | struct ocfs2_group_desc *bg, | 358 | struct ocfs2_group_desc *bg, |
359 | struct ocfs2_chain_list *cl, | 359 | struct ocfs2_chain_list *cl, |
360 | u64 p_blkno, u32 clusters) | 360 | u64 p_blkno, unsigned int clusters) |
361 | { | 361 | { |
362 | struct ocfs2_extent_list *el = &bg->bg_list; | 362 | struct ocfs2_extent_list *el = &bg->bg_list; |
363 | struct ocfs2_extent_rec *rec; | 363 | struct ocfs2_extent_rec *rec; |
@@ -369,7 +369,7 @@ static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | |||
369 | rec->e_blkno = cpu_to_le64(p_blkno); | 369 | rec->e_blkno = cpu_to_le64(p_blkno); |
370 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / | 370 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / |
371 | le16_to_cpu(cl->cl_bpc)); | 371 | le16_to_cpu(cl->cl_bpc)); |
372 | rec->e_leaf_clusters = cpu_to_le32(clusters); | 372 | rec->e_leaf_clusters = cpu_to_le16(clusters); |
373 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); | 373 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); |
374 | le16_add_cpu(&bg->bg_free_bits_count, | 374 | le16_add_cpu(&bg->bg_free_bits_count, |
375 | clusters * le16_to_cpu(cl->cl_bpc)); | 375 | clusters * le16_to_cpu(cl->cl_bpc)); |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 32499d213fc4..9975457c981f 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -128,7 +128,7 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry, | |||
128 | } | 128 | } |
129 | 129 | ||
130 | /* Fast symlinks can't be large */ | 130 | /* Fast symlinks can't be large */ |
131 | len = strlen(target); | 131 | len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb)); |
132 | link = kzalloc(len + 1, GFP_NOFS); | 132 | link = kzalloc(len + 1, GFP_NOFS); |
133 | if (!link) { | 133 | if (!link) { |
134 | status = -ENOMEM; | 134 | status = -ENOMEM; |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index d03469f61801..06fa5e77c40e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -1286,13 +1286,11 @@ int ocfs2_xattr_get_nolock(struct inode *inode, | |||
1286 | xis.inode_bh = xbs.inode_bh = di_bh; | 1286 | xis.inode_bh = xbs.inode_bh = di_bh; |
1287 | di = (struct ocfs2_dinode *)di_bh->b_data; | 1287 | di = (struct ocfs2_dinode *)di_bh->b_data; |
1288 | 1288 | ||
1289 | down_read(&oi->ip_xattr_sem); | ||
1290 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, | 1289 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, |
1291 | buffer_size, &xis); | 1290 | buffer_size, &xis); |
1292 | if (ret == -ENODATA && di->i_xattr_loc) | 1291 | if (ret == -ENODATA && di->i_xattr_loc) |
1293 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, | 1292 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, |
1294 | buffer_size, &xbs); | 1293 | buffer_size, &xbs); |
1295 | up_read(&oi->ip_xattr_sem); | ||
1296 | 1294 | ||
1297 | return ret; | 1295 | return ret; |
1298 | } | 1296 | } |
@@ -1316,8 +1314,10 @@ static int ocfs2_xattr_get(struct inode *inode, | |||
1316 | mlog_errno(ret); | 1314 | mlog_errno(ret); |
1317 | return ret; | 1315 | return ret; |
1318 | } | 1316 | } |
1317 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
1319 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, | 1318 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, |
1320 | name, buffer, buffer_size); | 1319 | name, buffer, buffer_size); |
1320 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
1321 | 1321 | ||
1322 | ocfs2_inode_unlock(inode, 0); | 1322 | ocfs2_inode_unlock(inode, 0); |
1323 | 1323 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index a1c43e7c8a7b..8e4addaa5424 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2675,7 +2675,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2675 | INF("auxv", S_IRUSR, proc_pid_auxv), | 2675 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2676 | ONE("status", S_IRUGO, proc_pid_status), | 2676 | ONE("status", S_IRUGO, proc_pid_status), |
2677 | ONE("personality", S_IRUSR, proc_pid_personality), | 2677 | ONE("personality", S_IRUSR, proc_pid_personality), |
2678 | INF("limits", S_IRUSR, proc_pid_limits), | 2678 | INF("limits", S_IRUGO, proc_pid_limits), |
2679 | #ifdef CONFIG_SCHED_DEBUG | 2679 | #ifdef CONFIG_SCHED_DEBUG |
2680 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2680 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2681 | #endif | 2681 | #endif |
@@ -3011,7 +3011,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3011 | INF("auxv", S_IRUSR, proc_pid_auxv), | 3011 | INF("auxv", S_IRUSR, proc_pid_auxv), |
3012 | ONE("status", S_IRUGO, proc_pid_status), | 3012 | ONE("status", S_IRUGO, proc_pid_status), |
3013 | ONE("personality", S_IRUSR, proc_pid_personality), | 3013 | ONE("personality", S_IRUSR, proc_pid_personality), |
3014 | INF("limits", S_IRUSR, proc_pid_limits), | 3014 | INF("limits", S_IRUGO, proc_pid_limits), |
3015 | #ifdef CONFIG_SCHED_DEBUG | 3015 | #ifdef CONFIG_SCHED_DEBUG |
3016 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 3016 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
3017 | #endif | 3017 | #endif |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 271afc48b9a5..1dbca4e8cc16 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -363,13 +363,13 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
363 | mss->referenced += PAGE_SIZE; | 363 | mss->referenced += PAGE_SIZE; |
364 | mapcount = page_mapcount(page); | 364 | mapcount = page_mapcount(page); |
365 | if (mapcount >= 2) { | 365 | if (mapcount >= 2) { |
366 | if (pte_dirty(ptent)) | 366 | if (pte_dirty(ptent) || PageDirty(page)) |
367 | mss->shared_dirty += PAGE_SIZE; | 367 | mss->shared_dirty += PAGE_SIZE; |
368 | else | 368 | else |
369 | mss->shared_clean += PAGE_SIZE; | 369 | mss->shared_clean += PAGE_SIZE; |
370 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; | 370 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; |
371 | } else { | 371 | } else { |
372 | if (pte_dirty(ptent)) | 372 | if (pte_dirty(ptent) || PageDirty(page)) |
373 | mss->private_dirty += PAGE_SIZE; | 373 | mss->private_dirty += PAGE_SIZE; |
374 | else | 374 | else |
375 | mss->private_clean += PAGE_SIZE; | 375 | mss->private_clean += PAGE_SIZE; |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 91c817ff02c3..2367fb3f70bc 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -163,7 +163,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, | |||
163 | 163 | ||
164 | static const struct file_operations proc_vmcore_operations = { | 164 | static const struct file_operations proc_vmcore_operations = { |
165 | .read = read_vmcore, | 165 | .read = read_vmcore, |
166 | .llseek = generic_file_llseek, | 166 | .llseek = default_llseek, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct vmcore* __init get_new_element(void) | 169 | static struct vmcore* __init get_new_element(void) |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index f53505de0712..5cbb81e134ac 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -170,6 +170,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page, | |||
170 | int reiserfs_unpack(struct inode *inode, struct file *filp) | 170 | int reiserfs_unpack(struct inode *inode, struct file *filp) |
171 | { | 171 | { |
172 | int retval = 0; | 172 | int retval = 0; |
173 | int depth; | ||
173 | int index; | 174 | int index; |
174 | struct page *page; | 175 | struct page *page; |
175 | struct address_space *mapping; | 176 | struct address_space *mapping; |
@@ -188,8 +189,8 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
188 | /* we need to make sure nobody is changing the file size beneath | 189 | /* we need to make sure nobody is changing the file size beneath |
189 | ** us | 190 | ** us |
190 | */ | 191 | */ |
191 | mutex_lock(&inode->i_mutex); | 192 | reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb); |
192 | reiserfs_write_lock(inode->i_sb); | 193 | depth = reiserfs_write_lock_once(inode->i_sb); |
193 | 194 | ||
194 | write_from = inode->i_size & (blocksize - 1); | 195 | write_from = inode->i_size & (blocksize - 1); |
195 | /* if we are on a block boundary, we are already unpacked. */ | 196 | /* if we are on a block boundary, we are already unpacked. */ |
@@ -224,6 +225,6 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
224 | 225 | ||
225 | out: | 226 | out: |
226 | mutex_unlock(&inode->i_mutex); | 227 | mutex_unlock(&inode->i_mutex); |
227 | reiserfs_write_unlock(inode->i_sb); | 228 | reiserfs_write_unlock_once(inode->i_sb, depth); |
228 | return retval; | 229 | return retval; |
229 | } | 230 | } |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index ed575fb4b495..7e206fc1fa36 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -405,9 +405,15 @@ xlog_cil_push( | |||
405 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); | 405 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); |
406 | new_ctx->ticket = xlog_cil_ticket_alloc(log); | 406 | new_ctx->ticket = xlog_cil_ticket_alloc(log); |
407 | 407 | ||
408 | /* lock out transaction commit, but don't block on background push */ | 408 | /* |
409 | * Lock out transaction commit, but don't block for background pushes | ||
410 | * unless we are well over the CIL space limit. See the definition of | ||
411 | * XLOG_CIL_HARD_SPACE_LIMIT() for the full explanation of the logic | ||
412 | * used here. | ||
413 | */ | ||
409 | if (!down_write_trylock(&cil->xc_ctx_lock)) { | 414 | if (!down_write_trylock(&cil->xc_ctx_lock)) { |
410 | if (!push_seq) | 415 | if (!push_seq && |
416 | cil->xc_ctx->space_used < XLOG_CIL_HARD_SPACE_LIMIT(log)) | ||
411 | goto out_free_ticket; | 417 | goto out_free_ticket; |
412 | down_write(&cil->xc_ctx_lock); | 418 | down_write(&cil->xc_ctx_lock); |
413 | } | 419 | } |
@@ -422,7 +428,7 @@ xlog_cil_push( | |||
422 | goto out_skip; | 428 | goto out_skip; |
423 | 429 | ||
424 | /* check for a previously pushed seqeunce */ | 430 | /* check for a previously pushed seqeunce */ |
425 | if (push_seq < cil->xc_ctx->sequence) | 431 | if (push_seq && push_seq < cil->xc_ctx->sequence) |
426 | goto out_skip; | 432 | goto out_skip; |
427 | 433 | ||
428 | /* | 434 | /* |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index ced52b98b322..edcdfe01617f 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -426,13 +426,13 @@ struct xfs_cil { | |||
426 | }; | 426 | }; |
427 | 427 | ||
428 | /* | 428 | /* |
429 | * The amount of log space we should the CIL to aggregate is difficult to size. | 429 | * The amount of log space we allow the CIL to aggregate is difficult to size. |
430 | * Whatever we chose we have to make we can get a reservation for the log space | 430 | * Whatever we choose, we have to make sure we can get a reservation for the |
431 | * effectively, that it is large enough to capture sufficient relogging to | 431 | * log space effectively, that it is large enough to capture sufficient |
432 | * reduce log buffer IO significantly, but it is not too large for the log or | 432 | * relogging to reduce log buffer IO significantly, but it is not too large for |
433 | * induces too much latency when writing out through the iclogs. We track both | 433 | * the log or induces too much latency when writing out through the iclogs. We |
434 | * space consumed and the number of vectors in the checkpoint context, so we | 434 | * track both space consumed and the number of vectors in the checkpoint |
435 | * need to decide which to use for limiting. | 435 | * context, so we need to decide which to use for limiting. |
436 | * | 436 | * |
437 | * Every log buffer we write out during a push needs a header reserved, which | 437 | * Every log buffer we write out during a push needs a header reserved, which |
438 | * is at least one sector and more for v2 logs. Hence we need a reservation of | 438 | * is at least one sector and more for v2 logs. Hence we need a reservation of |
@@ -459,16 +459,21 @@ struct xfs_cil { | |||
459 | * checkpoint transaction ticket is specific to the checkpoint context, rather | 459 | * checkpoint transaction ticket is specific to the checkpoint context, rather |
460 | * than the CIL itself. | 460 | * than the CIL itself. |
461 | * | 461 | * |
462 | * With dynamic reservations, we can basically make up arbitrary limits for the | 462 | * With dynamic reservations, we can effectively make up arbitrary limits for |
463 | * checkpoint size so long as they don't violate any other size rules. Hence | 463 | * the checkpoint size so long as they don't violate any other size rules. |
464 | * the initial maximum size for the checkpoint transaction will be set to a | 464 | * Recovery imposes a rule that no transaction exceed half the log, so we are |
465 | * quarter of the log or 8MB, which ever is smaller. 8MB is an arbitrary limit | 465 | * limited by that. Furthermore, the log transaction reservation subsystem |
466 | * right now based on the latency of writing out a large amount of data through | 466 | * tries to keep 25% of the log free, so we need to keep below that limit or we |
467 | * the circular iclog buffers. | 467 | * risk running out of free log space to start any new transactions. |
468 | * | ||
469 | * In order to keep background CIL push efficient, we will set a lower | ||
470 | * threshold at which background pushing is attempted without blocking current | ||
471 | * transaction commits. A separate, higher bound defines when CIL pushes are | ||
472 | * enforced to ensure we stay within our maximum checkpoint size bounds. | ||
473 | * threshold, yet give us plenty of space for aggregation on large logs. | ||
468 | */ | 474 | */ |
469 | 475 | #define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3) | |
470 | #define XLOG_CIL_SPACE_LIMIT(log) \ | 476 | #define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4)) |
471 | (min((log->l_logsize >> 2), (8 * 1024 * 1024))) | ||
472 | 477 | ||
473 | /* | 478 | /* |
474 | * The reservation head lsn is not made up of a cycle number and block number. | 479 | * The reservation head lsn is not made up of a cycle number and block number. |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c0786d446a00..984cdc62e30b 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -55,7 +55,7 @@ | |||
55 | extern u8 acpi_gbl_permanent_mmap; | 55 | extern u8 acpi_gbl_permanent_mmap; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * Globals that are publically available, allowing for | 58 | * Globals that are publicly available, allowing for |
59 | * run time configuration | 59 | * run time configuration |
60 | */ | 60 | */ |
61 | extern u32 acpi_dbg_level; | 61 | extern u32 acpi_dbg_level; |
diff --git a/include/asm-generic/hardirq.h b/include/asm-generic/hardirq.h index 62f59080e5cc..04d0a977cd43 100644 --- a/include/asm-generic/hardirq.h +++ b/include/asm-generic/hardirq.h | |||
@@ -3,13 +3,13 @@ | |||
3 | 3 | ||
4 | #include <linux/cache.h> | 4 | #include <linux/cache.h> |
5 | #include <linux/threads.h> | 5 | #include <linux/threads.h> |
6 | #include <linux/irq.h> | ||
7 | 6 | ||
8 | typedef struct { | 7 | typedef struct { |
9 | unsigned int __softirq_pending; | 8 | unsigned int __softirq_pending; |
10 | } ____cacheline_aligned irq_cpustat_t; | 9 | } ____cacheline_aligned irq_cpustat_t; |
11 | 10 | ||
12 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ | 11 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ |
12 | #include <linux/irq.h> | ||
13 | 13 | ||
14 | #ifndef ack_bad_irq | 14 | #ifndef ack_bad_irq |
15 | static inline void ack_bad_irq(unsigned int irq) | 15 | static inline void ack_bad_irq(unsigned int irq) |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8a92a170fb7d..ef2af9948eac 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -220,6 +220,8 @@ | |||
220 | \ | 220 | \ |
221 | BUG_TABLE \ | 221 | BUG_TABLE \ |
222 | \ | 222 | \ |
223 | JUMP_TABLE \ | ||
224 | \ | ||
223 | /* PCI quirks */ \ | 225 | /* PCI quirks */ \ |
224 | .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ | 226 | .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \ |
225 | VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ | 227 | VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \ |
@@ -563,6 +565,14 @@ | |||
563 | #define BUG_TABLE | 565 | #define BUG_TABLE |
564 | #endif | 566 | #endif |
565 | 567 | ||
568 | #define JUMP_TABLE \ | ||
569 | . = ALIGN(8); \ | ||
570 | __jump_table : AT(ADDR(__jump_table) - LOAD_OFFSET) { \ | ||
571 | VMLINUX_SYMBOL(__start___jump_table) = .; \ | ||
572 | *(__jump_table) \ | ||
573 | VMLINUX_SYMBOL(__stop___jump_table) = .; \ | ||
574 | } | ||
575 | |||
566 | #ifdef CONFIG_PM_TRACE | 576 | #ifdef CONFIG_PM_TRACE |
567 | #define TRACEDATA \ | 577 | #define TRACEDATA \ |
568 | . = ALIGN(4); \ | 578 | . = ALIGN(4); \ |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7809d230adee..4c9461a4f9e6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -612,7 +612,7 @@ struct drm_gem_object { | |||
612 | struct kref refcount; | 612 | struct kref refcount; |
613 | 613 | ||
614 | /** Handle count of this object. Each handle also holds a reference */ | 614 | /** Handle count of this object. Each handle also holds a reference */ |
615 | struct kref handlecount; | 615 | atomic_t handle_count; /* number of handles on this object */ |
616 | 616 | ||
617 | /** Related drm device */ | 617 | /** Related drm device */ |
618 | struct drm_device *dev; | 618 | struct drm_device *dev; |
@@ -808,7 +808,6 @@ struct drm_driver { | |||
808 | */ | 808 | */ |
809 | int (*gem_init_object) (struct drm_gem_object *obj); | 809 | int (*gem_init_object) (struct drm_gem_object *obj); |
810 | void (*gem_free_object) (struct drm_gem_object *obj); | 810 | void (*gem_free_object) (struct drm_gem_object *obj); |
811 | void (*gem_free_object_unlocked) (struct drm_gem_object *obj); | ||
812 | 811 | ||
813 | /* vga arb irq handler */ | 812 | /* vga arb irq handler */ |
814 | void (*vgaarb_irq)(struct drm_device *dev, bool state); | 813 | void (*vgaarb_irq)(struct drm_device *dev, bool state); |
@@ -1175,6 +1174,7 @@ extern int drm_release(struct inode *inode, struct file *filp); | |||
1175 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); | 1174 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); |
1176 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); | 1175 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); |
1177 | extern void drm_vm_open_locked(struct vm_area_struct *vma); | 1176 | extern void drm_vm_open_locked(struct vm_area_struct *vma); |
1177 | extern void drm_vm_close_locked(struct vm_area_struct *vma); | ||
1178 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); | 1178 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); |
1179 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); | 1179 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); |
1180 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); | 1180 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); |
@@ -1455,12 +1455,11 @@ int drm_gem_init(struct drm_device *dev); | |||
1455 | void drm_gem_destroy(struct drm_device *dev); | 1455 | void drm_gem_destroy(struct drm_device *dev); |
1456 | void drm_gem_object_release(struct drm_gem_object *obj); | 1456 | void drm_gem_object_release(struct drm_gem_object *obj); |
1457 | void drm_gem_object_free(struct kref *kref); | 1457 | void drm_gem_object_free(struct kref *kref); |
1458 | void drm_gem_object_free_unlocked(struct kref *kref); | ||
1459 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, | 1458 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, |
1460 | size_t size); | 1459 | size_t size); |
1461 | int drm_gem_object_init(struct drm_device *dev, | 1460 | int drm_gem_object_init(struct drm_device *dev, |
1462 | struct drm_gem_object *obj, size_t size); | 1461 | struct drm_gem_object *obj, size_t size); |
1463 | void drm_gem_object_handle_free(struct kref *kref); | 1462 | void drm_gem_object_handle_free(struct drm_gem_object *obj); |
1464 | void drm_gem_vm_open(struct vm_area_struct *vma); | 1463 | void drm_gem_vm_open(struct vm_area_struct *vma); |
1465 | void drm_gem_vm_close(struct vm_area_struct *vma); | 1464 | void drm_gem_vm_close(struct vm_area_struct *vma); |
1466 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); | 1465 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); |
@@ -1483,8 +1482,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj) | |||
1483 | static inline void | 1482 | static inline void |
1484 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) | 1483 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) |
1485 | { | 1484 | { |
1486 | if (obj != NULL) | 1485 | if (obj != NULL) { |
1487 | kref_put(&obj->refcount, drm_gem_object_free_unlocked); | 1486 | struct drm_device *dev = obj->dev; |
1487 | mutex_lock(&dev->struct_mutex); | ||
1488 | kref_put(&obj->refcount, drm_gem_object_free); | ||
1489 | mutex_unlock(&dev->struct_mutex); | ||
1490 | } | ||
1488 | } | 1491 | } |
1489 | 1492 | ||
1490 | int drm_gem_handle_create(struct drm_file *file_priv, | 1493 | int drm_gem_handle_create(struct drm_file *file_priv, |
@@ -1495,7 +1498,7 @@ static inline void | |||
1495 | drm_gem_object_handle_reference(struct drm_gem_object *obj) | 1498 | drm_gem_object_handle_reference(struct drm_gem_object *obj) |
1496 | { | 1499 | { |
1497 | drm_gem_object_reference(obj); | 1500 | drm_gem_object_reference(obj); |
1498 | kref_get(&obj->handlecount); | 1501 | atomic_inc(&obj->handle_count); |
1499 | } | 1502 | } |
1500 | 1503 | ||
1501 | static inline void | 1504 | static inline void |
@@ -1504,12 +1507,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) | |||
1504 | if (obj == NULL) | 1507 | if (obj == NULL) |
1505 | return; | 1508 | return; |
1506 | 1509 | ||
1510 | if (atomic_read(&obj->handle_count) == 0) | ||
1511 | return; | ||
1507 | /* | 1512 | /* |
1508 | * Must bump handle count first as this may be the last | 1513 | * Must bump handle count first as this may be the last |
1509 | * ref, in which case the object would disappear before we | 1514 | * ref, in which case the object would disappear before we |
1510 | * checked for a name | 1515 | * checked for a name |
1511 | */ | 1516 | */ |
1512 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1517 | if (atomic_dec_and_test(&obj->handle_count)) |
1518 | drm_gem_object_handle_free(obj); | ||
1513 | drm_gem_object_unreference(obj); | 1519 | drm_gem_object_unreference(obj); |
1514 | } | 1520 | } |
1515 | 1521 | ||
@@ -1519,12 +1525,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | |||
1519 | if (obj == NULL) | 1525 | if (obj == NULL) |
1520 | return; | 1526 | return; |
1521 | 1527 | ||
1528 | if (atomic_read(&obj->handle_count) == 0) | ||
1529 | return; | ||
1530 | |||
1522 | /* | 1531 | /* |
1523 | * Must bump handle count first as this may be the last | 1532 | * Must bump handle count first as this may be the last |
1524 | * ref, in which case the object would disappear before we | 1533 | * ref, in which case the object would disappear before we |
1525 | * checked for a name | 1534 | * checked for a name |
1526 | */ | 1535 | */ |
1527 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1536 | |
1537 | if (atomic_dec_and_test(&obj->handle_count)) | ||
1538 | drm_gem_object_handle_free(obj); | ||
1528 | drm_gem_object_unreference_unlocked(obj); | 1539 | drm_gem_object_unreference_unlocked(obj); |
1529 | } | 1540 | } |
1530 | 1541 | ||
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 3a9940ef728b..883c1d439899 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -85,7 +85,6 @@ | |||
85 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 85 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
86 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 86 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
87 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 87 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
88 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | ||
89 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 88 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
90 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 89 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
91 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 90 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
@@ -103,6 +102,7 @@ | |||
103 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 102 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
104 | {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 103 | {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
105 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 104 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
105 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | ||
106 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ | 106 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ |
107 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 107 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
108 | {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | 108 | {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 36ca9721a0c2..1be416bbbb82 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -53,6 +53,7 @@ struct cpuidle_state { | |||
53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ | 53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ |
54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ | 54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ |
55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ | 55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ |
56 | #define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */ | ||
56 | 57 | ||
57 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) | 58 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) |
58 | 59 | ||
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ce29b8151198..ba8319ae5fcc 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -102,6 +102,9 @@ static inline u64 dma_get_mask(struct device *dev) | |||
102 | return DMA_BIT_MASK(32); | 102 | return DMA_BIT_MASK(32); |
103 | } | 103 | } |
104 | 104 | ||
105 | #ifdef ARCH_HAS_DMA_SET_COHERENT_MASK | ||
106 | int dma_set_coherent_mask(struct device *dev, u64 mask); | ||
107 | #else | ||
105 | static inline int dma_set_coherent_mask(struct device *dev, u64 mask) | 108 | static inline int dma_set_coherent_mask(struct device *dev, u64 mask) |
106 | { | 109 | { |
107 | if (!dma_supported(dev, mask)) | 110 | if (!dma_supported(dev, mask)) |
@@ -109,6 +112,7 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask) | |||
109 | dev->coherent_dma_mask = mask; | 112 | dev->coherent_dma_mask = mask; |
110 | return 0; | 113 | return 0; |
111 | } | 114 | } |
115 | #endif | ||
112 | 116 | ||
113 | extern u64 dma_get_required_mask(struct device *dev); | 117 | extern u64 dma_get_required_mask(struct device *dev); |
114 | 118 | ||
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c61d4ca27bcc..e2106495cc11 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -548,7 +548,7 @@ static inline bool dma_dev_has_pq_continue(struct dma_device *dma) | |||
548 | return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE; | 548 | return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE; |
549 | } | 549 | } |
550 | 550 | ||
551 | static unsigned short dma_dev_to_maxpq(struct dma_device *dma) | 551 | static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma) |
552 | { | 552 | { |
553 | return dma->max_pq & ~DMA_HAS_PQ_CONTINUE; | 553 | return dma->max_pq & ~DMA_HAS_PQ_CONTINUE; |
554 | } | 554 | } |
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 52c0da4bdd18..bef3cda44c4c 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _DYNAMIC_DEBUG_H | 1 | #ifndef _DYNAMIC_DEBUG_H |
2 | #define _DYNAMIC_DEBUG_H | 2 | #define _DYNAMIC_DEBUG_H |
3 | 3 | ||
4 | #include <linux/jump_label.h> | ||
5 | |||
4 | /* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which | 6 | /* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which |
5 | * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They | 7 | * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They |
6 | * use independent hash functions, to reduce the chance of false positives. | 8 | * use independent hash functions, to reduce the chance of false positives. |
@@ -22,8 +24,6 @@ struct _ddebug { | |||
22 | const char *function; | 24 | const char *function; |
23 | const char *filename; | 25 | const char *filename; |
24 | const char *format; | 26 | const char *format; |
25 | char primary_hash; | ||
26 | char secondary_hash; | ||
27 | unsigned int lineno:24; | 27 | unsigned int lineno:24; |
28 | /* | 28 | /* |
29 | * The flags field controls the behaviour at the callsite. | 29 | * The flags field controls the behaviour at the callsite. |
@@ -33,6 +33,7 @@ struct _ddebug { | |||
33 | #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ | 33 | #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ |
34 | #define _DPRINTK_FLAGS_DEFAULT 0 | 34 | #define _DPRINTK_FLAGS_DEFAULT 0 |
35 | unsigned int flags:8; | 35 | unsigned int flags:8; |
36 | char enabled; | ||
36 | } __attribute__((aligned(8))); | 37 | } __attribute__((aligned(8))); |
37 | 38 | ||
38 | 39 | ||
@@ -42,33 +43,35 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
42 | #if defined(CONFIG_DYNAMIC_DEBUG) | 43 | #if defined(CONFIG_DYNAMIC_DEBUG) |
43 | extern int ddebug_remove_module(const char *mod_name); | 44 | extern int ddebug_remove_module(const char *mod_name); |
44 | 45 | ||
45 | #define __dynamic_dbg_enabled(dd) ({ \ | ||
46 | int __ret = 0; \ | ||
47 | if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) && \ | ||
48 | (dynamic_debug_enabled2 & (1LL << DEBUG_HASH2)))) \ | ||
49 | if (unlikely(dd.flags)) \ | ||
50 | __ret = 1; \ | ||
51 | __ret; }) | ||
52 | |||
53 | #define dynamic_pr_debug(fmt, ...) do { \ | 46 | #define dynamic_pr_debug(fmt, ...) do { \ |
47 | __label__ do_printk; \ | ||
48 | __label__ out; \ | ||
54 | static struct _ddebug descriptor \ | 49 | static struct _ddebug descriptor \ |
55 | __used \ | 50 | __used \ |
56 | __attribute__((section("__verbose"), aligned(8))) = \ | 51 | __attribute__((section("__verbose"), aligned(8))) = \ |
57 | { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \ | 52 | { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ |
58 | DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ | 53 | _DPRINTK_FLAGS_DEFAULT }; \ |
59 | if (__dynamic_dbg_enabled(descriptor)) \ | 54 | JUMP_LABEL(&descriptor.enabled, do_printk); \ |
60 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | 55 | goto out; \ |
56 | do_printk: \ | ||
57 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | ||
58 | out: ; \ | ||
61 | } while (0) | 59 | } while (0) |
62 | 60 | ||
63 | 61 | ||
64 | #define dynamic_dev_dbg(dev, fmt, ...) do { \ | 62 | #define dynamic_dev_dbg(dev, fmt, ...) do { \ |
63 | __label__ do_printk; \ | ||
64 | __label__ out; \ | ||
65 | static struct _ddebug descriptor \ | 65 | static struct _ddebug descriptor \ |
66 | __used \ | 66 | __used \ |
67 | __attribute__((section("__verbose"), aligned(8))) = \ | 67 | __attribute__((section("__verbose"), aligned(8))) = \ |
68 | { KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \ | 68 | { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ |
69 | DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ | 69 | _DPRINTK_FLAGS_DEFAULT }; \ |
70 | if (__dynamic_dbg_enabled(descriptor)) \ | 70 | JUMP_LABEL(&descriptor.enabled, do_printk); \ |
71 | dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ | 71 | goto out; \ |
72 | do_printk: \ | ||
73 | dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ | ||
74 | out: ; \ | ||
72 | } while (0) | 75 | } while (0) |
73 | 76 | ||
74 | #else | 77 | #else |
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 02b8b24f8f51..8beabb958f61 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -191,8 +191,8 @@ struct ftrace_event_call { | |||
191 | unsigned int flags; | 191 | unsigned int flags; |
192 | 192 | ||
193 | #ifdef CONFIG_PERF_EVENTS | 193 | #ifdef CONFIG_PERF_EVENTS |
194 | int perf_refcount; | 194 | int perf_refcount; |
195 | struct hlist_head *perf_events; | 195 | struct hlist_head __percpu *perf_events; |
196 | #endif | 196 | #endif |
197 | }; | 197 | }; |
198 | 198 | ||
@@ -252,8 +252,8 @@ DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); | |||
252 | 252 | ||
253 | extern int perf_trace_init(struct perf_event *event); | 253 | extern int perf_trace_init(struct perf_event *event); |
254 | extern void perf_trace_destroy(struct perf_event *event); | 254 | extern void perf_trace_destroy(struct perf_event *event); |
255 | extern int perf_trace_enable(struct perf_event *event); | 255 | extern int perf_trace_add(struct perf_event *event, int flags); |
256 | extern void perf_trace_disable(struct perf_event *event); | 256 | extern void perf_trace_del(struct perf_event *event, int flags); |
257 | extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, | 257 | extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, |
258 | char *filter_str); | 258 | char *filter_str); |
259 | extern void ftrace_profile_free_filter(struct perf_event *event); | 259 | extern void ftrace_profile_free_filter(struct perf_event *event); |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index a0384a4d1e6f..531495db1708 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/atomic.h> | 18 | #include <asm/atomic.h> |
19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
20 | #include <asm/system.h> | 20 | #include <asm/system.h> |
21 | #include <trace/events/irq.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * These correspond to the IORESOURCE_IRQ_* defines in | 24 | * These correspond to the IORESOURCE_IRQ_* defines in |
@@ -407,7 +408,12 @@ asmlinkage void do_softirq(void); | |||
407 | asmlinkage void __do_softirq(void); | 408 | asmlinkage void __do_softirq(void); |
408 | extern void open_softirq(int nr, void (*action)(struct softirq_action *)); | 409 | extern void open_softirq(int nr, void (*action)(struct softirq_action *)); |
409 | extern void softirq_init(void); | 410 | extern void softirq_init(void); |
410 | #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) | 411 | static inline void __raise_softirq_irqoff(unsigned int nr) |
412 | { | ||
413 | trace_softirq_raise((struct softirq_action *)(unsigned long)nr, NULL); | ||
414 | or_softirq_pending(1UL << nr); | ||
415 | } | ||
416 | |||
411 | extern void raise_softirq_irqoff(unsigned int nr); | 417 | extern void raise_softirq_irqoff(unsigned int nr); |
412 | extern void raise_softirq(unsigned int nr); | 418 | extern void raise_softirq(unsigned int nr); |
413 | extern void wakeup_softirqd(void); | 419 | extern void wakeup_softirqd(void); |
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h new file mode 100644 index 000000000000..b72cd9f92c2e --- /dev/null +++ b/include/linux/jump_label.h | |||
@@ -0,0 +1,64 @@ | |||
1 | #ifndef _LINUX_JUMP_LABEL_H | ||
2 | #define _LINUX_JUMP_LABEL_H | ||
3 | |||
4 | #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_HAVE_ARCH_JUMP_LABEL) | ||
5 | # include <asm/jump_label.h> | ||
6 | # define HAVE_JUMP_LABEL | ||
7 | #endif | ||
8 | |||
9 | enum jump_label_type { | ||
10 | JUMP_LABEL_ENABLE, | ||
11 | JUMP_LABEL_DISABLE | ||
12 | }; | ||
13 | |||
14 | struct module; | ||
15 | |||
16 | #ifdef HAVE_JUMP_LABEL | ||
17 | |||
18 | extern struct jump_entry __start___jump_table[]; | ||
19 | extern struct jump_entry __stop___jump_table[]; | ||
20 | |||
21 | extern void arch_jump_label_transform(struct jump_entry *entry, | ||
22 | enum jump_label_type type); | ||
23 | extern void arch_jump_label_text_poke_early(jump_label_t addr); | ||
24 | extern void jump_label_update(unsigned long key, enum jump_label_type type); | ||
25 | extern void jump_label_apply_nops(struct module *mod); | ||
26 | extern int jump_label_text_reserved(void *start, void *end); | ||
27 | |||
28 | #define enable_jump_label(key) \ | ||
29 | jump_label_update((unsigned long)key, JUMP_LABEL_ENABLE); | ||
30 | |||
31 | #define disable_jump_label(key) \ | ||
32 | jump_label_update((unsigned long)key, JUMP_LABEL_DISABLE); | ||
33 | |||
34 | #else | ||
35 | |||
36 | #define JUMP_LABEL(key, label) \ | ||
37 | do { \ | ||
38 | if (unlikely(*key)) \ | ||
39 | goto label; \ | ||
40 | } while (0) | ||
41 | |||
42 | #define enable_jump_label(cond_var) \ | ||
43 | do { \ | ||
44 | *(cond_var) = 1; \ | ||
45 | } while (0) | ||
46 | |||
47 | #define disable_jump_label(cond_var) \ | ||
48 | do { \ | ||
49 | *(cond_var) = 0; \ | ||
50 | } while (0) | ||
51 | |||
52 | static inline int jump_label_apply_nops(struct module *mod) | ||
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static inline int jump_label_text_reserved(void *start, void *end) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | #endif | ||
63 | |||
64 | #endif | ||
diff --git a/include/linux/module.h b/include/linux/module.h index 8a6b9fdc7ffa..b29e7458b966 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -350,7 +350,10 @@ struct module | |||
350 | struct tracepoint *tracepoints; | 350 | struct tracepoint *tracepoints; |
351 | unsigned int num_tracepoints; | 351 | unsigned int num_tracepoints; |
352 | #endif | 352 | #endif |
353 | 353 | #ifdef HAVE_JUMP_LABEL | |
354 | struct jump_entry *jump_entries; | ||
355 | unsigned int num_jump_entries; | ||
356 | #endif | ||
354 | #ifdef CONFIG_TRACING | 357 | #ifdef CONFIG_TRACING |
355 | const char **trace_bprintk_fmt_start; | 358 | const char **trace_bprintk_fmt_start; |
356 | unsigned int num_trace_bprintk_fmt; | 359 | unsigned int num_trace_bprintk_fmt; |
@@ -686,17 +689,16 @@ extern int module_sysfs_initialized; | |||
686 | 689 | ||
687 | 690 | ||
688 | #ifdef CONFIG_GENERIC_BUG | 691 | #ifdef CONFIG_GENERIC_BUG |
689 | int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, | 692 | void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, |
690 | struct module *); | 693 | struct module *); |
691 | void module_bug_cleanup(struct module *); | 694 | void module_bug_cleanup(struct module *); |
692 | 695 | ||
693 | #else /* !CONFIG_GENERIC_BUG */ | 696 | #else /* !CONFIG_GENERIC_BUG */ |
694 | 697 | ||
695 | static inline int module_bug_finalize(const Elf_Ehdr *hdr, | 698 | static inline void module_bug_finalize(const Elf_Ehdr *hdr, |
696 | const Elf_Shdr *sechdrs, | 699 | const Elf_Shdr *sechdrs, |
697 | struct module *mod) | 700 | struct module *mod) |
698 | { | 701 | { |
699 | return 0; | ||
700 | } | 702 | } |
701 | static inline void module_bug_cleanup(struct module *mod) {} | 703 | static inline void module_bug_cleanup(struct module *mod) {} |
702 | #endif /* CONFIG_GENERIC_BUG */ | 704 | #endif /* CONFIG_GENERIC_BUG */ |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 59d066936ab9..123566912d73 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | #define MAX_LINKS 32 | 28 | #define MAX_LINKS 32 |
29 | 29 | ||
30 | struct net; | ||
31 | |||
32 | struct sockaddr_nl { | 30 | struct sockaddr_nl { |
33 | sa_family_t nl_family; /* AF_NETLINK */ | 31 | sa_family_t nl_family; /* AF_NETLINK */ |
34 | unsigned short nl_pad; /* zero */ | 32 | unsigned short nl_pad; /* zero */ |
@@ -151,6 +149,8 @@ struct nlattr { | |||
151 | #include <linux/capability.h> | 149 | #include <linux/capability.h> |
152 | #include <linux/skbuff.h> | 150 | #include <linux/skbuff.h> |
153 | 151 | ||
152 | struct net; | ||
153 | |||
154 | static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) | 154 | static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) |
155 | { | 155 | { |
156 | return (struct nlmsghdr *)skb->data; | 156 | return (struct nlmsghdr *)skb->data; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 10d33309e9a6..570fddeb0388 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -393,6 +393,9 @@ | |||
393 | #define PCI_DEVICE_ID_VLSI_82C147 0x0105 | 393 | #define PCI_DEVICE_ID_VLSI_82C147 0x0105 |
394 | #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 | 394 | #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 |
395 | 395 | ||
396 | /* AMD RD890 Chipset */ | ||
397 | #define PCI_DEVICE_ID_RD890_IOMMU 0x5a23 | ||
398 | |||
396 | #define PCI_VENDOR_ID_ADL 0x1005 | 399 | #define PCI_VENDOR_ID_ADL 0x1005 |
397 | #define PCI_DEVICE_ID_ADL_2301 0x2301 | 400 | #define PCI_DEVICE_ID_ADL_2301 0x2301 |
398 | 401 | ||
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 49466b13c5c6..0eb50832aa00 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -39,6 +39,15 @@ | |||
39 | preempt_enable(); \ | 39 | preempt_enable(); \ |
40 | } while (0) | 40 | } while (0) |
41 | 41 | ||
42 | #define get_cpu_ptr(var) ({ \ | ||
43 | preempt_disable(); \ | ||
44 | this_cpu_ptr(var); }) | ||
45 | |||
46 | #define put_cpu_ptr(var) do { \ | ||
47 | (void)(var); \ | ||
48 | preempt_enable(); \ | ||
49 | } while (0) | ||
50 | |||
42 | #ifdef CONFIG_SMP | 51 | #ifdef CONFIG_SMP |
43 | 52 | ||
44 | /* minimum unit size, also is the maximum supported allocation size */ | 53 | /* minimum unit size, also is the maximum supported allocation size */ |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 33f08dafda2f..a9227e985207 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -529,7 +529,6 @@ struct hw_perf_event { | |||
529 | int last_cpu; | 529 | int last_cpu; |
530 | }; | 530 | }; |
531 | struct { /* software */ | 531 | struct { /* software */ |
532 | s64 remaining; | ||
533 | struct hrtimer hrtimer; | 532 | struct hrtimer hrtimer; |
534 | }; | 533 | }; |
535 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 534 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
@@ -539,6 +538,7 @@ struct hw_perf_event { | |||
539 | }; | 538 | }; |
540 | #endif | 539 | #endif |
541 | }; | 540 | }; |
541 | int state; | ||
542 | local64_t prev_count; | 542 | local64_t prev_count; |
543 | u64 sample_period; | 543 | u64 sample_period; |
544 | u64 last_period; | 544 | u64 last_period; |
@@ -550,6 +550,13 @@ struct hw_perf_event { | |||
550 | #endif | 550 | #endif |
551 | }; | 551 | }; |
552 | 552 | ||
553 | /* | ||
554 | * hw_perf_event::state flags | ||
555 | */ | ||
556 | #define PERF_HES_STOPPED 0x01 /* the counter is stopped */ | ||
557 | #define PERF_HES_UPTODATE 0x02 /* event->count up-to-date */ | ||
558 | #define PERF_HES_ARCH 0x04 | ||
559 | |||
553 | struct perf_event; | 560 | struct perf_event; |
554 | 561 | ||
555 | /* | 562 | /* |
@@ -561,36 +568,70 @@ struct perf_event; | |||
561 | * struct pmu - generic performance monitoring unit | 568 | * struct pmu - generic performance monitoring unit |
562 | */ | 569 | */ |
563 | struct pmu { | 570 | struct pmu { |
564 | int (*enable) (struct perf_event *event); | 571 | struct list_head entry; |
565 | void (*disable) (struct perf_event *event); | 572 | |
566 | int (*start) (struct perf_event *event); | 573 | int * __percpu pmu_disable_count; |
567 | void (*stop) (struct perf_event *event); | 574 | struct perf_cpu_context * __percpu pmu_cpu_context; |
568 | void (*read) (struct perf_event *event); | 575 | int task_ctx_nr; |
569 | void (*unthrottle) (struct perf_event *event); | ||
570 | 576 | ||
571 | /* | 577 | /* |
572 | * Group events scheduling is treated as a transaction, add group | 578 | * Fully disable/enable this PMU, can be used to protect from the PMI |
573 | * events as a whole and perform one schedulability test. If the test | 579 | * as well as for lazy/batch writing of the MSRs. |
574 | * fails, roll back the whole group | ||
575 | */ | 580 | */ |
581 | void (*pmu_enable) (struct pmu *pmu); /* optional */ | ||
582 | void (*pmu_disable) (struct pmu *pmu); /* optional */ | ||
576 | 583 | ||
577 | /* | 584 | /* |
578 | * Start the transaction, after this ->enable() doesn't need | 585 | * Try and initialize the event for this PMU. |
579 | * to do schedulability tests. | 586 | * Should return -ENOENT when the @event doesn't match this PMU. |
580 | */ | 587 | */ |
581 | void (*start_txn) (const struct pmu *pmu); | 588 | int (*event_init) (struct perf_event *event); |
589 | |||
590 | #define PERF_EF_START 0x01 /* start the counter when adding */ | ||
591 | #define PERF_EF_RELOAD 0x02 /* reload the counter when starting */ | ||
592 | #define PERF_EF_UPDATE 0x04 /* update the counter when stopping */ | ||
593 | |||
582 | /* | 594 | /* |
583 | * If ->start_txn() disabled the ->enable() schedulability test | 595 | * Adds/Removes a counter to/from the PMU, can be done inside |
596 | * a transaction, see the ->*_txn() methods. | ||
597 | */ | ||
598 | int (*add) (struct perf_event *event, int flags); | ||
599 | void (*del) (struct perf_event *event, int flags); | ||
600 | |||
601 | /* | ||
602 | * Starts/Stops a counter present on the PMU. The PMI handler | ||
603 | * should stop the counter when perf_event_overflow() returns | ||
604 | * !0. ->start() will be used to continue. | ||
605 | */ | ||
606 | void (*start) (struct perf_event *event, int flags); | ||
607 | void (*stop) (struct perf_event *event, int flags); | ||
608 | |||
609 | /* | ||
610 | * Updates the counter value of the event. | ||
611 | */ | ||
612 | void (*read) (struct perf_event *event); | ||
613 | |||
614 | /* | ||
615 | * Group events scheduling is treated as a transaction, add | ||
616 | * group events as a whole and perform one schedulability test. | ||
617 | * If the test fails, roll back the whole group | ||
618 | * | ||
619 | * Start the transaction, after this ->add() doesn't need to | ||
620 | * do schedulability tests. | ||
621 | */ | ||
622 | void (*start_txn) (struct pmu *pmu); /* optional */ | ||
623 | /* | ||
624 | * If ->start_txn() disabled the ->add() schedulability test | ||
584 | * then ->commit_txn() is required to perform one. On success | 625 | * then ->commit_txn() is required to perform one. On success |
585 | * the transaction is closed. On error the transaction is kept | 626 | * the transaction is closed. On error the transaction is kept |
586 | * open until ->cancel_txn() is called. | 627 | * open until ->cancel_txn() is called. |
587 | */ | 628 | */ |
588 | int (*commit_txn) (const struct pmu *pmu); | 629 | int (*commit_txn) (struct pmu *pmu); /* optional */ |
589 | /* | 630 | /* |
590 | * Will cancel the transaction, assumes ->disable() is called for | 631 | * Will cancel the transaction, assumes ->del() is called |
591 | * each successfull ->enable() during the transaction. | 632 | * for each successfull ->add() during the transaction. |
592 | */ | 633 | */ |
593 | void (*cancel_txn) (const struct pmu *pmu); | 634 | void (*cancel_txn) (struct pmu *pmu); /* optional */ |
594 | }; | 635 | }; |
595 | 636 | ||
596 | /** | 637 | /** |
@@ -669,7 +710,7 @@ struct perf_event { | |||
669 | int nr_siblings; | 710 | int nr_siblings; |
670 | int group_flags; | 711 | int group_flags; |
671 | struct perf_event *group_leader; | 712 | struct perf_event *group_leader; |
672 | const struct pmu *pmu; | 713 | struct pmu *pmu; |
673 | 714 | ||
674 | enum perf_event_active_state state; | 715 | enum perf_event_active_state state; |
675 | unsigned int attach_state; | 716 | unsigned int attach_state; |
@@ -763,12 +804,19 @@ struct perf_event { | |||
763 | #endif /* CONFIG_PERF_EVENTS */ | 804 | #endif /* CONFIG_PERF_EVENTS */ |
764 | }; | 805 | }; |
765 | 806 | ||
807 | enum perf_event_context_type { | ||
808 | task_context, | ||
809 | cpu_context, | ||
810 | }; | ||
811 | |||
766 | /** | 812 | /** |
767 | * struct perf_event_context - event context structure | 813 | * struct perf_event_context - event context structure |
768 | * | 814 | * |
769 | * Used as a container for task events and CPU events as well: | 815 | * Used as a container for task events and CPU events as well: |
770 | */ | 816 | */ |
771 | struct perf_event_context { | 817 | struct perf_event_context { |
818 | enum perf_event_context_type type; | ||
819 | struct pmu *pmu; | ||
772 | /* | 820 | /* |
773 | * Protect the states of the events in the list, | 821 | * Protect the states of the events in the list, |
774 | * nr_active, and the list: | 822 | * nr_active, and the list: |
@@ -808,6 +856,12 @@ struct perf_event_context { | |||
808 | struct rcu_head rcu_head; | 856 | struct rcu_head rcu_head; |
809 | }; | 857 | }; |
810 | 858 | ||
859 | /* | ||
860 | * Number of contexts where an event can trigger: | ||
861 | * task, softirq, hardirq, nmi. | ||
862 | */ | ||
863 | #define PERF_NR_CONTEXTS 4 | ||
864 | |||
811 | /** | 865 | /** |
812 | * struct perf_event_cpu_context - per cpu event context structure | 866 | * struct perf_event_cpu_context - per cpu event context structure |
813 | */ | 867 | */ |
@@ -815,18 +869,9 @@ struct perf_cpu_context { | |||
815 | struct perf_event_context ctx; | 869 | struct perf_event_context ctx; |
816 | struct perf_event_context *task_ctx; | 870 | struct perf_event_context *task_ctx; |
817 | int active_oncpu; | 871 | int active_oncpu; |
818 | int max_pertask; | ||
819 | int exclusive; | 872 | int exclusive; |
820 | struct swevent_hlist *swevent_hlist; | 873 | struct list_head rotation_list; |
821 | struct mutex hlist_mutex; | 874 | int jiffies_interval; |
822 | int hlist_refcount; | ||
823 | |||
824 | /* | ||
825 | * Recursion avoidance: | ||
826 | * | ||
827 | * task, softirq, irq, nmi context | ||
828 | */ | ||
829 | int recursion[4]; | ||
830 | }; | 875 | }; |
831 | 876 | ||
832 | struct perf_output_handle { | 877 | struct perf_output_handle { |
@@ -842,28 +887,22 @@ struct perf_output_handle { | |||
842 | 887 | ||
843 | #ifdef CONFIG_PERF_EVENTS | 888 | #ifdef CONFIG_PERF_EVENTS |
844 | 889 | ||
845 | /* | 890 | extern int perf_pmu_register(struct pmu *pmu); |
846 | * Set by architecture code: | 891 | extern void perf_pmu_unregister(struct pmu *pmu); |
847 | */ | ||
848 | extern int perf_max_events; | ||
849 | |||
850 | extern const struct pmu *hw_perf_event_init(struct perf_event *event); | ||
851 | 892 | ||
852 | extern int perf_num_counters(void); | 893 | extern int perf_num_counters(void); |
853 | extern const char *perf_pmu_name(void); | 894 | extern const char *perf_pmu_name(void); |
854 | extern void perf_event_task_sched_in(struct task_struct *task); | 895 | extern void perf_event_task_sched_in(struct task_struct *task); |
855 | extern void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next); | 896 | extern void perf_event_task_sched_out(struct task_struct *task, struct task_struct *next); |
856 | extern void perf_event_task_tick(struct task_struct *task); | ||
857 | extern int perf_event_init_task(struct task_struct *child); | 897 | extern int perf_event_init_task(struct task_struct *child); |
858 | extern void perf_event_exit_task(struct task_struct *child); | 898 | extern void perf_event_exit_task(struct task_struct *child); |
859 | extern void perf_event_free_task(struct task_struct *task); | 899 | extern void perf_event_free_task(struct task_struct *task); |
900 | extern void perf_event_delayed_put(struct task_struct *task); | ||
860 | extern void set_perf_event_pending(void); | 901 | extern void set_perf_event_pending(void); |
861 | extern void perf_event_do_pending(void); | 902 | extern void perf_event_do_pending(void); |
862 | extern void perf_event_print_debug(void); | 903 | extern void perf_event_print_debug(void); |
863 | extern void __perf_disable(void); | 904 | extern void perf_pmu_disable(struct pmu *pmu); |
864 | extern bool __perf_enable(void); | 905 | extern void perf_pmu_enable(struct pmu *pmu); |
865 | extern void perf_disable(void); | ||
866 | extern void perf_enable(void); | ||
867 | extern int perf_event_task_disable(void); | 906 | extern int perf_event_task_disable(void); |
868 | extern int perf_event_task_enable(void); | 907 | extern int perf_event_task_enable(void); |
869 | extern void perf_event_update_userpage(struct perf_event *event); | 908 | extern void perf_event_update_userpage(struct perf_event *event); |
@@ -871,7 +910,7 @@ extern int perf_event_release_kernel(struct perf_event *event); | |||
871 | extern struct perf_event * | 910 | extern struct perf_event * |
872 | perf_event_create_kernel_counter(struct perf_event_attr *attr, | 911 | perf_event_create_kernel_counter(struct perf_event_attr *attr, |
873 | int cpu, | 912 | int cpu, |
874 | pid_t pid, | 913 | struct task_struct *task, |
875 | perf_overflow_handler_t callback); | 914 | perf_overflow_handler_t callback); |
876 | extern u64 perf_event_read_value(struct perf_event *event, | 915 | extern u64 perf_event_read_value(struct perf_event *event, |
877 | u64 *enabled, u64 *running); | 916 | u64 *enabled, u64 *running); |
@@ -922,14 +961,7 @@ extern int perf_event_overflow(struct perf_event *event, int nmi, | |||
922 | */ | 961 | */ |
923 | static inline int is_software_event(struct perf_event *event) | 962 | static inline int is_software_event(struct perf_event *event) |
924 | { | 963 | { |
925 | switch (event->attr.type) { | 964 | return event->pmu->task_ctx_nr == perf_sw_context; |
926 | case PERF_TYPE_SOFTWARE: | ||
927 | case PERF_TYPE_TRACEPOINT: | ||
928 | /* for now the breakpoint stuff also works as software event */ | ||
929 | case PERF_TYPE_BREAKPOINT: | ||
930 | return 1; | ||
931 | } | ||
932 | return 0; | ||
933 | } | 965 | } |
934 | 966 | ||
935 | extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; | 967 | extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; |
@@ -978,7 +1010,21 @@ extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks | |||
978 | extern void perf_event_comm(struct task_struct *tsk); | 1010 | extern void perf_event_comm(struct task_struct *tsk); |
979 | extern void perf_event_fork(struct task_struct *tsk); | 1011 | extern void perf_event_fork(struct task_struct *tsk); |
980 | 1012 | ||
981 | extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); | 1013 | /* Callchains */ |
1014 | DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); | ||
1015 | |||
1016 | extern void perf_callchain_user(struct perf_callchain_entry *entry, | ||
1017 | struct pt_regs *regs); | ||
1018 | extern void perf_callchain_kernel(struct perf_callchain_entry *entry, | ||
1019 | struct pt_regs *regs); | ||
1020 | |||
1021 | |||
1022 | static inline void | ||
1023 | perf_callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
1024 | { | ||
1025 | if (entry->nr < PERF_MAX_STACK_DEPTH) | ||
1026 | entry->ip[entry->nr++] = ip; | ||
1027 | } | ||
982 | 1028 | ||
983 | extern int sysctl_perf_event_paranoid; | 1029 | extern int sysctl_perf_event_paranoid; |
984 | extern int sysctl_perf_event_mlock; | 1030 | extern int sysctl_perf_event_mlock; |
@@ -1021,21 +1067,19 @@ extern int perf_swevent_get_recursion_context(void); | |||
1021 | extern void perf_swevent_put_recursion_context(int rctx); | 1067 | extern void perf_swevent_put_recursion_context(int rctx); |
1022 | extern void perf_event_enable(struct perf_event *event); | 1068 | extern void perf_event_enable(struct perf_event *event); |
1023 | extern void perf_event_disable(struct perf_event *event); | 1069 | extern void perf_event_disable(struct perf_event *event); |
1070 | extern void perf_event_task_tick(void); | ||
1024 | #else | 1071 | #else |
1025 | static inline void | 1072 | static inline void |
1026 | perf_event_task_sched_in(struct task_struct *task) { } | 1073 | perf_event_task_sched_in(struct task_struct *task) { } |
1027 | static inline void | 1074 | static inline void |
1028 | perf_event_task_sched_out(struct task_struct *task, | 1075 | perf_event_task_sched_out(struct task_struct *task, |
1029 | struct task_struct *next) { } | 1076 | struct task_struct *next) { } |
1030 | static inline void | ||
1031 | perf_event_task_tick(struct task_struct *task) { } | ||
1032 | static inline int perf_event_init_task(struct task_struct *child) { return 0; } | 1077 | static inline int perf_event_init_task(struct task_struct *child) { return 0; } |
1033 | static inline void perf_event_exit_task(struct task_struct *child) { } | 1078 | static inline void perf_event_exit_task(struct task_struct *child) { } |
1034 | static inline void perf_event_free_task(struct task_struct *task) { } | 1079 | static inline void perf_event_free_task(struct task_struct *task) { } |
1080 | static inline void perf_event_delayed_put(struct task_struct *task) { } | ||
1035 | static inline void perf_event_do_pending(void) { } | 1081 | static inline void perf_event_do_pending(void) { } |
1036 | static inline void perf_event_print_debug(void) { } | 1082 | static inline void perf_event_print_debug(void) { } |
1037 | static inline void perf_disable(void) { } | ||
1038 | static inline void perf_enable(void) { } | ||
1039 | static inline int perf_event_task_disable(void) { return -EINVAL; } | 1083 | static inline int perf_event_task_disable(void) { return -EINVAL; } |
1040 | static inline int perf_event_task_enable(void) { return -EINVAL; } | 1084 | static inline int perf_event_task_enable(void) { return -EINVAL; } |
1041 | 1085 | ||
@@ -1058,6 +1102,7 @@ static inline int perf_swevent_get_recursion_context(void) { return -1; } | |||
1058 | static inline void perf_swevent_put_recursion_context(int rctx) { } | 1102 | static inline void perf_swevent_put_recursion_context(int rctx) { } |
1059 | static inline void perf_event_enable(struct perf_event *event) { } | 1103 | static inline void perf_event_enable(struct perf_event *event) { } |
1060 | static inline void perf_event_disable(struct perf_event *event) { } | 1104 | static inline void perf_event_disable(struct perf_event *event) { } |
1105 | static inline void perf_event_task_tick(void) { } | ||
1061 | #endif | 1106 | #endif |
1062 | 1107 | ||
1063 | #define perf_output_put(handle, x) \ | 1108 | #define perf_output_put(handle, x) \ |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9fbc54a2585d..83af1f8d8b74 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -454,7 +454,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
454 | * Makes rcu_dereference_check() do the dirty work. | 454 | * Makes rcu_dereference_check() do the dirty work. |
455 | */ | 455 | */ |
456 | #define rcu_dereference_bh(p) \ | 456 | #define rcu_dereference_bh(p) \ |
457 | rcu_dereference_check(p, rcu_read_lock_bh_held()) | 457 | rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled()) |
458 | 458 | ||
459 | /** | 459 | /** |
460 | * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched | 460 | * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 1e2a6db2d7dd..eb3c1ceec06e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1160,6 +1160,13 @@ struct sched_rt_entity { | |||
1160 | 1160 | ||
1161 | struct rcu_node; | 1161 | struct rcu_node; |
1162 | 1162 | ||
1163 | enum perf_event_task_context { | ||
1164 | perf_invalid_context = -1, | ||
1165 | perf_hw_context = 0, | ||
1166 | perf_sw_context, | ||
1167 | perf_nr_task_contexts, | ||
1168 | }; | ||
1169 | |||
1163 | struct task_struct { | 1170 | struct task_struct { |
1164 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ | 1171 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
1165 | void *stack; | 1172 | void *stack; |
@@ -1431,7 +1438,7 @@ struct task_struct { | |||
1431 | struct futex_pi_state *pi_state_cache; | 1438 | struct futex_pi_state *pi_state_cache; |
1432 | #endif | 1439 | #endif |
1433 | #ifdef CONFIG_PERF_EVENTS | 1440 | #ifdef CONFIG_PERF_EVENTS |
1434 | struct perf_event_context *perf_event_ctxp; | 1441 | struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; |
1435 | struct mutex perf_event_mutex; | 1442 | struct mutex perf_event_mutex; |
1436 | struct list_head perf_event_list; | 1443 | struct list_head perf_event_list; |
1437 | #endif | 1444 | #endif |
diff --git a/include/linux/socket.h b/include/linux/socket.h index a2fada9becb6..a8f56e1ec760 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -322,7 +322,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, | |||
322 | int offset, | 322 | int offset, |
323 | unsigned int len, __wsum *csump); | 323 | unsigned int len, __wsum *csump); |
324 | 324 | ||
325 | extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); | 325 | extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); |
326 | extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); | 326 | extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); |
327 | extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, | 327 | extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, |
328 | int offset, int len); | 328 | int offset, int len); |
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h index 6b524a0d02e4..1808960c5059 100644 --- a/include/linux/stop_machine.h +++ b/include/linux/stop_machine.h | |||
@@ -126,8 +126,8 @@ int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); | |||
126 | 126 | ||
127 | #else /* CONFIG_STOP_MACHINE && CONFIG_SMP */ | 127 | #else /* CONFIG_STOP_MACHINE && CONFIG_SMP */ |
128 | 128 | ||
129 | static inline int stop_machine(int (*fn)(void *), void *data, | 129 | static inline int __stop_machine(int (*fn)(void *), void *data, |
130 | const struct cpumask *cpus) | 130 | const struct cpumask *cpus) |
131 | { | 131 | { |
132 | int ret; | 132 | int ret; |
133 | local_irq_disable(); | 133 | local_irq_disable(); |
@@ -136,5 +136,11 @@ static inline int stop_machine(int (*fn)(void *), void *data, | |||
136 | return ret; | 136 | return ret; |
137 | } | 137 | } |
138 | 138 | ||
139 | static inline int stop_machine(int (*fn)(void *), void *data, | ||
140 | const struct cpumask *cpus) | ||
141 | { | ||
142 | return __stop_machine(fn, data, cpus); | ||
143 | } | ||
144 | |||
139 | #endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */ | 145 | #endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */ |
140 | #endif /* _LINUX_STOP_MACHINE */ | 146 | #endif /* _LINUX_STOP_MACHINE */ |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 103d1b61aacb..a4a90b6726ce 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/rcupdate.h> | 19 | #include <linux/rcupdate.h> |
20 | #include <linux/jump_label.h> | ||
20 | 21 | ||
21 | struct module; | 22 | struct module; |
22 | struct tracepoint; | 23 | struct tracepoint; |
@@ -145,7 +146,9 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
145 | extern struct tracepoint __tracepoint_##name; \ | 146 | extern struct tracepoint __tracepoint_##name; \ |
146 | static inline void trace_##name(proto) \ | 147 | static inline void trace_##name(proto) \ |
147 | { \ | 148 | { \ |
148 | if (unlikely(__tracepoint_##name.state)) \ | 149 | JUMP_LABEL(&__tracepoint_##name.state, do_trace); \ |
150 | return; \ | ||
151 | do_trace: \ | ||
149 | __DO_TRACE(&__tracepoint_##name, \ | 152 | __DO_TRACE(&__tracepoint_##name, \ |
150 | TP_PROTO(data_proto), \ | 153 | TP_PROTO(data_proto), \ |
151 | TP_ARGS(data_args)); \ | 154 | TP_ARGS(data_args)); \ |
diff --git a/include/linux/wait.h b/include/linux/wait.h index 0836ccc57121..3efc9f3f43a0 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -614,6 +614,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | |||
614 | (wait)->private = current; \ | 614 | (wait)->private = current; \ |
615 | (wait)->func = autoremove_wake_function; \ | 615 | (wait)->func = autoremove_wake_function; \ |
616 | INIT_LIST_HEAD(&(wait)->task_list); \ | 616 | INIT_LIST_HEAD(&(wait)->task_list); \ |
617 | (wait)->flags = 0; \ | ||
617 | } while (0) | 618 | } while (0) |
618 | 619 | ||
619 | /** | 620 | /** |
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 45375b41a2a0..4d40c4d0230b 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h | |||
@@ -121,6 +121,7 @@ static inline int addrconf_finite_timeout(unsigned long timeout) | |||
121 | * IPv6 Address Label subsystem (addrlabel.c) | 121 | * IPv6 Address Label subsystem (addrlabel.c) |
122 | */ | 122 | */ |
123 | extern int ipv6_addr_label_init(void); | 123 | extern int ipv6_addr_label_init(void); |
124 | extern void ipv6_addr_label_cleanup(void); | ||
124 | extern void ipv6_addr_label_rtnl_register(void); | 125 | extern void ipv6_addr_label_rtnl_register(void); |
125 | extern u32 ipv6_addr_label(struct net *net, | 126 | extern u32 ipv6_addr_label(struct net *net, |
126 | const struct in6_addr *addr, | 127 | const struct in6_addr *addr, |
diff --git a/include/net/dst.h b/include/net/dst.h index 81d1413a8701..02386505033d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -242,6 +242,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) | |||
242 | dev->stats.rx_packets++; | 242 | dev->stats.rx_packets++; |
243 | dev->stats.rx_bytes += skb->len; | 243 | dev->stats.rx_bytes += skb->len; |
244 | skb->rxhash = 0; | 244 | skb->rxhash = 0; |
245 | skb_set_queue_mapping(skb, 0); | ||
245 | skb_dst_drop(skb); | 246 | skb_dst_drop(skb); |
246 | nf_reset(skb); | 247 | nf_reset(skb); |
247 | } | 248 | } |
diff --git a/include/net/route.h b/include/net/route.h index bd732d62e1c3..7e5e73bfa4de 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -199,6 +199,8 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, | |||
199 | fl.fl_ip_sport = sport; | 199 | fl.fl_ip_sport = sport; |
200 | fl.fl_ip_dport = dport; | 200 | fl.fl_ip_dport = dport; |
201 | fl.proto = protocol; | 201 | fl.proto = protocol; |
202 | if (inet_sk(sk)->transparent) | ||
203 | fl.flags |= FLOWI_FLAG_ANYSRC; | ||
202 | ip_rt_put(*rp); | 204 | ip_rt_put(*rp); |
203 | *rp = NULL; | 205 | *rp = NULL; |
204 | security_sk_classify_flow(sk, &fl); | 206 | security_sk_classify_flow(sk, &fl); |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index fc8f36dd0f5c..4f53532d4c2f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -298,8 +298,8 @@ struct xfrm_state_afinfo { | |||
298 | const struct xfrm_type *type_map[IPPROTO_MAX]; | 298 | const struct xfrm_type *type_map[IPPROTO_MAX]; |
299 | struct xfrm_mode *mode_map[XFRM_MODE_MAX]; | 299 | struct xfrm_mode *mode_map[XFRM_MODE_MAX]; |
300 | int (*init_flags)(struct xfrm_state *x); | 300 | int (*init_flags)(struct xfrm_state *x); |
301 | void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, | 301 | void (*init_tempsel)(struct xfrm_selector *sel, struct flowi *fl); |
302 | struct xfrm_tmpl *tmpl, | 302 | void (*init_temprop)(struct xfrm_state *x, struct xfrm_tmpl *tmpl, |
303 | xfrm_address_t *daddr, xfrm_address_t *saddr); | 303 | xfrm_address_t *daddr, xfrm_address_t *saddr); |
304 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); | 304 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); |
305 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); | 305 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); |
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index 0e4cfb694fe7..6fa7cbab7d93 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h | |||
@@ -5,7 +5,9 @@ | |||
5 | #define _TRACE_IRQ_H | 5 | #define _TRACE_IRQ_H |
6 | 6 | ||
7 | #include <linux/tracepoint.h> | 7 | #include <linux/tracepoint.h> |
8 | #include <linux/interrupt.h> | 8 | |
9 | struct irqaction; | ||
10 | struct softirq_action; | ||
9 | 11 | ||
10 | #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } | 12 | #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } |
11 | #define show_softirq_name(val) \ | 13 | #define show_softirq_name(val) \ |
@@ -93,7 +95,10 @@ DECLARE_EVENT_CLASS(softirq, | |||
93 | ), | 95 | ), |
94 | 96 | ||
95 | TP_fast_assign( | 97 | TP_fast_assign( |
96 | __entry->vec = (int)(h - vec); | 98 | if (vec) |
99 | __entry->vec = (int)(h - vec); | ||
100 | else | ||
101 | __entry->vec = (int)(long)h; | ||
97 | ), | 102 | ), |
98 | 103 | ||
99 | TP_printk("vec=%d [action=%s]", __entry->vec, | 104 | TP_printk("vec=%d [action=%s]", __entry->vec, |
@@ -136,6 +141,23 @@ DEFINE_EVENT(softirq, softirq_exit, | |||
136 | TP_ARGS(h, vec) | 141 | TP_ARGS(h, vec) |
137 | ); | 142 | ); |
138 | 143 | ||
144 | /** | ||
145 | * softirq_raise - called immediately when a softirq is raised | ||
146 | * @h: pointer to struct softirq_action | ||
147 | * @vec: pointer to first struct softirq_action in softirq_vec array | ||
148 | * | ||
149 | * The @h parameter contains a pointer to the softirq vector number which is | ||
150 | * raised. @vec is NULL and it means @h includes vector number not | ||
151 | * softirq_action. When used in combination with the softirq_entry tracepoint | ||
152 | * we can determine the softirq raise latency. | ||
153 | */ | ||
154 | DEFINE_EVENT(softirq, softirq_raise, | ||
155 | |||
156 | TP_PROTO(struct softirq_action *h, struct softirq_action *vec), | ||
157 | |||
158 | TP_ARGS(h, vec) | ||
159 | ); | ||
160 | |||
139 | #endif /* _TRACE_IRQ_H */ | 161 | #endif /* _TRACE_IRQ_H */ |
140 | 162 | ||
141 | /* This part must be outside protection */ | 163 | /* This part must be outside protection */ |
diff --git a/include/trace/events/napi.h b/include/trace/events/napi.h index 188deca2f3c7..8fe1e93f531d 100644 --- a/include/trace/events/napi.h +++ b/include/trace/events/napi.h | |||
@@ -6,10 +6,31 @@ | |||
6 | 6 | ||
7 | #include <linux/netdevice.h> | 7 | #include <linux/netdevice.h> |
8 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
9 | #include <linux/ftrace.h> | ||
10 | |||
11 | #define NO_DEV "(no_device)" | ||
12 | |||
13 | TRACE_EVENT(napi_poll, | ||
9 | 14 | ||
10 | DECLARE_TRACE(napi_poll, | ||
11 | TP_PROTO(struct napi_struct *napi), | 15 | TP_PROTO(struct napi_struct *napi), |
12 | TP_ARGS(napi)); | 16 | |
17 | TP_ARGS(napi), | ||
18 | |||
19 | TP_STRUCT__entry( | ||
20 | __field( struct napi_struct *, napi) | ||
21 | __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) | ||
22 | ), | ||
23 | |||
24 | TP_fast_assign( | ||
25 | __entry->napi = napi; | ||
26 | __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV); | ||
27 | ), | ||
28 | |||
29 | TP_printk("napi poll on napi struct %p for device %s", | ||
30 | __entry->napi, __get_str(dev_name)) | ||
31 | ); | ||
32 | |||
33 | #undef NO_DEV | ||
13 | 34 | ||
14 | #endif /* _TRACE_NAPI_H_ */ | 35 | #endif /* _TRACE_NAPI_H_ */ |
15 | 36 | ||
diff --git a/include/trace/events/net.h b/include/trace/events/net.h new file mode 100644 index 000000000000..5f247f5ffc56 --- /dev/null +++ b/include/trace/events/net.h | |||
@@ -0,0 +1,82 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM net | ||
3 | |||
4 | #if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_NET_H | ||
6 | |||
7 | #include <linux/skbuff.h> | ||
8 | #include <linux/netdevice.h> | ||
9 | #include <linux/ip.h> | ||
10 | #include <linux/tracepoint.h> | ||
11 | |||
12 | TRACE_EVENT(net_dev_xmit, | ||
13 | |||
14 | TP_PROTO(struct sk_buff *skb, | ||
15 | int rc), | ||
16 | |||
17 | TP_ARGS(skb, rc), | ||
18 | |||
19 | TP_STRUCT__entry( | ||
20 | __field( void *, skbaddr ) | ||
21 | __field( unsigned int, len ) | ||
22 | __field( int, rc ) | ||
23 | __string( name, skb->dev->name ) | ||
24 | ), | ||
25 | |||
26 | TP_fast_assign( | ||
27 | __entry->skbaddr = skb; | ||
28 | __entry->len = skb->len; | ||
29 | __entry->rc = rc; | ||
30 | __assign_str(name, skb->dev->name); | ||
31 | ), | ||
32 | |||
33 | TP_printk("dev=%s skbaddr=%p len=%u rc=%d", | ||
34 | __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) | ||
35 | ); | ||
36 | |||
37 | DECLARE_EVENT_CLASS(net_dev_template, | ||
38 | |||
39 | TP_PROTO(struct sk_buff *skb), | ||
40 | |||
41 | TP_ARGS(skb), | ||
42 | |||
43 | TP_STRUCT__entry( | ||
44 | __field( void *, skbaddr ) | ||
45 | __field( unsigned int, len ) | ||
46 | __string( name, skb->dev->name ) | ||
47 | ), | ||
48 | |||
49 | TP_fast_assign( | ||
50 | __entry->skbaddr = skb; | ||
51 | __entry->len = skb->len; | ||
52 | __assign_str(name, skb->dev->name); | ||
53 | ), | ||
54 | |||
55 | TP_printk("dev=%s skbaddr=%p len=%u", | ||
56 | __get_str(name), __entry->skbaddr, __entry->len) | ||
57 | ) | ||
58 | |||
59 | DEFINE_EVENT(net_dev_template, net_dev_queue, | ||
60 | |||
61 | TP_PROTO(struct sk_buff *skb), | ||
62 | |||
63 | TP_ARGS(skb) | ||
64 | ); | ||
65 | |||
66 | DEFINE_EVENT(net_dev_template, netif_receive_skb, | ||
67 | |||
68 | TP_PROTO(struct sk_buff *skb), | ||
69 | |||
70 | TP_ARGS(skb) | ||
71 | ); | ||
72 | |||
73 | DEFINE_EVENT(net_dev_template, netif_rx, | ||
74 | |||
75 | TP_PROTO(struct sk_buff *skb), | ||
76 | |||
77 | TP_ARGS(skb) | ||
78 | ); | ||
79 | #endif /* _TRACE_NET_H */ | ||
80 | |||
81 | /* This part must be outside protection */ | ||
82 | #include <trace/define_trace.h> | ||
diff --git a/include/trace/events/power.h b/include/trace/events/power.h index 35a2a6e7bf1e..286784d69b8f 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h | |||
@@ -10,12 +10,17 @@ | |||
10 | #ifndef _TRACE_POWER_ENUM_ | 10 | #ifndef _TRACE_POWER_ENUM_ |
11 | #define _TRACE_POWER_ENUM_ | 11 | #define _TRACE_POWER_ENUM_ |
12 | enum { | 12 | enum { |
13 | POWER_NONE = 0, | 13 | POWER_NONE = 0, |
14 | POWER_CSTATE = 1, | 14 | POWER_CSTATE = 1, /* C-State */ |
15 | POWER_PSTATE = 2, | 15 | POWER_PSTATE = 2, /* Fequency change or DVFS */ |
16 | POWER_SSTATE = 3, /* Suspend */ | ||
16 | }; | 17 | }; |
17 | #endif | 18 | #endif |
18 | 19 | ||
20 | /* | ||
21 | * The power events are used for cpuidle & suspend (power_start, power_end) | ||
22 | * and for cpufreq (power_frequency) | ||
23 | */ | ||
19 | DECLARE_EVENT_CLASS(power, | 24 | DECLARE_EVENT_CLASS(power, |
20 | 25 | ||
21 | TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), | 26 | TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), |
@@ -70,6 +75,85 @@ TRACE_EVENT(power_end, | |||
70 | 75 | ||
71 | ); | 76 | ); |
72 | 77 | ||
78 | /* | ||
79 | * The clock events are used for clock enable/disable and for | ||
80 | * clock rate change | ||
81 | */ | ||
82 | DECLARE_EVENT_CLASS(clock, | ||
83 | |||
84 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
85 | |||
86 | TP_ARGS(name, state, cpu_id), | ||
87 | |||
88 | TP_STRUCT__entry( | ||
89 | __string( name, name ) | ||
90 | __field( u64, state ) | ||
91 | __field( u64, cpu_id ) | ||
92 | ), | ||
93 | |||
94 | TP_fast_assign( | ||
95 | __assign_str(name, name); | ||
96 | __entry->state = state; | ||
97 | __entry->cpu_id = cpu_id; | ||
98 | ), | ||
99 | |||
100 | TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), | ||
101 | (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) | ||
102 | ); | ||
103 | |||
104 | DEFINE_EVENT(clock, clock_enable, | ||
105 | |||
106 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
107 | |||
108 | TP_ARGS(name, state, cpu_id) | ||
109 | ); | ||
110 | |||
111 | DEFINE_EVENT(clock, clock_disable, | ||
112 | |||
113 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
114 | |||
115 | TP_ARGS(name, state, cpu_id) | ||
116 | ); | ||
117 | |||
118 | DEFINE_EVENT(clock, clock_set_rate, | ||
119 | |||
120 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
121 | |||
122 | TP_ARGS(name, state, cpu_id) | ||
123 | ); | ||
124 | |||
125 | /* | ||
126 | * The power domain events are used for power domains transitions | ||
127 | */ | ||
128 | DECLARE_EVENT_CLASS(power_domain, | ||
129 | |||
130 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
131 | |||
132 | TP_ARGS(name, state, cpu_id), | ||
133 | |||
134 | TP_STRUCT__entry( | ||
135 | __string( name, name ) | ||
136 | __field( u64, state ) | ||
137 | __field( u64, cpu_id ) | ||
138 | ), | ||
139 | |||
140 | TP_fast_assign( | ||
141 | __assign_str(name, name); | ||
142 | __entry->state = state; | ||
143 | __entry->cpu_id = cpu_id; | ||
144 | ), | ||
145 | |||
146 | TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), | ||
147 | (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) | ||
148 | ); | ||
149 | |||
150 | DEFINE_EVENT(power_domain, power_domain_target, | ||
151 | |||
152 | TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), | ||
153 | |||
154 | TP_ARGS(name, state, cpu_id) | ||
155 | ); | ||
156 | |||
73 | #endif /* _TRACE_POWER_H */ | 157 | #endif /* _TRACE_POWER_H */ |
74 | 158 | ||
75 | /* This part must be outside protection */ | 159 | /* This part must be outside protection */ |
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h index 4b2be6dc76f0..75ce9d500d8e 100644 --- a/include/trace/events/skb.h +++ b/include/trace/events/skb.h | |||
@@ -35,6 +35,23 @@ TRACE_EVENT(kfree_skb, | |||
35 | __entry->skbaddr, __entry->protocol, __entry->location) | 35 | __entry->skbaddr, __entry->protocol, __entry->location) |
36 | ); | 36 | ); |
37 | 37 | ||
38 | TRACE_EVENT(consume_skb, | ||
39 | |||
40 | TP_PROTO(struct sk_buff *skb), | ||
41 | |||
42 | TP_ARGS(skb), | ||
43 | |||
44 | TP_STRUCT__entry( | ||
45 | __field( void *, skbaddr ) | ||
46 | ), | ||
47 | |||
48 | TP_fast_assign( | ||
49 | __entry->skbaddr = skb; | ||
50 | ), | ||
51 | |||
52 | TP_printk("skbaddr=%p", __entry->skbaddr) | ||
53 | ); | ||
54 | |||
38 | TRACE_EVENT(skb_copy_datagram_iovec, | 55 | TRACE_EVENT(skb_copy_datagram_iovec, |
39 | 56 | ||
40 | TP_PROTO(const struct sk_buff *skb, int len), | 57 | TP_PROTO(const struct sk_buff *skb, int len), |
@@ -743,6 +743,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, | |||
743 | { | 743 | { |
744 | struct semid_ds out; | 744 | struct semid_ds out; |
745 | 745 | ||
746 | memset(&out, 0, sizeof(out)); | ||
747 | |||
746 | ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm); | 748 | ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm); |
747 | 749 | ||
748 | out.sem_otime = in->sem_otime; | 750 | out.sem_otime = in->sem_otime; |
diff --git a/kernel/Makefile b/kernel/Makefile index 0b72d1a74be0..d52b473c99a1 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -10,7 +10,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ | |||
10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ | 11 | hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ |
12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ | 12 | notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ |
13 | async.o range.o | 13 | async.o range.o jump_label.o |
14 | obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o | 14 | obj-$(CONFIG_HAVE_EARLY_RES) += early_res.o |
15 | obj-y += groups.o | 15 | obj-y += groups.o |
16 | 16 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 03120229db28..e2bdf37f9fde 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -149,9 +149,7 @@ static void delayed_put_task_struct(struct rcu_head *rhp) | |||
149 | { | 149 | { |
150 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); | 150 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); |
151 | 151 | ||
152 | #ifdef CONFIG_PERF_EVENTS | 152 | perf_event_delayed_put(tsk); |
153 | WARN_ON_ONCE(tsk->perf_event_ctxp); | ||
154 | #endif | ||
155 | trace_sched_process_free(tsk); | 153 | trace_sched_process_free(tsk); |
156 | put_task_struct(tsk); | 154 | put_task_struct(tsk); |
157 | } | 155 | } |
diff --git a/kernel/fork.c b/kernel/fork.c index b7e9d60a675d..c445f8cc408d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -356,10 +356,10 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
356 | if (IS_ERR(pol)) | 356 | if (IS_ERR(pol)) |
357 | goto fail_nomem_policy; | 357 | goto fail_nomem_policy; |
358 | vma_set_policy(tmp, pol); | 358 | vma_set_policy(tmp, pol); |
359 | tmp->vm_mm = mm; | ||
359 | if (anon_vma_fork(tmp, mpnt)) | 360 | if (anon_vma_fork(tmp, mpnt)) |
360 | goto fail_nomem_anon_vma_fork; | 361 | goto fail_nomem_anon_vma_fork; |
361 | tmp->vm_flags &= ~VM_LOCKED; | 362 | tmp->vm_flags &= ~VM_LOCKED; |
362 | tmp->vm_mm = mm; | ||
363 | tmp->vm_next = tmp->vm_prev = NULL; | 363 | tmp->vm_next = tmp->vm_prev = NULL; |
364 | file = tmp->vm_file; | 364 | file = tmp->vm_file; |
365 | if (file) { | 365 | if (file) { |
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index c7c2aed9e2dc..3b714e839c10 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
@@ -433,8 +433,7 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, | |||
433 | perf_overflow_handler_t triggered, | 433 | perf_overflow_handler_t triggered, |
434 | struct task_struct *tsk) | 434 | struct task_struct *tsk) |
435 | { | 435 | { |
436 | return perf_event_create_kernel_counter(attr, -1, task_pid_vnr(tsk), | 436 | return perf_event_create_kernel_counter(attr, -1, tsk, triggered); |
437 | triggered); | ||
438 | } | 437 | } |
439 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); | 438 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); |
440 | 439 | ||
@@ -516,7 +515,7 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, | |||
516 | get_online_cpus(); | 515 | get_online_cpus(); |
517 | for_each_online_cpu(cpu) { | 516 | for_each_online_cpu(cpu) { |
518 | pevent = per_cpu_ptr(cpu_events, cpu); | 517 | pevent = per_cpu_ptr(cpu_events, cpu); |
519 | bp = perf_event_create_kernel_counter(attr, cpu, -1, triggered); | 518 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, triggered); |
520 | 519 | ||
521 | *pevent = bp; | 520 | *pevent = bp; |
522 | 521 | ||
@@ -566,6 +565,61 @@ static struct notifier_block hw_breakpoint_exceptions_nb = { | |||
566 | .priority = 0x7fffffff | 565 | .priority = 0x7fffffff |
567 | }; | 566 | }; |
568 | 567 | ||
568 | static void bp_perf_event_destroy(struct perf_event *event) | ||
569 | { | ||
570 | release_bp_slot(event); | ||
571 | } | ||
572 | |||
573 | static int hw_breakpoint_event_init(struct perf_event *bp) | ||
574 | { | ||
575 | int err; | ||
576 | |||
577 | if (bp->attr.type != PERF_TYPE_BREAKPOINT) | ||
578 | return -ENOENT; | ||
579 | |||
580 | err = register_perf_hw_breakpoint(bp); | ||
581 | if (err) | ||
582 | return err; | ||
583 | |||
584 | bp->destroy = bp_perf_event_destroy; | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int hw_breakpoint_add(struct perf_event *bp, int flags) | ||
590 | { | ||
591 | if (!(flags & PERF_EF_START)) | ||
592 | bp->hw.state = PERF_HES_STOPPED; | ||
593 | |||
594 | return arch_install_hw_breakpoint(bp); | ||
595 | } | ||
596 | |||
597 | static void hw_breakpoint_del(struct perf_event *bp, int flags) | ||
598 | { | ||
599 | arch_uninstall_hw_breakpoint(bp); | ||
600 | } | ||
601 | |||
602 | static void hw_breakpoint_start(struct perf_event *bp, int flags) | ||
603 | { | ||
604 | bp->hw.state = 0; | ||
605 | } | ||
606 | |||
607 | static void hw_breakpoint_stop(struct perf_event *bp, int flags) | ||
608 | { | ||
609 | bp->hw.state = PERF_HES_STOPPED; | ||
610 | } | ||
611 | |||
612 | static struct pmu perf_breakpoint = { | ||
613 | .task_ctx_nr = perf_sw_context, /* could eventually get its own */ | ||
614 | |||
615 | .event_init = hw_breakpoint_event_init, | ||
616 | .add = hw_breakpoint_add, | ||
617 | .del = hw_breakpoint_del, | ||
618 | .start = hw_breakpoint_start, | ||
619 | .stop = hw_breakpoint_stop, | ||
620 | .read = hw_breakpoint_pmu_read, | ||
621 | }; | ||
622 | |||
569 | static int __init init_hw_breakpoint(void) | 623 | static int __init init_hw_breakpoint(void) |
570 | { | 624 | { |
571 | unsigned int **task_bp_pinned; | 625 | unsigned int **task_bp_pinned; |
@@ -587,6 +641,8 @@ static int __init init_hw_breakpoint(void) | |||
587 | 641 | ||
588 | constraints_initialized = 1; | 642 | constraints_initialized = 1; |
589 | 643 | ||
644 | perf_pmu_register(&perf_breakpoint); | ||
645 | |||
590 | return register_die_notifier(&hw_breakpoint_exceptions_nb); | 646 | return register_die_notifier(&hw_breakpoint_exceptions_nb); |
591 | 647 | ||
592 | err_alloc: | 648 | err_alloc: |
@@ -602,8 +658,3 @@ static int __init init_hw_breakpoint(void) | |||
602 | core_initcall(init_hw_breakpoint); | 658 | core_initcall(init_hw_breakpoint); |
603 | 659 | ||
604 | 660 | ||
605 | struct pmu perf_ops_bp = { | ||
606 | .enable = arch_install_hw_breakpoint, | ||
607 | .disable = arch_uninstall_hw_breakpoint, | ||
608 | .read = hw_breakpoint_pmu_read, | ||
609 | }; | ||
diff --git a/kernel/jump_label.c b/kernel/jump_label.c new file mode 100644 index 000000000000..7be868bf25c6 --- /dev/null +++ b/kernel/jump_label.c | |||
@@ -0,0 +1,429 @@ | |||
1 | /* | ||
2 | * jump label support | ||
3 | * | ||
4 | * Copyright (C) 2009 Jason Baron <jbaron@redhat.com> | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/jump_label.h> | ||
8 | #include <linux/memory.h> | ||
9 | #include <linux/uaccess.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/jhash.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/sort.h> | ||
15 | #include <linux/err.h> | ||
16 | |||
17 | #ifdef HAVE_JUMP_LABEL | ||
18 | |||
19 | #define JUMP_LABEL_HASH_BITS 6 | ||
20 | #define JUMP_LABEL_TABLE_SIZE (1 << JUMP_LABEL_HASH_BITS) | ||
21 | static struct hlist_head jump_label_table[JUMP_LABEL_TABLE_SIZE]; | ||
22 | |||
23 | /* mutex to protect coming/going of the the jump_label table */ | ||
24 | static DEFINE_MUTEX(jump_label_mutex); | ||
25 | |||
26 | struct jump_label_entry { | ||
27 | struct hlist_node hlist; | ||
28 | struct jump_entry *table; | ||
29 | int nr_entries; | ||
30 | /* hang modules off here */ | ||
31 | struct hlist_head modules; | ||
32 | unsigned long key; | ||
33 | }; | ||
34 | |||
35 | struct jump_label_module_entry { | ||
36 | struct hlist_node hlist; | ||
37 | struct jump_entry *table; | ||
38 | int nr_entries; | ||
39 | struct module *mod; | ||
40 | }; | ||
41 | |||
42 | static int jump_label_cmp(const void *a, const void *b) | ||
43 | { | ||
44 | const struct jump_entry *jea = a; | ||
45 | const struct jump_entry *jeb = b; | ||
46 | |||
47 | if (jea->key < jeb->key) | ||
48 | return -1; | ||
49 | |||
50 | if (jea->key > jeb->key) | ||
51 | return 1; | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static void | ||
57 | sort_jump_label_entries(struct jump_entry *start, struct jump_entry *stop) | ||
58 | { | ||
59 | unsigned long size; | ||
60 | |||
61 | size = (((unsigned long)stop - (unsigned long)start) | ||
62 | / sizeof(struct jump_entry)); | ||
63 | sort(start, size, sizeof(struct jump_entry), jump_label_cmp, NULL); | ||
64 | } | ||
65 | |||
66 | static struct jump_label_entry *get_jump_label_entry(jump_label_t key) | ||
67 | { | ||
68 | struct hlist_head *head; | ||
69 | struct hlist_node *node; | ||
70 | struct jump_label_entry *e; | ||
71 | u32 hash = jhash((void *)&key, sizeof(jump_label_t), 0); | ||
72 | |||
73 | head = &jump_label_table[hash & (JUMP_LABEL_TABLE_SIZE - 1)]; | ||
74 | hlist_for_each_entry(e, node, head, hlist) { | ||
75 | if (key == e->key) | ||
76 | return e; | ||
77 | } | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | static struct jump_label_entry * | ||
82 | add_jump_label_entry(jump_label_t key, int nr_entries, struct jump_entry *table) | ||
83 | { | ||
84 | struct hlist_head *head; | ||
85 | struct jump_label_entry *e; | ||
86 | u32 hash; | ||
87 | |||
88 | e = get_jump_label_entry(key); | ||
89 | if (e) | ||
90 | return ERR_PTR(-EEXIST); | ||
91 | |||
92 | e = kmalloc(sizeof(struct jump_label_entry), GFP_KERNEL); | ||
93 | if (!e) | ||
94 | return ERR_PTR(-ENOMEM); | ||
95 | |||
96 | hash = jhash((void *)&key, sizeof(jump_label_t), 0); | ||
97 | head = &jump_label_table[hash & (JUMP_LABEL_TABLE_SIZE - 1)]; | ||
98 | e->key = key; | ||
99 | e->table = table; | ||
100 | e->nr_entries = nr_entries; | ||
101 | INIT_HLIST_HEAD(&(e->modules)); | ||
102 | hlist_add_head(&e->hlist, head); | ||
103 | return e; | ||
104 | } | ||
105 | |||
106 | static int | ||
107 | build_jump_label_hashtable(struct jump_entry *start, struct jump_entry *stop) | ||
108 | { | ||
109 | struct jump_entry *iter, *iter_begin; | ||
110 | struct jump_label_entry *entry; | ||
111 | int count; | ||
112 | |||
113 | sort_jump_label_entries(start, stop); | ||
114 | iter = start; | ||
115 | while (iter < stop) { | ||
116 | entry = get_jump_label_entry(iter->key); | ||
117 | if (!entry) { | ||
118 | iter_begin = iter; | ||
119 | count = 0; | ||
120 | while ((iter < stop) && | ||
121 | (iter->key == iter_begin->key)) { | ||
122 | iter++; | ||
123 | count++; | ||
124 | } | ||
125 | entry = add_jump_label_entry(iter_begin->key, | ||
126 | count, iter_begin); | ||
127 | if (IS_ERR(entry)) | ||
128 | return PTR_ERR(entry); | ||
129 | } else { | ||
130 | WARN_ONCE(1, KERN_ERR "build_jump_hashtable: unexpected entry!\n"); | ||
131 | return -1; | ||
132 | } | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | /*** | ||
138 | * jump_label_update - update jump label text | ||
139 | * @key - key value associated with a a jump label | ||
140 | * @type - enum set to JUMP_LABEL_ENABLE or JUMP_LABEL_DISABLE | ||
141 | * | ||
142 | * Will enable/disable the jump for jump label @key, depending on the | ||
143 | * value of @type. | ||
144 | * | ||
145 | */ | ||
146 | |||
147 | void jump_label_update(unsigned long key, enum jump_label_type type) | ||
148 | { | ||
149 | struct jump_entry *iter; | ||
150 | struct jump_label_entry *entry; | ||
151 | struct hlist_node *module_node; | ||
152 | struct jump_label_module_entry *e_module; | ||
153 | int count; | ||
154 | |||
155 | mutex_lock(&jump_label_mutex); | ||
156 | entry = get_jump_label_entry((jump_label_t)key); | ||
157 | if (entry) { | ||
158 | count = entry->nr_entries; | ||
159 | iter = entry->table; | ||
160 | while (count--) { | ||
161 | if (kernel_text_address(iter->code)) | ||
162 | arch_jump_label_transform(iter, type); | ||
163 | iter++; | ||
164 | } | ||
165 | /* eanble/disable jump labels in modules */ | ||
166 | hlist_for_each_entry(e_module, module_node, &(entry->modules), | ||
167 | hlist) { | ||
168 | count = e_module->nr_entries; | ||
169 | iter = e_module->table; | ||
170 | while (count--) { | ||
171 | if (kernel_text_address(iter->code)) | ||
172 | arch_jump_label_transform(iter, type); | ||
173 | iter++; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | mutex_unlock(&jump_label_mutex); | ||
178 | } | ||
179 | |||
180 | static int addr_conflict(struct jump_entry *entry, void *start, void *end) | ||
181 | { | ||
182 | if (entry->code <= (unsigned long)end && | ||
183 | entry->code + JUMP_LABEL_NOP_SIZE > (unsigned long)start) | ||
184 | return 1; | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | #ifdef CONFIG_MODULES | ||
190 | |||
191 | static int module_conflict(void *start, void *end) | ||
192 | { | ||
193 | struct hlist_head *head; | ||
194 | struct hlist_node *node, *node_next, *module_node, *module_node_next; | ||
195 | struct jump_label_entry *e; | ||
196 | struct jump_label_module_entry *e_module; | ||
197 | struct jump_entry *iter; | ||
198 | int i, count; | ||
199 | int conflict = 0; | ||
200 | |||
201 | for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { | ||
202 | head = &jump_label_table[i]; | ||
203 | hlist_for_each_entry_safe(e, node, node_next, head, hlist) { | ||
204 | hlist_for_each_entry_safe(e_module, module_node, | ||
205 | module_node_next, | ||
206 | &(e->modules), hlist) { | ||
207 | count = e_module->nr_entries; | ||
208 | iter = e_module->table; | ||
209 | while (count--) { | ||
210 | if (addr_conflict(iter, start, end)) { | ||
211 | conflict = 1; | ||
212 | goto out; | ||
213 | } | ||
214 | iter++; | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | out: | ||
220 | return conflict; | ||
221 | } | ||
222 | |||
223 | #endif | ||
224 | |||
225 | /*** | ||
226 | * jump_label_text_reserved - check if addr range is reserved | ||
227 | * @start: start text addr | ||
228 | * @end: end text addr | ||
229 | * | ||
230 | * checks if the text addr located between @start and @end | ||
231 | * overlaps with any of the jump label patch addresses. Code | ||
232 | * that wants to modify kernel text should first verify that | ||
233 | * it does not overlap with any of the jump label addresses. | ||
234 | * | ||
235 | * returns 1 if there is an overlap, 0 otherwise | ||
236 | */ | ||
237 | int jump_label_text_reserved(void *start, void *end) | ||
238 | { | ||
239 | struct jump_entry *iter; | ||
240 | struct jump_entry *iter_start = __start___jump_table; | ||
241 | struct jump_entry *iter_stop = __start___jump_table; | ||
242 | int conflict = 0; | ||
243 | |||
244 | mutex_lock(&jump_label_mutex); | ||
245 | iter = iter_start; | ||
246 | while (iter < iter_stop) { | ||
247 | if (addr_conflict(iter, start, end)) { | ||
248 | conflict = 1; | ||
249 | goto out; | ||
250 | } | ||
251 | iter++; | ||
252 | } | ||
253 | |||
254 | /* now check modules */ | ||
255 | #ifdef CONFIG_MODULES | ||
256 | conflict = module_conflict(start, end); | ||
257 | #endif | ||
258 | out: | ||
259 | mutex_unlock(&jump_label_mutex); | ||
260 | return conflict; | ||
261 | } | ||
262 | |||
263 | static __init int init_jump_label(void) | ||
264 | { | ||
265 | int ret; | ||
266 | struct jump_entry *iter_start = __start___jump_table; | ||
267 | struct jump_entry *iter_stop = __stop___jump_table; | ||
268 | struct jump_entry *iter; | ||
269 | |||
270 | mutex_lock(&jump_label_mutex); | ||
271 | ret = build_jump_label_hashtable(__start___jump_table, | ||
272 | __stop___jump_table); | ||
273 | iter = iter_start; | ||
274 | while (iter < iter_stop) { | ||
275 | arch_jump_label_text_poke_early(iter->code); | ||
276 | iter++; | ||
277 | } | ||
278 | mutex_unlock(&jump_label_mutex); | ||
279 | return ret; | ||
280 | } | ||
281 | early_initcall(init_jump_label); | ||
282 | |||
283 | #ifdef CONFIG_MODULES | ||
284 | |||
285 | static struct jump_label_module_entry * | ||
286 | add_jump_label_module_entry(struct jump_label_entry *entry, | ||
287 | struct jump_entry *iter_begin, | ||
288 | int count, struct module *mod) | ||
289 | { | ||
290 | struct jump_label_module_entry *e; | ||
291 | |||
292 | e = kmalloc(sizeof(struct jump_label_module_entry), GFP_KERNEL); | ||
293 | if (!e) | ||
294 | return ERR_PTR(-ENOMEM); | ||
295 | e->mod = mod; | ||
296 | e->nr_entries = count; | ||
297 | e->table = iter_begin; | ||
298 | hlist_add_head(&e->hlist, &entry->modules); | ||
299 | return e; | ||
300 | } | ||
301 | |||
302 | static int add_jump_label_module(struct module *mod) | ||
303 | { | ||
304 | struct jump_entry *iter, *iter_begin; | ||
305 | struct jump_label_entry *entry; | ||
306 | struct jump_label_module_entry *module_entry; | ||
307 | int count; | ||
308 | |||
309 | /* if the module doesn't have jump label entries, just return */ | ||
310 | if (!mod->num_jump_entries) | ||
311 | return 0; | ||
312 | |||
313 | sort_jump_label_entries(mod->jump_entries, | ||
314 | mod->jump_entries + mod->num_jump_entries); | ||
315 | iter = mod->jump_entries; | ||
316 | while (iter < mod->jump_entries + mod->num_jump_entries) { | ||
317 | entry = get_jump_label_entry(iter->key); | ||
318 | iter_begin = iter; | ||
319 | count = 0; | ||
320 | while ((iter < mod->jump_entries + mod->num_jump_entries) && | ||
321 | (iter->key == iter_begin->key)) { | ||
322 | iter++; | ||
323 | count++; | ||
324 | } | ||
325 | if (!entry) { | ||
326 | entry = add_jump_label_entry(iter_begin->key, 0, NULL); | ||
327 | if (IS_ERR(entry)) | ||
328 | return PTR_ERR(entry); | ||
329 | } | ||
330 | module_entry = add_jump_label_module_entry(entry, iter_begin, | ||
331 | count, mod); | ||
332 | if (IS_ERR(module_entry)) | ||
333 | return PTR_ERR(module_entry); | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static void remove_jump_label_module(struct module *mod) | ||
339 | { | ||
340 | struct hlist_head *head; | ||
341 | struct hlist_node *node, *node_next, *module_node, *module_node_next; | ||
342 | struct jump_label_entry *e; | ||
343 | struct jump_label_module_entry *e_module; | ||
344 | int i; | ||
345 | |||
346 | /* if the module doesn't have jump label entries, just return */ | ||
347 | if (!mod->num_jump_entries) | ||
348 | return; | ||
349 | |||
350 | for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { | ||
351 | head = &jump_label_table[i]; | ||
352 | hlist_for_each_entry_safe(e, node, node_next, head, hlist) { | ||
353 | hlist_for_each_entry_safe(e_module, module_node, | ||
354 | module_node_next, | ||
355 | &(e->modules), hlist) { | ||
356 | if (e_module->mod == mod) { | ||
357 | hlist_del(&e_module->hlist); | ||
358 | kfree(e_module); | ||
359 | } | ||
360 | } | ||
361 | if (hlist_empty(&e->modules) && (e->nr_entries == 0)) { | ||
362 | hlist_del(&e->hlist); | ||
363 | kfree(e); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | } | ||
368 | |||
369 | static int | ||
370 | jump_label_module_notify(struct notifier_block *self, unsigned long val, | ||
371 | void *data) | ||
372 | { | ||
373 | struct module *mod = data; | ||
374 | int ret = 0; | ||
375 | |||
376 | switch (val) { | ||
377 | case MODULE_STATE_COMING: | ||
378 | mutex_lock(&jump_label_mutex); | ||
379 | ret = add_jump_label_module(mod); | ||
380 | if (ret) | ||
381 | remove_jump_label_module(mod); | ||
382 | mutex_unlock(&jump_label_mutex); | ||
383 | break; | ||
384 | case MODULE_STATE_GOING: | ||
385 | mutex_lock(&jump_label_mutex); | ||
386 | remove_jump_label_module(mod); | ||
387 | mutex_unlock(&jump_label_mutex); | ||
388 | break; | ||
389 | } | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | /*** | ||
394 | * apply_jump_label_nops - patch module jump labels with arch_get_jump_label_nop() | ||
395 | * @mod: module to patch | ||
396 | * | ||
397 | * Allow for run-time selection of the optimal nops. Before the module | ||
398 | * loads patch these with arch_get_jump_label_nop(), which is specified by | ||
399 | * the arch specific jump label code. | ||
400 | */ | ||
401 | void jump_label_apply_nops(struct module *mod) | ||
402 | { | ||
403 | struct jump_entry *iter; | ||
404 | |||
405 | /* if the module doesn't have jump label entries, just return */ | ||
406 | if (!mod->num_jump_entries) | ||
407 | return; | ||
408 | |||
409 | iter = mod->jump_entries; | ||
410 | while (iter < mod->jump_entries + mod->num_jump_entries) { | ||
411 | arch_jump_label_text_poke_early(iter->code); | ||
412 | iter++; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | struct notifier_block jump_label_module_nb = { | ||
417 | .notifier_call = jump_label_module_notify, | ||
418 | .priority = 0, | ||
419 | }; | ||
420 | |||
421 | static __init int init_jump_label_module(void) | ||
422 | { | ||
423 | return register_module_notifier(&jump_label_module_nb); | ||
424 | } | ||
425 | early_initcall(init_jump_label_module); | ||
426 | |||
427 | #endif /* CONFIG_MODULES */ | ||
428 | |||
429 | #endif | ||
diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 6b5580c57644..01a0700e873f 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c | |||
@@ -365,8 +365,6 @@ static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, | |||
365 | n = setup_sgl_buf(sgl, fifo->data + off, nents, l); | 365 | n = setup_sgl_buf(sgl, fifo->data + off, nents, l); |
366 | n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); | 366 | n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); |
367 | 367 | ||
368 | if (n) | ||
369 | sg_mark_end(sgl + n - 1); | ||
370 | return n; | 368 | return n; |
371 | } | 369 | } |
372 | 370 | ||
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 282035f3ae96..ec4210c6501e 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/memory.h> | 47 | #include <linux/memory.h> |
48 | #include <linux/ftrace.h> | 48 | #include <linux/ftrace.h> |
49 | #include <linux/cpu.h> | 49 | #include <linux/cpu.h> |
50 | #include <linux/jump_label.h> | ||
50 | 51 | ||
51 | #include <asm-generic/sections.h> | 52 | #include <asm-generic/sections.h> |
52 | #include <asm/cacheflush.h> | 53 | #include <asm/cacheflush.h> |
@@ -399,7 +400,7 @@ static inline int kprobe_optready(struct kprobe *p) | |||
399 | * Return an optimized kprobe whose optimizing code replaces | 400 | * Return an optimized kprobe whose optimizing code replaces |
400 | * instructions including addr (exclude breakpoint). | 401 | * instructions including addr (exclude breakpoint). |
401 | */ | 402 | */ |
402 | struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr) | 403 | static struct kprobe *__kprobes get_optimized_kprobe(unsigned long addr) |
403 | { | 404 | { |
404 | int i; | 405 | int i; |
405 | struct kprobe *p = NULL; | 406 | struct kprobe *p = NULL; |
@@ -831,6 +832,7 @@ void __kprobes recycle_rp_inst(struct kretprobe_instance *ri, | |||
831 | 832 | ||
832 | void __kprobes kretprobe_hash_lock(struct task_struct *tsk, | 833 | void __kprobes kretprobe_hash_lock(struct task_struct *tsk, |
833 | struct hlist_head **head, unsigned long *flags) | 834 | struct hlist_head **head, unsigned long *flags) |
835 | __acquires(hlist_lock) | ||
834 | { | 836 | { |
835 | unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); | 837 | unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); |
836 | spinlock_t *hlist_lock; | 838 | spinlock_t *hlist_lock; |
@@ -842,6 +844,7 @@ void __kprobes kretprobe_hash_lock(struct task_struct *tsk, | |||
842 | 844 | ||
843 | static void __kprobes kretprobe_table_lock(unsigned long hash, | 845 | static void __kprobes kretprobe_table_lock(unsigned long hash, |
844 | unsigned long *flags) | 846 | unsigned long *flags) |
847 | __acquires(hlist_lock) | ||
845 | { | 848 | { |
846 | spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); | 849 | spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); |
847 | spin_lock_irqsave(hlist_lock, *flags); | 850 | spin_lock_irqsave(hlist_lock, *flags); |
@@ -849,6 +852,7 @@ static void __kprobes kretprobe_table_lock(unsigned long hash, | |||
849 | 852 | ||
850 | void __kprobes kretprobe_hash_unlock(struct task_struct *tsk, | 853 | void __kprobes kretprobe_hash_unlock(struct task_struct *tsk, |
851 | unsigned long *flags) | 854 | unsigned long *flags) |
855 | __releases(hlist_lock) | ||
852 | { | 856 | { |
853 | unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); | 857 | unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); |
854 | spinlock_t *hlist_lock; | 858 | spinlock_t *hlist_lock; |
@@ -857,7 +861,9 @@ void __kprobes kretprobe_hash_unlock(struct task_struct *tsk, | |||
857 | spin_unlock_irqrestore(hlist_lock, *flags); | 861 | spin_unlock_irqrestore(hlist_lock, *flags); |
858 | } | 862 | } |
859 | 863 | ||
860 | void __kprobes kretprobe_table_unlock(unsigned long hash, unsigned long *flags) | 864 | static void __kprobes kretprobe_table_unlock(unsigned long hash, |
865 | unsigned long *flags) | ||
866 | __releases(hlist_lock) | ||
861 | { | 867 | { |
862 | spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); | 868 | spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); |
863 | spin_unlock_irqrestore(hlist_lock, *flags); | 869 | spin_unlock_irqrestore(hlist_lock, *flags); |
@@ -1141,7 +1147,8 @@ int __kprobes register_kprobe(struct kprobe *p) | |||
1141 | preempt_disable(); | 1147 | preempt_disable(); |
1142 | if (!kernel_text_address((unsigned long) p->addr) || | 1148 | if (!kernel_text_address((unsigned long) p->addr) || |
1143 | in_kprobes_functions((unsigned long) p->addr) || | 1149 | in_kprobes_functions((unsigned long) p->addr) || |
1144 | ftrace_text_reserved(p->addr, p->addr)) { | 1150 | ftrace_text_reserved(p->addr, p->addr) || |
1151 | jump_label_text_reserved(p->addr, p->addr)) { | ||
1145 | preempt_enable(); | 1152 | preempt_enable(); |
1146 | return -EINVAL; | 1153 | return -EINVAL; |
1147 | } | 1154 | } |
@@ -1339,18 +1346,19 @@ int __kprobes register_jprobes(struct jprobe **jps, int num) | |||
1339 | if (num <= 0) | 1346 | if (num <= 0) |
1340 | return -EINVAL; | 1347 | return -EINVAL; |
1341 | for (i = 0; i < num; i++) { | 1348 | for (i = 0; i < num; i++) { |
1342 | unsigned long addr; | 1349 | unsigned long addr, offset; |
1343 | jp = jps[i]; | 1350 | jp = jps[i]; |
1344 | addr = arch_deref_entry_point(jp->entry); | 1351 | addr = arch_deref_entry_point(jp->entry); |
1345 | 1352 | ||
1346 | if (!kernel_text_address(addr)) | 1353 | /* Verify probepoint is a function entry point */ |
1347 | ret = -EINVAL; | 1354 | if (kallsyms_lookup_size_offset(addr, NULL, &offset) && |
1348 | else { | 1355 | offset == 0) { |
1349 | /* Todo: Verify probepoint is a function entry point */ | ||
1350 | jp->kp.pre_handler = setjmp_pre_handler; | 1356 | jp->kp.pre_handler = setjmp_pre_handler; |
1351 | jp->kp.break_handler = longjmp_break_handler; | 1357 | jp->kp.break_handler = longjmp_break_handler; |
1352 | ret = register_kprobe(&jp->kp); | 1358 | ret = register_kprobe(&jp->kp); |
1353 | } | 1359 | } else |
1360 | ret = -EINVAL; | ||
1361 | |||
1354 | if (ret < 0) { | 1362 | if (ret < 0) { |
1355 | if (i > 0) | 1363 | if (i > 0) |
1356 | unregister_jprobes(jps, i); | 1364 | unregister_jprobes(jps, i); |
diff --git a/kernel/module.c b/kernel/module.c index d0b5f8db11b4..2df46301a7a4 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/async.h> | 55 | #include <linux/async.h> |
56 | #include <linux/percpu.h> | 56 | #include <linux/percpu.h> |
57 | #include <linux/kmemleak.h> | 57 | #include <linux/kmemleak.h> |
58 | #include <linux/jump_label.h> | ||
58 | 59 | ||
59 | #define CREATE_TRACE_POINTS | 60 | #define CREATE_TRACE_POINTS |
60 | #include <trace/events/module.h> | 61 | #include <trace/events/module.h> |
@@ -1537,6 +1538,7 @@ static int __unlink_module(void *_mod) | |||
1537 | { | 1538 | { |
1538 | struct module *mod = _mod; | 1539 | struct module *mod = _mod; |
1539 | list_del(&mod->list); | 1540 | list_del(&mod->list); |
1541 | module_bug_cleanup(mod); | ||
1540 | return 0; | 1542 | return 0; |
1541 | } | 1543 | } |
1542 | 1544 | ||
@@ -2308,6 +2310,11 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
2308 | sizeof(*mod->tracepoints), | 2310 | sizeof(*mod->tracepoints), |
2309 | &mod->num_tracepoints); | 2311 | &mod->num_tracepoints); |
2310 | #endif | 2312 | #endif |
2313 | #ifdef HAVE_JUMP_LABEL | ||
2314 | mod->jump_entries = section_objs(info, "__jump_table", | ||
2315 | sizeof(*mod->jump_entries), | ||
2316 | &mod->num_jump_entries); | ||
2317 | #endif | ||
2311 | #ifdef CONFIG_EVENT_TRACING | 2318 | #ifdef CONFIG_EVENT_TRACING |
2312 | mod->trace_events = section_objs(info, "_ftrace_events", | 2319 | mod->trace_events = section_objs(info, "_ftrace_events", |
2313 | sizeof(*mod->trace_events), | 2320 | sizeof(*mod->trace_events), |
@@ -2625,6 +2632,7 @@ static struct module *load_module(void __user *umod, | |||
2625 | if (err < 0) | 2632 | if (err < 0) |
2626 | goto ddebug; | 2633 | goto ddebug; |
2627 | 2634 | ||
2635 | module_bug_finalize(info.hdr, info.sechdrs, mod); | ||
2628 | list_add_rcu(&mod->list, &modules); | 2636 | list_add_rcu(&mod->list, &modules); |
2629 | mutex_unlock(&module_mutex); | 2637 | mutex_unlock(&module_mutex); |
2630 | 2638 | ||
@@ -2650,6 +2658,8 @@ static struct module *load_module(void __user *umod, | |||
2650 | mutex_lock(&module_mutex); | 2658 | mutex_lock(&module_mutex); |
2651 | /* Unlink carefully: kallsyms could be walking list. */ | 2659 | /* Unlink carefully: kallsyms could be walking list. */ |
2652 | list_del_rcu(&mod->list); | 2660 | list_del_rcu(&mod->list); |
2661 | module_bug_cleanup(mod); | ||
2662 | |||
2653 | ddebug: | 2663 | ddebug: |
2654 | if (!mod->taints) | 2664 | if (!mod->taints) |
2655 | dynamic_debug_remove(info.debug); | 2665 | dynamic_debug_remove(info.debug); |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index fc512684423f..1ec3916ffef0 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -31,24 +31,18 @@ | |||
31 | #include <linux/kernel_stat.h> | 31 | #include <linux/kernel_stat.h> |
32 | #include <linux/perf_event.h> | 32 | #include <linux/perf_event.h> |
33 | #include <linux/ftrace_event.h> | 33 | #include <linux/ftrace_event.h> |
34 | #include <linux/hw_breakpoint.h> | ||
35 | 34 | ||
36 | #include <asm/irq_regs.h> | 35 | #include <asm/irq_regs.h> |
37 | 36 | ||
38 | /* | ||
39 | * Each CPU has a list of per CPU events: | ||
40 | */ | ||
41 | static DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); | ||
42 | |||
43 | int perf_max_events __read_mostly = 1; | ||
44 | static int perf_reserved_percpu __read_mostly; | ||
45 | static int perf_overcommit __read_mostly = 1; | ||
46 | |||
47 | static atomic_t nr_events __read_mostly; | 37 | static atomic_t nr_events __read_mostly; |
48 | static atomic_t nr_mmap_events __read_mostly; | 38 | static atomic_t nr_mmap_events __read_mostly; |
49 | static atomic_t nr_comm_events __read_mostly; | 39 | static atomic_t nr_comm_events __read_mostly; |
50 | static atomic_t nr_task_events __read_mostly; | 40 | static atomic_t nr_task_events __read_mostly; |
51 | 41 | ||
42 | static LIST_HEAD(pmus); | ||
43 | static DEFINE_MUTEX(pmus_lock); | ||
44 | static struct srcu_struct pmus_srcu; | ||
45 | |||
52 | /* | 46 | /* |
53 | * perf event paranoia level: | 47 | * perf event paranoia level: |
54 | * -1 - not paranoid at all | 48 | * -1 - not paranoid at all |
@@ -67,22 +61,6 @@ int sysctl_perf_event_sample_rate __read_mostly = 100000; | |||
67 | 61 | ||
68 | static atomic64_t perf_event_id; | 62 | static atomic64_t perf_event_id; |
69 | 63 | ||
70 | /* | ||
71 | * Lock for (sysadmin-configurable) event reservations: | ||
72 | */ | ||
73 | static DEFINE_SPINLOCK(perf_resource_lock); | ||
74 | |||
75 | /* | ||
76 | * Architecture provided APIs - weak aliases: | ||
77 | */ | ||
78 | extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event) | ||
79 | { | ||
80 | return NULL; | ||
81 | } | ||
82 | |||
83 | void __weak hw_perf_disable(void) { barrier(); } | ||
84 | void __weak hw_perf_enable(void) { barrier(); } | ||
85 | |||
86 | void __weak perf_event_print_debug(void) { } | 64 | void __weak perf_event_print_debug(void) { } |
87 | 65 | ||
88 | extern __weak const char *perf_pmu_name(void) | 66 | extern __weak const char *perf_pmu_name(void) |
@@ -90,18 +68,36 @@ extern __weak const char *perf_pmu_name(void) | |||
90 | return "pmu"; | 68 | return "pmu"; |
91 | } | 69 | } |
92 | 70 | ||
93 | static DEFINE_PER_CPU(int, perf_disable_count); | 71 | void perf_pmu_disable(struct pmu *pmu) |
72 | { | ||
73 | int *count = this_cpu_ptr(pmu->pmu_disable_count); | ||
74 | if (!(*count)++) | ||
75 | pmu->pmu_disable(pmu); | ||
76 | } | ||
94 | 77 | ||
95 | void perf_disable(void) | 78 | void perf_pmu_enable(struct pmu *pmu) |
96 | { | 79 | { |
97 | if (!__get_cpu_var(perf_disable_count)++) | 80 | int *count = this_cpu_ptr(pmu->pmu_disable_count); |
98 | hw_perf_disable(); | 81 | if (!--(*count)) |
82 | pmu->pmu_enable(pmu); | ||
99 | } | 83 | } |
100 | 84 | ||
101 | void perf_enable(void) | 85 | static DEFINE_PER_CPU(struct list_head, rotation_list); |
86 | |||
87 | /* | ||
88 | * perf_pmu_rotate_start() and perf_rotate_context() are fully serialized | ||
89 | * because they're strictly cpu affine and rotate_start is called with IRQs | ||
90 | * disabled, while rotate_context is called from IRQ context. | ||
91 | */ | ||
92 | static void perf_pmu_rotate_start(struct pmu *pmu) | ||
102 | { | 93 | { |
103 | if (!--__get_cpu_var(perf_disable_count)) | 94 | struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); |
104 | hw_perf_enable(); | 95 | struct list_head *head = &__get_cpu_var(rotation_list); |
96 | |||
97 | WARN_ON(!irqs_disabled()); | ||
98 | |||
99 | if (list_empty(&cpuctx->rotation_list)) | ||
100 | list_add(&cpuctx->rotation_list, head); | ||
105 | } | 101 | } |
106 | 102 | ||
107 | static void get_ctx(struct perf_event_context *ctx) | 103 | static void get_ctx(struct perf_event_context *ctx) |
@@ -156,13 +152,13 @@ static u64 primary_event_id(struct perf_event *event) | |||
156 | * the context could get moved to another task. | 152 | * the context could get moved to another task. |
157 | */ | 153 | */ |
158 | static struct perf_event_context * | 154 | static struct perf_event_context * |
159 | perf_lock_task_context(struct task_struct *task, unsigned long *flags) | 155 | perf_lock_task_context(struct task_struct *task, int ctxn, unsigned long *flags) |
160 | { | 156 | { |
161 | struct perf_event_context *ctx; | 157 | struct perf_event_context *ctx; |
162 | 158 | ||
163 | rcu_read_lock(); | 159 | rcu_read_lock(); |
164 | retry: | 160 | retry: |
165 | ctx = rcu_dereference(task->perf_event_ctxp); | 161 | ctx = rcu_dereference(task->perf_event_ctxp[ctxn]); |
166 | if (ctx) { | 162 | if (ctx) { |
167 | /* | 163 | /* |
168 | * If this context is a clone of another, it might | 164 | * If this context is a clone of another, it might |
@@ -175,7 +171,7 @@ perf_lock_task_context(struct task_struct *task, unsigned long *flags) | |||
175 | * can't get swapped on us any more. | 171 | * can't get swapped on us any more. |
176 | */ | 172 | */ |
177 | raw_spin_lock_irqsave(&ctx->lock, *flags); | 173 | raw_spin_lock_irqsave(&ctx->lock, *flags); |
178 | if (ctx != rcu_dereference(task->perf_event_ctxp)) { | 174 | if (ctx != rcu_dereference(task->perf_event_ctxp[ctxn])) { |
179 | raw_spin_unlock_irqrestore(&ctx->lock, *flags); | 175 | raw_spin_unlock_irqrestore(&ctx->lock, *flags); |
180 | goto retry; | 176 | goto retry; |
181 | } | 177 | } |
@@ -194,12 +190,13 @@ perf_lock_task_context(struct task_struct *task, unsigned long *flags) | |||
194 | * can't get swapped to another task. This also increments its | 190 | * can't get swapped to another task. This also increments its |
195 | * reference count so that the context can't get freed. | 191 | * reference count so that the context can't get freed. |
196 | */ | 192 | */ |
197 | static struct perf_event_context *perf_pin_task_context(struct task_struct *task) | 193 | static struct perf_event_context * |
194 | perf_pin_task_context(struct task_struct *task, int ctxn) | ||
198 | { | 195 | { |
199 | struct perf_event_context *ctx; | 196 | struct perf_event_context *ctx; |
200 | unsigned long flags; | 197 | unsigned long flags; |
201 | 198 | ||
202 | ctx = perf_lock_task_context(task, &flags); | 199 | ctx = perf_lock_task_context(task, ctxn, &flags); |
203 | if (ctx) { | 200 | if (ctx) { |
204 | ++ctx->pin_count; | 201 | ++ctx->pin_count; |
205 | raw_spin_unlock_irqrestore(&ctx->lock, flags); | 202 | raw_spin_unlock_irqrestore(&ctx->lock, flags); |
@@ -307,6 +304,8 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx) | |||
307 | } | 304 | } |
308 | 305 | ||
309 | list_add_rcu(&event->event_entry, &ctx->event_list); | 306 | list_add_rcu(&event->event_entry, &ctx->event_list); |
307 | if (!ctx->nr_events) | ||
308 | perf_pmu_rotate_start(ctx->pmu); | ||
310 | ctx->nr_events++; | 309 | ctx->nr_events++; |
311 | if (event->attr.inherit_stat) | 310 | if (event->attr.inherit_stat) |
312 | ctx->nr_stat++; | 311 | ctx->nr_stat++; |
@@ -441,7 +440,7 @@ event_sched_out(struct perf_event *event, | |||
441 | event->state = PERF_EVENT_STATE_OFF; | 440 | event->state = PERF_EVENT_STATE_OFF; |
442 | } | 441 | } |
443 | event->tstamp_stopped = ctx->time; | 442 | event->tstamp_stopped = ctx->time; |
444 | event->pmu->disable(event); | 443 | event->pmu->del(event, 0); |
445 | event->oncpu = -1; | 444 | event->oncpu = -1; |
446 | 445 | ||
447 | if (!is_software_event(event)) | 446 | if (!is_software_event(event)) |
@@ -471,6 +470,12 @@ group_sched_out(struct perf_event *group_event, | |||
471 | cpuctx->exclusive = 0; | 470 | cpuctx->exclusive = 0; |
472 | } | 471 | } |
473 | 472 | ||
473 | static inline struct perf_cpu_context * | ||
474 | __get_cpu_context(struct perf_event_context *ctx) | ||
475 | { | ||
476 | return this_cpu_ptr(ctx->pmu->pmu_cpu_context); | ||
477 | } | ||
478 | |||
474 | /* | 479 | /* |
475 | * Cross CPU call to remove a performance event | 480 | * Cross CPU call to remove a performance event |
476 | * | 481 | * |
@@ -479,9 +484,9 @@ group_sched_out(struct perf_event *group_event, | |||
479 | */ | 484 | */ |
480 | static void __perf_event_remove_from_context(void *info) | 485 | static void __perf_event_remove_from_context(void *info) |
481 | { | 486 | { |
482 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
483 | struct perf_event *event = info; | 487 | struct perf_event *event = info; |
484 | struct perf_event_context *ctx = event->ctx; | 488 | struct perf_event_context *ctx = event->ctx; |
489 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
485 | 490 | ||
486 | /* | 491 | /* |
487 | * If this is a task context, we need to check whether it is | 492 | * If this is a task context, we need to check whether it is |
@@ -492,27 +497,11 @@ static void __perf_event_remove_from_context(void *info) | |||
492 | return; | 497 | return; |
493 | 498 | ||
494 | raw_spin_lock(&ctx->lock); | 499 | raw_spin_lock(&ctx->lock); |
495 | /* | ||
496 | * Protect the list operation against NMI by disabling the | ||
497 | * events on a global level. | ||
498 | */ | ||
499 | perf_disable(); | ||
500 | 500 | ||
501 | event_sched_out(event, cpuctx, ctx); | 501 | event_sched_out(event, cpuctx, ctx); |
502 | 502 | ||
503 | list_del_event(event, ctx); | 503 | list_del_event(event, ctx); |
504 | 504 | ||
505 | if (!ctx->task) { | ||
506 | /* | ||
507 | * Allow more per task events with respect to the | ||
508 | * reservation: | ||
509 | */ | ||
510 | cpuctx->max_pertask = | ||
511 | min(perf_max_events - ctx->nr_events, | ||
512 | perf_max_events - perf_reserved_percpu); | ||
513 | } | ||
514 | |||
515 | perf_enable(); | ||
516 | raw_spin_unlock(&ctx->lock); | 505 | raw_spin_unlock(&ctx->lock); |
517 | } | 506 | } |
518 | 507 | ||
@@ -577,8 +566,8 @@ retry: | |||
577 | static void __perf_event_disable(void *info) | 566 | static void __perf_event_disable(void *info) |
578 | { | 567 | { |
579 | struct perf_event *event = info; | 568 | struct perf_event *event = info; |
580 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
581 | struct perf_event_context *ctx = event->ctx; | 569 | struct perf_event_context *ctx = event->ctx; |
570 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
582 | 571 | ||
583 | /* | 572 | /* |
584 | * If this is a per-task event, need to check whether this | 573 | * If this is a per-task event, need to check whether this |
@@ -633,7 +622,7 @@ void perf_event_disable(struct perf_event *event) | |||
633 | return; | 622 | return; |
634 | } | 623 | } |
635 | 624 | ||
636 | retry: | 625 | retry: |
637 | task_oncpu_function_call(task, __perf_event_disable, event); | 626 | task_oncpu_function_call(task, __perf_event_disable, event); |
638 | 627 | ||
639 | raw_spin_lock_irq(&ctx->lock); | 628 | raw_spin_lock_irq(&ctx->lock); |
@@ -672,7 +661,7 @@ event_sched_in(struct perf_event *event, | |||
672 | */ | 661 | */ |
673 | smp_wmb(); | 662 | smp_wmb(); |
674 | 663 | ||
675 | if (event->pmu->enable(event)) { | 664 | if (event->pmu->add(event, PERF_EF_START)) { |
676 | event->state = PERF_EVENT_STATE_INACTIVE; | 665 | event->state = PERF_EVENT_STATE_INACTIVE; |
677 | event->oncpu = -1; | 666 | event->oncpu = -1; |
678 | return -EAGAIN; | 667 | return -EAGAIN; |
@@ -696,22 +685,15 @@ group_sched_in(struct perf_event *group_event, | |||
696 | struct perf_event_context *ctx) | 685 | struct perf_event_context *ctx) |
697 | { | 686 | { |
698 | struct perf_event *event, *partial_group = NULL; | 687 | struct perf_event *event, *partial_group = NULL; |
699 | const struct pmu *pmu = group_event->pmu; | 688 | struct pmu *pmu = group_event->pmu; |
700 | bool txn = false; | ||
701 | 689 | ||
702 | if (group_event->state == PERF_EVENT_STATE_OFF) | 690 | if (group_event->state == PERF_EVENT_STATE_OFF) |
703 | return 0; | 691 | return 0; |
704 | 692 | ||
705 | /* Check if group transaction availabe */ | 693 | pmu->start_txn(pmu); |
706 | if (pmu->start_txn) | ||
707 | txn = true; | ||
708 | |||
709 | if (txn) | ||
710 | pmu->start_txn(pmu); | ||
711 | 694 | ||
712 | if (event_sched_in(group_event, cpuctx, ctx)) { | 695 | if (event_sched_in(group_event, cpuctx, ctx)) { |
713 | if (txn) | 696 | pmu->cancel_txn(pmu); |
714 | pmu->cancel_txn(pmu); | ||
715 | return -EAGAIN; | 697 | return -EAGAIN; |
716 | } | 698 | } |
717 | 699 | ||
@@ -725,7 +707,7 @@ group_sched_in(struct perf_event *group_event, | |||
725 | } | 707 | } |
726 | } | 708 | } |
727 | 709 | ||
728 | if (!txn || !pmu->commit_txn(pmu)) | 710 | if (!pmu->commit_txn(pmu)) |
729 | return 0; | 711 | return 0; |
730 | 712 | ||
731 | group_error: | 713 | group_error: |
@@ -740,8 +722,7 @@ group_error: | |||
740 | } | 722 | } |
741 | event_sched_out(group_event, cpuctx, ctx); | 723 | event_sched_out(group_event, cpuctx, ctx); |
742 | 724 | ||
743 | if (txn) | 725 | pmu->cancel_txn(pmu); |
744 | pmu->cancel_txn(pmu); | ||
745 | 726 | ||
746 | return -EAGAIN; | 727 | return -EAGAIN; |
747 | } | 728 | } |
@@ -794,10 +775,10 @@ static void add_event_to_ctx(struct perf_event *event, | |||
794 | */ | 775 | */ |
795 | static void __perf_install_in_context(void *info) | 776 | static void __perf_install_in_context(void *info) |
796 | { | 777 | { |
797 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
798 | struct perf_event *event = info; | 778 | struct perf_event *event = info; |
799 | struct perf_event_context *ctx = event->ctx; | 779 | struct perf_event_context *ctx = event->ctx; |
800 | struct perf_event *leader = event->group_leader; | 780 | struct perf_event *leader = event->group_leader; |
781 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
801 | int err; | 782 | int err; |
802 | 783 | ||
803 | /* | 784 | /* |
@@ -817,12 +798,6 @@ static void __perf_install_in_context(void *info) | |||
817 | ctx->is_active = 1; | 798 | ctx->is_active = 1; |
818 | update_context_time(ctx); | 799 | update_context_time(ctx); |
819 | 800 | ||
820 | /* | ||
821 | * Protect the list operation against NMI by disabling the | ||
822 | * events on a global level. NOP for non NMI based events. | ||
823 | */ | ||
824 | perf_disable(); | ||
825 | |||
826 | add_event_to_ctx(event, ctx); | 801 | add_event_to_ctx(event, ctx); |
827 | 802 | ||
828 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 803 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
@@ -860,12 +835,7 @@ static void __perf_install_in_context(void *info) | |||
860 | } | 835 | } |
861 | } | 836 | } |
862 | 837 | ||
863 | if (!err && !ctx->task && cpuctx->max_pertask) | 838 | unlock: |
864 | cpuctx->max_pertask--; | ||
865 | |||
866 | unlock: | ||
867 | perf_enable(); | ||
868 | |||
869 | raw_spin_unlock(&ctx->lock); | 839 | raw_spin_unlock(&ctx->lock); |
870 | } | 840 | } |
871 | 841 | ||
@@ -888,6 +858,8 @@ perf_install_in_context(struct perf_event_context *ctx, | |||
888 | { | 858 | { |
889 | struct task_struct *task = ctx->task; | 859 | struct task_struct *task = ctx->task; |
890 | 860 | ||
861 | event->ctx = ctx; | ||
862 | |||
891 | if (!task) { | 863 | if (!task) { |
892 | /* | 864 | /* |
893 | * Per cpu events are installed via an smp call and | 865 | * Per cpu events are installed via an smp call and |
@@ -936,10 +908,12 @@ static void __perf_event_mark_enabled(struct perf_event *event, | |||
936 | 908 | ||
937 | event->state = PERF_EVENT_STATE_INACTIVE; | 909 | event->state = PERF_EVENT_STATE_INACTIVE; |
938 | event->tstamp_enabled = ctx->time - event->total_time_enabled; | 910 | event->tstamp_enabled = ctx->time - event->total_time_enabled; |
939 | list_for_each_entry(sub, &event->sibling_list, group_entry) | 911 | list_for_each_entry(sub, &event->sibling_list, group_entry) { |
940 | if (sub->state >= PERF_EVENT_STATE_INACTIVE) | 912 | if (sub->state >= PERF_EVENT_STATE_INACTIVE) { |
941 | sub->tstamp_enabled = | 913 | sub->tstamp_enabled = |
942 | ctx->time - sub->total_time_enabled; | 914 | ctx->time - sub->total_time_enabled; |
915 | } | ||
916 | } | ||
943 | } | 917 | } |
944 | 918 | ||
945 | /* | 919 | /* |
@@ -948,9 +922,9 @@ static void __perf_event_mark_enabled(struct perf_event *event, | |||
948 | static void __perf_event_enable(void *info) | 922 | static void __perf_event_enable(void *info) |
949 | { | 923 | { |
950 | struct perf_event *event = info; | 924 | struct perf_event *event = info; |
951 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
952 | struct perf_event_context *ctx = event->ctx; | 925 | struct perf_event_context *ctx = event->ctx; |
953 | struct perf_event *leader = event->group_leader; | 926 | struct perf_event *leader = event->group_leader; |
927 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
954 | int err; | 928 | int err; |
955 | 929 | ||
956 | /* | 930 | /* |
@@ -984,12 +958,10 @@ static void __perf_event_enable(void *info) | |||
984 | if (!group_can_go_on(event, cpuctx, 1)) { | 958 | if (!group_can_go_on(event, cpuctx, 1)) { |
985 | err = -EEXIST; | 959 | err = -EEXIST; |
986 | } else { | 960 | } else { |
987 | perf_disable(); | ||
988 | if (event == leader) | 961 | if (event == leader) |
989 | err = group_sched_in(event, cpuctx, ctx); | 962 | err = group_sched_in(event, cpuctx, ctx); |
990 | else | 963 | else |
991 | err = event_sched_in(event, cpuctx, ctx); | 964 | err = event_sched_in(event, cpuctx, ctx); |
992 | perf_enable(); | ||
993 | } | 965 | } |
994 | 966 | ||
995 | if (err) { | 967 | if (err) { |
@@ -1005,7 +977,7 @@ static void __perf_event_enable(void *info) | |||
1005 | } | 977 | } |
1006 | } | 978 | } |
1007 | 979 | ||
1008 | unlock: | 980 | unlock: |
1009 | raw_spin_unlock(&ctx->lock); | 981 | raw_spin_unlock(&ctx->lock); |
1010 | } | 982 | } |
1011 | 983 | ||
@@ -1046,7 +1018,7 @@ void perf_event_enable(struct perf_event *event) | |||
1046 | if (event->state == PERF_EVENT_STATE_ERROR) | 1018 | if (event->state == PERF_EVENT_STATE_ERROR) |
1047 | event->state = PERF_EVENT_STATE_OFF; | 1019 | event->state = PERF_EVENT_STATE_OFF; |
1048 | 1020 | ||
1049 | retry: | 1021 | retry: |
1050 | raw_spin_unlock_irq(&ctx->lock); | 1022 | raw_spin_unlock_irq(&ctx->lock); |
1051 | task_oncpu_function_call(task, __perf_event_enable, event); | 1023 | task_oncpu_function_call(task, __perf_event_enable, event); |
1052 | 1024 | ||
@@ -1066,7 +1038,7 @@ void perf_event_enable(struct perf_event *event) | |||
1066 | if (event->state == PERF_EVENT_STATE_OFF) | 1038 | if (event->state == PERF_EVENT_STATE_OFF) |
1067 | __perf_event_mark_enabled(event, ctx); | 1039 | __perf_event_mark_enabled(event, ctx); |
1068 | 1040 | ||
1069 | out: | 1041 | out: |
1070 | raw_spin_unlock_irq(&ctx->lock); | 1042 | raw_spin_unlock_irq(&ctx->lock); |
1071 | } | 1043 | } |
1072 | 1044 | ||
@@ -1097,26 +1069,26 @@ static void ctx_sched_out(struct perf_event_context *ctx, | |||
1097 | struct perf_event *event; | 1069 | struct perf_event *event; |
1098 | 1070 | ||
1099 | raw_spin_lock(&ctx->lock); | 1071 | raw_spin_lock(&ctx->lock); |
1072 | perf_pmu_disable(ctx->pmu); | ||
1100 | ctx->is_active = 0; | 1073 | ctx->is_active = 0; |
1101 | if (likely(!ctx->nr_events)) | 1074 | if (likely(!ctx->nr_events)) |
1102 | goto out; | 1075 | goto out; |
1103 | update_context_time(ctx); | 1076 | update_context_time(ctx); |
1104 | 1077 | ||
1105 | perf_disable(); | ||
1106 | if (!ctx->nr_active) | 1078 | if (!ctx->nr_active) |
1107 | goto out_enable; | 1079 | goto out; |
1108 | 1080 | ||
1109 | if (event_type & EVENT_PINNED) | 1081 | if (event_type & EVENT_PINNED) { |
1110 | list_for_each_entry(event, &ctx->pinned_groups, group_entry) | 1082 | list_for_each_entry(event, &ctx->pinned_groups, group_entry) |
1111 | group_sched_out(event, cpuctx, ctx); | 1083 | group_sched_out(event, cpuctx, ctx); |
1084 | } | ||
1112 | 1085 | ||
1113 | if (event_type & EVENT_FLEXIBLE) | 1086 | if (event_type & EVENT_FLEXIBLE) { |
1114 | list_for_each_entry(event, &ctx->flexible_groups, group_entry) | 1087 | list_for_each_entry(event, &ctx->flexible_groups, group_entry) |
1115 | group_sched_out(event, cpuctx, ctx); | 1088 | group_sched_out(event, cpuctx, ctx); |
1116 | 1089 | } | |
1117 | out_enable: | 1090 | out: |
1118 | perf_enable(); | 1091 | perf_pmu_enable(ctx->pmu); |
1119 | out: | ||
1120 | raw_spin_unlock(&ctx->lock); | 1092 | raw_spin_unlock(&ctx->lock); |
1121 | } | 1093 | } |
1122 | 1094 | ||
@@ -1214,34 +1186,25 @@ static void perf_event_sync_stat(struct perf_event_context *ctx, | |||
1214 | } | 1186 | } |
1215 | } | 1187 | } |
1216 | 1188 | ||
1217 | /* | 1189 | void perf_event_context_sched_out(struct task_struct *task, int ctxn, |
1218 | * Called from scheduler to remove the events of the current task, | 1190 | struct task_struct *next) |
1219 | * with interrupts disabled. | ||
1220 | * | ||
1221 | * We stop each event and update the event value in event->count. | ||
1222 | * | ||
1223 | * This does not protect us against NMI, but disable() | ||
1224 | * sets the disabled bit in the control field of event _before_ | ||
1225 | * accessing the event control register. If a NMI hits, then it will | ||
1226 | * not restart the event. | ||
1227 | */ | ||
1228 | void perf_event_task_sched_out(struct task_struct *task, | ||
1229 | struct task_struct *next) | ||
1230 | { | 1191 | { |
1231 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 1192 | struct perf_event_context *ctx = task->perf_event_ctxp[ctxn]; |
1232 | struct perf_event_context *ctx = task->perf_event_ctxp; | ||
1233 | struct perf_event_context *next_ctx; | 1193 | struct perf_event_context *next_ctx; |
1234 | struct perf_event_context *parent; | 1194 | struct perf_event_context *parent; |
1195 | struct perf_cpu_context *cpuctx; | ||
1235 | int do_switch = 1; | 1196 | int do_switch = 1; |
1236 | 1197 | ||
1237 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | 1198 | if (likely(!ctx)) |
1199 | return; | ||
1238 | 1200 | ||
1239 | if (likely(!ctx || !cpuctx->task_ctx)) | 1201 | cpuctx = __get_cpu_context(ctx); |
1202 | if (!cpuctx->task_ctx) | ||
1240 | return; | 1203 | return; |
1241 | 1204 | ||
1242 | rcu_read_lock(); | 1205 | rcu_read_lock(); |
1243 | parent = rcu_dereference(ctx->parent_ctx); | 1206 | parent = rcu_dereference(ctx->parent_ctx); |
1244 | next_ctx = next->perf_event_ctxp; | 1207 | next_ctx = next->perf_event_ctxp[ctxn]; |
1245 | if (parent && next_ctx && | 1208 | if (parent && next_ctx && |
1246 | rcu_dereference(next_ctx->parent_ctx) == parent) { | 1209 | rcu_dereference(next_ctx->parent_ctx) == parent) { |
1247 | /* | 1210 | /* |
@@ -1260,8 +1223,8 @@ void perf_event_task_sched_out(struct task_struct *task, | |||
1260 | * XXX do we need a memory barrier of sorts | 1223 | * XXX do we need a memory barrier of sorts |
1261 | * wrt to rcu_dereference() of perf_event_ctxp | 1224 | * wrt to rcu_dereference() of perf_event_ctxp |
1262 | */ | 1225 | */ |
1263 | task->perf_event_ctxp = next_ctx; | 1226 | task->perf_event_ctxp[ctxn] = next_ctx; |
1264 | next->perf_event_ctxp = ctx; | 1227 | next->perf_event_ctxp[ctxn] = ctx; |
1265 | ctx->task = next; | 1228 | ctx->task = next; |
1266 | next_ctx->task = task; | 1229 | next_ctx->task = task; |
1267 | do_switch = 0; | 1230 | do_switch = 0; |
@@ -1279,10 +1242,35 @@ void perf_event_task_sched_out(struct task_struct *task, | |||
1279 | } | 1242 | } |
1280 | } | 1243 | } |
1281 | 1244 | ||
1245 | #define for_each_task_context_nr(ctxn) \ | ||
1246 | for ((ctxn) = 0; (ctxn) < perf_nr_task_contexts; (ctxn)++) | ||
1247 | |||
1248 | /* | ||
1249 | * Called from scheduler to remove the events of the current task, | ||
1250 | * with interrupts disabled. | ||
1251 | * | ||
1252 | * We stop each event and update the event value in event->count. | ||
1253 | * | ||
1254 | * This does not protect us against NMI, but disable() | ||
1255 | * sets the disabled bit in the control field of event _before_ | ||
1256 | * accessing the event control register. If a NMI hits, then it will | ||
1257 | * not restart the event. | ||
1258 | */ | ||
1259 | void perf_event_task_sched_out(struct task_struct *task, | ||
1260 | struct task_struct *next) | ||
1261 | { | ||
1262 | int ctxn; | ||
1263 | |||
1264 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | ||
1265 | |||
1266 | for_each_task_context_nr(ctxn) | ||
1267 | perf_event_context_sched_out(task, ctxn, next); | ||
1268 | } | ||
1269 | |||
1282 | static void task_ctx_sched_out(struct perf_event_context *ctx, | 1270 | static void task_ctx_sched_out(struct perf_event_context *ctx, |
1283 | enum event_type_t event_type) | 1271 | enum event_type_t event_type) |
1284 | { | 1272 | { |
1285 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 1273 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); |
1286 | 1274 | ||
1287 | if (!cpuctx->task_ctx) | 1275 | if (!cpuctx->task_ctx) |
1288 | return; | 1276 | return; |
@@ -1355,9 +1343,10 @@ ctx_flexible_sched_in(struct perf_event_context *ctx, | |||
1355 | if (event->cpu != -1 && event->cpu != smp_processor_id()) | 1343 | if (event->cpu != -1 && event->cpu != smp_processor_id()) |
1356 | continue; | 1344 | continue; |
1357 | 1345 | ||
1358 | if (group_can_go_on(event, cpuctx, can_add_hw)) | 1346 | if (group_can_go_on(event, cpuctx, can_add_hw)) { |
1359 | if (group_sched_in(event, cpuctx, ctx)) | 1347 | if (group_sched_in(event, cpuctx, ctx)) |
1360 | can_add_hw = 0; | 1348 | can_add_hw = 0; |
1349 | } | ||
1361 | } | 1350 | } |
1362 | } | 1351 | } |
1363 | 1352 | ||
@@ -1373,8 +1362,6 @@ ctx_sched_in(struct perf_event_context *ctx, | |||
1373 | 1362 | ||
1374 | ctx->timestamp = perf_clock(); | 1363 | ctx->timestamp = perf_clock(); |
1375 | 1364 | ||
1376 | perf_disable(); | ||
1377 | |||
1378 | /* | 1365 | /* |
1379 | * First go through the list and put on any pinned groups | 1366 | * First go through the list and put on any pinned groups |
1380 | * in order to give them the best chance of going on. | 1367 | * in order to give them the best chance of going on. |
@@ -1386,8 +1373,7 @@ ctx_sched_in(struct perf_event_context *ctx, | |||
1386 | if (event_type & EVENT_FLEXIBLE) | 1373 | if (event_type & EVENT_FLEXIBLE) |
1387 | ctx_flexible_sched_in(ctx, cpuctx); | 1374 | ctx_flexible_sched_in(ctx, cpuctx); |
1388 | 1375 | ||
1389 | perf_enable(); | 1376 | out: |
1390 | out: | ||
1391 | raw_spin_unlock(&ctx->lock); | 1377 | raw_spin_unlock(&ctx->lock); |
1392 | } | 1378 | } |
1393 | 1379 | ||
@@ -1399,43 +1385,28 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, | |||
1399 | ctx_sched_in(ctx, cpuctx, event_type); | 1385 | ctx_sched_in(ctx, cpuctx, event_type); |
1400 | } | 1386 | } |
1401 | 1387 | ||
1402 | static void task_ctx_sched_in(struct task_struct *task, | 1388 | static void task_ctx_sched_in(struct perf_event_context *ctx, |
1403 | enum event_type_t event_type) | 1389 | enum event_type_t event_type) |
1404 | { | 1390 | { |
1405 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 1391 | struct perf_cpu_context *cpuctx; |
1406 | struct perf_event_context *ctx = task->perf_event_ctxp; | ||
1407 | 1392 | ||
1408 | if (likely(!ctx)) | 1393 | cpuctx = __get_cpu_context(ctx); |
1409 | return; | ||
1410 | if (cpuctx->task_ctx == ctx) | 1394 | if (cpuctx->task_ctx == ctx) |
1411 | return; | 1395 | return; |
1396 | |||
1412 | ctx_sched_in(ctx, cpuctx, event_type); | 1397 | ctx_sched_in(ctx, cpuctx, event_type); |
1413 | cpuctx->task_ctx = ctx; | 1398 | cpuctx->task_ctx = ctx; |
1414 | } | 1399 | } |
1415 | /* | ||
1416 | * Called from scheduler to add the events of the current task | ||
1417 | * with interrupts disabled. | ||
1418 | * | ||
1419 | * We restore the event value and then enable it. | ||
1420 | * | ||
1421 | * This does not protect us against NMI, but enable() | ||
1422 | * sets the enabled bit in the control field of event _before_ | ||
1423 | * accessing the event control register. If a NMI hits, then it will | ||
1424 | * keep the event running. | ||
1425 | */ | ||
1426 | void perf_event_task_sched_in(struct task_struct *task) | ||
1427 | { | ||
1428 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
1429 | struct perf_event_context *ctx = task->perf_event_ctxp; | ||
1430 | 1400 | ||
1431 | if (likely(!ctx)) | 1401 | void perf_event_context_sched_in(struct perf_event_context *ctx) |
1432 | return; | 1402 | { |
1403 | struct perf_cpu_context *cpuctx; | ||
1433 | 1404 | ||
1405 | cpuctx = __get_cpu_context(ctx); | ||
1434 | if (cpuctx->task_ctx == ctx) | 1406 | if (cpuctx->task_ctx == ctx) |
1435 | return; | 1407 | return; |
1436 | 1408 | ||
1437 | perf_disable(); | 1409 | perf_pmu_disable(ctx->pmu); |
1438 | |||
1439 | /* | 1410 | /* |
1440 | * We want to keep the following priority order: | 1411 | * We want to keep the following priority order: |
1441 | * cpu pinned (that don't need to move), task pinned, | 1412 | * cpu pinned (that don't need to move), task pinned, |
@@ -1449,7 +1420,37 @@ void perf_event_task_sched_in(struct task_struct *task) | |||
1449 | 1420 | ||
1450 | cpuctx->task_ctx = ctx; | 1421 | cpuctx->task_ctx = ctx; |
1451 | 1422 | ||
1452 | perf_enable(); | 1423 | /* |
1424 | * Since these rotations are per-cpu, we need to ensure the | ||
1425 | * cpu-context we got scheduled on is actually rotating. | ||
1426 | */ | ||
1427 | perf_pmu_rotate_start(ctx->pmu); | ||
1428 | perf_pmu_enable(ctx->pmu); | ||
1429 | } | ||
1430 | |||
1431 | /* | ||
1432 | * Called from scheduler to add the events of the current task | ||
1433 | * with interrupts disabled. | ||
1434 | * | ||
1435 | * We restore the event value and then enable it. | ||
1436 | * | ||
1437 | * This does not protect us against NMI, but enable() | ||
1438 | * sets the enabled bit in the control field of event _before_ | ||
1439 | * accessing the event control register. If a NMI hits, then it will | ||
1440 | * keep the event running. | ||
1441 | */ | ||
1442 | void perf_event_task_sched_in(struct task_struct *task) | ||
1443 | { | ||
1444 | struct perf_event_context *ctx; | ||
1445 | int ctxn; | ||
1446 | |||
1447 | for_each_task_context_nr(ctxn) { | ||
1448 | ctx = task->perf_event_ctxp[ctxn]; | ||
1449 | if (likely(!ctx)) | ||
1450 | continue; | ||
1451 | |||
1452 | perf_event_context_sched_in(ctx); | ||
1453 | } | ||
1453 | } | 1454 | } |
1454 | 1455 | ||
1455 | #define MAX_INTERRUPTS (~0ULL) | 1456 | #define MAX_INTERRUPTS (~0ULL) |
@@ -1529,22 +1530,6 @@ do { \ | |||
1529 | return div64_u64(dividend, divisor); | 1530 | return div64_u64(dividend, divisor); |
1530 | } | 1531 | } |
1531 | 1532 | ||
1532 | static void perf_event_stop(struct perf_event *event) | ||
1533 | { | ||
1534 | if (!event->pmu->stop) | ||
1535 | return event->pmu->disable(event); | ||
1536 | |||
1537 | return event->pmu->stop(event); | ||
1538 | } | ||
1539 | |||
1540 | static int perf_event_start(struct perf_event *event) | ||
1541 | { | ||
1542 | if (!event->pmu->start) | ||
1543 | return event->pmu->enable(event); | ||
1544 | |||
1545 | return event->pmu->start(event); | ||
1546 | } | ||
1547 | |||
1548 | static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) | 1533 | static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) |
1549 | { | 1534 | { |
1550 | struct hw_perf_event *hwc = &event->hw; | 1535 | struct hw_perf_event *hwc = &event->hw; |
@@ -1564,15 +1549,13 @@ static void perf_adjust_period(struct perf_event *event, u64 nsec, u64 count) | |||
1564 | hwc->sample_period = sample_period; | 1549 | hwc->sample_period = sample_period; |
1565 | 1550 | ||
1566 | if (local64_read(&hwc->period_left) > 8*sample_period) { | 1551 | if (local64_read(&hwc->period_left) > 8*sample_period) { |
1567 | perf_disable(); | 1552 | event->pmu->stop(event, PERF_EF_UPDATE); |
1568 | perf_event_stop(event); | ||
1569 | local64_set(&hwc->period_left, 0); | 1553 | local64_set(&hwc->period_left, 0); |
1570 | perf_event_start(event); | 1554 | event->pmu->start(event, PERF_EF_RELOAD); |
1571 | perf_enable(); | ||
1572 | } | 1555 | } |
1573 | } | 1556 | } |
1574 | 1557 | ||
1575 | static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | 1558 | static void perf_ctx_adjust_freq(struct perf_event_context *ctx, u64 period) |
1576 | { | 1559 | { |
1577 | struct perf_event *event; | 1560 | struct perf_event *event; |
1578 | struct hw_perf_event *hwc; | 1561 | struct hw_perf_event *hwc; |
@@ -1597,23 +1580,19 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) | |||
1597 | */ | 1580 | */ |
1598 | if (interrupts == MAX_INTERRUPTS) { | 1581 | if (interrupts == MAX_INTERRUPTS) { |
1599 | perf_log_throttle(event, 1); | 1582 | perf_log_throttle(event, 1); |
1600 | perf_disable(); | 1583 | event->pmu->start(event, 0); |
1601 | event->pmu->unthrottle(event); | ||
1602 | perf_enable(); | ||
1603 | } | 1584 | } |
1604 | 1585 | ||
1605 | if (!event->attr.freq || !event->attr.sample_freq) | 1586 | if (!event->attr.freq || !event->attr.sample_freq) |
1606 | continue; | 1587 | continue; |
1607 | 1588 | ||
1608 | perf_disable(); | ||
1609 | event->pmu->read(event); | 1589 | event->pmu->read(event); |
1610 | now = local64_read(&event->count); | 1590 | now = local64_read(&event->count); |
1611 | delta = now - hwc->freq_count_stamp; | 1591 | delta = now - hwc->freq_count_stamp; |
1612 | hwc->freq_count_stamp = now; | 1592 | hwc->freq_count_stamp = now; |
1613 | 1593 | ||
1614 | if (delta > 0) | 1594 | if (delta > 0) |
1615 | perf_adjust_period(event, TICK_NSEC, delta); | 1595 | perf_adjust_period(event, period, delta); |
1616 | perf_enable(); | ||
1617 | } | 1596 | } |
1618 | raw_spin_unlock(&ctx->lock); | 1597 | raw_spin_unlock(&ctx->lock); |
1619 | } | 1598 | } |
@@ -1631,32 +1610,38 @@ static void rotate_ctx(struct perf_event_context *ctx) | |||
1631 | raw_spin_unlock(&ctx->lock); | 1610 | raw_spin_unlock(&ctx->lock); |
1632 | } | 1611 | } |
1633 | 1612 | ||
1634 | void perf_event_task_tick(struct task_struct *curr) | 1613 | /* |
1614 | * perf_pmu_rotate_start() and perf_rotate_context() are fully serialized | ||
1615 | * because they're strictly cpu affine and rotate_start is called with IRQs | ||
1616 | * disabled, while rotate_context is called from IRQ context. | ||
1617 | */ | ||
1618 | static void perf_rotate_context(struct perf_cpu_context *cpuctx) | ||
1635 | { | 1619 | { |
1636 | struct perf_cpu_context *cpuctx; | 1620 | u64 interval = (u64)cpuctx->jiffies_interval * TICK_NSEC; |
1637 | struct perf_event_context *ctx; | 1621 | struct perf_event_context *ctx = NULL; |
1638 | int rotate = 0; | 1622 | int rotate = 0, remove = 1; |
1639 | |||
1640 | if (!atomic_read(&nr_events)) | ||
1641 | return; | ||
1642 | 1623 | ||
1643 | cpuctx = &__get_cpu_var(perf_cpu_context); | 1624 | if (cpuctx->ctx.nr_events) { |
1644 | if (cpuctx->ctx.nr_events && | 1625 | remove = 0; |
1645 | cpuctx->ctx.nr_events != cpuctx->ctx.nr_active) | 1626 | if (cpuctx->ctx.nr_events != cpuctx->ctx.nr_active) |
1646 | rotate = 1; | 1627 | rotate = 1; |
1628 | } | ||
1647 | 1629 | ||
1648 | ctx = curr->perf_event_ctxp; | 1630 | ctx = cpuctx->task_ctx; |
1649 | if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active) | 1631 | if (ctx && ctx->nr_events) { |
1650 | rotate = 1; | 1632 | remove = 0; |
1633 | if (ctx->nr_events != ctx->nr_active) | ||
1634 | rotate = 1; | ||
1635 | } | ||
1651 | 1636 | ||
1652 | perf_ctx_adjust_freq(&cpuctx->ctx); | 1637 | perf_pmu_disable(cpuctx->ctx.pmu); |
1638 | perf_ctx_adjust_freq(&cpuctx->ctx, interval); | ||
1653 | if (ctx) | 1639 | if (ctx) |
1654 | perf_ctx_adjust_freq(ctx); | 1640 | perf_ctx_adjust_freq(ctx, interval); |
1655 | 1641 | ||
1656 | if (!rotate) | 1642 | if (!rotate) |
1657 | return; | 1643 | goto done; |
1658 | 1644 | ||
1659 | perf_disable(); | ||
1660 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); | 1645 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); |
1661 | if (ctx) | 1646 | if (ctx) |
1662 | task_ctx_sched_out(ctx, EVENT_FLEXIBLE); | 1647 | task_ctx_sched_out(ctx, EVENT_FLEXIBLE); |
@@ -1667,8 +1652,27 @@ void perf_event_task_tick(struct task_struct *curr) | |||
1667 | 1652 | ||
1668 | cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); | 1653 | cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); |
1669 | if (ctx) | 1654 | if (ctx) |
1670 | task_ctx_sched_in(curr, EVENT_FLEXIBLE); | 1655 | task_ctx_sched_in(ctx, EVENT_FLEXIBLE); |
1671 | perf_enable(); | 1656 | |
1657 | done: | ||
1658 | if (remove) | ||
1659 | list_del_init(&cpuctx->rotation_list); | ||
1660 | |||
1661 | perf_pmu_enable(cpuctx->ctx.pmu); | ||
1662 | } | ||
1663 | |||
1664 | void perf_event_task_tick(void) | ||
1665 | { | ||
1666 | struct list_head *head = &__get_cpu_var(rotation_list); | ||
1667 | struct perf_cpu_context *cpuctx, *tmp; | ||
1668 | |||
1669 | WARN_ON(!irqs_disabled()); | ||
1670 | |||
1671 | list_for_each_entry_safe(cpuctx, tmp, head, rotation_list) { | ||
1672 | if (cpuctx->jiffies_interval == 1 || | ||
1673 | !(jiffies % cpuctx->jiffies_interval)) | ||
1674 | perf_rotate_context(cpuctx); | ||
1675 | } | ||
1672 | } | 1676 | } |
1673 | 1677 | ||
1674 | static int event_enable_on_exec(struct perf_event *event, | 1678 | static int event_enable_on_exec(struct perf_event *event, |
@@ -1690,20 +1694,18 @@ static int event_enable_on_exec(struct perf_event *event, | |||
1690 | * Enable all of a task's events that have been marked enable-on-exec. | 1694 | * Enable all of a task's events that have been marked enable-on-exec. |
1691 | * This expects task == current. | 1695 | * This expects task == current. |
1692 | */ | 1696 | */ |
1693 | static void perf_event_enable_on_exec(struct task_struct *task) | 1697 | static void perf_event_enable_on_exec(struct perf_event_context *ctx) |
1694 | { | 1698 | { |
1695 | struct perf_event_context *ctx; | ||
1696 | struct perf_event *event; | 1699 | struct perf_event *event; |
1697 | unsigned long flags; | 1700 | unsigned long flags; |
1698 | int enabled = 0; | 1701 | int enabled = 0; |
1699 | int ret; | 1702 | int ret; |
1700 | 1703 | ||
1701 | local_irq_save(flags); | 1704 | local_irq_save(flags); |
1702 | ctx = task->perf_event_ctxp; | ||
1703 | if (!ctx || !ctx->nr_events) | 1705 | if (!ctx || !ctx->nr_events) |
1704 | goto out; | 1706 | goto out; |
1705 | 1707 | ||
1706 | __perf_event_task_sched_out(ctx); | 1708 | task_ctx_sched_out(ctx, EVENT_ALL); |
1707 | 1709 | ||
1708 | raw_spin_lock(&ctx->lock); | 1710 | raw_spin_lock(&ctx->lock); |
1709 | 1711 | ||
@@ -1727,8 +1729,8 @@ static void perf_event_enable_on_exec(struct task_struct *task) | |||
1727 | 1729 | ||
1728 | raw_spin_unlock(&ctx->lock); | 1730 | raw_spin_unlock(&ctx->lock); |
1729 | 1731 | ||
1730 | perf_event_task_sched_in(task); | 1732 | perf_event_context_sched_in(ctx); |
1731 | out: | 1733 | out: |
1732 | local_irq_restore(flags); | 1734 | local_irq_restore(flags); |
1733 | } | 1735 | } |
1734 | 1736 | ||
@@ -1737,9 +1739,9 @@ static void perf_event_enable_on_exec(struct task_struct *task) | |||
1737 | */ | 1739 | */ |
1738 | static void __perf_event_read(void *info) | 1740 | static void __perf_event_read(void *info) |
1739 | { | 1741 | { |
1740 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | ||
1741 | struct perf_event *event = info; | 1742 | struct perf_event *event = info; |
1742 | struct perf_event_context *ctx = event->ctx; | 1743 | struct perf_event_context *ctx = event->ctx; |
1744 | struct perf_cpu_context *cpuctx = __get_cpu_context(ctx); | ||
1743 | 1745 | ||
1744 | /* | 1746 | /* |
1745 | * If this is a task context, we need to check whether it is | 1747 | * If this is a task context, we need to check whether it is |
@@ -1787,11 +1789,219 @@ static u64 perf_event_read(struct perf_event *event) | |||
1787 | } | 1789 | } |
1788 | 1790 | ||
1789 | /* | 1791 | /* |
1790 | * Initialize the perf_event context in a task_struct: | 1792 | * Callchain support |
1791 | */ | 1793 | */ |
1794 | |||
1795 | struct callchain_cpus_entries { | ||
1796 | struct rcu_head rcu_head; | ||
1797 | struct perf_callchain_entry *cpu_entries[0]; | ||
1798 | }; | ||
1799 | |||
1800 | static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]); | ||
1801 | static atomic_t nr_callchain_events; | ||
1802 | static DEFINE_MUTEX(callchain_mutex); | ||
1803 | struct callchain_cpus_entries *callchain_cpus_entries; | ||
1804 | |||
1805 | |||
1806 | __weak void perf_callchain_kernel(struct perf_callchain_entry *entry, | ||
1807 | struct pt_regs *regs) | ||
1808 | { | ||
1809 | } | ||
1810 | |||
1811 | __weak void perf_callchain_user(struct perf_callchain_entry *entry, | ||
1812 | struct pt_regs *regs) | ||
1813 | { | ||
1814 | } | ||
1815 | |||
1816 | static void release_callchain_buffers_rcu(struct rcu_head *head) | ||
1817 | { | ||
1818 | struct callchain_cpus_entries *entries; | ||
1819 | int cpu; | ||
1820 | |||
1821 | entries = container_of(head, struct callchain_cpus_entries, rcu_head); | ||
1822 | |||
1823 | for_each_possible_cpu(cpu) | ||
1824 | kfree(entries->cpu_entries[cpu]); | ||
1825 | |||
1826 | kfree(entries); | ||
1827 | } | ||
1828 | |||
1829 | static void release_callchain_buffers(void) | ||
1830 | { | ||
1831 | struct callchain_cpus_entries *entries; | ||
1832 | |||
1833 | entries = callchain_cpus_entries; | ||
1834 | rcu_assign_pointer(callchain_cpus_entries, NULL); | ||
1835 | call_rcu(&entries->rcu_head, release_callchain_buffers_rcu); | ||
1836 | } | ||
1837 | |||
1838 | static int alloc_callchain_buffers(void) | ||
1839 | { | ||
1840 | int cpu; | ||
1841 | int size; | ||
1842 | struct callchain_cpus_entries *entries; | ||
1843 | |||
1844 | /* | ||
1845 | * We can't use the percpu allocation API for data that can be | ||
1846 | * accessed from NMI. Use a temporary manual per cpu allocation | ||
1847 | * until that gets sorted out. | ||
1848 | */ | ||
1849 | size = sizeof(*entries) + sizeof(struct perf_callchain_entry *) * | ||
1850 | num_possible_cpus(); | ||
1851 | |||
1852 | entries = kzalloc(size, GFP_KERNEL); | ||
1853 | if (!entries) | ||
1854 | return -ENOMEM; | ||
1855 | |||
1856 | size = sizeof(struct perf_callchain_entry) * PERF_NR_CONTEXTS; | ||
1857 | |||
1858 | for_each_possible_cpu(cpu) { | ||
1859 | entries->cpu_entries[cpu] = kmalloc_node(size, GFP_KERNEL, | ||
1860 | cpu_to_node(cpu)); | ||
1861 | if (!entries->cpu_entries[cpu]) | ||
1862 | goto fail; | ||
1863 | } | ||
1864 | |||
1865 | rcu_assign_pointer(callchain_cpus_entries, entries); | ||
1866 | |||
1867 | return 0; | ||
1868 | |||
1869 | fail: | ||
1870 | for_each_possible_cpu(cpu) | ||
1871 | kfree(entries->cpu_entries[cpu]); | ||
1872 | kfree(entries); | ||
1873 | |||
1874 | return -ENOMEM; | ||
1875 | } | ||
1876 | |||
1877 | static int get_callchain_buffers(void) | ||
1878 | { | ||
1879 | int err = 0; | ||
1880 | int count; | ||
1881 | |||
1882 | mutex_lock(&callchain_mutex); | ||
1883 | |||
1884 | count = atomic_inc_return(&nr_callchain_events); | ||
1885 | if (WARN_ON_ONCE(count < 1)) { | ||
1886 | err = -EINVAL; | ||
1887 | goto exit; | ||
1888 | } | ||
1889 | |||
1890 | if (count > 1) { | ||
1891 | /* If the allocation failed, give up */ | ||
1892 | if (!callchain_cpus_entries) | ||
1893 | err = -ENOMEM; | ||
1894 | goto exit; | ||
1895 | } | ||
1896 | |||
1897 | err = alloc_callchain_buffers(); | ||
1898 | if (err) | ||
1899 | release_callchain_buffers(); | ||
1900 | exit: | ||
1901 | mutex_unlock(&callchain_mutex); | ||
1902 | |||
1903 | return err; | ||
1904 | } | ||
1905 | |||
1906 | static void put_callchain_buffers(void) | ||
1907 | { | ||
1908 | if (atomic_dec_and_mutex_lock(&nr_callchain_events, &callchain_mutex)) { | ||
1909 | release_callchain_buffers(); | ||
1910 | mutex_unlock(&callchain_mutex); | ||
1911 | } | ||
1912 | } | ||
1913 | |||
1914 | static int get_recursion_context(int *recursion) | ||
1915 | { | ||
1916 | int rctx; | ||
1917 | |||
1918 | if (in_nmi()) | ||
1919 | rctx = 3; | ||
1920 | else if (in_irq()) | ||
1921 | rctx = 2; | ||
1922 | else if (in_softirq()) | ||
1923 | rctx = 1; | ||
1924 | else | ||
1925 | rctx = 0; | ||
1926 | |||
1927 | if (recursion[rctx]) | ||
1928 | return -1; | ||
1929 | |||
1930 | recursion[rctx]++; | ||
1931 | barrier(); | ||
1932 | |||
1933 | return rctx; | ||
1934 | } | ||
1935 | |||
1936 | static inline void put_recursion_context(int *recursion, int rctx) | ||
1937 | { | ||
1938 | barrier(); | ||
1939 | recursion[rctx]--; | ||
1940 | } | ||
1941 | |||
1942 | static struct perf_callchain_entry *get_callchain_entry(int *rctx) | ||
1943 | { | ||
1944 | int cpu; | ||
1945 | struct callchain_cpus_entries *entries; | ||
1946 | |||
1947 | *rctx = get_recursion_context(__get_cpu_var(callchain_recursion)); | ||
1948 | if (*rctx == -1) | ||
1949 | return NULL; | ||
1950 | |||
1951 | entries = rcu_dereference(callchain_cpus_entries); | ||
1952 | if (!entries) | ||
1953 | return NULL; | ||
1954 | |||
1955 | cpu = smp_processor_id(); | ||
1956 | |||
1957 | return &entries->cpu_entries[cpu][*rctx]; | ||
1958 | } | ||
1959 | |||
1792 | static void | 1960 | static void |
1793 | __perf_event_init_context(struct perf_event_context *ctx, | 1961 | put_callchain_entry(int rctx) |
1794 | struct task_struct *task) | 1962 | { |
1963 | put_recursion_context(__get_cpu_var(callchain_recursion), rctx); | ||
1964 | } | ||
1965 | |||
1966 | static struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
1967 | { | ||
1968 | int rctx; | ||
1969 | struct perf_callchain_entry *entry; | ||
1970 | |||
1971 | |||
1972 | entry = get_callchain_entry(&rctx); | ||
1973 | if (rctx == -1) | ||
1974 | return NULL; | ||
1975 | |||
1976 | if (!entry) | ||
1977 | goto exit_put; | ||
1978 | |||
1979 | entry->nr = 0; | ||
1980 | |||
1981 | if (!user_mode(regs)) { | ||
1982 | perf_callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
1983 | perf_callchain_kernel(entry, regs); | ||
1984 | if (current->mm) | ||
1985 | regs = task_pt_regs(current); | ||
1986 | else | ||
1987 | regs = NULL; | ||
1988 | } | ||
1989 | |||
1990 | if (regs) { | ||
1991 | perf_callchain_store(entry, PERF_CONTEXT_USER); | ||
1992 | perf_callchain_user(entry, regs); | ||
1993 | } | ||
1994 | |||
1995 | exit_put: | ||
1996 | put_callchain_entry(rctx); | ||
1997 | |||
1998 | return entry; | ||
1999 | } | ||
2000 | |||
2001 | /* | ||
2002 | * Initialize the perf_event context in a task_struct: | ||
2003 | */ | ||
2004 | static void __perf_event_init_context(struct perf_event_context *ctx) | ||
1795 | { | 2005 | { |
1796 | raw_spin_lock_init(&ctx->lock); | 2006 | raw_spin_lock_init(&ctx->lock); |
1797 | mutex_init(&ctx->mutex); | 2007 | mutex_init(&ctx->mutex); |
@@ -1799,45 +2009,38 @@ __perf_event_init_context(struct perf_event_context *ctx, | |||
1799 | INIT_LIST_HEAD(&ctx->flexible_groups); | 2009 | INIT_LIST_HEAD(&ctx->flexible_groups); |
1800 | INIT_LIST_HEAD(&ctx->event_list); | 2010 | INIT_LIST_HEAD(&ctx->event_list); |
1801 | atomic_set(&ctx->refcount, 1); | 2011 | atomic_set(&ctx->refcount, 1); |
1802 | ctx->task = task; | ||
1803 | } | 2012 | } |
1804 | 2013 | ||
1805 | static struct perf_event_context *find_get_context(pid_t pid, int cpu) | 2014 | static struct perf_event_context * |
2015 | alloc_perf_context(struct pmu *pmu, struct task_struct *task) | ||
1806 | { | 2016 | { |
1807 | struct perf_event_context *ctx; | 2017 | struct perf_event_context *ctx; |
1808 | struct perf_cpu_context *cpuctx; | ||
1809 | struct task_struct *task; | ||
1810 | unsigned long flags; | ||
1811 | int err; | ||
1812 | |||
1813 | if (pid == -1 && cpu != -1) { | ||
1814 | /* Must be root to operate on a CPU event: */ | ||
1815 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) | ||
1816 | return ERR_PTR(-EACCES); | ||
1817 | 2018 | ||
1818 | if (cpu < 0 || cpu >= nr_cpumask_bits) | 2019 | ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL); |
1819 | return ERR_PTR(-EINVAL); | 2020 | if (!ctx) |
2021 | return NULL; | ||
1820 | 2022 | ||
1821 | /* | 2023 | __perf_event_init_context(ctx); |
1822 | * We could be clever and allow to attach a event to an | 2024 | if (task) { |
1823 | * offline CPU and activate it when the CPU comes up, but | 2025 | ctx->task = task; |
1824 | * that's for later. | 2026 | get_task_struct(task); |
1825 | */ | 2027 | } |
1826 | if (!cpu_online(cpu)) | 2028 | ctx->pmu = pmu; |
1827 | return ERR_PTR(-ENODEV); | ||
1828 | 2029 | ||
1829 | cpuctx = &per_cpu(perf_cpu_context, cpu); | 2030 | return ctx; |
1830 | ctx = &cpuctx->ctx; | 2031 | } |
1831 | get_ctx(ctx); | ||
1832 | 2032 | ||
1833 | return ctx; | 2033 | static struct task_struct * |
1834 | } | 2034 | find_lively_task_by_vpid(pid_t vpid) |
2035 | { | ||
2036 | struct task_struct *task; | ||
2037 | int err; | ||
1835 | 2038 | ||
1836 | rcu_read_lock(); | 2039 | rcu_read_lock(); |
1837 | if (!pid) | 2040 | if (!vpid) |
1838 | task = current; | 2041 | task = current; |
1839 | else | 2042 | else |
1840 | task = find_task_by_vpid(pid); | 2043 | task = find_task_by_vpid(vpid); |
1841 | if (task) | 2044 | if (task) |
1842 | get_task_struct(task); | 2045 | get_task_struct(task); |
1843 | rcu_read_unlock(); | 2046 | rcu_read_unlock(); |
@@ -1857,35 +2060,79 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu) | |||
1857 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | 2060 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
1858 | goto errout; | 2061 | goto errout; |
1859 | 2062 | ||
1860 | retry: | 2063 | return task; |
1861 | ctx = perf_lock_task_context(task, &flags); | 2064 | errout: |
2065 | put_task_struct(task); | ||
2066 | return ERR_PTR(err); | ||
2067 | |||
2068 | } | ||
2069 | |||
2070 | static struct perf_event_context * | ||
2071 | find_get_context(struct pmu *pmu, struct task_struct *task, int cpu) | ||
2072 | { | ||
2073 | struct perf_event_context *ctx; | ||
2074 | struct perf_cpu_context *cpuctx; | ||
2075 | unsigned long flags; | ||
2076 | int ctxn, err; | ||
2077 | |||
2078 | if (!task && cpu != -1) { | ||
2079 | /* Must be root to operate on a CPU event: */ | ||
2080 | if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) | ||
2081 | return ERR_PTR(-EACCES); | ||
2082 | |||
2083 | if (cpu < 0 || cpu >= nr_cpumask_bits) | ||
2084 | return ERR_PTR(-EINVAL); | ||
2085 | |||
2086 | /* | ||
2087 | * We could be clever and allow to attach a event to an | ||
2088 | * offline CPU and activate it when the CPU comes up, but | ||
2089 | * that's for later. | ||
2090 | */ | ||
2091 | if (!cpu_online(cpu)) | ||
2092 | return ERR_PTR(-ENODEV); | ||
2093 | |||
2094 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); | ||
2095 | ctx = &cpuctx->ctx; | ||
2096 | get_ctx(ctx); | ||
2097 | |||
2098 | return ctx; | ||
2099 | } | ||
2100 | |||
2101 | err = -EINVAL; | ||
2102 | ctxn = pmu->task_ctx_nr; | ||
2103 | if (ctxn < 0) | ||
2104 | goto errout; | ||
2105 | |||
2106 | retry: | ||
2107 | ctx = perf_lock_task_context(task, ctxn, &flags); | ||
1862 | if (ctx) { | 2108 | if (ctx) { |
1863 | unclone_ctx(ctx); | 2109 | unclone_ctx(ctx); |
1864 | raw_spin_unlock_irqrestore(&ctx->lock, flags); | 2110 | raw_spin_unlock_irqrestore(&ctx->lock, flags); |
1865 | } | 2111 | } |
1866 | 2112 | ||
1867 | if (!ctx) { | 2113 | if (!ctx) { |
1868 | ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL); | 2114 | ctx = alloc_perf_context(pmu, task); |
1869 | err = -ENOMEM; | 2115 | err = -ENOMEM; |
1870 | if (!ctx) | 2116 | if (!ctx) |
1871 | goto errout; | 2117 | goto errout; |
1872 | __perf_event_init_context(ctx, task); | 2118 | |
1873 | get_ctx(ctx); | 2119 | get_ctx(ctx); |
1874 | if (cmpxchg(&task->perf_event_ctxp, NULL, ctx)) { | 2120 | |
2121 | if (cmpxchg(&task->perf_event_ctxp[ctxn], NULL, ctx)) { | ||
1875 | /* | 2122 | /* |
1876 | * We raced with some other task; use | 2123 | * We raced with some other task; use |
1877 | * the context they set. | 2124 | * the context they set. |
1878 | */ | 2125 | */ |
2126 | put_task_struct(task); | ||
1879 | kfree(ctx); | 2127 | kfree(ctx); |
1880 | goto retry; | 2128 | goto retry; |
1881 | } | 2129 | } |
1882 | get_task_struct(task); | ||
1883 | } | 2130 | } |
1884 | 2131 | ||
1885 | put_task_struct(task); | 2132 | put_task_struct(task); |
1886 | return ctx; | 2133 | return ctx; |
1887 | 2134 | ||
1888 | errout: | 2135 | errout: |
1889 | put_task_struct(task); | 2136 | put_task_struct(task); |
1890 | return ERR_PTR(err); | 2137 | return ERR_PTR(err); |
1891 | } | 2138 | } |
@@ -1918,6 +2165,8 @@ static void free_event(struct perf_event *event) | |||
1918 | atomic_dec(&nr_comm_events); | 2165 | atomic_dec(&nr_comm_events); |
1919 | if (event->attr.task) | 2166 | if (event->attr.task) |
1920 | atomic_dec(&nr_task_events); | 2167 | atomic_dec(&nr_task_events); |
2168 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) | ||
2169 | put_callchain_buffers(); | ||
1921 | } | 2170 | } |
1922 | 2171 | ||
1923 | if (event->buffer) { | 2172 | if (event->buffer) { |
@@ -1928,7 +2177,9 @@ static void free_event(struct perf_event *event) | |||
1928 | if (event->destroy) | 2177 | if (event->destroy) |
1929 | event->destroy(event); | 2178 | event->destroy(event); |
1930 | 2179 | ||
1931 | put_ctx(event->ctx); | 2180 | if (event->ctx) |
2181 | put_ctx(event->ctx); | ||
2182 | |||
1932 | call_rcu(&event->rcu_head, free_event_rcu); | 2183 | call_rcu(&event->rcu_head, free_event_rcu); |
1933 | } | 2184 | } |
1934 | 2185 | ||
@@ -2349,6 +2600,9 @@ int perf_event_task_disable(void) | |||
2349 | 2600 | ||
2350 | static int perf_event_index(struct perf_event *event) | 2601 | static int perf_event_index(struct perf_event *event) |
2351 | { | 2602 | { |
2603 | if (event->hw.state & PERF_HES_STOPPED) | ||
2604 | return 0; | ||
2605 | |||
2352 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 2606 | if (event->state != PERF_EVENT_STATE_ACTIVE) |
2353 | return 0; | 2607 | return 0; |
2354 | 2608 | ||
@@ -2961,16 +3215,6 @@ void perf_event_do_pending(void) | |||
2961 | } | 3215 | } |
2962 | 3216 | ||
2963 | /* | 3217 | /* |
2964 | * Callchain support -- arch specific | ||
2965 | */ | ||
2966 | |||
2967 | __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
2968 | { | ||
2969 | return NULL; | ||
2970 | } | ||
2971 | |||
2972 | |||
2973 | /* | ||
2974 | * We assume there is only KVM supporting the callbacks. | 3218 | * We assume there is only KVM supporting the callbacks. |
2975 | * Later on, we might change it to a list if there is | 3219 | * Later on, we might change it to a list if there is |
2976 | * another virtualization implementation supporting the callbacks. | 3220 | * another virtualization implementation supporting the callbacks. |
@@ -3076,7 +3320,7 @@ again: | |||
3076 | if (handle->wakeup != local_read(&buffer->wakeup)) | 3320 | if (handle->wakeup != local_read(&buffer->wakeup)) |
3077 | perf_output_wakeup(handle); | 3321 | perf_output_wakeup(handle); |
3078 | 3322 | ||
3079 | out: | 3323 | out: |
3080 | preempt_enable(); | 3324 | preempt_enable(); |
3081 | } | 3325 | } |
3082 | 3326 | ||
@@ -3464,14 +3708,20 @@ static void perf_event_output(struct perf_event *event, int nmi, | |||
3464 | struct perf_output_handle handle; | 3708 | struct perf_output_handle handle; |
3465 | struct perf_event_header header; | 3709 | struct perf_event_header header; |
3466 | 3710 | ||
3711 | /* protect the callchain buffers */ | ||
3712 | rcu_read_lock(); | ||
3713 | |||
3467 | perf_prepare_sample(&header, data, event, regs); | 3714 | perf_prepare_sample(&header, data, event, regs); |
3468 | 3715 | ||
3469 | if (perf_output_begin(&handle, event, header.size, nmi, 1)) | 3716 | if (perf_output_begin(&handle, event, header.size, nmi, 1)) |
3470 | return; | 3717 | goto exit; |
3471 | 3718 | ||
3472 | perf_output_sample(&handle, &header, data, event); | 3719 | perf_output_sample(&handle, &header, data, event); |
3473 | 3720 | ||
3474 | perf_output_end(&handle); | 3721 | perf_output_end(&handle); |
3722 | |||
3723 | exit: | ||
3724 | rcu_read_unlock(); | ||
3475 | } | 3725 | } |
3476 | 3726 | ||
3477 | /* | 3727 | /* |
@@ -3585,16 +3835,27 @@ static void perf_event_task_ctx(struct perf_event_context *ctx, | |||
3585 | static void perf_event_task_event(struct perf_task_event *task_event) | 3835 | static void perf_event_task_event(struct perf_task_event *task_event) |
3586 | { | 3836 | { |
3587 | struct perf_cpu_context *cpuctx; | 3837 | struct perf_cpu_context *cpuctx; |
3588 | struct perf_event_context *ctx = task_event->task_ctx; | 3838 | struct perf_event_context *ctx; |
3839 | struct pmu *pmu; | ||
3840 | int ctxn; | ||
3589 | 3841 | ||
3590 | rcu_read_lock(); | 3842 | rcu_read_lock(); |
3591 | cpuctx = &get_cpu_var(perf_cpu_context); | 3843 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
3592 | perf_event_task_ctx(&cpuctx->ctx, task_event); | 3844 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
3593 | if (!ctx) | 3845 | perf_event_task_ctx(&cpuctx->ctx, task_event); |
3594 | ctx = rcu_dereference(current->perf_event_ctxp); | 3846 | |
3595 | if (ctx) | 3847 | ctx = task_event->task_ctx; |
3596 | perf_event_task_ctx(ctx, task_event); | 3848 | if (!ctx) { |
3597 | put_cpu_var(perf_cpu_context); | 3849 | ctxn = pmu->task_ctx_nr; |
3850 | if (ctxn < 0) | ||
3851 | goto next; | ||
3852 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
3853 | } | ||
3854 | if (ctx) | ||
3855 | perf_event_task_ctx(ctx, task_event); | ||
3856 | next: | ||
3857 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
3858 | } | ||
3598 | rcu_read_unlock(); | 3859 | rcu_read_unlock(); |
3599 | } | 3860 | } |
3600 | 3861 | ||
@@ -3699,8 +3960,10 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
3699 | { | 3960 | { |
3700 | struct perf_cpu_context *cpuctx; | 3961 | struct perf_cpu_context *cpuctx; |
3701 | struct perf_event_context *ctx; | 3962 | struct perf_event_context *ctx; |
3702 | unsigned int size; | ||
3703 | char comm[TASK_COMM_LEN]; | 3963 | char comm[TASK_COMM_LEN]; |
3964 | unsigned int size; | ||
3965 | struct pmu *pmu; | ||
3966 | int ctxn; | ||
3704 | 3967 | ||
3705 | memset(comm, 0, sizeof(comm)); | 3968 | memset(comm, 0, sizeof(comm)); |
3706 | strlcpy(comm, comm_event->task->comm, sizeof(comm)); | 3969 | strlcpy(comm, comm_event->task->comm, sizeof(comm)); |
@@ -3712,21 +3975,36 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
3712 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; | 3975 | comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; |
3713 | 3976 | ||
3714 | rcu_read_lock(); | 3977 | rcu_read_lock(); |
3715 | cpuctx = &get_cpu_var(perf_cpu_context); | 3978 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
3716 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); | 3979 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
3717 | ctx = rcu_dereference(current->perf_event_ctxp); | 3980 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); |
3718 | if (ctx) | 3981 | |
3719 | perf_event_comm_ctx(ctx, comm_event); | 3982 | ctxn = pmu->task_ctx_nr; |
3720 | put_cpu_var(perf_cpu_context); | 3983 | if (ctxn < 0) |
3984 | goto next; | ||
3985 | |||
3986 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
3987 | if (ctx) | ||
3988 | perf_event_comm_ctx(ctx, comm_event); | ||
3989 | next: | ||
3990 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
3991 | } | ||
3721 | rcu_read_unlock(); | 3992 | rcu_read_unlock(); |
3722 | } | 3993 | } |
3723 | 3994 | ||
3724 | void perf_event_comm(struct task_struct *task) | 3995 | void perf_event_comm(struct task_struct *task) |
3725 | { | 3996 | { |
3726 | struct perf_comm_event comm_event; | 3997 | struct perf_comm_event comm_event; |
3998 | struct perf_event_context *ctx; | ||
3999 | int ctxn; | ||
4000 | |||
4001 | for_each_task_context_nr(ctxn) { | ||
4002 | ctx = task->perf_event_ctxp[ctxn]; | ||
4003 | if (!ctx) | ||
4004 | continue; | ||
3727 | 4005 | ||
3728 | if (task->perf_event_ctxp) | 4006 | perf_event_enable_on_exec(ctx); |
3729 | perf_event_enable_on_exec(task); | 4007 | } |
3730 | 4008 | ||
3731 | if (!atomic_read(&nr_comm_events)) | 4009 | if (!atomic_read(&nr_comm_events)) |
3732 | return; | 4010 | return; |
@@ -3828,6 +4106,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
3828 | char tmp[16]; | 4106 | char tmp[16]; |
3829 | char *buf = NULL; | 4107 | char *buf = NULL; |
3830 | const char *name; | 4108 | const char *name; |
4109 | struct pmu *pmu; | ||
4110 | int ctxn; | ||
3831 | 4111 | ||
3832 | memset(tmp, 0, sizeof(tmp)); | 4112 | memset(tmp, 0, sizeof(tmp)); |
3833 | 4113 | ||
@@ -3880,12 +4160,23 @@ got_name: | |||
3880 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; | 4160 | mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; |
3881 | 4161 | ||
3882 | rcu_read_lock(); | 4162 | rcu_read_lock(); |
3883 | cpuctx = &get_cpu_var(perf_cpu_context); | 4163 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
3884 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, vma->vm_flags & VM_EXEC); | 4164 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
3885 | ctx = rcu_dereference(current->perf_event_ctxp); | 4165 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, |
3886 | if (ctx) | 4166 | vma->vm_flags & VM_EXEC); |
3887 | perf_event_mmap_ctx(ctx, mmap_event, vma->vm_flags & VM_EXEC); | 4167 | |
3888 | put_cpu_var(perf_cpu_context); | 4168 | ctxn = pmu->task_ctx_nr; |
4169 | if (ctxn < 0) | ||
4170 | goto next; | ||
4171 | |||
4172 | ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); | ||
4173 | if (ctx) { | ||
4174 | perf_event_mmap_ctx(ctx, mmap_event, | ||
4175 | vma->vm_flags & VM_EXEC); | ||
4176 | } | ||
4177 | next: | ||
4178 | put_cpu_ptr(pmu->pmu_cpu_context); | ||
4179 | } | ||
3889 | rcu_read_unlock(); | 4180 | rcu_read_unlock(); |
3890 | 4181 | ||
3891 | kfree(buf); | 4182 | kfree(buf); |
@@ -3967,8 +4258,6 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, | |||
3967 | struct hw_perf_event *hwc = &event->hw; | 4258 | struct hw_perf_event *hwc = &event->hw; |
3968 | int ret = 0; | 4259 | int ret = 0; |
3969 | 4260 | ||
3970 | throttle = (throttle && event->pmu->unthrottle != NULL); | ||
3971 | |||
3972 | if (!throttle) { | 4261 | if (!throttle) { |
3973 | hwc->interrupts++; | 4262 | hwc->interrupts++; |
3974 | } else { | 4263 | } else { |
@@ -4036,6 +4325,17 @@ int perf_event_overflow(struct perf_event *event, int nmi, | |||
4036 | * Generic software event infrastructure | 4325 | * Generic software event infrastructure |
4037 | */ | 4326 | */ |
4038 | 4327 | ||
4328 | struct swevent_htable { | ||
4329 | struct swevent_hlist *swevent_hlist; | ||
4330 | struct mutex hlist_mutex; | ||
4331 | int hlist_refcount; | ||
4332 | |||
4333 | /* Recursion avoidance in each contexts */ | ||
4334 | int recursion[PERF_NR_CONTEXTS]; | ||
4335 | }; | ||
4336 | |||
4337 | static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); | ||
4338 | |||
4039 | /* | 4339 | /* |
4040 | * We directly increment event->count and keep a second value in | 4340 | * We directly increment event->count and keep a second value in |
4041 | * event->hw.period_left to count intervals. This period event | 4341 | * event->hw.period_left to count intervals. This period event |
@@ -4093,7 +4393,7 @@ static void perf_swevent_overflow(struct perf_event *event, u64 overflow, | |||
4093 | } | 4393 | } |
4094 | } | 4394 | } |
4095 | 4395 | ||
4096 | static void perf_swevent_add(struct perf_event *event, u64 nr, | 4396 | static void perf_swevent_event(struct perf_event *event, u64 nr, |
4097 | int nmi, struct perf_sample_data *data, | 4397 | int nmi, struct perf_sample_data *data, |
4098 | struct pt_regs *regs) | 4398 | struct pt_regs *regs) |
4099 | { | 4399 | { |
@@ -4119,6 +4419,9 @@ static void perf_swevent_add(struct perf_event *event, u64 nr, | |||
4119 | static int perf_exclude_event(struct perf_event *event, | 4419 | static int perf_exclude_event(struct perf_event *event, |
4120 | struct pt_regs *regs) | 4420 | struct pt_regs *regs) |
4121 | { | 4421 | { |
4422 | if (event->hw.state & PERF_HES_STOPPED) | ||
4423 | return 0; | ||
4424 | |||
4122 | if (regs) { | 4425 | if (regs) { |
4123 | if (event->attr.exclude_user && user_mode(regs)) | 4426 | if (event->attr.exclude_user && user_mode(regs)) |
4124 | return 1; | 4427 | return 1; |
@@ -4165,11 +4468,11 @@ __find_swevent_head(struct swevent_hlist *hlist, u64 type, u32 event_id) | |||
4165 | 4468 | ||
4166 | /* For the read side: events when they trigger */ | 4469 | /* For the read side: events when they trigger */ |
4167 | static inline struct hlist_head * | 4470 | static inline struct hlist_head * |
4168 | find_swevent_head_rcu(struct perf_cpu_context *ctx, u64 type, u32 event_id) | 4471 | find_swevent_head_rcu(struct swevent_htable *swhash, u64 type, u32 event_id) |
4169 | { | 4472 | { |
4170 | struct swevent_hlist *hlist; | 4473 | struct swevent_hlist *hlist; |
4171 | 4474 | ||
4172 | hlist = rcu_dereference(ctx->swevent_hlist); | 4475 | hlist = rcu_dereference(swhash->swevent_hlist); |
4173 | if (!hlist) | 4476 | if (!hlist) |
4174 | return NULL; | 4477 | return NULL; |
4175 | 4478 | ||
@@ -4178,7 +4481,7 @@ find_swevent_head_rcu(struct perf_cpu_context *ctx, u64 type, u32 event_id) | |||
4178 | 4481 | ||
4179 | /* For the event head insertion and removal in the hlist */ | 4482 | /* For the event head insertion and removal in the hlist */ |
4180 | static inline struct hlist_head * | 4483 | static inline struct hlist_head * |
4181 | find_swevent_head(struct perf_cpu_context *ctx, struct perf_event *event) | 4484 | find_swevent_head(struct swevent_htable *swhash, struct perf_event *event) |
4182 | { | 4485 | { |
4183 | struct swevent_hlist *hlist; | 4486 | struct swevent_hlist *hlist; |
4184 | u32 event_id = event->attr.config; | 4487 | u32 event_id = event->attr.config; |
@@ -4189,7 +4492,7 @@ find_swevent_head(struct perf_cpu_context *ctx, struct perf_event *event) | |||
4189 | * and release. Which makes the protected version suitable here. | 4492 | * and release. Which makes the protected version suitable here. |
4190 | * The context lock guarantees that. | 4493 | * The context lock guarantees that. |
4191 | */ | 4494 | */ |
4192 | hlist = rcu_dereference_protected(ctx->swevent_hlist, | 4495 | hlist = rcu_dereference_protected(swhash->swevent_hlist, |
4193 | lockdep_is_held(&event->ctx->lock)); | 4496 | lockdep_is_held(&event->ctx->lock)); |
4194 | if (!hlist) | 4497 | if (!hlist) |
4195 | return NULL; | 4498 | return NULL; |
@@ -4202,23 +4505,19 @@ static void do_perf_sw_event(enum perf_type_id type, u32 event_id, | |||
4202 | struct perf_sample_data *data, | 4505 | struct perf_sample_data *data, |
4203 | struct pt_regs *regs) | 4506 | struct pt_regs *regs) |
4204 | { | 4507 | { |
4205 | struct perf_cpu_context *cpuctx; | 4508 | struct swevent_htable *swhash = &__get_cpu_var(swevent_htable); |
4206 | struct perf_event *event; | 4509 | struct perf_event *event; |
4207 | struct hlist_node *node; | 4510 | struct hlist_node *node; |
4208 | struct hlist_head *head; | 4511 | struct hlist_head *head; |
4209 | 4512 | ||
4210 | cpuctx = &__get_cpu_var(perf_cpu_context); | ||
4211 | |||
4212 | rcu_read_lock(); | 4513 | rcu_read_lock(); |
4213 | 4514 | head = find_swevent_head_rcu(swhash, type, event_id); | |
4214 | head = find_swevent_head_rcu(cpuctx, type, event_id); | ||
4215 | |||
4216 | if (!head) | 4515 | if (!head) |
4217 | goto end; | 4516 | goto end; |
4218 | 4517 | ||
4219 | hlist_for_each_entry_rcu(event, node, head, hlist_entry) { | 4518 | hlist_for_each_entry_rcu(event, node, head, hlist_entry) { |
4220 | if (perf_swevent_match(event, type, event_id, data, regs)) | 4519 | if (perf_swevent_match(event, type, event_id, data, regs)) |
4221 | perf_swevent_add(event, nr, nmi, data, regs); | 4520 | perf_swevent_event(event, nr, nmi, data, regs); |
4222 | } | 4521 | } |
4223 | end: | 4522 | end: |
4224 | rcu_read_unlock(); | 4523 | rcu_read_unlock(); |
@@ -4226,33 +4525,17 @@ end: | |||
4226 | 4525 | ||
4227 | int perf_swevent_get_recursion_context(void) | 4526 | int perf_swevent_get_recursion_context(void) |
4228 | { | 4527 | { |
4229 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 4528 | struct swevent_htable *swhash = &__get_cpu_var(swevent_htable); |
4230 | int rctx; | ||
4231 | 4529 | ||
4232 | if (in_nmi()) | 4530 | return get_recursion_context(swhash->recursion); |
4233 | rctx = 3; | ||
4234 | else if (in_irq()) | ||
4235 | rctx = 2; | ||
4236 | else if (in_softirq()) | ||
4237 | rctx = 1; | ||
4238 | else | ||
4239 | rctx = 0; | ||
4240 | |||
4241 | if (cpuctx->recursion[rctx]) | ||
4242 | return -1; | ||
4243 | |||
4244 | cpuctx->recursion[rctx]++; | ||
4245 | barrier(); | ||
4246 | |||
4247 | return rctx; | ||
4248 | } | 4531 | } |
4249 | EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context); | 4532 | EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context); |
4250 | 4533 | ||
4251 | void inline perf_swevent_put_recursion_context(int rctx) | 4534 | void inline perf_swevent_put_recursion_context(int rctx) |
4252 | { | 4535 | { |
4253 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 4536 | struct swevent_htable *swhash = &__get_cpu_var(swevent_htable); |
4254 | barrier(); | 4537 | |
4255 | cpuctx->recursion[rctx]--; | 4538 | put_recursion_context(swhash->recursion, rctx); |
4256 | } | 4539 | } |
4257 | 4540 | ||
4258 | void __perf_sw_event(u32 event_id, u64 nr, int nmi, | 4541 | void __perf_sw_event(u32 event_id, u64 nr, int nmi, |
@@ -4278,20 +4561,20 @@ static void perf_swevent_read(struct perf_event *event) | |||
4278 | { | 4561 | { |
4279 | } | 4562 | } |
4280 | 4563 | ||
4281 | static int perf_swevent_enable(struct perf_event *event) | 4564 | static int perf_swevent_add(struct perf_event *event, int flags) |
4282 | { | 4565 | { |
4566 | struct swevent_htable *swhash = &__get_cpu_var(swevent_htable); | ||
4283 | struct hw_perf_event *hwc = &event->hw; | 4567 | struct hw_perf_event *hwc = &event->hw; |
4284 | struct perf_cpu_context *cpuctx; | ||
4285 | struct hlist_head *head; | 4568 | struct hlist_head *head; |
4286 | 4569 | ||
4287 | cpuctx = &__get_cpu_var(perf_cpu_context); | ||
4288 | |||
4289 | if (hwc->sample_period) { | 4570 | if (hwc->sample_period) { |
4290 | hwc->last_period = hwc->sample_period; | 4571 | hwc->last_period = hwc->sample_period; |
4291 | perf_swevent_set_period(event); | 4572 | perf_swevent_set_period(event); |
4292 | } | 4573 | } |
4293 | 4574 | ||
4294 | head = find_swevent_head(cpuctx, event); | 4575 | hwc->state = !(flags & PERF_EF_START); |
4576 | |||
4577 | head = find_swevent_head(swhash, event); | ||
4295 | if (WARN_ON_ONCE(!head)) | 4578 | if (WARN_ON_ONCE(!head)) |
4296 | return -EINVAL; | 4579 | return -EINVAL; |
4297 | 4580 | ||
@@ -4300,202 +4583,27 @@ static int perf_swevent_enable(struct perf_event *event) | |||
4300 | return 0; | 4583 | return 0; |
4301 | } | 4584 | } |
4302 | 4585 | ||
4303 | static void perf_swevent_disable(struct perf_event *event) | 4586 | static void perf_swevent_del(struct perf_event *event, int flags) |
4304 | { | 4587 | { |
4305 | hlist_del_rcu(&event->hlist_entry); | 4588 | hlist_del_rcu(&event->hlist_entry); |
4306 | } | 4589 | } |
4307 | 4590 | ||
4308 | static void perf_swevent_void(struct perf_event *event) | 4591 | static void perf_swevent_start(struct perf_event *event, int flags) |
4309 | { | 4592 | { |
4593 | event->hw.state = 0; | ||
4310 | } | 4594 | } |
4311 | 4595 | ||
4312 | static int perf_swevent_int(struct perf_event *event) | 4596 | static void perf_swevent_stop(struct perf_event *event, int flags) |
4313 | { | 4597 | { |
4314 | return 0; | 4598 | event->hw.state = PERF_HES_STOPPED; |
4315 | } | ||
4316 | |||
4317 | static const struct pmu perf_ops_generic = { | ||
4318 | .enable = perf_swevent_enable, | ||
4319 | .disable = perf_swevent_disable, | ||
4320 | .start = perf_swevent_int, | ||
4321 | .stop = perf_swevent_void, | ||
4322 | .read = perf_swevent_read, | ||
4323 | .unthrottle = perf_swevent_void, /* hwc->interrupts already reset */ | ||
4324 | }; | ||
4325 | |||
4326 | /* | ||
4327 | * hrtimer based swevent callback | ||
4328 | */ | ||
4329 | |||
4330 | static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) | ||
4331 | { | ||
4332 | enum hrtimer_restart ret = HRTIMER_RESTART; | ||
4333 | struct perf_sample_data data; | ||
4334 | struct pt_regs *regs; | ||
4335 | struct perf_event *event; | ||
4336 | u64 period; | ||
4337 | |||
4338 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); | ||
4339 | event->pmu->read(event); | ||
4340 | |||
4341 | perf_sample_data_init(&data, 0); | ||
4342 | data.period = event->hw.last_period; | ||
4343 | regs = get_irq_regs(); | ||
4344 | |||
4345 | if (regs && !perf_exclude_event(event, regs)) { | ||
4346 | if (!(event->attr.exclude_idle && current->pid == 0)) | ||
4347 | if (perf_event_overflow(event, 0, &data, regs)) | ||
4348 | ret = HRTIMER_NORESTART; | ||
4349 | } | ||
4350 | |||
4351 | period = max_t(u64, 10000, event->hw.sample_period); | ||
4352 | hrtimer_forward_now(hrtimer, ns_to_ktime(period)); | ||
4353 | |||
4354 | return ret; | ||
4355 | } | 4599 | } |
4356 | 4600 | ||
4357 | static void perf_swevent_start_hrtimer(struct perf_event *event) | ||
4358 | { | ||
4359 | struct hw_perf_event *hwc = &event->hw; | ||
4360 | |||
4361 | hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
4362 | hwc->hrtimer.function = perf_swevent_hrtimer; | ||
4363 | if (hwc->sample_period) { | ||
4364 | u64 period; | ||
4365 | |||
4366 | if (hwc->remaining) { | ||
4367 | if (hwc->remaining < 0) | ||
4368 | period = 10000; | ||
4369 | else | ||
4370 | period = hwc->remaining; | ||
4371 | hwc->remaining = 0; | ||
4372 | } else { | ||
4373 | period = max_t(u64, 10000, hwc->sample_period); | ||
4374 | } | ||
4375 | __hrtimer_start_range_ns(&hwc->hrtimer, | ||
4376 | ns_to_ktime(period), 0, | ||
4377 | HRTIMER_MODE_REL, 0); | ||
4378 | } | ||
4379 | } | ||
4380 | |||
4381 | static void perf_swevent_cancel_hrtimer(struct perf_event *event) | ||
4382 | { | ||
4383 | struct hw_perf_event *hwc = &event->hw; | ||
4384 | |||
4385 | if (hwc->sample_period) { | ||
4386 | ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer); | ||
4387 | hwc->remaining = ktime_to_ns(remaining); | ||
4388 | |||
4389 | hrtimer_cancel(&hwc->hrtimer); | ||
4390 | } | ||
4391 | } | ||
4392 | |||
4393 | /* | ||
4394 | * Software event: cpu wall time clock | ||
4395 | */ | ||
4396 | |||
4397 | static void cpu_clock_perf_event_update(struct perf_event *event) | ||
4398 | { | ||
4399 | int cpu = raw_smp_processor_id(); | ||
4400 | s64 prev; | ||
4401 | u64 now; | ||
4402 | |||
4403 | now = cpu_clock(cpu); | ||
4404 | prev = local64_xchg(&event->hw.prev_count, now); | ||
4405 | local64_add(now - prev, &event->count); | ||
4406 | } | ||
4407 | |||
4408 | static int cpu_clock_perf_event_enable(struct perf_event *event) | ||
4409 | { | ||
4410 | struct hw_perf_event *hwc = &event->hw; | ||
4411 | int cpu = raw_smp_processor_id(); | ||
4412 | |||
4413 | local64_set(&hwc->prev_count, cpu_clock(cpu)); | ||
4414 | perf_swevent_start_hrtimer(event); | ||
4415 | |||
4416 | return 0; | ||
4417 | } | ||
4418 | |||
4419 | static void cpu_clock_perf_event_disable(struct perf_event *event) | ||
4420 | { | ||
4421 | perf_swevent_cancel_hrtimer(event); | ||
4422 | cpu_clock_perf_event_update(event); | ||
4423 | } | ||
4424 | |||
4425 | static void cpu_clock_perf_event_read(struct perf_event *event) | ||
4426 | { | ||
4427 | cpu_clock_perf_event_update(event); | ||
4428 | } | ||
4429 | |||
4430 | static const struct pmu perf_ops_cpu_clock = { | ||
4431 | .enable = cpu_clock_perf_event_enable, | ||
4432 | .disable = cpu_clock_perf_event_disable, | ||
4433 | .read = cpu_clock_perf_event_read, | ||
4434 | }; | ||
4435 | |||
4436 | /* | ||
4437 | * Software event: task time clock | ||
4438 | */ | ||
4439 | |||
4440 | static void task_clock_perf_event_update(struct perf_event *event, u64 now) | ||
4441 | { | ||
4442 | u64 prev; | ||
4443 | s64 delta; | ||
4444 | |||
4445 | prev = local64_xchg(&event->hw.prev_count, now); | ||
4446 | delta = now - prev; | ||
4447 | local64_add(delta, &event->count); | ||
4448 | } | ||
4449 | |||
4450 | static int task_clock_perf_event_enable(struct perf_event *event) | ||
4451 | { | ||
4452 | struct hw_perf_event *hwc = &event->hw; | ||
4453 | u64 now; | ||
4454 | |||
4455 | now = event->ctx->time; | ||
4456 | |||
4457 | local64_set(&hwc->prev_count, now); | ||
4458 | |||
4459 | perf_swevent_start_hrtimer(event); | ||
4460 | |||
4461 | return 0; | ||
4462 | } | ||
4463 | |||
4464 | static void task_clock_perf_event_disable(struct perf_event *event) | ||
4465 | { | ||
4466 | perf_swevent_cancel_hrtimer(event); | ||
4467 | task_clock_perf_event_update(event, event->ctx->time); | ||
4468 | |||
4469 | } | ||
4470 | |||
4471 | static void task_clock_perf_event_read(struct perf_event *event) | ||
4472 | { | ||
4473 | u64 time; | ||
4474 | |||
4475 | if (!in_nmi()) { | ||
4476 | update_context_time(event->ctx); | ||
4477 | time = event->ctx->time; | ||
4478 | } else { | ||
4479 | u64 now = perf_clock(); | ||
4480 | u64 delta = now - event->ctx->timestamp; | ||
4481 | time = event->ctx->time + delta; | ||
4482 | } | ||
4483 | |||
4484 | task_clock_perf_event_update(event, time); | ||
4485 | } | ||
4486 | |||
4487 | static const struct pmu perf_ops_task_clock = { | ||
4488 | .enable = task_clock_perf_event_enable, | ||
4489 | .disable = task_clock_perf_event_disable, | ||
4490 | .read = task_clock_perf_event_read, | ||
4491 | }; | ||
4492 | |||
4493 | /* Deref the hlist from the update side */ | 4601 | /* Deref the hlist from the update side */ |
4494 | static inline struct swevent_hlist * | 4602 | static inline struct swevent_hlist * |
4495 | swevent_hlist_deref(struct perf_cpu_context *cpuctx) | 4603 | swevent_hlist_deref(struct swevent_htable *swhash) |
4496 | { | 4604 | { |
4497 | return rcu_dereference_protected(cpuctx->swevent_hlist, | 4605 | return rcu_dereference_protected(swhash->swevent_hlist, |
4498 | lockdep_is_held(&cpuctx->hlist_mutex)); | 4606 | lockdep_is_held(&swhash->hlist_mutex)); |
4499 | } | 4607 | } |
4500 | 4608 | ||
4501 | static void swevent_hlist_release_rcu(struct rcu_head *rcu_head) | 4609 | static void swevent_hlist_release_rcu(struct rcu_head *rcu_head) |
@@ -4506,27 +4614,27 @@ static void swevent_hlist_release_rcu(struct rcu_head *rcu_head) | |||
4506 | kfree(hlist); | 4614 | kfree(hlist); |
4507 | } | 4615 | } |
4508 | 4616 | ||
4509 | static void swevent_hlist_release(struct perf_cpu_context *cpuctx) | 4617 | static void swevent_hlist_release(struct swevent_htable *swhash) |
4510 | { | 4618 | { |
4511 | struct swevent_hlist *hlist = swevent_hlist_deref(cpuctx); | 4619 | struct swevent_hlist *hlist = swevent_hlist_deref(swhash); |
4512 | 4620 | ||
4513 | if (!hlist) | 4621 | if (!hlist) |
4514 | return; | 4622 | return; |
4515 | 4623 | ||
4516 | rcu_assign_pointer(cpuctx->swevent_hlist, NULL); | 4624 | rcu_assign_pointer(swhash->swevent_hlist, NULL); |
4517 | call_rcu(&hlist->rcu_head, swevent_hlist_release_rcu); | 4625 | call_rcu(&hlist->rcu_head, swevent_hlist_release_rcu); |
4518 | } | 4626 | } |
4519 | 4627 | ||
4520 | static void swevent_hlist_put_cpu(struct perf_event *event, int cpu) | 4628 | static void swevent_hlist_put_cpu(struct perf_event *event, int cpu) |
4521 | { | 4629 | { |
4522 | struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); | 4630 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
4523 | 4631 | ||
4524 | mutex_lock(&cpuctx->hlist_mutex); | 4632 | mutex_lock(&swhash->hlist_mutex); |
4525 | 4633 | ||
4526 | if (!--cpuctx->hlist_refcount) | 4634 | if (!--swhash->hlist_refcount) |
4527 | swevent_hlist_release(cpuctx); | 4635 | swevent_hlist_release(swhash); |
4528 | 4636 | ||
4529 | mutex_unlock(&cpuctx->hlist_mutex); | 4637 | mutex_unlock(&swhash->hlist_mutex); |
4530 | } | 4638 | } |
4531 | 4639 | ||
4532 | static void swevent_hlist_put(struct perf_event *event) | 4640 | static void swevent_hlist_put(struct perf_event *event) |
@@ -4544,12 +4652,12 @@ static void swevent_hlist_put(struct perf_event *event) | |||
4544 | 4652 | ||
4545 | static int swevent_hlist_get_cpu(struct perf_event *event, int cpu) | 4653 | static int swevent_hlist_get_cpu(struct perf_event *event, int cpu) |
4546 | { | 4654 | { |
4547 | struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); | 4655 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
4548 | int err = 0; | 4656 | int err = 0; |
4549 | 4657 | ||
4550 | mutex_lock(&cpuctx->hlist_mutex); | 4658 | mutex_lock(&swhash->hlist_mutex); |
4551 | 4659 | ||
4552 | if (!swevent_hlist_deref(cpuctx) && cpu_online(cpu)) { | 4660 | if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) { |
4553 | struct swevent_hlist *hlist; | 4661 | struct swevent_hlist *hlist; |
4554 | 4662 | ||
4555 | hlist = kzalloc(sizeof(*hlist), GFP_KERNEL); | 4663 | hlist = kzalloc(sizeof(*hlist), GFP_KERNEL); |
@@ -4557,11 +4665,11 @@ static int swevent_hlist_get_cpu(struct perf_event *event, int cpu) | |||
4557 | err = -ENOMEM; | 4665 | err = -ENOMEM; |
4558 | goto exit; | 4666 | goto exit; |
4559 | } | 4667 | } |
4560 | rcu_assign_pointer(cpuctx->swevent_hlist, hlist); | 4668 | rcu_assign_pointer(swhash->swevent_hlist, hlist); |
4561 | } | 4669 | } |
4562 | cpuctx->hlist_refcount++; | 4670 | swhash->hlist_refcount++; |
4563 | exit: | 4671 | exit: |
4564 | mutex_unlock(&cpuctx->hlist_mutex); | 4672 | mutex_unlock(&swhash->hlist_mutex); |
4565 | 4673 | ||
4566 | return err; | 4674 | return err; |
4567 | } | 4675 | } |
@@ -4585,7 +4693,7 @@ static int swevent_hlist_get(struct perf_event *event) | |||
4585 | put_online_cpus(); | 4693 | put_online_cpus(); |
4586 | 4694 | ||
4587 | return 0; | 4695 | return 0; |
4588 | fail: | 4696 | fail: |
4589 | for_each_possible_cpu(cpu) { | 4697 | for_each_possible_cpu(cpu) { |
4590 | if (cpu == failed_cpu) | 4698 | if (cpu == failed_cpu) |
4591 | break; | 4699 | break; |
@@ -4596,17 +4704,64 @@ static int swevent_hlist_get(struct perf_event *event) | |||
4596 | return err; | 4704 | return err; |
4597 | } | 4705 | } |
4598 | 4706 | ||
4599 | #ifdef CONFIG_EVENT_TRACING | 4707 | atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; |
4708 | |||
4709 | static void sw_perf_event_destroy(struct perf_event *event) | ||
4710 | { | ||
4711 | u64 event_id = event->attr.config; | ||
4712 | |||
4713 | WARN_ON(event->parent); | ||
4714 | |||
4715 | atomic_dec(&perf_swevent_enabled[event_id]); | ||
4716 | swevent_hlist_put(event); | ||
4717 | } | ||
4718 | |||
4719 | static int perf_swevent_init(struct perf_event *event) | ||
4720 | { | ||
4721 | int event_id = event->attr.config; | ||
4722 | |||
4723 | if (event->attr.type != PERF_TYPE_SOFTWARE) | ||
4724 | return -ENOENT; | ||
4725 | |||
4726 | switch (event_id) { | ||
4727 | case PERF_COUNT_SW_CPU_CLOCK: | ||
4728 | case PERF_COUNT_SW_TASK_CLOCK: | ||
4729 | return -ENOENT; | ||
4730 | |||
4731 | default: | ||
4732 | break; | ||
4733 | } | ||
4734 | |||
4735 | if (event_id > PERF_COUNT_SW_MAX) | ||
4736 | return -ENOENT; | ||
4737 | |||
4738 | if (!event->parent) { | ||
4739 | int err; | ||
4740 | |||
4741 | err = swevent_hlist_get(event); | ||
4742 | if (err) | ||
4743 | return err; | ||
4744 | |||
4745 | atomic_inc(&perf_swevent_enabled[event_id]); | ||
4746 | event->destroy = sw_perf_event_destroy; | ||
4747 | } | ||
4748 | |||
4749 | return 0; | ||
4750 | } | ||
4751 | |||
4752 | static struct pmu perf_swevent = { | ||
4753 | .task_ctx_nr = perf_sw_context, | ||
4600 | 4754 | ||
4601 | static const struct pmu perf_ops_tracepoint = { | 4755 | .event_init = perf_swevent_init, |
4602 | .enable = perf_trace_enable, | 4756 | .add = perf_swevent_add, |
4603 | .disable = perf_trace_disable, | 4757 | .del = perf_swevent_del, |
4604 | .start = perf_swevent_int, | 4758 | .start = perf_swevent_start, |
4605 | .stop = perf_swevent_void, | 4759 | .stop = perf_swevent_stop, |
4606 | .read = perf_swevent_read, | 4760 | .read = perf_swevent_read, |
4607 | .unthrottle = perf_swevent_void, | ||
4608 | }; | 4761 | }; |
4609 | 4762 | ||
4763 | #ifdef CONFIG_EVENT_TRACING | ||
4764 | |||
4610 | static int perf_tp_filter_match(struct perf_event *event, | 4765 | static int perf_tp_filter_match(struct perf_event *event, |
4611 | struct perf_sample_data *data) | 4766 | struct perf_sample_data *data) |
4612 | { | 4767 | { |
@@ -4650,7 +4805,7 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, | |||
4650 | 4805 | ||
4651 | hlist_for_each_entry_rcu(event, node, head, hlist_entry) { | 4806 | hlist_for_each_entry_rcu(event, node, head, hlist_entry) { |
4652 | if (perf_tp_event_match(event, &data, regs)) | 4807 | if (perf_tp_event_match(event, &data, regs)) |
4653 | perf_swevent_add(event, count, 1, &data, regs); | 4808 | perf_swevent_event(event, count, 1, &data, regs); |
4654 | } | 4809 | } |
4655 | 4810 | ||
4656 | perf_swevent_put_recursion_context(rctx); | 4811 | perf_swevent_put_recursion_context(rctx); |
@@ -4662,10 +4817,13 @@ static void tp_perf_event_destroy(struct perf_event *event) | |||
4662 | perf_trace_destroy(event); | 4817 | perf_trace_destroy(event); |
4663 | } | 4818 | } |
4664 | 4819 | ||
4665 | static const struct pmu *tp_perf_event_init(struct perf_event *event) | 4820 | static int perf_tp_event_init(struct perf_event *event) |
4666 | { | 4821 | { |
4667 | int err; | 4822 | int err; |
4668 | 4823 | ||
4824 | if (event->attr.type != PERF_TYPE_TRACEPOINT) | ||
4825 | return -ENOENT; | ||
4826 | |||
4669 | /* | 4827 | /* |
4670 | * Raw tracepoint data is a severe data leak, only allow root to | 4828 | * Raw tracepoint data is a severe data leak, only allow root to |
4671 | * have these. | 4829 | * have these. |
@@ -4673,15 +4831,31 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event) | |||
4673 | if ((event->attr.sample_type & PERF_SAMPLE_RAW) && | 4831 | if ((event->attr.sample_type & PERF_SAMPLE_RAW) && |
4674 | perf_paranoid_tracepoint_raw() && | 4832 | perf_paranoid_tracepoint_raw() && |
4675 | !capable(CAP_SYS_ADMIN)) | 4833 | !capable(CAP_SYS_ADMIN)) |
4676 | return ERR_PTR(-EPERM); | 4834 | return -EPERM; |
4677 | 4835 | ||
4678 | err = perf_trace_init(event); | 4836 | err = perf_trace_init(event); |
4679 | if (err) | 4837 | if (err) |
4680 | return NULL; | 4838 | return err; |
4681 | 4839 | ||
4682 | event->destroy = tp_perf_event_destroy; | 4840 | event->destroy = tp_perf_event_destroy; |
4683 | 4841 | ||
4684 | return &perf_ops_tracepoint; | 4842 | return 0; |
4843 | } | ||
4844 | |||
4845 | static struct pmu perf_tracepoint = { | ||
4846 | .task_ctx_nr = perf_sw_context, | ||
4847 | |||
4848 | .event_init = perf_tp_event_init, | ||
4849 | .add = perf_trace_add, | ||
4850 | .del = perf_trace_del, | ||
4851 | .start = perf_swevent_start, | ||
4852 | .stop = perf_swevent_stop, | ||
4853 | .read = perf_swevent_read, | ||
4854 | }; | ||
4855 | |||
4856 | static inline void perf_tp_register(void) | ||
4857 | { | ||
4858 | perf_pmu_register(&perf_tracepoint); | ||
4685 | } | 4859 | } |
4686 | 4860 | ||
4687 | static int perf_event_set_filter(struct perf_event *event, void __user *arg) | 4861 | static int perf_event_set_filter(struct perf_event *event, void __user *arg) |
@@ -4709,9 +4883,8 @@ static void perf_event_free_filter(struct perf_event *event) | |||
4709 | 4883 | ||
4710 | #else | 4884 | #else |
4711 | 4885 | ||
4712 | static const struct pmu *tp_perf_event_init(struct perf_event *event) | 4886 | static inline void perf_tp_register(void) |
4713 | { | 4887 | { |
4714 | return NULL; | ||
4715 | } | 4888 | } |
4716 | 4889 | ||
4717 | static int perf_event_set_filter(struct perf_event *event, void __user *arg) | 4890 | static int perf_event_set_filter(struct perf_event *event, void __user *arg) |
@@ -4726,105 +4899,389 @@ static void perf_event_free_filter(struct perf_event *event) | |||
4726 | #endif /* CONFIG_EVENT_TRACING */ | 4899 | #endif /* CONFIG_EVENT_TRACING */ |
4727 | 4900 | ||
4728 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 4901 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
4729 | static void bp_perf_event_destroy(struct perf_event *event) | 4902 | void perf_bp_event(struct perf_event *bp, void *data) |
4730 | { | 4903 | { |
4731 | release_bp_slot(event); | 4904 | struct perf_sample_data sample; |
4905 | struct pt_regs *regs = data; | ||
4906 | |||
4907 | perf_sample_data_init(&sample, bp->attr.bp_addr); | ||
4908 | |||
4909 | if (!bp->hw.state && !perf_exclude_event(bp, regs)) | ||
4910 | perf_swevent_event(bp, 1, 1, &sample, regs); | ||
4732 | } | 4911 | } |
4912 | #endif | ||
4733 | 4913 | ||
4734 | static const struct pmu *bp_perf_event_init(struct perf_event *bp) | 4914 | /* |
4915 | * hrtimer based swevent callback | ||
4916 | */ | ||
4917 | |||
4918 | static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) | ||
4735 | { | 4919 | { |
4736 | int err; | 4920 | enum hrtimer_restart ret = HRTIMER_RESTART; |
4921 | struct perf_sample_data data; | ||
4922 | struct pt_regs *regs; | ||
4923 | struct perf_event *event; | ||
4924 | u64 period; | ||
4737 | 4925 | ||
4738 | err = register_perf_hw_breakpoint(bp); | 4926 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); |
4739 | if (err) | 4927 | event->pmu->read(event); |
4740 | return ERR_PTR(err); | ||
4741 | 4928 | ||
4742 | bp->destroy = bp_perf_event_destroy; | 4929 | perf_sample_data_init(&data, 0); |
4930 | data.period = event->hw.last_period; | ||
4931 | regs = get_irq_regs(); | ||
4932 | |||
4933 | if (regs && !perf_exclude_event(event, regs)) { | ||
4934 | if (!(event->attr.exclude_idle && current->pid == 0)) | ||
4935 | if (perf_event_overflow(event, 0, &data, regs)) | ||
4936 | ret = HRTIMER_NORESTART; | ||
4937 | } | ||
4743 | 4938 | ||
4744 | return &perf_ops_bp; | 4939 | period = max_t(u64, 10000, event->hw.sample_period); |
4940 | hrtimer_forward_now(hrtimer, ns_to_ktime(period)); | ||
4941 | |||
4942 | return ret; | ||
4745 | } | 4943 | } |
4746 | 4944 | ||
4747 | void perf_bp_event(struct perf_event *bp, void *data) | 4945 | static void perf_swevent_start_hrtimer(struct perf_event *event) |
4748 | { | 4946 | { |
4749 | struct perf_sample_data sample; | 4947 | struct hw_perf_event *hwc = &event->hw; |
4750 | struct pt_regs *regs = data; | ||
4751 | 4948 | ||
4752 | perf_sample_data_init(&sample, bp->attr.bp_addr); | 4949 | hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
4950 | hwc->hrtimer.function = perf_swevent_hrtimer; | ||
4951 | if (hwc->sample_period) { | ||
4952 | s64 period = local64_read(&hwc->period_left); | ||
4953 | |||
4954 | if (period) { | ||
4955 | if (period < 0) | ||
4956 | period = 10000; | ||
4753 | 4957 | ||
4754 | if (!perf_exclude_event(bp, regs)) | 4958 | local64_set(&hwc->period_left, 0); |
4755 | perf_swevent_add(bp, 1, 1, &sample, regs); | 4959 | } else { |
4960 | period = max_t(u64, 10000, hwc->sample_period); | ||
4961 | } | ||
4962 | __hrtimer_start_range_ns(&hwc->hrtimer, | ||
4963 | ns_to_ktime(period), 0, | ||
4964 | HRTIMER_MODE_REL_PINNED, 0); | ||
4965 | } | ||
4756 | } | 4966 | } |
4757 | #else | 4967 | |
4758 | static const struct pmu *bp_perf_event_init(struct perf_event *bp) | 4968 | static void perf_swevent_cancel_hrtimer(struct perf_event *event) |
4759 | { | 4969 | { |
4760 | return NULL; | 4970 | struct hw_perf_event *hwc = &event->hw; |
4971 | |||
4972 | if (hwc->sample_period) { | ||
4973 | ktime_t remaining = hrtimer_get_remaining(&hwc->hrtimer); | ||
4974 | local64_set(&hwc->period_left, ktime_to_ns(remaining)); | ||
4975 | |||
4976 | hrtimer_cancel(&hwc->hrtimer); | ||
4977 | } | ||
4761 | } | 4978 | } |
4762 | 4979 | ||
4763 | void perf_bp_event(struct perf_event *bp, void *regs) | 4980 | /* |
4981 | * Software event: cpu wall time clock | ||
4982 | */ | ||
4983 | |||
4984 | static void cpu_clock_event_update(struct perf_event *event) | ||
4764 | { | 4985 | { |
4986 | s64 prev; | ||
4987 | u64 now; | ||
4988 | |||
4989 | now = local_clock(); | ||
4990 | prev = local64_xchg(&event->hw.prev_count, now); | ||
4991 | local64_add(now - prev, &event->count); | ||
4765 | } | 4992 | } |
4766 | #endif | ||
4767 | 4993 | ||
4768 | atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX]; | 4994 | static void cpu_clock_event_start(struct perf_event *event, int flags) |
4995 | { | ||
4996 | local64_set(&event->hw.prev_count, local_clock()); | ||
4997 | perf_swevent_start_hrtimer(event); | ||
4998 | } | ||
4769 | 4999 | ||
4770 | static void sw_perf_event_destroy(struct perf_event *event) | 5000 | static void cpu_clock_event_stop(struct perf_event *event, int flags) |
4771 | { | 5001 | { |
4772 | u64 event_id = event->attr.config; | 5002 | perf_swevent_cancel_hrtimer(event); |
5003 | cpu_clock_event_update(event); | ||
5004 | } | ||
4773 | 5005 | ||
4774 | WARN_ON(event->parent); | 5006 | static int cpu_clock_event_add(struct perf_event *event, int flags) |
5007 | { | ||
5008 | if (flags & PERF_EF_START) | ||
5009 | cpu_clock_event_start(event, flags); | ||
4775 | 5010 | ||
4776 | atomic_dec(&perf_swevent_enabled[event_id]); | 5011 | return 0; |
4777 | swevent_hlist_put(event); | ||
4778 | } | 5012 | } |
4779 | 5013 | ||
4780 | static const struct pmu *sw_perf_event_init(struct perf_event *event) | 5014 | static void cpu_clock_event_del(struct perf_event *event, int flags) |
4781 | { | 5015 | { |
4782 | const struct pmu *pmu = NULL; | 5016 | cpu_clock_event_stop(event, flags); |
4783 | u64 event_id = event->attr.config; | 5017 | } |
5018 | |||
5019 | static void cpu_clock_event_read(struct perf_event *event) | ||
5020 | { | ||
5021 | cpu_clock_event_update(event); | ||
5022 | } | ||
5023 | |||
5024 | static int cpu_clock_event_init(struct perf_event *event) | ||
5025 | { | ||
5026 | if (event->attr.type != PERF_TYPE_SOFTWARE) | ||
5027 | return -ENOENT; | ||
5028 | |||
5029 | if (event->attr.config != PERF_COUNT_SW_CPU_CLOCK) | ||
5030 | return -ENOENT; | ||
4784 | 5031 | ||
5032 | return 0; | ||
5033 | } | ||
5034 | |||
5035 | static struct pmu perf_cpu_clock = { | ||
5036 | .task_ctx_nr = perf_sw_context, | ||
5037 | |||
5038 | .event_init = cpu_clock_event_init, | ||
5039 | .add = cpu_clock_event_add, | ||
5040 | .del = cpu_clock_event_del, | ||
5041 | .start = cpu_clock_event_start, | ||
5042 | .stop = cpu_clock_event_stop, | ||
5043 | .read = cpu_clock_event_read, | ||
5044 | }; | ||
5045 | |||
5046 | /* | ||
5047 | * Software event: task time clock | ||
5048 | */ | ||
5049 | |||
5050 | static void task_clock_event_update(struct perf_event *event, u64 now) | ||
5051 | { | ||
5052 | u64 prev; | ||
5053 | s64 delta; | ||
5054 | |||
5055 | prev = local64_xchg(&event->hw.prev_count, now); | ||
5056 | delta = now - prev; | ||
5057 | local64_add(delta, &event->count); | ||
5058 | } | ||
5059 | |||
5060 | static void task_clock_event_start(struct perf_event *event, int flags) | ||
5061 | { | ||
5062 | local64_set(&event->hw.prev_count, event->ctx->time); | ||
5063 | perf_swevent_start_hrtimer(event); | ||
5064 | } | ||
5065 | |||
5066 | static void task_clock_event_stop(struct perf_event *event, int flags) | ||
5067 | { | ||
5068 | perf_swevent_cancel_hrtimer(event); | ||
5069 | task_clock_event_update(event, event->ctx->time); | ||
5070 | } | ||
5071 | |||
5072 | static int task_clock_event_add(struct perf_event *event, int flags) | ||
5073 | { | ||
5074 | if (flags & PERF_EF_START) | ||
5075 | task_clock_event_start(event, flags); | ||
5076 | |||
5077 | return 0; | ||
5078 | } | ||
5079 | |||
5080 | static void task_clock_event_del(struct perf_event *event, int flags) | ||
5081 | { | ||
5082 | task_clock_event_stop(event, PERF_EF_UPDATE); | ||
5083 | } | ||
5084 | |||
5085 | static void task_clock_event_read(struct perf_event *event) | ||
5086 | { | ||
5087 | u64 time; | ||
5088 | |||
5089 | if (!in_nmi()) { | ||
5090 | update_context_time(event->ctx); | ||
5091 | time = event->ctx->time; | ||
5092 | } else { | ||
5093 | u64 now = perf_clock(); | ||
5094 | u64 delta = now - event->ctx->timestamp; | ||
5095 | time = event->ctx->time + delta; | ||
5096 | } | ||
5097 | |||
5098 | task_clock_event_update(event, time); | ||
5099 | } | ||
5100 | |||
5101 | static int task_clock_event_init(struct perf_event *event) | ||
5102 | { | ||
5103 | if (event->attr.type != PERF_TYPE_SOFTWARE) | ||
5104 | return -ENOENT; | ||
5105 | |||
5106 | if (event->attr.config != PERF_COUNT_SW_TASK_CLOCK) | ||
5107 | return -ENOENT; | ||
5108 | |||
5109 | return 0; | ||
5110 | } | ||
5111 | |||
5112 | static struct pmu perf_task_clock = { | ||
5113 | .task_ctx_nr = perf_sw_context, | ||
5114 | |||
5115 | .event_init = task_clock_event_init, | ||
5116 | .add = task_clock_event_add, | ||
5117 | .del = task_clock_event_del, | ||
5118 | .start = task_clock_event_start, | ||
5119 | .stop = task_clock_event_stop, | ||
5120 | .read = task_clock_event_read, | ||
5121 | }; | ||
5122 | |||
5123 | static void perf_pmu_nop_void(struct pmu *pmu) | ||
5124 | { | ||
5125 | } | ||
5126 | |||
5127 | static int perf_pmu_nop_int(struct pmu *pmu) | ||
5128 | { | ||
5129 | return 0; | ||
5130 | } | ||
5131 | |||
5132 | static void perf_pmu_start_txn(struct pmu *pmu) | ||
5133 | { | ||
5134 | perf_pmu_disable(pmu); | ||
5135 | } | ||
5136 | |||
5137 | static int perf_pmu_commit_txn(struct pmu *pmu) | ||
5138 | { | ||
5139 | perf_pmu_enable(pmu); | ||
5140 | return 0; | ||
5141 | } | ||
5142 | |||
5143 | static void perf_pmu_cancel_txn(struct pmu *pmu) | ||
5144 | { | ||
5145 | perf_pmu_enable(pmu); | ||
5146 | } | ||
5147 | |||
5148 | /* | ||
5149 | * Ensures all contexts with the same task_ctx_nr have the same | ||
5150 | * pmu_cpu_context too. | ||
5151 | */ | ||
5152 | static void *find_pmu_context(int ctxn) | ||
5153 | { | ||
5154 | struct pmu *pmu; | ||
5155 | |||
5156 | if (ctxn < 0) | ||
5157 | return NULL; | ||
5158 | |||
5159 | list_for_each_entry(pmu, &pmus, entry) { | ||
5160 | if (pmu->task_ctx_nr == ctxn) | ||
5161 | return pmu->pmu_cpu_context; | ||
5162 | } | ||
5163 | |||
5164 | return NULL; | ||
5165 | } | ||
5166 | |||
5167 | static void free_pmu_context(void * __percpu cpu_context) | ||
5168 | { | ||
5169 | struct pmu *pmu; | ||
5170 | |||
5171 | mutex_lock(&pmus_lock); | ||
4785 | /* | 5172 | /* |
4786 | * Software events (currently) can't in general distinguish | 5173 | * Like a real lame refcount. |
4787 | * between user, kernel and hypervisor events. | ||
4788 | * However, context switches and cpu migrations are considered | ||
4789 | * to be kernel events, and page faults are never hypervisor | ||
4790 | * events. | ||
4791 | */ | 5174 | */ |
4792 | switch (event_id) { | 5175 | list_for_each_entry(pmu, &pmus, entry) { |
4793 | case PERF_COUNT_SW_CPU_CLOCK: | 5176 | if (pmu->pmu_cpu_context == cpu_context) |
4794 | pmu = &perf_ops_cpu_clock; | 5177 | goto out; |
5178 | } | ||
4795 | 5179 | ||
4796 | break; | 5180 | free_percpu(cpu_context); |
4797 | case PERF_COUNT_SW_TASK_CLOCK: | 5181 | out: |
4798 | /* | 5182 | mutex_unlock(&pmus_lock); |
4799 | * If the user instantiates this as a per-cpu event, | 5183 | } |
4800 | * use the cpu_clock event instead. | ||
4801 | */ | ||
4802 | if (event->ctx->task) | ||
4803 | pmu = &perf_ops_task_clock; | ||
4804 | else | ||
4805 | pmu = &perf_ops_cpu_clock; | ||
4806 | 5184 | ||
4807 | break; | 5185 | int perf_pmu_register(struct pmu *pmu) |
4808 | case PERF_COUNT_SW_PAGE_FAULTS: | 5186 | { |
4809 | case PERF_COUNT_SW_PAGE_FAULTS_MIN: | 5187 | int cpu, ret; |
4810 | case PERF_COUNT_SW_PAGE_FAULTS_MAJ: | ||
4811 | case PERF_COUNT_SW_CONTEXT_SWITCHES: | ||
4812 | case PERF_COUNT_SW_CPU_MIGRATIONS: | ||
4813 | case PERF_COUNT_SW_ALIGNMENT_FAULTS: | ||
4814 | case PERF_COUNT_SW_EMULATION_FAULTS: | ||
4815 | if (!event->parent) { | ||
4816 | int err; | ||
4817 | |||
4818 | err = swevent_hlist_get(event); | ||
4819 | if (err) | ||
4820 | return ERR_PTR(err); | ||
4821 | 5188 | ||
4822 | atomic_inc(&perf_swevent_enabled[event_id]); | 5189 | mutex_lock(&pmus_lock); |
4823 | event->destroy = sw_perf_event_destroy; | 5190 | ret = -ENOMEM; |
5191 | pmu->pmu_disable_count = alloc_percpu(int); | ||
5192 | if (!pmu->pmu_disable_count) | ||
5193 | goto unlock; | ||
5194 | |||
5195 | pmu->pmu_cpu_context = find_pmu_context(pmu->task_ctx_nr); | ||
5196 | if (pmu->pmu_cpu_context) | ||
5197 | goto got_cpu_context; | ||
5198 | |||
5199 | pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context); | ||
5200 | if (!pmu->pmu_cpu_context) | ||
5201 | goto free_pdc; | ||
5202 | |||
5203 | for_each_possible_cpu(cpu) { | ||
5204 | struct perf_cpu_context *cpuctx; | ||
5205 | |||
5206 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); | ||
5207 | __perf_event_init_context(&cpuctx->ctx); | ||
5208 | cpuctx->ctx.type = cpu_context; | ||
5209 | cpuctx->ctx.pmu = pmu; | ||
5210 | cpuctx->jiffies_interval = 1; | ||
5211 | INIT_LIST_HEAD(&cpuctx->rotation_list); | ||
5212 | } | ||
5213 | |||
5214 | got_cpu_context: | ||
5215 | if (!pmu->start_txn) { | ||
5216 | if (pmu->pmu_enable) { | ||
5217 | /* | ||
5218 | * If we have pmu_enable/pmu_disable calls, install | ||
5219 | * transaction stubs that use that to try and batch | ||
5220 | * hardware accesses. | ||
5221 | */ | ||
5222 | pmu->start_txn = perf_pmu_start_txn; | ||
5223 | pmu->commit_txn = perf_pmu_commit_txn; | ||
5224 | pmu->cancel_txn = perf_pmu_cancel_txn; | ||
5225 | } else { | ||
5226 | pmu->start_txn = perf_pmu_nop_void; | ||
5227 | pmu->commit_txn = perf_pmu_nop_int; | ||
5228 | pmu->cancel_txn = perf_pmu_nop_void; | ||
5229 | } | ||
5230 | } | ||
5231 | |||
5232 | if (!pmu->pmu_enable) { | ||
5233 | pmu->pmu_enable = perf_pmu_nop_void; | ||
5234 | pmu->pmu_disable = perf_pmu_nop_void; | ||
5235 | } | ||
5236 | |||
5237 | list_add_rcu(&pmu->entry, &pmus); | ||
5238 | ret = 0; | ||
5239 | unlock: | ||
5240 | mutex_unlock(&pmus_lock); | ||
5241 | |||
5242 | return ret; | ||
5243 | |||
5244 | free_pdc: | ||
5245 | free_percpu(pmu->pmu_disable_count); | ||
5246 | goto unlock; | ||
5247 | } | ||
5248 | |||
5249 | void perf_pmu_unregister(struct pmu *pmu) | ||
5250 | { | ||
5251 | mutex_lock(&pmus_lock); | ||
5252 | list_del_rcu(&pmu->entry); | ||
5253 | mutex_unlock(&pmus_lock); | ||
5254 | |||
5255 | /* | ||
5256 | * We dereference the pmu list under both SRCU and regular RCU, so | ||
5257 | * synchronize against both of those. | ||
5258 | */ | ||
5259 | synchronize_srcu(&pmus_srcu); | ||
5260 | synchronize_rcu(); | ||
5261 | |||
5262 | free_percpu(pmu->pmu_disable_count); | ||
5263 | free_pmu_context(pmu->pmu_cpu_context); | ||
5264 | } | ||
5265 | |||
5266 | struct pmu *perf_init_event(struct perf_event *event) | ||
5267 | { | ||
5268 | struct pmu *pmu = NULL; | ||
5269 | int idx; | ||
5270 | |||
5271 | idx = srcu_read_lock(&pmus_srcu); | ||
5272 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
5273 | int ret = pmu->event_init(event); | ||
5274 | if (!ret) | ||
5275 | goto unlock; | ||
5276 | |||
5277 | if (ret != -ENOENT) { | ||
5278 | pmu = ERR_PTR(ret); | ||
5279 | goto unlock; | ||
4824 | } | 5280 | } |
4825 | pmu = &perf_ops_generic; | ||
4826 | break; | ||
4827 | } | 5281 | } |
5282 | pmu = ERR_PTR(-ENOENT); | ||
5283 | unlock: | ||
5284 | srcu_read_unlock(&pmus_srcu, idx); | ||
4828 | 5285 | ||
4829 | return pmu; | 5286 | return pmu; |
4830 | } | 5287 | } |
@@ -4833,20 +5290,17 @@ static const struct pmu *sw_perf_event_init(struct perf_event *event) | |||
4833 | * Allocate and initialize a event structure | 5290 | * Allocate and initialize a event structure |
4834 | */ | 5291 | */ |
4835 | static struct perf_event * | 5292 | static struct perf_event * |
4836 | perf_event_alloc(struct perf_event_attr *attr, | 5293 | perf_event_alloc(struct perf_event_attr *attr, int cpu, |
4837 | int cpu, | ||
4838 | struct perf_event_context *ctx, | ||
4839 | struct perf_event *group_leader, | 5294 | struct perf_event *group_leader, |
4840 | struct perf_event *parent_event, | 5295 | struct perf_event *parent_event, |
4841 | perf_overflow_handler_t overflow_handler, | 5296 | perf_overflow_handler_t overflow_handler) |
4842 | gfp_t gfpflags) | ||
4843 | { | 5297 | { |
4844 | const struct pmu *pmu; | 5298 | struct pmu *pmu; |
4845 | struct perf_event *event; | 5299 | struct perf_event *event; |
4846 | struct hw_perf_event *hwc; | 5300 | struct hw_perf_event *hwc; |
4847 | long err; | 5301 | long err; |
4848 | 5302 | ||
4849 | event = kzalloc(sizeof(*event), gfpflags); | 5303 | event = kzalloc(sizeof(*event), GFP_KERNEL); |
4850 | if (!event) | 5304 | if (!event) |
4851 | return ERR_PTR(-ENOMEM); | 5305 | return ERR_PTR(-ENOMEM); |
4852 | 5306 | ||
@@ -4871,7 +5325,6 @@ perf_event_alloc(struct perf_event_attr *attr, | |||
4871 | event->attr = *attr; | 5325 | event->attr = *attr; |
4872 | event->group_leader = group_leader; | 5326 | event->group_leader = group_leader; |
4873 | event->pmu = NULL; | 5327 | event->pmu = NULL; |
4874 | event->ctx = ctx; | ||
4875 | event->oncpu = -1; | 5328 | event->oncpu = -1; |
4876 | 5329 | ||
4877 | event->parent = parent_event; | 5330 | event->parent = parent_event; |
@@ -4905,29 +5358,8 @@ perf_event_alloc(struct perf_event_attr *attr, | |||
4905 | if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) | 5358 | if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) |
4906 | goto done; | 5359 | goto done; |
4907 | 5360 | ||
4908 | switch (attr->type) { | 5361 | pmu = perf_init_event(event); |
4909 | case PERF_TYPE_RAW: | ||
4910 | case PERF_TYPE_HARDWARE: | ||
4911 | case PERF_TYPE_HW_CACHE: | ||
4912 | pmu = hw_perf_event_init(event); | ||
4913 | break; | ||
4914 | 5362 | ||
4915 | case PERF_TYPE_SOFTWARE: | ||
4916 | pmu = sw_perf_event_init(event); | ||
4917 | break; | ||
4918 | |||
4919 | case PERF_TYPE_TRACEPOINT: | ||
4920 | pmu = tp_perf_event_init(event); | ||
4921 | break; | ||
4922 | |||
4923 | case PERF_TYPE_BREAKPOINT: | ||
4924 | pmu = bp_perf_event_init(event); | ||
4925 | break; | ||
4926 | |||
4927 | |||
4928 | default: | ||
4929 | break; | ||
4930 | } | ||
4931 | done: | 5363 | done: |
4932 | err = 0; | 5364 | err = 0; |
4933 | if (!pmu) | 5365 | if (!pmu) |
@@ -4952,6 +5384,13 @@ done: | |||
4952 | atomic_inc(&nr_comm_events); | 5384 | atomic_inc(&nr_comm_events); |
4953 | if (event->attr.task) | 5385 | if (event->attr.task) |
4954 | atomic_inc(&nr_task_events); | 5386 | atomic_inc(&nr_task_events); |
5387 | if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { | ||
5388 | err = get_callchain_buffers(); | ||
5389 | if (err) { | ||
5390 | free_event(event); | ||
5391 | return ERR_PTR(err); | ||
5392 | } | ||
5393 | } | ||
4955 | } | 5394 | } |
4956 | 5395 | ||
4957 | return event; | 5396 | return event; |
@@ -5099,12 +5538,16 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5099 | struct perf_event_attr __user *, attr_uptr, | 5538 | struct perf_event_attr __user *, attr_uptr, |
5100 | pid_t, pid, int, cpu, int, group_fd, unsigned long, flags) | 5539 | pid_t, pid, int, cpu, int, group_fd, unsigned long, flags) |
5101 | { | 5540 | { |
5102 | struct perf_event *event, *group_leader = NULL, *output_event = NULL; | 5541 | struct perf_event *group_leader = NULL, *output_event = NULL; |
5542 | struct perf_event *event, *sibling; | ||
5103 | struct perf_event_attr attr; | 5543 | struct perf_event_attr attr; |
5104 | struct perf_event_context *ctx; | 5544 | struct perf_event_context *ctx; |
5105 | struct file *event_file = NULL; | 5545 | struct file *event_file = NULL; |
5106 | struct file *group_file = NULL; | 5546 | struct file *group_file = NULL; |
5547 | struct task_struct *task = NULL; | ||
5548 | struct pmu *pmu; | ||
5107 | int event_fd; | 5549 | int event_fd; |
5550 | int move_group = 0; | ||
5108 | int fput_needed = 0; | 5551 | int fput_needed = 0; |
5109 | int err; | 5552 | int err; |
5110 | 5553 | ||
@@ -5130,20 +5573,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5130 | if (event_fd < 0) | 5573 | if (event_fd < 0) |
5131 | return event_fd; | 5574 | return event_fd; |
5132 | 5575 | ||
5133 | /* | ||
5134 | * Get the target context (task or percpu): | ||
5135 | */ | ||
5136 | ctx = find_get_context(pid, cpu); | ||
5137 | if (IS_ERR(ctx)) { | ||
5138 | err = PTR_ERR(ctx); | ||
5139 | goto err_fd; | ||
5140 | } | ||
5141 | |||
5142 | if (group_fd != -1) { | 5576 | if (group_fd != -1) { |
5143 | group_leader = perf_fget_light(group_fd, &fput_needed); | 5577 | group_leader = perf_fget_light(group_fd, &fput_needed); |
5144 | if (IS_ERR(group_leader)) { | 5578 | if (IS_ERR(group_leader)) { |
5145 | err = PTR_ERR(group_leader); | 5579 | err = PTR_ERR(group_leader); |
5146 | goto err_put_context; | 5580 | goto err_fd; |
5147 | } | 5581 | } |
5148 | group_file = group_leader->filp; | 5582 | group_file = group_leader->filp; |
5149 | if (flags & PERF_FLAG_FD_OUTPUT) | 5583 | if (flags & PERF_FLAG_FD_OUTPUT) |
@@ -5152,6 +5586,58 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5152 | group_leader = NULL; | 5586 | group_leader = NULL; |
5153 | } | 5587 | } |
5154 | 5588 | ||
5589 | event = perf_event_alloc(&attr, cpu, group_leader, NULL, NULL); | ||
5590 | if (IS_ERR(event)) { | ||
5591 | err = PTR_ERR(event); | ||
5592 | goto err_fd; | ||
5593 | } | ||
5594 | |||
5595 | /* | ||
5596 | * Special case software events and allow them to be part of | ||
5597 | * any hardware group. | ||
5598 | */ | ||
5599 | pmu = event->pmu; | ||
5600 | |||
5601 | if (group_leader && | ||
5602 | (is_software_event(event) != is_software_event(group_leader))) { | ||
5603 | if (is_software_event(event)) { | ||
5604 | /* | ||
5605 | * If event and group_leader are not both a software | ||
5606 | * event, and event is, then group leader is not. | ||
5607 | * | ||
5608 | * Allow the addition of software events to !software | ||
5609 | * groups, this is safe because software events never | ||
5610 | * fail to schedule. | ||
5611 | */ | ||
5612 | pmu = group_leader->pmu; | ||
5613 | } else if (is_software_event(group_leader) && | ||
5614 | (group_leader->group_flags & PERF_GROUP_SOFTWARE)) { | ||
5615 | /* | ||
5616 | * In case the group is a pure software group, and we | ||
5617 | * try to add a hardware event, move the whole group to | ||
5618 | * the hardware context. | ||
5619 | */ | ||
5620 | move_group = 1; | ||
5621 | } | ||
5622 | } | ||
5623 | |||
5624 | if (pid != -1) { | ||
5625 | task = find_lively_task_by_vpid(pid); | ||
5626 | if (IS_ERR(task)) { | ||
5627 | err = PTR_ERR(task); | ||
5628 | goto err_group_fd; | ||
5629 | } | ||
5630 | } | ||
5631 | |||
5632 | /* | ||
5633 | * Get the target context (task or percpu): | ||
5634 | */ | ||
5635 | ctx = find_get_context(pmu, task, cpu); | ||
5636 | if (IS_ERR(ctx)) { | ||
5637 | err = PTR_ERR(ctx); | ||
5638 | goto err_group_fd; | ||
5639 | } | ||
5640 | |||
5155 | /* | 5641 | /* |
5156 | * Look up the group leader (we will attach this event to it): | 5642 | * Look up the group leader (we will attach this event to it): |
5157 | */ | 5643 | */ |
@@ -5163,42 +5649,66 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5163 | * becoming part of another group-sibling): | 5649 | * becoming part of another group-sibling): |
5164 | */ | 5650 | */ |
5165 | if (group_leader->group_leader != group_leader) | 5651 | if (group_leader->group_leader != group_leader) |
5166 | goto err_put_context; | 5652 | goto err_context; |
5167 | /* | 5653 | /* |
5168 | * Do not allow to attach to a group in a different | 5654 | * Do not allow to attach to a group in a different |
5169 | * task or CPU context: | 5655 | * task or CPU context: |
5170 | */ | 5656 | */ |
5171 | if (group_leader->ctx != ctx) | 5657 | if (move_group) { |
5172 | goto err_put_context; | 5658 | if (group_leader->ctx->type != ctx->type) |
5659 | goto err_context; | ||
5660 | } else { | ||
5661 | if (group_leader->ctx != ctx) | ||
5662 | goto err_context; | ||
5663 | } | ||
5664 | |||
5173 | /* | 5665 | /* |
5174 | * Only a group leader can be exclusive or pinned | 5666 | * Only a group leader can be exclusive or pinned |
5175 | */ | 5667 | */ |
5176 | if (attr.exclusive || attr.pinned) | 5668 | if (attr.exclusive || attr.pinned) |
5177 | goto err_put_context; | 5669 | goto err_context; |
5178 | } | ||
5179 | |||
5180 | event = perf_event_alloc(&attr, cpu, ctx, group_leader, | ||
5181 | NULL, NULL, GFP_KERNEL); | ||
5182 | if (IS_ERR(event)) { | ||
5183 | err = PTR_ERR(event); | ||
5184 | goto err_put_context; | ||
5185 | } | 5670 | } |
5186 | 5671 | ||
5187 | if (output_event) { | 5672 | if (output_event) { |
5188 | err = perf_event_set_output(event, output_event); | 5673 | err = perf_event_set_output(event, output_event); |
5189 | if (err) | 5674 | if (err) |
5190 | goto err_free_put_context; | 5675 | goto err_context; |
5191 | } | 5676 | } |
5192 | 5677 | ||
5193 | event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR); | 5678 | event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR); |
5194 | if (IS_ERR(event_file)) { | 5679 | if (IS_ERR(event_file)) { |
5195 | err = PTR_ERR(event_file); | 5680 | err = PTR_ERR(event_file); |
5196 | goto err_free_put_context; | 5681 | goto err_context; |
5682 | } | ||
5683 | |||
5684 | if (move_group) { | ||
5685 | struct perf_event_context *gctx = group_leader->ctx; | ||
5686 | |||
5687 | mutex_lock(&gctx->mutex); | ||
5688 | perf_event_remove_from_context(group_leader); | ||
5689 | list_for_each_entry(sibling, &group_leader->sibling_list, | ||
5690 | group_entry) { | ||
5691 | perf_event_remove_from_context(sibling); | ||
5692 | put_ctx(gctx); | ||
5693 | } | ||
5694 | mutex_unlock(&gctx->mutex); | ||
5695 | put_ctx(gctx); | ||
5197 | } | 5696 | } |
5198 | 5697 | ||
5199 | event->filp = event_file; | 5698 | event->filp = event_file; |
5200 | WARN_ON_ONCE(ctx->parent_ctx); | 5699 | WARN_ON_ONCE(ctx->parent_ctx); |
5201 | mutex_lock(&ctx->mutex); | 5700 | mutex_lock(&ctx->mutex); |
5701 | |||
5702 | if (move_group) { | ||
5703 | perf_install_in_context(ctx, group_leader, cpu); | ||
5704 | get_ctx(ctx); | ||
5705 | list_for_each_entry(sibling, &group_leader->sibling_list, | ||
5706 | group_entry) { | ||
5707 | perf_install_in_context(ctx, sibling, cpu); | ||
5708 | get_ctx(ctx); | ||
5709 | } | ||
5710 | } | ||
5711 | |||
5202 | perf_install_in_context(ctx, event, cpu); | 5712 | perf_install_in_context(ctx, event, cpu); |
5203 | ++ctx->generation; | 5713 | ++ctx->generation; |
5204 | mutex_unlock(&ctx->mutex); | 5714 | mutex_unlock(&ctx->mutex); |
@@ -5219,11 +5729,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5219 | fd_install(event_fd, event_file); | 5729 | fd_install(event_fd, event_file); |
5220 | return event_fd; | 5730 | return event_fd; |
5221 | 5731 | ||
5222 | err_free_put_context: | 5732 | err_context: |
5223 | free_event(event); | ||
5224 | err_put_context: | ||
5225 | fput_light(group_file, fput_needed); | ||
5226 | put_ctx(ctx); | 5733 | put_ctx(ctx); |
5734 | err_group_fd: | ||
5735 | fput_light(group_file, fput_needed); | ||
5736 | free_event(event); | ||
5227 | err_fd: | 5737 | err_fd: |
5228 | put_unused_fd(event_fd); | 5738 | put_unused_fd(event_fd); |
5229 | return err; | 5739 | return err; |
@@ -5234,32 +5744,31 @@ err_fd: | |||
5234 | * | 5744 | * |
5235 | * @attr: attributes of the counter to create | 5745 | * @attr: attributes of the counter to create |
5236 | * @cpu: cpu in which the counter is bound | 5746 | * @cpu: cpu in which the counter is bound |
5237 | * @pid: task to profile | 5747 | * @task: task to profile (NULL for percpu) |
5238 | */ | 5748 | */ |
5239 | struct perf_event * | 5749 | struct perf_event * |
5240 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | 5750 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, |
5241 | pid_t pid, | 5751 | struct task_struct *task, |
5242 | perf_overflow_handler_t overflow_handler) | 5752 | perf_overflow_handler_t overflow_handler) |
5243 | { | 5753 | { |
5244 | struct perf_event *event; | ||
5245 | struct perf_event_context *ctx; | 5754 | struct perf_event_context *ctx; |
5755 | struct perf_event *event; | ||
5246 | int err; | 5756 | int err; |
5247 | 5757 | ||
5248 | /* | 5758 | /* |
5249 | * Get the target context (task or percpu): | 5759 | * Get the target context (task or percpu): |
5250 | */ | 5760 | */ |
5251 | 5761 | ||
5252 | ctx = find_get_context(pid, cpu); | 5762 | event = perf_event_alloc(attr, cpu, NULL, NULL, overflow_handler); |
5253 | if (IS_ERR(ctx)) { | ||
5254 | err = PTR_ERR(ctx); | ||
5255 | goto err_exit; | ||
5256 | } | ||
5257 | |||
5258 | event = perf_event_alloc(attr, cpu, ctx, NULL, | ||
5259 | NULL, overflow_handler, GFP_KERNEL); | ||
5260 | if (IS_ERR(event)) { | 5763 | if (IS_ERR(event)) { |
5261 | err = PTR_ERR(event); | 5764 | err = PTR_ERR(event); |
5262 | goto err_put_context; | 5765 | goto err; |
5766 | } | ||
5767 | |||
5768 | ctx = find_get_context(event->pmu, task, cpu); | ||
5769 | if (IS_ERR(ctx)) { | ||
5770 | err = PTR_ERR(ctx); | ||
5771 | goto err_free; | ||
5263 | } | 5772 | } |
5264 | 5773 | ||
5265 | event->filp = NULL; | 5774 | event->filp = NULL; |
@@ -5277,112 +5786,13 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
5277 | 5786 | ||
5278 | return event; | 5787 | return event; |
5279 | 5788 | ||
5280 | err_put_context: | 5789 | err_free: |
5281 | put_ctx(ctx); | 5790 | free_event(event); |
5282 | err_exit: | 5791 | err: |
5283 | return ERR_PTR(err); | 5792 | return ERR_PTR(err); |
5284 | } | 5793 | } |
5285 | EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); | 5794 | EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); |
5286 | 5795 | ||
5287 | /* | ||
5288 | * inherit a event from parent task to child task: | ||
5289 | */ | ||
5290 | static struct perf_event * | ||
5291 | inherit_event(struct perf_event *parent_event, | ||
5292 | struct task_struct *parent, | ||
5293 | struct perf_event_context *parent_ctx, | ||
5294 | struct task_struct *child, | ||
5295 | struct perf_event *group_leader, | ||
5296 | struct perf_event_context *child_ctx) | ||
5297 | { | ||
5298 | struct perf_event *child_event; | ||
5299 | |||
5300 | /* | ||
5301 | * Instead of creating recursive hierarchies of events, | ||
5302 | * we link inherited events back to the original parent, | ||
5303 | * which has a filp for sure, which we use as the reference | ||
5304 | * count: | ||
5305 | */ | ||
5306 | if (parent_event->parent) | ||
5307 | parent_event = parent_event->parent; | ||
5308 | |||
5309 | child_event = perf_event_alloc(&parent_event->attr, | ||
5310 | parent_event->cpu, child_ctx, | ||
5311 | group_leader, parent_event, | ||
5312 | NULL, GFP_KERNEL); | ||
5313 | if (IS_ERR(child_event)) | ||
5314 | return child_event; | ||
5315 | get_ctx(child_ctx); | ||
5316 | |||
5317 | /* | ||
5318 | * Make the child state follow the state of the parent event, | ||
5319 | * not its attr.disabled bit. We hold the parent's mutex, | ||
5320 | * so we won't race with perf_event_{en, dis}able_family. | ||
5321 | */ | ||
5322 | if (parent_event->state >= PERF_EVENT_STATE_INACTIVE) | ||
5323 | child_event->state = PERF_EVENT_STATE_INACTIVE; | ||
5324 | else | ||
5325 | child_event->state = PERF_EVENT_STATE_OFF; | ||
5326 | |||
5327 | if (parent_event->attr.freq) { | ||
5328 | u64 sample_period = parent_event->hw.sample_period; | ||
5329 | struct hw_perf_event *hwc = &child_event->hw; | ||
5330 | |||
5331 | hwc->sample_period = sample_period; | ||
5332 | hwc->last_period = sample_period; | ||
5333 | |||
5334 | local64_set(&hwc->period_left, sample_period); | ||
5335 | } | ||
5336 | |||
5337 | child_event->overflow_handler = parent_event->overflow_handler; | ||
5338 | |||
5339 | /* | ||
5340 | * Link it up in the child's context: | ||
5341 | */ | ||
5342 | add_event_to_ctx(child_event, child_ctx); | ||
5343 | |||
5344 | /* | ||
5345 | * Get a reference to the parent filp - we will fput it | ||
5346 | * when the child event exits. This is safe to do because | ||
5347 | * we are in the parent and we know that the filp still | ||
5348 | * exists and has a nonzero count: | ||
5349 | */ | ||
5350 | atomic_long_inc(&parent_event->filp->f_count); | ||
5351 | |||
5352 | /* | ||
5353 | * Link this into the parent event's child list | ||
5354 | */ | ||
5355 | WARN_ON_ONCE(parent_event->ctx->parent_ctx); | ||
5356 | mutex_lock(&parent_event->child_mutex); | ||
5357 | list_add_tail(&child_event->child_list, &parent_event->child_list); | ||
5358 | mutex_unlock(&parent_event->child_mutex); | ||
5359 | |||
5360 | return child_event; | ||
5361 | } | ||
5362 | |||
5363 | static int inherit_group(struct perf_event *parent_event, | ||
5364 | struct task_struct *parent, | ||
5365 | struct perf_event_context *parent_ctx, | ||
5366 | struct task_struct *child, | ||
5367 | struct perf_event_context *child_ctx) | ||
5368 | { | ||
5369 | struct perf_event *leader; | ||
5370 | struct perf_event *sub; | ||
5371 | struct perf_event *child_ctr; | ||
5372 | |||
5373 | leader = inherit_event(parent_event, parent, parent_ctx, | ||
5374 | child, NULL, child_ctx); | ||
5375 | if (IS_ERR(leader)) | ||
5376 | return PTR_ERR(leader); | ||
5377 | list_for_each_entry(sub, &parent_event->sibling_list, group_entry) { | ||
5378 | child_ctr = inherit_event(sub, parent, parent_ctx, | ||
5379 | child, leader, child_ctx); | ||
5380 | if (IS_ERR(child_ctr)) | ||
5381 | return PTR_ERR(child_ctr); | ||
5382 | } | ||
5383 | return 0; | ||
5384 | } | ||
5385 | |||
5386 | static void sync_child_event(struct perf_event *child_event, | 5796 | static void sync_child_event(struct perf_event *child_event, |
5387 | struct task_struct *child) | 5797 | struct task_struct *child) |
5388 | { | 5798 | { |
@@ -5439,16 +5849,13 @@ __perf_event_exit_task(struct perf_event *child_event, | |||
5439 | } | 5849 | } |
5440 | } | 5850 | } |
5441 | 5851 | ||
5442 | /* | 5852 | static void perf_event_exit_task_context(struct task_struct *child, int ctxn) |
5443 | * When a child task exits, feed back event values to parent events. | ||
5444 | */ | ||
5445 | void perf_event_exit_task(struct task_struct *child) | ||
5446 | { | 5853 | { |
5447 | struct perf_event *child_event, *tmp; | 5854 | struct perf_event *child_event, *tmp; |
5448 | struct perf_event_context *child_ctx; | 5855 | struct perf_event_context *child_ctx; |
5449 | unsigned long flags; | 5856 | unsigned long flags; |
5450 | 5857 | ||
5451 | if (likely(!child->perf_event_ctxp)) { | 5858 | if (likely(!child->perf_event_ctxp[ctxn])) { |
5452 | perf_event_task(child, NULL, 0); | 5859 | perf_event_task(child, NULL, 0); |
5453 | return; | 5860 | return; |
5454 | } | 5861 | } |
@@ -5460,7 +5867,7 @@ void perf_event_exit_task(struct task_struct *child) | |||
5460 | * scheduled, so we are now safe from rescheduling changing | 5867 | * scheduled, so we are now safe from rescheduling changing |
5461 | * our context. | 5868 | * our context. |
5462 | */ | 5869 | */ |
5463 | child_ctx = child->perf_event_ctxp; | 5870 | child_ctx = child->perf_event_ctxp[ctxn]; |
5464 | __perf_event_task_sched_out(child_ctx); | 5871 | __perf_event_task_sched_out(child_ctx); |
5465 | 5872 | ||
5466 | /* | 5873 | /* |
@@ -5469,7 +5876,7 @@ void perf_event_exit_task(struct task_struct *child) | |||
5469 | * incremented the context's refcount before we do put_ctx below. | 5876 | * incremented the context's refcount before we do put_ctx below. |
5470 | */ | 5877 | */ |
5471 | raw_spin_lock(&child_ctx->lock); | 5878 | raw_spin_lock(&child_ctx->lock); |
5472 | child->perf_event_ctxp = NULL; | 5879 | child->perf_event_ctxp[ctxn] = NULL; |
5473 | /* | 5880 | /* |
5474 | * If this context is a clone; unclone it so it can't get | 5881 | * If this context is a clone; unclone it so it can't get |
5475 | * swapped to another process while we're removing all | 5882 | * swapped to another process while we're removing all |
@@ -5522,6 +5929,17 @@ again: | |||
5522 | put_ctx(child_ctx); | 5929 | put_ctx(child_ctx); |
5523 | } | 5930 | } |
5524 | 5931 | ||
5932 | /* | ||
5933 | * When a child task exits, feed back event values to parent events. | ||
5934 | */ | ||
5935 | void perf_event_exit_task(struct task_struct *child) | ||
5936 | { | ||
5937 | int ctxn; | ||
5938 | |||
5939 | for_each_task_context_nr(ctxn) | ||
5940 | perf_event_exit_task_context(child, ctxn); | ||
5941 | } | ||
5942 | |||
5525 | static void perf_free_event(struct perf_event *event, | 5943 | static void perf_free_event(struct perf_event *event, |
5526 | struct perf_event_context *ctx) | 5944 | struct perf_event_context *ctx) |
5527 | { | 5945 | { |
@@ -5543,48 +5961,165 @@ static void perf_free_event(struct perf_event *event, | |||
5543 | 5961 | ||
5544 | /* | 5962 | /* |
5545 | * free an unexposed, unused context as created by inheritance by | 5963 | * free an unexposed, unused context as created by inheritance by |
5546 | * init_task below, used by fork() in case of fail. | 5964 | * perf_event_init_task below, used by fork() in case of fail. |
5547 | */ | 5965 | */ |
5548 | void perf_event_free_task(struct task_struct *task) | 5966 | void perf_event_free_task(struct task_struct *task) |
5549 | { | 5967 | { |
5550 | struct perf_event_context *ctx = task->perf_event_ctxp; | 5968 | struct perf_event_context *ctx; |
5551 | struct perf_event *event, *tmp; | 5969 | struct perf_event *event, *tmp; |
5970 | int ctxn; | ||
5552 | 5971 | ||
5553 | if (!ctx) | 5972 | for_each_task_context_nr(ctxn) { |
5554 | return; | 5973 | ctx = task->perf_event_ctxp[ctxn]; |
5974 | if (!ctx) | ||
5975 | continue; | ||
5555 | 5976 | ||
5556 | mutex_lock(&ctx->mutex); | 5977 | mutex_lock(&ctx->mutex); |
5557 | again: | 5978 | again: |
5558 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry) | 5979 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, |
5559 | perf_free_event(event, ctx); | 5980 | group_entry) |
5981 | perf_free_event(event, ctx); | ||
5560 | 5982 | ||
5561 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, | 5983 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, |
5562 | group_entry) | 5984 | group_entry) |
5563 | perf_free_event(event, ctx); | 5985 | perf_free_event(event, ctx); |
5564 | 5986 | ||
5565 | if (!list_empty(&ctx->pinned_groups) || | 5987 | if (!list_empty(&ctx->pinned_groups) || |
5566 | !list_empty(&ctx->flexible_groups)) | 5988 | !list_empty(&ctx->flexible_groups)) |
5567 | goto again; | 5989 | goto again; |
5568 | 5990 | ||
5569 | mutex_unlock(&ctx->mutex); | 5991 | mutex_unlock(&ctx->mutex); |
5570 | 5992 | ||
5571 | put_ctx(ctx); | 5993 | put_ctx(ctx); |
5994 | } | ||
5995 | } | ||
5996 | |||
5997 | void perf_event_delayed_put(struct task_struct *task) | ||
5998 | { | ||
5999 | int ctxn; | ||
6000 | |||
6001 | for_each_task_context_nr(ctxn) | ||
6002 | WARN_ON_ONCE(task->perf_event_ctxp[ctxn]); | ||
6003 | } | ||
6004 | |||
6005 | /* | ||
6006 | * inherit a event from parent task to child task: | ||
6007 | */ | ||
6008 | static struct perf_event * | ||
6009 | inherit_event(struct perf_event *parent_event, | ||
6010 | struct task_struct *parent, | ||
6011 | struct perf_event_context *parent_ctx, | ||
6012 | struct task_struct *child, | ||
6013 | struct perf_event *group_leader, | ||
6014 | struct perf_event_context *child_ctx) | ||
6015 | { | ||
6016 | struct perf_event *child_event; | ||
6017 | unsigned long flags; | ||
6018 | |||
6019 | /* | ||
6020 | * Instead of creating recursive hierarchies of events, | ||
6021 | * we link inherited events back to the original parent, | ||
6022 | * which has a filp for sure, which we use as the reference | ||
6023 | * count: | ||
6024 | */ | ||
6025 | if (parent_event->parent) | ||
6026 | parent_event = parent_event->parent; | ||
6027 | |||
6028 | child_event = perf_event_alloc(&parent_event->attr, | ||
6029 | parent_event->cpu, | ||
6030 | group_leader, parent_event, | ||
6031 | NULL); | ||
6032 | if (IS_ERR(child_event)) | ||
6033 | return child_event; | ||
6034 | get_ctx(child_ctx); | ||
6035 | |||
6036 | /* | ||
6037 | * Make the child state follow the state of the parent event, | ||
6038 | * not its attr.disabled bit. We hold the parent's mutex, | ||
6039 | * so we won't race with perf_event_{en, dis}able_family. | ||
6040 | */ | ||
6041 | if (parent_event->state >= PERF_EVENT_STATE_INACTIVE) | ||
6042 | child_event->state = PERF_EVENT_STATE_INACTIVE; | ||
6043 | else | ||
6044 | child_event->state = PERF_EVENT_STATE_OFF; | ||
6045 | |||
6046 | if (parent_event->attr.freq) { | ||
6047 | u64 sample_period = parent_event->hw.sample_period; | ||
6048 | struct hw_perf_event *hwc = &child_event->hw; | ||
6049 | |||
6050 | hwc->sample_period = sample_period; | ||
6051 | hwc->last_period = sample_period; | ||
6052 | |||
6053 | local64_set(&hwc->period_left, sample_period); | ||
6054 | } | ||
6055 | |||
6056 | child_event->ctx = child_ctx; | ||
6057 | child_event->overflow_handler = parent_event->overflow_handler; | ||
6058 | |||
6059 | /* | ||
6060 | * Link it up in the child's context: | ||
6061 | */ | ||
6062 | raw_spin_lock_irqsave(&child_ctx->lock, flags); | ||
6063 | add_event_to_ctx(child_event, child_ctx); | ||
6064 | raw_spin_unlock_irqrestore(&child_ctx->lock, flags); | ||
6065 | |||
6066 | /* | ||
6067 | * Get a reference to the parent filp - we will fput it | ||
6068 | * when the child event exits. This is safe to do because | ||
6069 | * we are in the parent and we know that the filp still | ||
6070 | * exists and has a nonzero count: | ||
6071 | */ | ||
6072 | atomic_long_inc(&parent_event->filp->f_count); | ||
6073 | |||
6074 | /* | ||
6075 | * Link this into the parent event's child list | ||
6076 | */ | ||
6077 | WARN_ON_ONCE(parent_event->ctx->parent_ctx); | ||
6078 | mutex_lock(&parent_event->child_mutex); | ||
6079 | list_add_tail(&child_event->child_list, &parent_event->child_list); | ||
6080 | mutex_unlock(&parent_event->child_mutex); | ||
6081 | |||
6082 | return child_event; | ||
6083 | } | ||
6084 | |||
6085 | static int inherit_group(struct perf_event *parent_event, | ||
6086 | struct task_struct *parent, | ||
6087 | struct perf_event_context *parent_ctx, | ||
6088 | struct task_struct *child, | ||
6089 | struct perf_event_context *child_ctx) | ||
6090 | { | ||
6091 | struct perf_event *leader; | ||
6092 | struct perf_event *sub; | ||
6093 | struct perf_event *child_ctr; | ||
6094 | |||
6095 | leader = inherit_event(parent_event, parent, parent_ctx, | ||
6096 | child, NULL, child_ctx); | ||
6097 | if (IS_ERR(leader)) | ||
6098 | return PTR_ERR(leader); | ||
6099 | list_for_each_entry(sub, &parent_event->sibling_list, group_entry) { | ||
6100 | child_ctr = inherit_event(sub, parent, parent_ctx, | ||
6101 | child, leader, child_ctx); | ||
6102 | if (IS_ERR(child_ctr)) | ||
6103 | return PTR_ERR(child_ctr); | ||
6104 | } | ||
6105 | return 0; | ||
5572 | } | 6106 | } |
5573 | 6107 | ||
5574 | static int | 6108 | static int |
5575 | inherit_task_group(struct perf_event *event, struct task_struct *parent, | 6109 | inherit_task_group(struct perf_event *event, struct task_struct *parent, |
5576 | struct perf_event_context *parent_ctx, | 6110 | struct perf_event_context *parent_ctx, |
5577 | struct task_struct *child, | 6111 | struct task_struct *child, int ctxn, |
5578 | int *inherited_all) | 6112 | int *inherited_all) |
5579 | { | 6113 | { |
5580 | int ret; | 6114 | int ret; |
5581 | struct perf_event_context *child_ctx = child->perf_event_ctxp; | 6115 | struct perf_event_context *child_ctx; |
5582 | 6116 | ||
5583 | if (!event->attr.inherit) { | 6117 | if (!event->attr.inherit) { |
5584 | *inherited_all = 0; | 6118 | *inherited_all = 0; |
5585 | return 0; | 6119 | return 0; |
5586 | } | 6120 | } |
5587 | 6121 | ||
6122 | child_ctx = child->perf_event_ctxp[ctxn]; | ||
5588 | if (!child_ctx) { | 6123 | if (!child_ctx) { |
5589 | /* | 6124 | /* |
5590 | * This is executed from the parent task context, so | 6125 | * This is executed from the parent task context, so |
@@ -5593,14 +6128,11 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, | |||
5593 | * child. | 6128 | * child. |
5594 | */ | 6129 | */ |
5595 | 6130 | ||
5596 | child_ctx = kzalloc(sizeof(struct perf_event_context), | 6131 | child_ctx = alloc_perf_context(event->pmu, child); |
5597 | GFP_KERNEL); | ||
5598 | if (!child_ctx) | 6132 | if (!child_ctx) |
5599 | return -ENOMEM; | 6133 | return -ENOMEM; |
5600 | 6134 | ||
5601 | __perf_event_init_context(child_ctx, child); | 6135 | child->perf_event_ctxp[ctxn] = child_ctx; |
5602 | child->perf_event_ctxp = child_ctx; | ||
5603 | get_task_struct(child); | ||
5604 | } | 6136 | } |
5605 | 6137 | ||
5606 | ret = inherit_group(event, parent, parent_ctx, | 6138 | ret = inherit_group(event, parent, parent_ctx, |
@@ -5612,11 +6144,10 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, | |||
5612 | return ret; | 6144 | return ret; |
5613 | } | 6145 | } |
5614 | 6146 | ||
5615 | |||
5616 | /* | 6147 | /* |
5617 | * Initialize the perf_event context in task_struct | 6148 | * Initialize the perf_event context in task_struct |
5618 | */ | 6149 | */ |
5619 | int perf_event_init_task(struct task_struct *child) | 6150 | int perf_event_init_context(struct task_struct *child, int ctxn) |
5620 | { | 6151 | { |
5621 | struct perf_event_context *child_ctx, *parent_ctx; | 6152 | struct perf_event_context *child_ctx, *parent_ctx; |
5622 | struct perf_event_context *cloned_ctx; | 6153 | struct perf_event_context *cloned_ctx; |
@@ -5625,19 +6156,19 @@ int perf_event_init_task(struct task_struct *child) | |||
5625 | int inherited_all = 1; | 6156 | int inherited_all = 1; |
5626 | int ret = 0; | 6157 | int ret = 0; |
5627 | 6158 | ||
5628 | child->perf_event_ctxp = NULL; | 6159 | child->perf_event_ctxp[ctxn] = NULL; |
5629 | 6160 | ||
5630 | mutex_init(&child->perf_event_mutex); | 6161 | mutex_init(&child->perf_event_mutex); |
5631 | INIT_LIST_HEAD(&child->perf_event_list); | 6162 | INIT_LIST_HEAD(&child->perf_event_list); |
5632 | 6163 | ||
5633 | if (likely(!parent->perf_event_ctxp)) | 6164 | if (likely(!parent->perf_event_ctxp[ctxn])) |
5634 | return 0; | 6165 | return 0; |
5635 | 6166 | ||
5636 | /* | 6167 | /* |
5637 | * If the parent's context is a clone, pin it so it won't get | 6168 | * If the parent's context is a clone, pin it so it won't get |
5638 | * swapped under us. | 6169 | * swapped under us. |
5639 | */ | 6170 | */ |
5640 | parent_ctx = perf_pin_task_context(parent); | 6171 | parent_ctx = perf_pin_task_context(parent, ctxn); |
5641 | 6172 | ||
5642 | /* | 6173 | /* |
5643 | * No need to check if parent_ctx != NULL here; since we saw | 6174 | * No need to check if parent_ctx != NULL here; since we saw |
@@ -5657,20 +6188,20 @@ int perf_event_init_task(struct task_struct *child) | |||
5657 | * the list, not manipulating it: | 6188 | * the list, not manipulating it: |
5658 | */ | 6189 | */ |
5659 | list_for_each_entry(event, &parent_ctx->pinned_groups, group_entry) { | 6190 | list_for_each_entry(event, &parent_ctx->pinned_groups, group_entry) { |
5660 | ret = inherit_task_group(event, parent, parent_ctx, child, | 6191 | ret = inherit_task_group(event, parent, parent_ctx, |
5661 | &inherited_all); | 6192 | child, ctxn, &inherited_all); |
5662 | if (ret) | 6193 | if (ret) |
5663 | break; | 6194 | break; |
5664 | } | 6195 | } |
5665 | 6196 | ||
5666 | list_for_each_entry(event, &parent_ctx->flexible_groups, group_entry) { | 6197 | list_for_each_entry(event, &parent_ctx->flexible_groups, group_entry) { |
5667 | ret = inherit_task_group(event, parent, parent_ctx, child, | 6198 | ret = inherit_task_group(event, parent, parent_ctx, |
5668 | &inherited_all); | 6199 | child, ctxn, &inherited_all); |
5669 | if (ret) | 6200 | if (ret) |
5670 | break; | 6201 | break; |
5671 | } | 6202 | } |
5672 | 6203 | ||
5673 | child_ctx = child->perf_event_ctxp; | 6204 | child_ctx = child->perf_event_ctxp[ctxn]; |
5674 | 6205 | ||
5675 | if (child_ctx && inherited_all) { | 6206 | if (child_ctx && inherited_all) { |
5676 | /* | 6207 | /* |
@@ -5699,63 +6230,98 @@ int perf_event_init_task(struct task_struct *child) | |||
5699 | return ret; | 6230 | return ret; |
5700 | } | 6231 | } |
5701 | 6232 | ||
6233 | /* | ||
6234 | * Initialize the perf_event context in task_struct | ||
6235 | */ | ||
6236 | int perf_event_init_task(struct task_struct *child) | ||
6237 | { | ||
6238 | int ctxn, ret; | ||
6239 | |||
6240 | for_each_task_context_nr(ctxn) { | ||
6241 | ret = perf_event_init_context(child, ctxn); | ||
6242 | if (ret) | ||
6243 | return ret; | ||
6244 | } | ||
6245 | |||
6246 | return 0; | ||
6247 | } | ||
6248 | |||
5702 | static void __init perf_event_init_all_cpus(void) | 6249 | static void __init perf_event_init_all_cpus(void) |
5703 | { | 6250 | { |
6251 | struct swevent_htable *swhash; | ||
5704 | int cpu; | 6252 | int cpu; |
5705 | struct perf_cpu_context *cpuctx; | ||
5706 | 6253 | ||
5707 | for_each_possible_cpu(cpu) { | 6254 | for_each_possible_cpu(cpu) { |
5708 | cpuctx = &per_cpu(perf_cpu_context, cpu); | 6255 | swhash = &per_cpu(swevent_htable, cpu); |
5709 | mutex_init(&cpuctx->hlist_mutex); | 6256 | mutex_init(&swhash->hlist_mutex); |
5710 | __perf_event_init_context(&cpuctx->ctx, NULL); | 6257 | INIT_LIST_HEAD(&per_cpu(rotation_list, cpu)); |
5711 | } | 6258 | } |
5712 | } | 6259 | } |
5713 | 6260 | ||
5714 | static void __cpuinit perf_event_init_cpu(int cpu) | 6261 | static void __cpuinit perf_event_init_cpu(int cpu) |
5715 | { | 6262 | { |
5716 | struct perf_cpu_context *cpuctx; | 6263 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
5717 | |||
5718 | cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
5719 | |||
5720 | spin_lock(&perf_resource_lock); | ||
5721 | cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; | ||
5722 | spin_unlock(&perf_resource_lock); | ||
5723 | 6264 | ||
5724 | mutex_lock(&cpuctx->hlist_mutex); | 6265 | mutex_lock(&swhash->hlist_mutex); |
5725 | if (cpuctx->hlist_refcount > 0) { | 6266 | if (swhash->hlist_refcount > 0) { |
5726 | struct swevent_hlist *hlist; | 6267 | struct swevent_hlist *hlist; |
5727 | 6268 | ||
5728 | hlist = kzalloc(sizeof(*hlist), GFP_KERNEL); | 6269 | hlist = kzalloc_node(sizeof(*hlist), GFP_KERNEL, cpu_to_node(cpu)); |
5729 | WARN_ON_ONCE(!hlist); | 6270 | WARN_ON(!hlist); |
5730 | rcu_assign_pointer(cpuctx->swevent_hlist, hlist); | 6271 | rcu_assign_pointer(swhash->swevent_hlist, hlist); |
5731 | } | 6272 | } |
5732 | mutex_unlock(&cpuctx->hlist_mutex); | 6273 | mutex_unlock(&swhash->hlist_mutex); |
5733 | } | 6274 | } |
5734 | 6275 | ||
5735 | #ifdef CONFIG_HOTPLUG_CPU | 6276 | #ifdef CONFIG_HOTPLUG_CPU |
5736 | static void __perf_event_exit_cpu(void *info) | 6277 | static void perf_pmu_rotate_stop(struct pmu *pmu) |
5737 | { | 6278 | { |
5738 | struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); | 6279 | struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); |
5739 | struct perf_event_context *ctx = &cpuctx->ctx; | 6280 | |
6281 | WARN_ON(!irqs_disabled()); | ||
6282 | |||
6283 | list_del_init(&cpuctx->rotation_list); | ||
6284 | } | ||
6285 | |||
6286 | static void __perf_event_exit_context(void *__info) | ||
6287 | { | ||
6288 | struct perf_event_context *ctx = __info; | ||
5740 | struct perf_event *event, *tmp; | 6289 | struct perf_event *event, *tmp; |
5741 | 6290 | ||
6291 | perf_pmu_rotate_stop(ctx->pmu); | ||
6292 | |||
5742 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry) | 6293 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, group_entry) |
5743 | __perf_event_remove_from_context(event); | 6294 | __perf_event_remove_from_context(event); |
5744 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry) | 6295 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, group_entry) |
5745 | __perf_event_remove_from_context(event); | 6296 | __perf_event_remove_from_context(event); |
5746 | } | 6297 | } |
6298 | |||
6299 | static void perf_event_exit_cpu_context(int cpu) | ||
6300 | { | ||
6301 | struct perf_event_context *ctx; | ||
6302 | struct pmu *pmu; | ||
6303 | int idx; | ||
6304 | |||
6305 | idx = srcu_read_lock(&pmus_srcu); | ||
6306 | list_for_each_entry_rcu(pmu, &pmus, entry) { | ||
6307 | ctx = &per_cpu_ptr(pmu->pmu_cpu_context, cpu)->ctx; | ||
6308 | |||
6309 | mutex_lock(&ctx->mutex); | ||
6310 | smp_call_function_single(cpu, __perf_event_exit_context, ctx, 1); | ||
6311 | mutex_unlock(&ctx->mutex); | ||
6312 | } | ||
6313 | srcu_read_unlock(&pmus_srcu, idx); | ||
6314 | } | ||
6315 | |||
5747 | static void perf_event_exit_cpu(int cpu) | 6316 | static void perf_event_exit_cpu(int cpu) |
5748 | { | 6317 | { |
5749 | struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); | 6318 | struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); |
5750 | struct perf_event_context *ctx = &cpuctx->ctx; | ||
5751 | 6319 | ||
5752 | mutex_lock(&cpuctx->hlist_mutex); | 6320 | mutex_lock(&swhash->hlist_mutex); |
5753 | swevent_hlist_release(cpuctx); | 6321 | swevent_hlist_release(swhash); |
5754 | mutex_unlock(&cpuctx->hlist_mutex); | 6322 | mutex_unlock(&swhash->hlist_mutex); |
5755 | 6323 | ||
5756 | mutex_lock(&ctx->mutex); | 6324 | perf_event_exit_cpu_context(cpu); |
5757 | smp_call_function_single(cpu, __perf_event_exit_cpu, NULL, 1); | ||
5758 | mutex_unlock(&ctx->mutex); | ||
5759 | } | 6325 | } |
5760 | #else | 6326 | #else |
5761 | static inline void perf_event_exit_cpu(int cpu) { } | 6327 | static inline void perf_event_exit_cpu(int cpu) { } |
@@ -5785,118 +6351,13 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) | |||
5785 | return NOTIFY_OK; | 6351 | return NOTIFY_OK; |
5786 | } | 6352 | } |
5787 | 6353 | ||
5788 | /* | ||
5789 | * This has to have a higher priority than migration_notifier in sched.c. | ||
5790 | */ | ||
5791 | static struct notifier_block __cpuinitdata perf_cpu_nb = { | ||
5792 | .notifier_call = perf_cpu_notify, | ||
5793 | .priority = 20, | ||
5794 | }; | ||
5795 | |||
5796 | void __init perf_event_init(void) | 6354 | void __init perf_event_init(void) |
5797 | { | 6355 | { |
5798 | perf_event_init_all_cpus(); | 6356 | perf_event_init_all_cpus(); |
5799 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, | 6357 | init_srcu_struct(&pmus_srcu); |
5800 | (void *)(long)smp_processor_id()); | 6358 | perf_pmu_register(&perf_swevent); |
5801 | perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE, | 6359 | perf_pmu_register(&perf_cpu_clock); |
5802 | (void *)(long)smp_processor_id()); | 6360 | perf_pmu_register(&perf_task_clock); |
5803 | register_cpu_notifier(&perf_cpu_nb); | 6361 | perf_tp_register(); |
5804 | } | 6362 | perf_cpu_notifier(perf_cpu_notify); |
5805 | |||
5806 | static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, | ||
5807 | struct sysdev_class_attribute *attr, | ||
5808 | char *buf) | ||
5809 | { | ||
5810 | return sprintf(buf, "%d\n", perf_reserved_percpu); | ||
5811 | } | ||
5812 | |||
5813 | static ssize_t | ||
5814 | perf_set_reserve_percpu(struct sysdev_class *class, | ||
5815 | struct sysdev_class_attribute *attr, | ||
5816 | const char *buf, | ||
5817 | size_t count) | ||
5818 | { | ||
5819 | struct perf_cpu_context *cpuctx; | ||
5820 | unsigned long val; | ||
5821 | int err, cpu, mpt; | ||
5822 | |||
5823 | err = strict_strtoul(buf, 10, &val); | ||
5824 | if (err) | ||
5825 | return err; | ||
5826 | if (val > perf_max_events) | ||
5827 | return -EINVAL; | ||
5828 | |||
5829 | spin_lock(&perf_resource_lock); | ||
5830 | perf_reserved_percpu = val; | ||
5831 | for_each_online_cpu(cpu) { | ||
5832 | cpuctx = &per_cpu(perf_cpu_context, cpu); | ||
5833 | raw_spin_lock_irq(&cpuctx->ctx.lock); | ||
5834 | mpt = min(perf_max_events - cpuctx->ctx.nr_events, | ||
5835 | perf_max_events - perf_reserved_percpu); | ||
5836 | cpuctx->max_pertask = mpt; | ||
5837 | raw_spin_unlock_irq(&cpuctx->ctx.lock); | ||
5838 | } | ||
5839 | spin_unlock(&perf_resource_lock); | ||
5840 | |||
5841 | return count; | ||
5842 | } | ||
5843 | |||
5844 | static ssize_t perf_show_overcommit(struct sysdev_class *class, | ||
5845 | struct sysdev_class_attribute *attr, | ||
5846 | char *buf) | ||
5847 | { | ||
5848 | return sprintf(buf, "%d\n", perf_overcommit); | ||
5849 | } | ||
5850 | |||
5851 | static ssize_t | ||
5852 | perf_set_overcommit(struct sysdev_class *class, | ||
5853 | struct sysdev_class_attribute *attr, | ||
5854 | const char *buf, size_t count) | ||
5855 | { | ||
5856 | unsigned long val; | ||
5857 | int err; | ||
5858 | |||
5859 | err = strict_strtoul(buf, 10, &val); | ||
5860 | if (err) | ||
5861 | return err; | ||
5862 | if (val > 1) | ||
5863 | return -EINVAL; | ||
5864 | |||
5865 | spin_lock(&perf_resource_lock); | ||
5866 | perf_overcommit = val; | ||
5867 | spin_unlock(&perf_resource_lock); | ||
5868 | |||
5869 | return count; | ||
5870 | } | ||
5871 | |||
5872 | static SYSDEV_CLASS_ATTR( | ||
5873 | reserve_percpu, | ||
5874 | 0644, | ||
5875 | perf_show_reserve_percpu, | ||
5876 | perf_set_reserve_percpu | ||
5877 | ); | ||
5878 | |||
5879 | static SYSDEV_CLASS_ATTR( | ||
5880 | overcommit, | ||
5881 | 0644, | ||
5882 | perf_show_overcommit, | ||
5883 | perf_set_overcommit | ||
5884 | ); | ||
5885 | |||
5886 | static struct attribute *perfclass_attrs[] = { | ||
5887 | &attr_reserve_percpu.attr, | ||
5888 | &attr_overcommit.attr, | ||
5889 | NULL | ||
5890 | }; | ||
5891 | |||
5892 | static struct attribute_group perfclass_attr_group = { | ||
5893 | .attrs = perfclass_attrs, | ||
5894 | .name = "perf_events", | ||
5895 | }; | ||
5896 | |||
5897 | static int __init perf_event_sysfs_init(void) | ||
5898 | { | ||
5899 | return sysfs_create_group(&cpu_sysdev_class.kset.kobj, | ||
5900 | &perfclass_attr_group); | ||
5901 | } | 6363 | } |
5902 | device_initcall(perf_event_sysfs_init); | ||
diff --git a/kernel/sched.c b/kernel/sched.c index dc85ceb90832..c0d2067f3e0d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3584,7 +3584,7 @@ void scheduler_tick(void) | |||
3584 | curr->sched_class->task_tick(rq, curr, 0); | 3584 | curr->sched_class->task_tick(rq, curr, 0); |
3585 | raw_spin_unlock(&rq->lock); | 3585 | raw_spin_unlock(&rq->lock); |
3586 | 3586 | ||
3587 | perf_event_task_tick(curr); | 3587 | perf_event_task_tick(); |
3588 | 3588 | ||
3589 | #ifdef CONFIG_SMP | 3589 | #ifdef CONFIG_SMP |
3590 | rq->idle_at_tick = idle_cpu(cpu); | 3590 | rq->idle_at_tick = idle_cpu(cpu); |
diff --git a/kernel/smp.c b/kernel/smp.c index 75c970c715d3..ed6aacfcb7ef 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -365,9 +365,10 @@ call: | |||
365 | EXPORT_SYMBOL_GPL(smp_call_function_any); | 365 | EXPORT_SYMBOL_GPL(smp_call_function_any); |
366 | 366 | ||
367 | /** | 367 | /** |
368 | * __smp_call_function_single(): Run a function on another CPU | 368 | * __smp_call_function_single(): Run a function on a specific CPU |
369 | * @cpu: The CPU to run on. | 369 | * @cpu: The CPU to run on. |
370 | * @data: Pre-allocated and setup data structure | 370 | * @data: Pre-allocated and setup data structure |
371 | * @wait: If true, wait until function has completed on specified CPU. | ||
371 | * | 372 | * |
372 | * Like smp_call_function_single(), but allow caller to pass in a | 373 | * Like smp_call_function_single(), but allow caller to pass in a |
373 | * pre-allocated data structure. Useful for embedding @data inside | 374 | * pre-allocated data structure. Useful for embedding @data inside |
@@ -376,8 +377,10 @@ EXPORT_SYMBOL_GPL(smp_call_function_any); | |||
376 | void __smp_call_function_single(int cpu, struct call_single_data *data, | 377 | void __smp_call_function_single(int cpu, struct call_single_data *data, |
377 | int wait) | 378 | int wait) |
378 | { | 379 | { |
379 | csd_lock(data); | 380 | unsigned int this_cpu; |
381 | unsigned long flags; | ||
380 | 382 | ||
383 | this_cpu = get_cpu(); | ||
381 | /* | 384 | /* |
382 | * Can deadlock when called with interrupts disabled. | 385 | * Can deadlock when called with interrupts disabled. |
383 | * We allow cpu's that are not yet online though, as no one else can | 386 | * We allow cpu's that are not yet online though, as no one else can |
@@ -387,7 +390,15 @@ void __smp_call_function_single(int cpu, struct call_single_data *data, | |||
387 | WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() | 390 | WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() |
388 | && !oops_in_progress); | 391 | && !oops_in_progress); |
389 | 392 | ||
390 | generic_exec_single(cpu, data, wait); | 393 | if (cpu == this_cpu) { |
394 | local_irq_save(flags); | ||
395 | data->func(data->info); | ||
396 | local_irq_restore(flags); | ||
397 | } else { | ||
398 | csd_lock(data); | ||
399 | generic_exec_single(cpu, data, wait); | ||
400 | } | ||
401 | put_cpu(); | ||
391 | } | 402 | } |
392 | 403 | ||
393 | /** | 404 | /** |
diff --git a/kernel/test_kprobes.c b/kernel/test_kprobes.c index 4f104515a19b..f8b11a283171 100644 --- a/kernel/test_kprobes.c +++ b/kernel/test_kprobes.c | |||
@@ -115,7 +115,9 @@ static int test_kprobes(void) | |||
115 | int ret; | 115 | int ret; |
116 | struct kprobe *kps[2] = {&kp, &kp2}; | 116 | struct kprobe *kps[2] = {&kp, &kp2}; |
117 | 117 | ||
118 | kp.addr = 0; /* addr should be cleard for reusing kprobe. */ | 118 | /* addr and flags should be cleard for reusing kprobe. */ |
119 | kp.addr = NULL; | ||
120 | kp.flags = 0; | ||
119 | ret = register_kprobes(kps, 2); | 121 | ret = register_kprobes(kps, 2); |
120 | if (ret < 0) { | 122 | if (ret < 0) { |
121 | printk(KERN_ERR "Kprobe smoke test failed: " | 123 | printk(KERN_ERR "Kprobe smoke test failed: " |
@@ -210,7 +212,9 @@ static int test_jprobes(void) | |||
210 | int ret; | 212 | int ret; |
211 | struct jprobe *jps[2] = {&jp, &jp2}; | 213 | struct jprobe *jps[2] = {&jp, &jp2}; |
212 | 214 | ||
213 | jp.kp.addr = 0; /* addr should be cleard for reusing kprobe. */ | 215 | /* addr and flags should be cleard for reusing kprobe. */ |
216 | jp.kp.addr = NULL; | ||
217 | jp.kp.flags = 0; | ||
214 | ret = register_jprobes(jps, 2); | 218 | ret = register_jprobes(jps, 2); |
215 | if (ret < 0) { | 219 | if (ret < 0) { |
216 | printk(KERN_ERR "Kprobe smoke test failed: " | 220 | printk(KERN_ERR "Kprobe smoke test failed: " |
@@ -323,7 +327,9 @@ static int test_kretprobes(void) | |||
323 | int ret; | 327 | int ret; |
324 | struct kretprobe *rps[2] = {&rp, &rp2}; | 328 | struct kretprobe *rps[2] = {&rp, &rp2}; |
325 | 329 | ||
326 | rp.kp.addr = 0; /* addr should be cleard for reusing kprobe. */ | 330 | /* addr and flags should be cleard for reusing kprobe. */ |
331 | rp.kp.addr = NULL; | ||
332 | rp.kp.flags = 0; | ||
327 | ret = register_kretprobes(rps, 2); | 333 | ret = register_kretprobes(rps, 2); |
328 | if (ret < 0) { | 334 | if (ret < 0) { |
329 | printk(KERN_ERR "Kprobe smoke test failed: " | 335 | printk(KERN_ERR "Kprobe smoke test failed: " |
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 538501c6ea50..e550d2eda1df 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
@@ -49,6 +49,11 @@ config HAVE_SYSCALL_TRACEPOINTS | |||
49 | help | 49 | help |
50 | See Documentation/trace/ftrace-design.txt | 50 | See Documentation/trace/ftrace-design.txt |
51 | 51 | ||
52 | config HAVE_C_RECORDMCOUNT | ||
53 | bool | ||
54 | help | ||
55 | C version of recordmcount available? | ||
56 | |||
52 | config TRACER_MAX_TRACE | 57 | config TRACER_MAX_TRACE |
53 | bool | 58 | bool |
54 | 59 | ||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index fa7ece649fe1..65fb077ea79c 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -884,10 +884,8 @@ enum { | |||
884 | FTRACE_ENABLE_CALLS = (1 << 0), | 884 | FTRACE_ENABLE_CALLS = (1 << 0), |
885 | FTRACE_DISABLE_CALLS = (1 << 1), | 885 | FTRACE_DISABLE_CALLS = (1 << 1), |
886 | FTRACE_UPDATE_TRACE_FUNC = (1 << 2), | 886 | FTRACE_UPDATE_TRACE_FUNC = (1 << 2), |
887 | FTRACE_ENABLE_MCOUNT = (1 << 3), | 887 | FTRACE_START_FUNC_RET = (1 << 3), |
888 | FTRACE_DISABLE_MCOUNT = (1 << 4), | 888 | FTRACE_STOP_FUNC_RET = (1 << 4), |
889 | FTRACE_START_FUNC_RET = (1 << 5), | ||
890 | FTRACE_STOP_FUNC_RET = (1 << 6), | ||
891 | }; | 889 | }; |
892 | 890 | ||
893 | static int ftrace_filtered; | 891 | static int ftrace_filtered; |
@@ -1226,8 +1224,6 @@ static void ftrace_shutdown(int command) | |||
1226 | 1224 | ||
1227 | static void ftrace_startup_sysctl(void) | 1225 | static void ftrace_startup_sysctl(void) |
1228 | { | 1226 | { |
1229 | int command = FTRACE_ENABLE_MCOUNT; | ||
1230 | |||
1231 | if (unlikely(ftrace_disabled)) | 1227 | if (unlikely(ftrace_disabled)) |
1232 | return; | 1228 | return; |
1233 | 1229 | ||
@@ -1235,23 +1231,17 @@ static void ftrace_startup_sysctl(void) | |||
1235 | saved_ftrace_func = NULL; | 1231 | saved_ftrace_func = NULL; |
1236 | /* ftrace_start_up is true if we want ftrace running */ | 1232 | /* ftrace_start_up is true if we want ftrace running */ |
1237 | if (ftrace_start_up) | 1233 | if (ftrace_start_up) |
1238 | command |= FTRACE_ENABLE_CALLS; | 1234 | ftrace_run_update_code(FTRACE_ENABLE_CALLS); |
1239 | |||
1240 | ftrace_run_update_code(command); | ||
1241 | } | 1235 | } |
1242 | 1236 | ||
1243 | static void ftrace_shutdown_sysctl(void) | 1237 | static void ftrace_shutdown_sysctl(void) |
1244 | { | 1238 | { |
1245 | int command = FTRACE_DISABLE_MCOUNT; | ||
1246 | |||
1247 | if (unlikely(ftrace_disabled)) | 1239 | if (unlikely(ftrace_disabled)) |
1248 | return; | 1240 | return; |
1249 | 1241 | ||
1250 | /* ftrace_start_up is true if ftrace is running */ | 1242 | /* ftrace_start_up is true if ftrace is running */ |
1251 | if (ftrace_start_up) | 1243 | if (ftrace_start_up) |
1252 | command |= FTRACE_DISABLE_CALLS; | 1244 | ftrace_run_update_code(FTRACE_DISABLE_CALLS); |
1253 | |||
1254 | ftrace_run_update_code(command); | ||
1255 | } | 1245 | } |
1256 | 1246 | ||
1257 | static cycle_t ftrace_update_time; | 1247 | static cycle_t ftrace_update_time; |
@@ -1368,24 +1358,29 @@ enum { | |||
1368 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ | 1358 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ |
1369 | 1359 | ||
1370 | struct ftrace_iterator { | 1360 | struct ftrace_iterator { |
1371 | struct ftrace_page *pg; | 1361 | loff_t pos; |
1372 | int hidx; | 1362 | loff_t func_pos; |
1373 | int idx; | 1363 | struct ftrace_page *pg; |
1374 | unsigned flags; | 1364 | struct dyn_ftrace *func; |
1375 | struct trace_parser parser; | 1365 | struct ftrace_func_probe *probe; |
1366 | struct trace_parser parser; | ||
1367 | int hidx; | ||
1368 | int idx; | ||
1369 | unsigned flags; | ||
1376 | }; | 1370 | }; |
1377 | 1371 | ||
1378 | static void * | 1372 | static void * |
1379 | t_hash_next(struct seq_file *m, void *v, loff_t *pos) | 1373 | t_hash_next(struct seq_file *m, loff_t *pos) |
1380 | { | 1374 | { |
1381 | struct ftrace_iterator *iter = m->private; | 1375 | struct ftrace_iterator *iter = m->private; |
1382 | struct hlist_node *hnd = v; | 1376 | struct hlist_node *hnd = NULL; |
1383 | struct hlist_head *hhd; | 1377 | struct hlist_head *hhd; |
1384 | 1378 | ||
1385 | WARN_ON(!(iter->flags & FTRACE_ITER_HASH)); | ||
1386 | |||
1387 | (*pos)++; | 1379 | (*pos)++; |
1380 | iter->pos = *pos; | ||
1388 | 1381 | ||
1382 | if (iter->probe) | ||
1383 | hnd = &iter->probe->node; | ||
1389 | retry: | 1384 | retry: |
1390 | if (iter->hidx >= FTRACE_FUNC_HASHSIZE) | 1385 | if (iter->hidx >= FTRACE_FUNC_HASHSIZE) |
1391 | return NULL; | 1386 | return NULL; |
@@ -1408,7 +1403,12 @@ t_hash_next(struct seq_file *m, void *v, loff_t *pos) | |||
1408 | } | 1403 | } |
1409 | } | 1404 | } |
1410 | 1405 | ||
1411 | return hnd; | 1406 | if (WARN_ON_ONCE(!hnd)) |
1407 | return NULL; | ||
1408 | |||
1409 | iter->probe = hlist_entry(hnd, struct ftrace_func_probe, node); | ||
1410 | |||
1411 | return iter; | ||
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | static void *t_hash_start(struct seq_file *m, loff_t *pos) | 1414 | static void *t_hash_start(struct seq_file *m, loff_t *pos) |
@@ -1417,26 +1417,32 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos) | |||
1417 | void *p = NULL; | 1417 | void *p = NULL; |
1418 | loff_t l; | 1418 | loff_t l; |
1419 | 1419 | ||
1420 | if (!(iter->flags & FTRACE_ITER_HASH)) | 1420 | if (iter->func_pos > *pos) |
1421 | *pos = 0; | 1421 | return NULL; |
1422 | |||
1423 | iter->flags |= FTRACE_ITER_HASH; | ||
1424 | 1422 | ||
1425 | iter->hidx = 0; | 1423 | iter->hidx = 0; |
1426 | for (l = 0; l <= *pos; ) { | 1424 | for (l = 0; l <= (*pos - iter->func_pos); ) { |
1427 | p = t_hash_next(m, p, &l); | 1425 | p = t_hash_next(m, &l); |
1428 | if (!p) | 1426 | if (!p) |
1429 | break; | 1427 | break; |
1430 | } | 1428 | } |
1431 | return p; | 1429 | if (!p) |
1430 | return NULL; | ||
1431 | |||
1432 | /* Only set this if we have an item */ | ||
1433 | iter->flags |= FTRACE_ITER_HASH; | ||
1434 | |||
1435 | return iter; | ||
1432 | } | 1436 | } |
1433 | 1437 | ||
1434 | static int t_hash_show(struct seq_file *m, void *v) | 1438 | static int |
1439 | t_hash_show(struct seq_file *m, struct ftrace_iterator *iter) | ||
1435 | { | 1440 | { |
1436 | struct ftrace_func_probe *rec; | 1441 | struct ftrace_func_probe *rec; |
1437 | struct hlist_node *hnd = v; | ||
1438 | 1442 | ||
1439 | rec = hlist_entry(hnd, struct ftrace_func_probe, node); | 1443 | rec = iter->probe; |
1444 | if (WARN_ON_ONCE(!rec)) | ||
1445 | return -EIO; | ||
1440 | 1446 | ||
1441 | if (rec->ops->print) | 1447 | if (rec->ops->print) |
1442 | return rec->ops->print(m, rec->ip, rec->ops, rec->data); | 1448 | return rec->ops->print(m, rec->ip, rec->ops, rec->data); |
@@ -1457,12 +1463,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
1457 | struct dyn_ftrace *rec = NULL; | 1463 | struct dyn_ftrace *rec = NULL; |
1458 | 1464 | ||
1459 | if (iter->flags & FTRACE_ITER_HASH) | 1465 | if (iter->flags & FTRACE_ITER_HASH) |
1460 | return t_hash_next(m, v, pos); | 1466 | return t_hash_next(m, pos); |
1461 | 1467 | ||
1462 | (*pos)++; | 1468 | (*pos)++; |
1469 | iter->pos = *pos; | ||
1463 | 1470 | ||
1464 | if (iter->flags & FTRACE_ITER_PRINTALL) | 1471 | if (iter->flags & FTRACE_ITER_PRINTALL) |
1465 | return NULL; | 1472 | return t_hash_start(m, pos); |
1466 | 1473 | ||
1467 | retry: | 1474 | retry: |
1468 | if (iter->idx >= iter->pg->index) { | 1475 | if (iter->idx >= iter->pg->index) { |
@@ -1491,7 +1498,20 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
1491 | } | 1498 | } |
1492 | } | 1499 | } |
1493 | 1500 | ||
1494 | return rec; | 1501 | if (!rec) |
1502 | return t_hash_start(m, pos); | ||
1503 | |||
1504 | iter->func_pos = *pos; | ||
1505 | iter->func = rec; | ||
1506 | |||
1507 | return iter; | ||
1508 | } | ||
1509 | |||
1510 | static void reset_iter_read(struct ftrace_iterator *iter) | ||
1511 | { | ||
1512 | iter->pos = 0; | ||
1513 | iter->func_pos = 0; | ||
1514 | iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH); | ||
1495 | } | 1515 | } |
1496 | 1516 | ||
1497 | static void *t_start(struct seq_file *m, loff_t *pos) | 1517 | static void *t_start(struct seq_file *m, loff_t *pos) |
@@ -1502,6 +1522,12 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1502 | 1522 | ||
1503 | mutex_lock(&ftrace_lock); | 1523 | mutex_lock(&ftrace_lock); |
1504 | /* | 1524 | /* |
1525 | * If an lseek was done, then reset and start from beginning. | ||
1526 | */ | ||
1527 | if (*pos < iter->pos) | ||
1528 | reset_iter_read(iter); | ||
1529 | |||
1530 | /* | ||
1505 | * For set_ftrace_filter reading, if we have the filter | 1531 | * For set_ftrace_filter reading, if we have the filter |
1506 | * off, we can short cut and just print out that all | 1532 | * off, we can short cut and just print out that all |
1507 | * functions are enabled. | 1533 | * functions are enabled. |
@@ -1518,6 +1544,11 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1518 | if (iter->flags & FTRACE_ITER_HASH) | 1544 | if (iter->flags & FTRACE_ITER_HASH) |
1519 | return t_hash_start(m, pos); | 1545 | return t_hash_start(m, pos); |
1520 | 1546 | ||
1547 | /* | ||
1548 | * Unfortunately, we need to restart at ftrace_pages_start | ||
1549 | * every time we let go of the ftrace_mutex. This is because | ||
1550 | * those pointers can change without the lock. | ||
1551 | */ | ||
1521 | iter->pg = ftrace_pages_start; | 1552 | iter->pg = ftrace_pages_start; |
1522 | iter->idx = 0; | 1553 | iter->idx = 0; |
1523 | for (l = 0; l <= *pos; ) { | 1554 | for (l = 0; l <= *pos; ) { |
@@ -1526,10 +1557,14 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1526 | break; | 1557 | break; |
1527 | } | 1558 | } |
1528 | 1559 | ||
1529 | if (!p && iter->flags & FTRACE_ITER_FILTER) | 1560 | if (!p) { |
1530 | return t_hash_start(m, pos); | 1561 | if (iter->flags & FTRACE_ITER_FILTER) |
1562 | return t_hash_start(m, pos); | ||
1531 | 1563 | ||
1532 | return p; | 1564 | return NULL; |
1565 | } | ||
1566 | |||
1567 | return iter; | ||
1533 | } | 1568 | } |
1534 | 1569 | ||
1535 | static void t_stop(struct seq_file *m, void *p) | 1570 | static void t_stop(struct seq_file *m, void *p) |
@@ -1540,16 +1575,18 @@ static void t_stop(struct seq_file *m, void *p) | |||
1540 | static int t_show(struct seq_file *m, void *v) | 1575 | static int t_show(struct seq_file *m, void *v) |
1541 | { | 1576 | { |
1542 | struct ftrace_iterator *iter = m->private; | 1577 | struct ftrace_iterator *iter = m->private; |
1543 | struct dyn_ftrace *rec = v; | 1578 | struct dyn_ftrace *rec; |
1544 | 1579 | ||
1545 | if (iter->flags & FTRACE_ITER_HASH) | 1580 | if (iter->flags & FTRACE_ITER_HASH) |
1546 | return t_hash_show(m, v); | 1581 | return t_hash_show(m, iter); |
1547 | 1582 | ||
1548 | if (iter->flags & FTRACE_ITER_PRINTALL) { | 1583 | if (iter->flags & FTRACE_ITER_PRINTALL) { |
1549 | seq_printf(m, "#### all functions enabled ####\n"); | 1584 | seq_printf(m, "#### all functions enabled ####\n"); |
1550 | return 0; | 1585 | return 0; |
1551 | } | 1586 | } |
1552 | 1587 | ||
1588 | rec = iter->func; | ||
1589 | |||
1553 | if (!rec) | 1590 | if (!rec) |
1554 | return 0; | 1591 | return 0; |
1555 | 1592 | ||
@@ -2418,7 +2455,7 @@ static const struct file_operations ftrace_filter_fops = { | |||
2418 | .open = ftrace_filter_open, | 2455 | .open = ftrace_filter_open, |
2419 | .read = seq_read, | 2456 | .read = seq_read, |
2420 | .write = ftrace_filter_write, | 2457 | .write = ftrace_filter_write, |
2421 | .llseek = no_llseek, | 2458 | .llseek = ftrace_regex_lseek, |
2422 | .release = ftrace_filter_release, | 2459 | .release = ftrace_filter_release, |
2423 | }; | 2460 | }; |
2424 | 2461 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 492197e2f86c..4e2f03410377 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -2606,6 +2606,19 @@ void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu) | |||
2606 | } | 2606 | } |
2607 | EXPORT_SYMBOL_GPL(ring_buffer_record_enable_cpu); | 2607 | EXPORT_SYMBOL_GPL(ring_buffer_record_enable_cpu); |
2608 | 2608 | ||
2609 | /* | ||
2610 | * The total entries in the ring buffer is the running counter | ||
2611 | * of entries entered into the ring buffer, minus the sum of | ||
2612 | * the entries read from the ring buffer and the number of | ||
2613 | * entries that were overwritten. | ||
2614 | */ | ||
2615 | static inline unsigned long | ||
2616 | rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer) | ||
2617 | { | ||
2618 | return local_read(&cpu_buffer->entries) - | ||
2619 | (local_read(&cpu_buffer->overrun) + cpu_buffer->read); | ||
2620 | } | ||
2621 | |||
2609 | /** | 2622 | /** |
2610 | * ring_buffer_entries_cpu - get the number of entries in a cpu buffer | 2623 | * ring_buffer_entries_cpu - get the number of entries in a cpu buffer |
2611 | * @buffer: The ring buffer | 2624 | * @buffer: The ring buffer |
@@ -2614,16 +2627,13 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_enable_cpu); | |||
2614 | unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu) | 2627 | unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu) |
2615 | { | 2628 | { |
2616 | struct ring_buffer_per_cpu *cpu_buffer; | 2629 | struct ring_buffer_per_cpu *cpu_buffer; |
2617 | unsigned long ret; | ||
2618 | 2630 | ||
2619 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) | 2631 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
2620 | return 0; | 2632 | return 0; |
2621 | 2633 | ||
2622 | cpu_buffer = buffer->buffers[cpu]; | 2634 | cpu_buffer = buffer->buffers[cpu]; |
2623 | ret = (local_read(&cpu_buffer->entries) - local_read(&cpu_buffer->overrun)) | ||
2624 | - cpu_buffer->read; | ||
2625 | 2635 | ||
2626 | return ret; | 2636 | return rb_num_of_entries(cpu_buffer); |
2627 | } | 2637 | } |
2628 | EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu); | 2638 | EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu); |
2629 | 2639 | ||
@@ -2684,8 +2694,7 @@ unsigned long ring_buffer_entries(struct ring_buffer *buffer) | |||
2684 | /* if you care about this being correct, lock the buffer */ | 2694 | /* if you care about this being correct, lock the buffer */ |
2685 | for_each_buffer_cpu(buffer, cpu) { | 2695 | for_each_buffer_cpu(buffer, cpu) { |
2686 | cpu_buffer = buffer->buffers[cpu]; | 2696 | cpu_buffer = buffer->buffers[cpu]; |
2687 | entries += (local_read(&cpu_buffer->entries) - | 2697 | entries += rb_num_of_entries(cpu_buffer); |
2688 | local_read(&cpu_buffer->overrun)) - cpu_buffer->read; | ||
2689 | } | 2698 | } |
2690 | 2699 | ||
2691 | return entries; | 2700 | return entries; |
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 31cc4cb0dbf2..39c059ca670e 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/kprobes.h> | 9 | #include <linux/kprobes.h> |
10 | #include "trace.h" | 10 | #include "trace.h" |
11 | 11 | ||
12 | static char *perf_trace_buf[4]; | 12 | static char __percpu *perf_trace_buf[PERF_NR_CONTEXTS]; |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Force it to be aligned to unsigned long to avoid misaligned accesses | 15 | * Force it to be aligned to unsigned long to avoid misaligned accesses |
@@ -24,7 +24,7 @@ static int total_ref_count; | |||
24 | static int perf_trace_event_init(struct ftrace_event_call *tp_event, | 24 | static int perf_trace_event_init(struct ftrace_event_call *tp_event, |
25 | struct perf_event *p_event) | 25 | struct perf_event *p_event) |
26 | { | 26 | { |
27 | struct hlist_head *list; | 27 | struct hlist_head __percpu *list; |
28 | int ret = -ENOMEM; | 28 | int ret = -ENOMEM; |
29 | int cpu; | 29 | int cpu; |
30 | 30 | ||
@@ -42,11 +42,11 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event, | |||
42 | tp_event->perf_events = list; | 42 | tp_event->perf_events = list; |
43 | 43 | ||
44 | if (!total_ref_count) { | 44 | if (!total_ref_count) { |
45 | char *buf; | 45 | char __percpu *buf; |
46 | int i; | 46 | int i; |
47 | 47 | ||
48 | for (i = 0; i < 4; i++) { | 48 | for (i = 0; i < PERF_NR_CONTEXTS; i++) { |
49 | buf = (char *)alloc_percpu(perf_trace_t); | 49 | buf = (char __percpu *)alloc_percpu(perf_trace_t); |
50 | if (!buf) | 50 | if (!buf) |
51 | goto fail; | 51 | goto fail; |
52 | 52 | ||
@@ -65,7 +65,7 @@ fail: | |||
65 | if (!total_ref_count) { | 65 | if (!total_ref_count) { |
66 | int i; | 66 | int i; |
67 | 67 | ||
68 | for (i = 0; i < 4; i++) { | 68 | for (i = 0; i < PERF_NR_CONTEXTS; i++) { |
69 | free_percpu(perf_trace_buf[i]); | 69 | free_percpu(perf_trace_buf[i]); |
70 | perf_trace_buf[i] = NULL; | 70 | perf_trace_buf[i] = NULL; |
71 | } | 71 | } |
@@ -101,22 +101,26 @@ int perf_trace_init(struct perf_event *p_event) | |||
101 | return ret; | 101 | return ret; |
102 | } | 102 | } |
103 | 103 | ||
104 | int perf_trace_enable(struct perf_event *p_event) | 104 | int perf_trace_add(struct perf_event *p_event, int flags) |
105 | { | 105 | { |
106 | struct ftrace_event_call *tp_event = p_event->tp_event; | 106 | struct ftrace_event_call *tp_event = p_event->tp_event; |
107 | struct hlist_head __percpu *pcpu_list; | ||
107 | struct hlist_head *list; | 108 | struct hlist_head *list; |
108 | 109 | ||
109 | list = tp_event->perf_events; | 110 | pcpu_list = tp_event->perf_events; |
110 | if (WARN_ON_ONCE(!list)) | 111 | if (WARN_ON_ONCE(!pcpu_list)) |
111 | return -EINVAL; | 112 | return -EINVAL; |
112 | 113 | ||
113 | list = this_cpu_ptr(list); | 114 | if (!(flags & PERF_EF_START)) |
115 | p_event->hw.state = PERF_HES_STOPPED; | ||
116 | |||
117 | list = this_cpu_ptr(pcpu_list); | ||
114 | hlist_add_head_rcu(&p_event->hlist_entry, list); | 118 | hlist_add_head_rcu(&p_event->hlist_entry, list); |
115 | 119 | ||
116 | return 0; | 120 | return 0; |
117 | } | 121 | } |
118 | 122 | ||
119 | void perf_trace_disable(struct perf_event *p_event) | 123 | void perf_trace_del(struct perf_event *p_event, int flags) |
120 | { | 124 | { |
121 | hlist_del_rcu(&p_event->hlist_entry); | 125 | hlist_del_rcu(&p_event->hlist_entry); |
122 | } | 126 | } |
@@ -142,7 +146,7 @@ void perf_trace_destroy(struct perf_event *p_event) | |||
142 | tp_event->perf_events = NULL; | 146 | tp_event->perf_events = NULL; |
143 | 147 | ||
144 | if (!--total_ref_count) { | 148 | if (!--total_ref_count) { |
145 | for (i = 0; i < 4; i++) { | 149 | for (i = 0; i < PERF_NR_CONTEXTS; i++) { |
146 | free_percpu(perf_trace_buf[i]); | 150 | free_percpu(perf_trace_buf[i]); |
147 | perf_trace_buf[i] = NULL; | 151 | perf_trace_buf[i] = NULL; |
148 | } | 152 | } |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 4c758f146328..398c0e8b332c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -600,21 +600,29 @@ out: | |||
600 | 600 | ||
601 | enum { | 601 | enum { |
602 | FORMAT_HEADER = 1, | 602 | FORMAT_HEADER = 1, |
603 | FORMAT_PRINTFMT = 2, | 603 | FORMAT_FIELD_SEPERATOR = 2, |
604 | FORMAT_PRINTFMT = 3, | ||
604 | }; | 605 | }; |
605 | 606 | ||
606 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) | 607 | static void *f_next(struct seq_file *m, void *v, loff_t *pos) |
607 | { | 608 | { |
608 | struct ftrace_event_call *call = m->private; | 609 | struct ftrace_event_call *call = m->private; |
609 | struct ftrace_event_field *field; | 610 | struct ftrace_event_field *field; |
610 | struct list_head *head; | 611 | struct list_head *common_head = &ftrace_common_fields; |
612 | struct list_head *head = trace_get_fields(call); | ||
611 | 613 | ||
612 | (*pos)++; | 614 | (*pos)++; |
613 | 615 | ||
614 | switch ((unsigned long)v) { | 616 | switch ((unsigned long)v) { |
615 | case FORMAT_HEADER: | 617 | case FORMAT_HEADER: |
616 | head = &ftrace_common_fields; | 618 | if (unlikely(list_empty(common_head))) |
619 | return NULL; | ||
620 | |||
621 | field = list_entry(common_head->prev, | ||
622 | struct ftrace_event_field, link); | ||
623 | return field; | ||
617 | 624 | ||
625 | case FORMAT_FIELD_SEPERATOR: | ||
618 | if (unlikely(list_empty(head))) | 626 | if (unlikely(list_empty(head))) |
619 | return NULL; | 627 | return NULL; |
620 | 628 | ||
@@ -626,31 +634,10 @@ static void *f_next(struct seq_file *m, void *v, loff_t *pos) | |||
626 | return NULL; | 634 | return NULL; |
627 | } | 635 | } |
628 | 636 | ||
629 | head = trace_get_fields(call); | ||
630 | |||
631 | /* | ||
632 | * To separate common fields from event fields, the | ||
633 | * LSB is set on the first event field. Clear it in case. | ||
634 | */ | ||
635 | v = (void *)((unsigned long)v & ~1L); | ||
636 | |||
637 | field = v; | 637 | field = v; |
638 | /* | 638 | if (field->link.prev == common_head) |
639 | * If this is a common field, and at the end of the list, then | 639 | return (void *)FORMAT_FIELD_SEPERATOR; |
640 | * continue with main list. | 640 | else if (field->link.prev == head) |
641 | */ | ||
642 | if (field->link.prev == &ftrace_common_fields) { | ||
643 | if (unlikely(list_empty(head))) | ||
644 | return NULL; | ||
645 | field = list_entry(head->prev, struct ftrace_event_field, link); | ||
646 | /* Set the LSB to notify f_show to print an extra newline */ | ||
647 | field = (struct ftrace_event_field *) | ||
648 | ((unsigned long)field | 1); | ||
649 | return field; | ||
650 | } | ||
651 | |||
652 | /* If we are done tell f_show to print the format */ | ||
653 | if (field->link.prev == head) | ||
654 | return (void *)FORMAT_PRINTFMT; | 641 | return (void *)FORMAT_PRINTFMT; |
655 | 642 | ||
656 | field = list_entry(field->link.prev, struct ftrace_event_field, link); | 643 | field = list_entry(field->link.prev, struct ftrace_event_field, link); |
@@ -688,22 +675,16 @@ static int f_show(struct seq_file *m, void *v) | |||
688 | seq_printf(m, "format:\n"); | 675 | seq_printf(m, "format:\n"); |
689 | return 0; | 676 | return 0; |
690 | 677 | ||
678 | case FORMAT_FIELD_SEPERATOR: | ||
679 | seq_putc(m, '\n'); | ||
680 | return 0; | ||
681 | |||
691 | case FORMAT_PRINTFMT: | 682 | case FORMAT_PRINTFMT: |
692 | seq_printf(m, "\nprint fmt: %s\n", | 683 | seq_printf(m, "\nprint fmt: %s\n", |
693 | call->print_fmt); | 684 | call->print_fmt); |
694 | return 0; | 685 | return 0; |
695 | } | 686 | } |
696 | 687 | ||
697 | /* | ||
698 | * To separate common fields from event fields, the | ||
699 | * LSB is set on the first event field. Clear it and | ||
700 | * print a newline if it is set. | ||
701 | */ | ||
702 | if ((unsigned long)v & 1) { | ||
703 | seq_putc(m, '\n'); | ||
704 | v = (void *)((unsigned long)v & ~1L); | ||
705 | } | ||
706 | |||
707 | field = v; | 688 | field = v; |
708 | 689 | ||
709 | /* | 690 | /* |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 6f233698518e..ef49e9370b25 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -15,15 +15,19 @@ | |||
15 | #include "trace.h" | 15 | #include "trace.h" |
16 | #include "trace_output.h" | 16 | #include "trace_output.h" |
17 | 17 | ||
18 | /* When set, irq functions will be ignored */ | ||
19 | static int ftrace_graph_skip_irqs; | ||
20 | |||
18 | struct fgraph_cpu_data { | 21 | struct fgraph_cpu_data { |
19 | pid_t last_pid; | 22 | pid_t last_pid; |
20 | int depth; | 23 | int depth; |
24 | int depth_irq; | ||
21 | int ignore; | 25 | int ignore; |
22 | unsigned long enter_funcs[FTRACE_RETFUNC_DEPTH]; | 26 | unsigned long enter_funcs[FTRACE_RETFUNC_DEPTH]; |
23 | }; | 27 | }; |
24 | 28 | ||
25 | struct fgraph_data { | 29 | struct fgraph_data { |
26 | struct fgraph_cpu_data *cpu_data; | 30 | struct fgraph_cpu_data __percpu *cpu_data; |
27 | 31 | ||
28 | /* Place to preserve last processed entry. */ | 32 | /* Place to preserve last processed entry. */ |
29 | struct ftrace_graph_ent_entry ent; | 33 | struct ftrace_graph_ent_entry ent; |
@@ -41,6 +45,7 @@ struct fgraph_data { | |||
41 | #define TRACE_GRAPH_PRINT_PROC 0x8 | 45 | #define TRACE_GRAPH_PRINT_PROC 0x8 |
42 | #define TRACE_GRAPH_PRINT_DURATION 0x10 | 46 | #define TRACE_GRAPH_PRINT_DURATION 0x10 |
43 | #define TRACE_GRAPH_PRINT_ABS_TIME 0x20 | 47 | #define TRACE_GRAPH_PRINT_ABS_TIME 0x20 |
48 | #define TRACE_GRAPH_PRINT_IRQS 0x40 | ||
44 | 49 | ||
45 | static struct tracer_opt trace_opts[] = { | 50 | static struct tracer_opt trace_opts[] = { |
46 | /* Display overruns? (for self-debug purpose) */ | 51 | /* Display overruns? (for self-debug purpose) */ |
@@ -55,13 +60,15 @@ static struct tracer_opt trace_opts[] = { | |||
55 | { TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) }, | 60 | { TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) }, |
56 | /* Display absolute time of an entry */ | 61 | /* Display absolute time of an entry */ |
57 | { TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) }, | 62 | { TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) }, |
63 | /* Display interrupts */ | ||
64 | { TRACER_OPT(funcgraph-irqs, TRACE_GRAPH_PRINT_IRQS) }, | ||
58 | { } /* Empty entry */ | 65 | { } /* Empty entry */ |
59 | }; | 66 | }; |
60 | 67 | ||
61 | static struct tracer_flags tracer_flags = { | 68 | static struct tracer_flags tracer_flags = { |
62 | /* Don't display overruns and proc by default */ | 69 | /* Don't display overruns and proc by default */ |
63 | .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD | | 70 | .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD | |
64 | TRACE_GRAPH_PRINT_DURATION, | 71 | TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS, |
65 | .opts = trace_opts | 72 | .opts = trace_opts |
66 | }; | 73 | }; |
67 | 74 | ||
@@ -204,6 +211,14 @@ int __trace_graph_entry(struct trace_array *tr, | |||
204 | return 1; | 211 | return 1; |
205 | } | 212 | } |
206 | 213 | ||
214 | static inline int ftrace_graph_ignore_irqs(void) | ||
215 | { | ||
216 | if (!ftrace_graph_skip_irqs) | ||
217 | return 0; | ||
218 | |||
219 | return in_irq(); | ||
220 | } | ||
221 | |||
207 | int trace_graph_entry(struct ftrace_graph_ent *trace) | 222 | int trace_graph_entry(struct ftrace_graph_ent *trace) |
208 | { | 223 | { |
209 | struct trace_array *tr = graph_array; | 224 | struct trace_array *tr = graph_array; |
@@ -218,7 +233,8 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) | |||
218 | return 0; | 233 | return 0; |
219 | 234 | ||
220 | /* trace it when it is-nested-in or is a function enabled. */ | 235 | /* trace it when it is-nested-in or is a function enabled. */ |
221 | if (!(trace->depth || ftrace_graph_addr(trace->func))) | 236 | if (!(trace->depth || ftrace_graph_addr(trace->func)) || |
237 | ftrace_graph_ignore_irqs()) | ||
222 | return 0; | 238 | return 0; |
223 | 239 | ||
224 | local_irq_save(flags); | 240 | local_irq_save(flags); |
@@ -649,8 +665,9 @@ trace_print_graph_duration(unsigned long long duration, struct trace_seq *s) | |||
649 | 665 | ||
650 | /* Print nsecs (we don't want to exceed 7 numbers) */ | 666 | /* Print nsecs (we don't want to exceed 7 numbers) */ |
651 | if (len < 7) { | 667 | if (len < 7) { |
652 | snprintf(nsecs_str, min(sizeof(nsecs_str), 8UL - len), "%03lu", | 668 | size_t slen = min_t(size_t, sizeof(nsecs_str), 8UL - len); |
653 | nsecs_rem); | 669 | |
670 | snprintf(nsecs_str, slen, "%03lu", nsecs_rem); | ||
654 | ret = trace_seq_printf(s, ".%s", nsecs_str); | 671 | ret = trace_seq_printf(s, ".%s", nsecs_str); |
655 | if (!ret) | 672 | if (!ret) |
656 | return TRACE_TYPE_PARTIAL_LINE; | 673 | return TRACE_TYPE_PARTIAL_LINE; |
@@ -855,6 +872,92 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, | |||
855 | return 0; | 872 | return 0; |
856 | } | 873 | } |
857 | 874 | ||
875 | /* | ||
876 | * Entry check for irq code | ||
877 | * | ||
878 | * returns 1 if | ||
879 | * - we are inside irq code | ||
880 | * - we just extered irq code | ||
881 | * | ||
882 | * retunns 0 if | ||
883 | * - funcgraph-interrupts option is set | ||
884 | * - we are not inside irq code | ||
885 | */ | ||
886 | static int | ||
887 | check_irq_entry(struct trace_iterator *iter, u32 flags, | ||
888 | unsigned long addr, int depth) | ||
889 | { | ||
890 | int cpu = iter->cpu; | ||
891 | struct fgraph_data *data = iter->private; | ||
892 | int *depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); | ||
893 | |||
894 | if (flags & TRACE_GRAPH_PRINT_IRQS) | ||
895 | return 0; | ||
896 | |||
897 | /* | ||
898 | * We are inside the irq code | ||
899 | */ | ||
900 | if (*depth_irq >= 0) | ||
901 | return 1; | ||
902 | |||
903 | if ((addr < (unsigned long)__irqentry_text_start) || | ||
904 | (addr >= (unsigned long)__irqentry_text_end)) | ||
905 | return 0; | ||
906 | |||
907 | /* | ||
908 | * We are entering irq code. | ||
909 | */ | ||
910 | *depth_irq = depth; | ||
911 | return 1; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Return check for irq code | ||
916 | * | ||
917 | * returns 1 if | ||
918 | * - we are inside irq code | ||
919 | * - we just left irq code | ||
920 | * | ||
921 | * returns 0 if | ||
922 | * - funcgraph-interrupts option is set | ||
923 | * - we are not inside irq code | ||
924 | */ | ||
925 | static int | ||
926 | check_irq_return(struct trace_iterator *iter, u32 flags, int depth) | ||
927 | { | ||
928 | int cpu = iter->cpu; | ||
929 | struct fgraph_data *data = iter->private; | ||
930 | int *depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); | ||
931 | |||
932 | if (flags & TRACE_GRAPH_PRINT_IRQS) | ||
933 | return 0; | ||
934 | |||
935 | /* | ||
936 | * We are not inside the irq code. | ||
937 | */ | ||
938 | if (*depth_irq == -1) | ||
939 | return 0; | ||
940 | |||
941 | /* | ||
942 | * We are inside the irq code, and this is returning entry. | ||
943 | * Let's not trace it and clear the entry depth, since | ||
944 | * we are out of irq code. | ||
945 | * | ||
946 | * This condition ensures that we 'leave the irq code' once | ||
947 | * we are out of the entry depth. Thus protecting us from | ||
948 | * the RETURN entry loss. | ||
949 | */ | ||
950 | if (*depth_irq >= depth) { | ||
951 | *depth_irq = -1; | ||
952 | return 1; | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * We are inside the irq code, and this is not the entry. | ||
957 | */ | ||
958 | return 1; | ||
959 | } | ||
960 | |||
858 | static enum print_line_t | 961 | static enum print_line_t |
859 | print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, | 962 | print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, |
860 | struct trace_iterator *iter, u32 flags) | 963 | struct trace_iterator *iter, u32 flags) |
@@ -865,6 +968,9 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, | |||
865 | static enum print_line_t ret; | 968 | static enum print_line_t ret; |
866 | int cpu = iter->cpu; | 969 | int cpu = iter->cpu; |
867 | 970 | ||
971 | if (check_irq_entry(iter, flags, call->func, call->depth)) | ||
972 | return TRACE_TYPE_HANDLED; | ||
973 | |||
868 | if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags)) | 974 | if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags)) |
869 | return TRACE_TYPE_PARTIAL_LINE; | 975 | return TRACE_TYPE_PARTIAL_LINE; |
870 | 976 | ||
@@ -902,6 +1008,9 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, | |||
902 | int ret; | 1008 | int ret; |
903 | int i; | 1009 | int i; |
904 | 1010 | ||
1011 | if (check_irq_return(iter, flags, trace->depth)) | ||
1012 | return TRACE_TYPE_HANDLED; | ||
1013 | |||
905 | if (data) { | 1014 | if (data) { |
906 | struct fgraph_cpu_data *cpu_data; | 1015 | struct fgraph_cpu_data *cpu_data; |
907 | int cpu = iter->cpu; | 1016 | int cpu = iter->cpu; |
@@ -1210,9 +1319,12 @@ void graph_trace_open(struct trace_iterator *iter) | |||
1210 | pid_t *pid = &(per_cpu_ptr(data->cpu_data, cpu)->last_pid); | 1319 | pid_t *pid = &(per_cpu_ptr(data->cpu_data, cpu)->last_pid); |
1211 | int *depth = &(per_cpu_ptr(data->cpu_data, cpu)->depth); | 1320 | int *depth = &(per_cpu_ptr(data->cpu_data, cpu)->depth); |
1212 | int *ignore = &(per_cpu_ptr(data->cpu_data, cpu)->ignore); | 1321 | int *ignore = &(per_cpu_ptr(data->cpu_data, cpu)->ignore); |
1322 | int *depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); | ||
1323 | |||
1213 | *pid = -1; | 1324 | *pid = -1; |
1214 | *depth = 0; | 1325 | *depth = 0; |
1215 | *ignore = 0; | 1326 | *ignore = 0; |
1327 | *depth_irq = -1; | ||
1216 | } | 1328 | } |
1217 | 1329 | ||
1218 | iter->private = data; | 1330 | iter->private = data; |
@@ -1235,6 +1347,14 @@ void graph_trace_close(struct trace_iterator *iter) | |||
1235 | } | 1347 | } |
1236 | } | 1348 | } |
1237 | 1349 | ||
1350 | static int func_graph_set_flag(u32 old_flags, u32 bit, int set) | ||
1351 | { | ||
1352 | if (bit == TRACE_GRAPH_PRINT_IRQS) | ||
1353 | ftrace_graph_skip_irqs = !set; | ||
1354 | |||
1355 | return 0; | ||
1356 | } | ||
1357 | |||
1238 | static struct trace_event_functions graph_functions = { | 1358 | static struct trace_event_functions graph_functions = { |
1239 | .trace = print_graph_function_event, | 1359 | .trace = print_graph_function_event, |
1240 | }; | 1360 | }; |
@@ -1261,6 +1381,7 @@ static struct tracer graph_trace __read_mostly = { | |||
1261 | .print_line = print_graph_function, | 1381 | .print_line = print_graph_function, |
1262 | .print_header = print_graph_headers, | 1382 | .print_header = print_graph_headers, |
1263 | .flags = &tracer_flags, | 1383 | .flags = &tracer_flags, |
1384 | .set_flag = func_graph_set_flag, | ||
1264 | #ifdef CONFIG_FTRACE_SELFTEST | 1385 | #ifdef CONFIG_FTRACE_SELFTEST |
1265 | .selftest = trace_selftest_startup_function_graph, | 1386 | .selftest = trace_selftest_startup_function_graph, |
1266 | #endif | 1387 | #endif |
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c index a7cc3793baf6..209b379a4721 100644 --- a/kernel/trace/trace_workqueue.c +++ b/kernel/trace/trace_workqueue.c | |||
@@ -263,6 +263,11 @@ int __init trace_workqueue_early_init(void) | |||
263 | { | 263 | { |
264 | int ret, cpu; | 264 | int ret, cpu; |
265 | 265 | ||
266 | for_each_possible_cpu(cpu) { | ||
267 | spin_lock_init(&workqueue_cpu_stat(cpu)->lock); | ||
268 | INIT_LIST_HEAD(&workqueue_cpu_stat(cpu)->list); | ||
269 | } | ||
270 | |||
266 | ret = register_trace_workqueue_insertion(probe_workqueue_insertion, NULL); | 271 | ret = register_trace_workqueue_insertion(probe_workqueue_insertion, NULL); |
267 | if (ret) | 272 | if (ret) |
268 | goto out; | 273 | goto out; |
@@ -279,11 +284,6 @@ int __init trace_workqueue_early_init(void) | |||
279 | if (ret) | 284 | if (ret) |
280 | goto no_creation; | 285 | goto no_creation; |
281 | 286 | ||
282 | for_each_possible_cpu(cpu) { | ||
283 | spin_lock_init(&workqueue_cpu_stat(cpu)->lock); | ||
284 | INIT_LIST_HEAD(&workqueue_cpu_stat(cpu)->list); | ||
285 | } | ||
286 | |||
287 | return 0; | 287 | return 0; |
288 | 288 | ||
289 | no_creation: | 289 | no_creation: |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index c77f3eceea25..d6073a50a6ca 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/jump_label.h> | ||
28 | 29 | ||
29 | extern struct tracepoint __start___tracepoints[]; | 30 | extern struct tracepoint __start___tracepoints[]; |
30 | extern struct tracepoint __stop___tracepoints[]; | 31 | extern struct tracepoint __stop___tracepoints[]; |
@@ -263,7 +264,13 @@ static void set_tracepoint(struct tracepoint_entry **entry, | |||
263 | * is used. | 264 | * is used. |
264 | */ | 265 | */ |
265 | rcu_assign_pointer(elem->funcs, (*entry)->funcs); | 266 | rcu_assign_pointer(elem->funcs, (*entry)->funcs); |
266 | elem->state = active; | 267 | if (!elem->state && active) { |
268 | enable_jump_label(&elem->state); | ||
269 | elem->state = active; | ||
270 | } else if (elem->state && !active) { | ||
271 | disable_jump_label(&elem->state); | ||
272 | elem->state = active; | ||
273 | } | ||
267 | } | 274 | } |
268 | 275 | ||
269 | /* | 276 | /* |
@@ -277,7 +284,10 @@ static void disable_tracepoint(struct tracepoint *elem) | |||
277 | if (elem->unregfunc && elem->state) | 284 | if (elem->unregfunc && elem->state) |
278 | elem->unregfunc(); | 285 | elem->unregfunc(); |
279 | 286 | ||
280 | elem->state = 0; | 287 | if (elem->state) { |
288 | disable_jump_label(&elem->state); | ||
289 | elem->state = 0; | ||
290 | } | ||
281 | rcu_assign_pointer(elem->funcs, NULL); | 291 | rcu_assign_pointer(elem->funcs, NULL); |
282 | } | 292 | } |
283 | 293 | ||
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 7f9c3c52ecc1..dc8e16824b51 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -43,7 +43,6 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); | |||
43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); | 43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | static int __read_mostly did_panic; | ||
47 | static int __initdata no_watchdog; | 46 | static int __initdata no_watchdog; |
48 | 47 | ||
49 | 48 | ||
@@ -187,18 +186,6 @@ static int is_softlockup(unsigned long touch_ts) | |||
187 | return 0; | 186 | return 0; |
188 | } | 187 | } |
189 | 188 | ||
190 | static int | ||
191 | watchdog_panic(struct notifier_block *this, unsigned long event, void *ptr) | ||
192 | { | ||
193 | did_panic = 1; | ||
194 | |||
195 | return NOTIFY_DONE; | ||
196 | } | ||
197 | |||
198 | static struct notifier_block panic_block = { | ||
199 | .notifier_call = watchdog_panic, | ||
200 | }; | ||
201 | |||
202 | #ifdef CONFIG_HARDLOCKUP_DETECTOR | 189 | #ifdef CONFIG_HARDLOCKUP_DETECTOR |
203 | static struct perf_event_attr wd_hw_attr = { | 190 | static struct perf_event_attr wd_hw_attr = { |
204 | .type = PERF_TYPE_HARDWARE, | 191 | .type = PERF_TYPE_HARDWARE, |
@@ -371,14 +358,14 @@ static int watchdog_nmi_enable(int cpu) | |||
371 | /* Try to register using hardware perf events */ | 358 | /* Try to register using hardware perf events */ |
372 | wd_attr = &wd_hw_attr; | 359 | wd_attr = &wd_hw_attr; |
373 | wd_attr->sample_period = hw_nmi_get_sample_period(); | 360 | wd_attr->sample_period = hw_nmi_get_sample_period(); |
374 | event = perf_event_create_kernel_counter(wd_attr, cpu, -1, watchdog_overflow_callback); | 361 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback); |
375 | if (!IS_ERR(event)) { | 362 | if (!IS_ERR(event)) { |
376 | printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); | 363 | printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); |
377 | goto out_save; | 364 | goto out_save; |
378 | } | 365 | } |
379 | 366 | ||
380 | printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event); | 367 | printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event); |
381 | return -1; | 368 | return PTR_ERR(event); |
382 | 369 | ||
383 | /* success path */ | 370 | /* success path */ |
384 | out_save: | 371 | out_save: |
@@ -422,17 +409,19 @@ static int watchdog_prepare_cpu(int cpu) | |||
422 | static int watchdog_enable(int cpu) | 409 | static int watchdog_enable(int cpu) |
423 | { | 410 | { |
424 | struct task_struct *p = per_cpu(softlockup_watchdog, cpu); | 411 | struct task_struct *p = per_cpu(softlockup_watchdog, cpu); |
412 | int err; | ||
425 | 413 | ||
426 | /* enable the perf event */ | 414 | /* enable the perf event */ |
427 | if (watchdog_nmi_enable(cpu) != 0) | 415 | err = watchdog_nmi_enable(cpu); |
428 | return -1; | 416 | if (err) |
417 | return err; | ||
429 | 418 | ||
430 | /* create the watchdog thread */ | 419 | /* create the watchdog thread */ |
431 | if (!p) { | 420 | if (!p) { |
432 | p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); | 421 | p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); |
433 | if (IS_ERR(p)) { | 422 | if (IS_ERR(p)) { |
434 | printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); | 423 | printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); |
435 | return -1; | 424 | return PTR_ERR(p); |
436 | } | 425 | } |
437 | kthread_bind(p, cpu); | 426 | kthread_bind(p, cpu); |
438 | per_cpu(watchdog_touch_ts, cpu) = 0; | 427 | per_cpu(watchdog_touch_ts, cpu) = 0; |
@@ -484,6 +473,9 @@ static void watchdog_disable_all_cpus(void) | |||
484 | { | 473 | { |
485 | int cpu; | 474 | int cpu; |
486 | 475 | ||
476 | if (no_watchdog) | ||
477 | return; | ||
478 | |||
487 | for_each_online_cpu(cpu) | 479 | for_each_online_cpu(cpu) |
488 | watchdog_disable(cpu); | 480 | watchdog_disable(cpu); |
489 | 481 | ||
@@ -526,17 +518,16 @@ static int __cpuinit | |||
526 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 518 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
527 | { | 519 | { |
528 | int hotcpu = (unsigned long)hcpu; | 520 | int hotcpu = (unsigned long)hcpu; |
521 | int err = 0; | ||
529 | 522 | ||
530 | switch (action) { | 523 | switch (action) { |
531 | case CPU_UP_PREPARE: | 524 | case CPU_UP_PREPARE: |
532 | case CPU_UP_PREPARE_FROZEN: | 525 | case CPU_UP_PREPARE_FROZEN: |
533 | if (watchdog_prepare_cpu(hotcpu)) | 526 | err = watchdog_prepare_cpu(hotcpu); |
534 | return NOTIFY_BAD; | ||
535 | break; | 527 | break; |
536 | case CPU_ONLINE: | 528 | case CPU_ONLINE: |
537 | case CPU_ONLINE_FROZEN: | 529 | case CPU_ONLINE_FROZEN: |
538 | if (watchdog_enable(hotcpu)) | 530 | err = watchdog_enable(hotcpu); |
539 | return NOTIFY_BAD; | ||
540 | break; | 531 | break; |
541 | #ifdef CONFIG_HOTPLUG_CPU | 532 | #ifdef CONFIG_HOTPLUG_CPU |
542 | case CPU_UP_CANCELED: | 533 | case CPU_UP_CANCELED: |
@@ -549,7 +540,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
549 | break; | 540 | break; |
550 | #endif /* CONFIG_HOTPLUG_CPU */ | 541 | #endif /* CONFIG_HOTPLUG_CPU */ |
551 | } | 542 | } |
552 | return NOTIFY_OK; | 543 | return notifier_from_errno(err); |
553 | } | 544 | } |
554 | 545 | ||
555 | static struct notifier_block __cpuinitdata cpu_nfb = { | 546 | static struct notifier_block __cpuinitdata cpu_nfb = { |
@@ -565,13 +556,11 @@ static int __init spawn_watchdog_task(void) | |||
565 | return 0; | 556 | return 0; |
566 | 557 | ||
567 | err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | 558 | err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); |
568 | WARN_ON(err == NOTIFY_BAD); | 559 | WARN_ON(notifier_to_errno(err)); |
569 | 560 | ||
570 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); | 561 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
571 | register_cpu_notifier(&cpu_nfb); | 562 | register_cpu_notifier(&cpu_nfb); |
572 | 563 | ||
573 | atomic_notifier_chain_register(&panic_notifier_list, &panic_block); | ||
574 | |||
575 | return 0; | 564 | return 0; |
576 | } | 565 | } |
577 | early_initcall(spawn_watchdog_task); | 566 | early_initcall(spawn_watchdog_task); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1b4afd2e6ca0..e85d549b6eac 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -482,6 +482,7 @@ config PROVE_LOCKING | |||
482 | select DEBUG_SPINLOCK | 482 | select DEBUG_SPINLOCK |
483 | select DEBUG_MUTEXES | 483 | select DEBUG_MUTEXES |
484 | select DEBUG_LOCK_ALLOC | 484 | select DEBUG_LOCK_ALLOC |
485 | select TRACE_IRQFLAGS | ||
485 | default n | 486 | default n |
486 | help | 487 | help |
487 | This feature enables the kernel to prove that all locking | 488 | This feature enables the kernel to prove that all locking |
@@ -579,11 +580,10 @@ config DEBUG_LOCKDEP | |||
579 | of more runtime overhead. | 580 | of more runtime overhead. |
580 | 581 | ||
581 | config TRACE_IRQFLAGS | 582 | config TRACE_IRQFLAGS |
582 | depends on DEBUG_KERNEL | ||
583 | bool | 583 | bool |
584 | default y | 584 | help |
585 | depends on TRACE_IRQFLAGS_SUPPORT | 585 | Enables hooks to interrupt enabling and disabling for |
586 | depends on PROVE_LOCKING | 586 | either tracing or lock debugging. |
587 | 587 | ||
588 | config DEBUG_SPINLOCK_SLEEP | 588 | config DEBUG_SPINLOCK_SLEEP |
589 | bool "Spinlock debugging: sleep-inside-spinlock checking" | 589 | bool "Spinlock debugging: sleep-inside-spinlock checking" |
@@ -72,8 +72,8 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr) | |||
72 | return NULL; | 72 | return NULL; |
73 | } | 73 | } |
74 | 74 | ||
75 | int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | 75 | void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, |
76 | struct module *mod) | 76 | struct module *mod) |
77 | { | 77 | { |
78 | char *secstrings; | 78 | char *secstrings; |
79 | unsigned int i; | 79 | unsigned int i; |
@@ -97,8 +97,6 @@ int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
97 | * could potentially lead to deadlock and thus be counter-productive. | 97 | * could potentially lead to deadlock and thus be counter-productive. |
98 | */ | 98 | */ |
99 | list_add(&mod->bug_list, &module_bug_list); | 99 | list_add(&mod->bug_list, &module_bug_list); |
100 | |||
101 | return 0; | ||
102 | } | 100 | } |
103 | 101 | ||
104 | void module_bug_cleanup(struct module *mod) | 102 | void module_bug_cleanup(struct module *mod) |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 02afc2533728..e925c7b960f1 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -26,19 +26,11 @@ | |||
26 | #include <linux/dynamic_debug.h> | 26 | #include <linux/dynamic_debug.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/jump_label.h> | ||
29 | 30 | ||
30 | extern struct _ddebug __start___verbose[]; | 31 | extern struct _ddebug __start___verbose[]; |
31 | extern struct _ddebug __stop___verbose[]; | 32 | extern struct _ddebug __stop___verbose[]; |
32 | 33 | ||
33 | /* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which | ||
34 | * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They | ||
35 | * use independent hash functions, to reduce the chance of false positives. | ||
36 | */ | ||
37 | long long dynamic_debug_enabled; | ||
38 | EXPORT_SYMBOL_GPL(dynamic_debug_enabled); | ||
39 | long long dynamic_debug_enabled2; | ||
40 | EXPORT_SYMBOL_GPL(dynamic_debug_enabled2); | ||
41 | |||
42 | struct ddebug_table { | 34 | struct ddebug_table { |
43 | struct list_head link; | 35 | struct list_head link; |
44 | char *mod_name; | 36 | char *mod_name; |
@@ -88,26 +80,6 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | |||
88 | } | 80 | } |
89 | 81 | ||
90 | /* | 82 | /* |
91 | * must be called with ddebug_lock held | ||
92 | */ | ||
93 | |||
94 | static int disabled_hash(char hash, bool first_table) | ||
95 | { | ||
96 | struct ddebug_table *dt; | ||
97 | char table_hash_value; | ||
98 | |||
99 | list_for_each_entry(dt, &ddebug_tables, link) { | ||
100 | if (first_table) | ||
101 | table_hash_value = dt->ddebugs->primary_hash; | ||
102 | else | ||
103 | table_hash_value = dt->ddebugs->secondary_hash; | ||
104 | if (dt->num_enabled && (hash == table_hash_value)) | ||
105 | return 0; | ||
106 | } | ||
107 | return 1; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Search the tables for _ddebug's which match the given | 83 | * Search the tables for _ddebug's which match the given |
112 | * `query' and apply the `flags' and `mask' to them. Tells | 84 | * `query' and apply the `flags' and `mask' to them. Tells |
113 | * the user which ddebug's were changed, or whether none | 85 | * the user which ddebug's were changed, or whether none |
@@ -170,17 +142,9 @@ static void ddebug_change(const struct ddebug_query *query, | |||
170 | dt->num_enabled++; | 142 | dt->num_enabled++; |
171 | dp->flags = newflags; | 143 | dp->flags = newflags; |
172 | if (newflags) { | 144 | if (newflags) { |
173 | dynamic_debug_enabled |= | 145 | enable_jump_label(&dp->enabled); |
174 | (1LL << dp->primary_hash); | ||
175 | dynamic_debug_enabled2 |= | ||
176 | (1LL << dp->secondary_hash); | ||
177 | } else { | 146 | } else { |
178 | if (disabled_hash(dp->primary_hash, true)) | 147 | disable_jump_label(&dp->enabled); |
179 | dynamic_debug_enabled &= | ||
180 | ~(1LL << dp->primary_hash); | ||
181 | if (disabled_hash(dp->secondary_hash, false)) | ||
182 | dynamic_debug_enabled2 &= | ||
183 | ~(1LL << dp->secondary_hash); | ||
184 | } | 148 | } |
185 | if (verbose) | 149 | if (verbose) |
186 | printk(KERN_INFO | 150 | printk(KERN_INFO |
diff --git a/lib/list_sort.c b/lib/list_sort.c index 4b5cb794c38b..a7616fa3162e 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c | |||
@@ -70,7 +70,7 @@ static void merge_and_restore_back_links(void *priv, | |||
70 | * element comparison is needed, so the client's cmp() | 70 | * element comparison is needed, so the client's cmp() |
71 | * routine can invoke cond_resched() periodically. | 71 | * routine can invoke cond_resched() periodically. |
72 | */ | 72 | */ |
73 | (*cmp)(priv, tail, tail); | 73 | (*cmp)(priv, tail->next, tail->next); |
74 | 74 | ||
75 | tail->next->prev = tail; | 75 | tail->next->prev = tail; |
76 | tail = tail->next; | 76 | tail = tail->next; |
diff --git a/mm/fremap.c b/mm/fremap.c index 46f5dacf90a2..ec520c7b28df 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
@@ -125,7 +125,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
125 | { | 125 | { |
126 | struct mm_struct *mm = current->mm; | 126 | struct mm_struct *mm = current->mm; |
127 | struct address_space *mapping; | 127 | struct address_space *mapping; |
128 | unsigned long end = start + size; | ||
129 | struct vm_area_struct *vma; | 128 | struct vm_area_struct *vma; |
130 | int err = -EINVAL; | 129 | int err = -EINVAL; |
131 | int has_write_lock = 0; | 130 | int has_write_lock = 0; |
@@ -142,6 +141,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
142 | if (start + size <= start) | 141 | if (start + size <= start) |
143 | return err; | 142 | return err; |
144 | 143 | ||
144 | /* Does pgoff wrap? */ | ||
145 | if (pgoff + (size >> PAGE_SHIFT) < pgoff) | ||
146 | return err; | ||
147 | |||
145 | /* Can we represent this offset inside this architecture's pte's? */ | 148 | /* Can we represent this offset inside this architecture's pte's? */ |
146 | #if PTE_FILE_MAX_BITS < BITS_PER_LONG | 149 | #if PTE_FILE_MAX_BITS < BITS_PER_LONG |
147 | if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS)) | 150 | if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS)) |
@@ -168,7 +171,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
168 | if (!(vma->vm_flags & VM_CAN_NONLINEAR)) | 171 | if (!(vma->vm_flags & VM_CAN_NONLINEAR)) |
169 | goto out; | 172 | goto out; |
170 | 173 | ||
171 | if (end <= start || start < vma->vm_start || end > vma->vm_end) | 174 | if (start < vma->vm_start || start + size > vma->vm_end) |
172 | goto out; | 175 | goto out; |
173 | 176 | ||
174 | /* Must set VM_NONLINEAR before any pages are populated. */ | 177 | /* Must set VM_NONLINEAR before any pages are populated. */ |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index cc5be788a39f..c03273807182 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2324,11 +2324,8 @@ retry_avoidcopy: | |||
2324 | * and just make the page writable */ | 2324 | * and just make the page writable */ |
2325 | avoidcopy = (page_mapcount(old_page) == 1); | 2325 | avoidcopy = (page_mapcount(old_page) == 1); |
2326 | if (avoidcopy) { | 2326 | if (avoidcopy) { |
2327 | if (!trylock_page(old_page)) { | 2327 | if (PageAnon(old_page)) |
2328 | if (PageAnon(old_page)) | 2328 | page_move_anon_rmap(old_page, vma, address); |
2329 | page_move_anon_rmap(old_page, vma, address); | ||
2330 | } else | ||
2331 | unlock_page(old_page); | ||
2332 | set_huge_ptep_writable(vma, address, ptep); | 2329 | set_huge_ptep_writable(vma, address, ptep); |
2333 | return 0; | 2330 | return 0; |
2334 | } | 2331 | } |
@@ -2404,7 +2401,7 @@ retry_avoidcopy: | |||
2404 | set_huge_pte_at(mm, address, ptep, | 2401 | set_huge_pte_at(mm, address, ptep, |
2405 | make_huge_pte(vma, new_page, 1)); | 2402 | make_huge_pte(vma, new_page, 1)); |
2406 | page_remove_rmap(old_page); | 2403 | page_remove_rmap(old_page); |
2407 | hugepage_add_anon_rmap(new_page, vma, address); | 2404 | hugepage_add_new_anon_rmap(new_page, vma, address); |
2408 | /* Make the old page be freed below */ | 2405 | /* Make the old page be freed below */ |
2409 | new_page = old_page; | 2406 | new_page = old_page; |
2410 | mmu_notifier_invalidate_range_end(mm, | 2407 | mmu_notifier_invalidate_range_end(mm, |
@@ -2631,10 +2628,16 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2631 | vma, address); | 2628 | vma, address); |
2632 | } | 2629 | } |
2633 | 2630 | ||
2634 | if (!pagecache_page) { | 2631 | /* |
2635 | page = pte_page(entry); | 2632 | * hugetlb_cow() requires page locks of pte_page(entry) and |
2633 | * pagecache_page, so here we need take the former one | ||
2634 | * when page != pagecache_page or !pagecache_page. | ||
2635 | * Note that locking order is always pagecache_page -> page, | ||
2636 | * so no worry about deadlock. | ||
2637 | */ | ||
2638 | page = pte_page(entry); | ||
2639 | if (page != pagecache_page) | ||
2636 | lock_page(page); | 2640 | lock_page(page); |
2637 | } | ||
2638 | 2641 | ||
2639 | spin_lock(&mm->page_table_lock); | 2642 | spin_lock(&mm->page_table_lock); |
2640 | /* Check for a racing update before calling hugetlb_cow */ | 2643 | /* Check for a racing update before calling hugetlb_cow */ |
@@ -2661,9 +2664,8 @@ out_page_table_lock: | |||
2661 | if (pagecache_page) { | 2664 | if (pagecache_page) { |
2662 | unlock_page(pagecache_page); | 2665 | unlock_page(pagecache_page); |
2663 | put_page(pagecache_page); | 2666 | put_page(pagecache_page); |
2664 | } else { | ||
2665 | unlock_page(page); | ||
2666 | } | 2667 | } |
2668 | unlock_page(page); | ||
2667 | 2669 | ||
2668 | out_mutex: | 2670 | out_mutex: |
2669 | mutex_unlock(&hugetlb_instantiation_mutex); | 2671 | mutex_unlock(&hugetlb_instantiation_mutex); |
@@ -712,7 +712,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, | |||
712 | if (!ptep) | 712 | if (!ptep) |
713 | goto out; | 713 | goto out; |
714 | 714 | ||
715 | if (pte_write(*ptep)) { | 715 | if (pte_write(*ptep) || pte_dirty(*ptep)) { |
716 | pte_t entry; | 716 | pte_t entry; |
717 | 717 | ||
718 | swapped = PageSwapCache(page); | 718 | swapped = PageSwapCache(page); |
@@ -735,7 +735,9 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, | |||
735 | set_pte_at(mm, addr, ptep, entry); | 735 | set_pte_at(mm, addr, ptep, entry); |
736 | goto out_unlock; | 736 | goto out_unlock; |
737 | } | 737 | } |
738 | entry = pte_wrprotect(entry); | 738 | if (pte_dirty(entry)) |
739 | set_page_dirty(page); | ||
740 | entry = pte_mkclean(pte_wrprotect(entry)); | ||
739 | set_pte_at_notify(mm, addr, ptep, entry); | 741 | set_pte_at_notify(mm, addr, ptep, entry); |
740 | } | 742 | } |
741 | *orig_pte = *ptep; | 743 | *orig_pte = *ptep; |
@@ -2009,6 +2009,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, | |||
2009 | removed_exe_file_vma(mm); | 2009 | removed_exe_file_vma(mm); |
2010 | fput(new->vm_file); | 2010 | fput(new->vm_file); |
2011 | } | 2011 | } |
2012 | unlink_anon_vmas(new); | ||
2012 | out_free_mpol: | 2013 | out_free_mpol: |
2013 | mpol_put(pol); | 2014 | mpol_put(pol); |
2014 | out_free_vma: | 2015 | out_free_vma: |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index fc81cb22869e..4029583a1024 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -121,8 +121,8 @@ struct task_struct *find_lock_task_mm(struct task_struct *p) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /* return true if the task is not adequate as candidate victim task. */ | 123 | /* return true if the task is not adequate as candidate victim task. */ |
124 | static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem, | 124 | static bool oom_unkillable_task(struct task_struct *p, |
125 | const nodemask_t *nodemask) | 125 | const struct mem_cgroup *mem, const nodemask_t *nodemask) |
126 | { | 126 | { |
127 | if (is_global_init(p)) | 127 | if (is_global_init(p)) |
128 | return true; | 128 | return true; |
@@ -208,8 +208,13 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, | |||
208 | */ | 208 | */ |
209 | points += p->signal->oom_score_adj; | 209 | points += p->signal->oom_score_adj; |
210 | 210 | ||
211 | if (points < 0) | 211 | /* |
212 | return 0; | 212 | * Never return 0 for an eligible task that may be killed since it's |
213 | * possible that no single user task uses more than 0.1% of memory and | ||
214 | * no single admin tasks uses more than 3.0%. | ||
215 | */ | ||
216 | if (points <= 0) | ||
217 | return 1; | ||
213 | return (points < 1000) ? points : 1000; | 218 | return (points < 1000) ? points : 1000; |
214 | } | 219 | } |
215 | 220 | ||
@@ -339,26 +344,24 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, | |||
339 | /** | 344 | /** |
340 | * dump_tasks - dump current memory state of all system tasks | 345 | * dump_tasks - dump current memory state of all system tasks |
341 | * @mem: current's memory controller, if constrained | 346 | * @mem: current's memory controller, if constrained |
347 | * @nodemask: nodemask passed to page allocator for mempolicy ooms | ||
342 | * | 348 | * |
343 | * Dumps the current memory state of all system tasks, excluding kernel threads. | 349 | * Dumps the current memory state of all eligible tasks. Tasks not in the same |
350 | * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes | ||
351 | * are not shown. | ||
344 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj | 352 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj |
345 | * value, oom_score_adj value, and name. | 353 | * value, oom_score_adj value, and name. |
346 | * | 354 | * |
347 | * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are | ||
348 | * shown. | ||
349 | * | ||
350 | * Call with tasklist_lock read-locked. | 355 | * Call with tasklist_lock read-locked. |
351 | */ | 356 | */ |
352 | static void dump_tasks(const struct mem_cgroup *mem) | 357 | static void dump_tasks(const struct mem_cgroup *mem, const nodemask_t *nodemask) |
353 | { | 358 | { |
354 | struct task_struct *p; | 359 | struct task_struct *p; |
355 | struct task_struct *task; | 360 | struct task_struct *task; |
356 | 361 | ||
357 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); | 362 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); |
358 | for_each_process(p) { | 363 | for_each_process(p) { |
359 | if (p->flags & PF_KTHREAD) | 364 | if (oom_unkillable_task(p, mem, nodemask)) |
360 | continue; | ||
361 | if (mem && !task_in_mem_cgroup(p, mem)) | ||
362 | continue; | 365 | continue; |
363 | 366 | ||
364 | task = find_lock_task_mm(p); | 367 | task = find_lock_task_mm(p); |
@@ -381,7 +384,7 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
381 | } | 384 | } |
382 | 385 | ||
383 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | 386 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, |
384 | struct mem_cgroup *mem) | 387 | struct mem_cgroup *mem, const nodemask_t *nodemask) |
385 | { | 388 | { |
386 | task_lock(current); | 389 | task_lock(current); |
387 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " | 390 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " |
@@ -394,7 +397,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
394 | mem_cgroup_print_oom_info(mem, p); | 397 | mem_cgroup_print_oom_info(mem, p); |
395 | show_mem(); | 398 | show_mem(); |
396 | if (sysctl_oom_dump_tasks) | 399 | if (sysctl_oom_dump_tasks) |
397 | dump_tasks(mem); | 400 | dump_tasks(mem, nodemask); |
398 | } | 401 | } |
399 | 402 | ||
400 | #define K(x) ((x) << (PAGE_SHIFT-10)) | 403 | #define K(x) ((x) << (PAGE_SHIFT-10)) |
@@ -436,7 +439,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
436 | unsigned int victim_points = 0; | 439 | unsigned int victim_points = 0; |
437 | 440 | ||
438 | if (printk_ratelimit()) | 441 | if (printk_ratelimit()) |
439 | dump_header(p, gfp_mask, order, mem); | 442 | dump_header(p, gfp_mask, order, mem, nodemask); |
440 | 443 | ||
441 | /* | 444 | /* |
442 | * If the task is already exiting, don't alarm the sysadmin or kill | 445 | * If the task is already exiting, don't alarm the sysadmin or kill |
@@ -482,7 +485,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
482 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. | 485 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. |
483 | */ | 486 | */ |
484 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | 487 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, |
485 | int order) | 488 | int order, const nodemask_t *nodemask) |
486 | { | 489 | { |
487 | if (likely(!sysctl_panic_on_oom)) | 490 | if (likely(!sysctl_panic_on_oom)) |
488 | return; | 491 | return; |
@@ -496,7 +499,7 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | |||
496 | return; | 499 | return; |
497 | } | 500 | } |
498 | read_lock(&tasklist_lock); | 501 | read_lock(&tasklist_lock); |
499 | dump_header(NULL, gfp_mask, order, NULL); | 502 | dump_header(NULL, gfp_mask, order, NULL, nodemask); |
500 | read_unlock(&tasklist_lock); | 503 | read_unlock(&tasklist_lock); |
501 | panic("Out of memory: %s panic_on_oom is enabled\n", | 504 | panic("Out of memory: %s panic_on_oom is enabled\n", |
502 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); | 505 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); |
@@ -509,7 +512,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) | |||
509 | unsigned int points = 0; | 512 | unsigned int points = 0; |
510 | struct task_struct *p; | 513 | struct task_struct *p; |
511 | 514 | ||
512 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0); | 515 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL); |
513 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; | 516 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; |
514 | read_lock(&tasklist_lock); | 517 | read_lock(&tasklist_lock); |
515 | retry: | 518 | retry: |
@@ -641,6 +644,7 @@ static void clear_system_oom(void) | |||
641 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | 644 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, |
642 | int order, nodemask_t *nodemask) | 645 | int order, nodemask_t *nodemask) |
643 | { | 646 | { |
647 | const nodemask_t *mpol_mask; | ||
644 | struct task_struct *p; | 648 | struct task_struct *p; |
645 | unsigned long totalpages; | 649 | unsigned long totalpages; |
646 | unsigned long freed = 0; | 650 | unsigned long freed = 0; |
@@ -670,7 +674,8 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
670 | */ | 674 | */ |
671 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, | 675 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, |
672 | &totalpages); | 676 | &totalpages); |
673 | check_panic_on_oom(constraint, gfp_mask, order); | 677 | mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL; |
678 | check_panic_on_oom(constraint, gfp_mask, order, mpol_mask); | ||
674 | 679 | ||
675 | read_lock(&tasklist_lock); | 680 | read_lock(&tasklist_lock); |
676 | if (sysctl_oom_kill_allocating_task && | 681 | if (sysctl_oom_kill_allocating_task && |
@@ -688,15 +693,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
688 | } | 693 | } |
689 | 694 | ||
690 | retry: | 695 | retry: |
691 | p = select_bad_process(&points, totalpages, NULL, | 696 | p = select_bad_process(&points, totalpages, NULL, mpol_mask); |
692 | constraint == CONSTRAINT_MEMORY_POLICY ? nodemask : | ||
693 | NULL); | ||
694 | if (PTR_ERR(p) == -1UL) | 697 | if (PTR_ERR(p) == -1UL) |
695 | goto out; | 698 | goto out; |
696 | 699 | ||
697 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 700 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
698 | if (!p) { | 701 | if (!p) { |
699 | dump_header(NULL, gfp_mask, order, NULL); | 702 | dump_header(NULL, gfp_mask, order, NULL, mpol_mask); |
700 | read_unlock(&tasklist_lock); | 703 | read_unlock(&tasklist_lock); |
701 | panic("Out of memory and no killable processes...\n"); | 704 | panic("Out of memory and no killable processes...\n"); |
702 | } | 705 | } |
diff --git a/mm/percpu.c b/mm/percpu.c index 58c572b18b07..c76ef3891e0d 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1401,9 +1401,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, | |||
1401 | 1401 | ||
1402 | if (pcpu_first_unit_cpu == NR_CPUS) | 1402 | if (pcpu_first_unit_cpu == NR_CPUS) |
1403 | pcpu_first_unit_cpu = cpu; | 1403 | pcpu_first_unit_cpu = cpu; |
1404 | pcpu_last_unit_cpu = cpu; | ||
1404 | } | 1405 | } |
1405 | } | 1406 | } |
1406 | pcpu_last_unit_cpu = cpu; | ||
1407 | pcpu_nr_units = unit; | 1407 | pcpu_nr_units = unit; |
1408 | 1408 | ||
1409 | for_each_possible_cpu(cpu) | 1409 | for_each_possible_cpu(cpu) |
@@ -381,7 +381,13 @@ vma_address(struct page *page, struct vm_area_struct *vma) | |||
381 | unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) | 381 | unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) |
382 | { | 382 | { |
383 | if (PageAnon(page)) { | 383 | if (PageAnon(page)) { |
384 | if (vma->anon_vma->root != page_anon_vma(page)->root) | 384 | struct anon_vma *page__anon_vma = page_anon_vma(page); |
385 | /* | ||
386 | * Note: swapoff's unuse_vma() is more efficient with this | ||
387 | * check, and needs it to match anon_vma when KSM is active. | ||
388 | */ | ||
389 | if (!vma->anon_vma || !page__anon_vma || | ||
390 | vma->anon_vma->root != page__anon_vma->root) | ||
385 | return -EFAULT; | 391 | return -EFAULT; |
386 | } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { | 392 | } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { |
387 | if (!vma->vm_file || | 393 | if (!vma->vm_file || |
@@ -1564,13 +1570,14 @@ static void __hugepage_set_anon_rmap(struct page *page, | |||
1564 | struct vm_area_struct *vma, unsigned long address, int exclusive) | 1570 | struct vm_area_struct *vma, unsigned long address, int exclusive) |
1565 | { | 1571 | { |
1566 | struct anon_vma *anon_vma = vma->anon_vma; | 1572 | struct anon_vma *anon_vma = vma->anon_vma; |
1573 | |||
1567 | BUG_ON(!anon_vma); | 1574 | BUG_ON(!anon_vma); |
1568 | if (!exclusive) { | 1575 | |
1569 | struct anon_vma_chain *avc; | 1576 | if (PageAnon(page)) |
1570 | avc = list_entry(vma->anon_vma_chain.prev, | 1577 | return; |
1571 | struct anon_vma_chain, same_vma); | 1578 | if (!exclusive) |
1572 | anon_vma = avc->anon_vma; | 1579 | anon_vma = anon_vma->root; |
1573 | } | 1580 | |
1574 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; | 1581 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; |
1575 | page->mapping = (struct address_space *) anon_vma; | 1582 | page->mapping = (struct address_space *) anon_vma; |
1576 | page->index = linear_page_index(vma, address); | 1583 | page->index = linear_page_index(vma, address); |
@@ -1581,6 +1588,8 @@ void hugepage_add_anon_rmap(struct page *page, | |||
1581 | { | 1588 | { |
1582 | struct anon_vma *anon_vma = vma->anon_vma; | 1589 | struct anon_vma *anon_vma = vma->anon_vma; |
1583 | int first; | 1590 | int first; |
1591 | |||
1592 | BUG_ON(!PageLocked(page)); | ||
1584 | BUG_ON(!anon_vma); | 1593 | BUG_ON(!anon_vma); |
1585 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1594 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
1586 | first = atomic_inc_and_test(&page->_mapcount); | 1595 | first = atomic_inc_and_test(&page->_mapcount); |
diff --git a/mm/vmscan.c b/mm/vmscan.c index c391c320dbaf..c5dfabf25f11 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1804,12 +1804,11 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1804 | * If a zone is deemed to be full of pinned pages then just give it a light | 1804 | * If a zone is deemed to be full of pinned pages then just give it a light |
1805 | * scan then give up on it. | 1805 | * scan then give up on it. |
1806 | */ | 1806 | */ |
1807 | static bool shrink_zones(int priority, struct zonelist *zonelist, | 1807 | static void shrink_zones(int priority, struct zonelist *zonelist, |
1808 | struct scan_control *sc) | 1808 | struct scan_control *sc) |
1809 | { | 1809 | { |
1810 | struct zoneref *z; | 1810 | struct zoneref *z; |
1811 | struct zone *zone; | 1811 | struct zone *zone; |
1812 | bool all_unreclaimable = true; | ||
1813 | 1812 | ||
1814 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 1813 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
1815 | gfp_zone(sc->gfp_mask), sc->nodemask) { | 1814 | gfp_zone(sc->gfp_mask), sc->nodemask) { |
@@ -1827,8 +1826,38 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, | |||
1827 | } | 1826 | } |
1828 | 1827 | ||
1829 | shrink_zone(priority, zone, sc); | 1828 | shrink_zone(priority, zone, sc); |
1830 | all_unreclaimable = false; | ||
1831 | } | 1829 | } |
1830 | } | ||
1831 | |||
1832 | static bool zone_reclaimable(struct zone *zone) | ||
1833 | { | ||
1834 | return zone->pages_scanned < zone_reclaimable_pages(zone) * 6; | ||
1835 | } | ||
1836 | |||
1837 | /* | ||
1838 | * As hibernation is going on, kswapd is freezed so that it can't mark | ||
1839 | * the zone into all_unreclaimable. It can't handle OOM during hibernation. | ||
1840 | * So let's check zone's unreclaimable in direct reclaim as well as kswapd. | ||
1841 | */ | ||
1842 | static bool all_unreclaimable(struct zonelist *zonelist, | ||
1843 | struct scan_control *sc) | ||
1844 | { | ||
1845 | struct zoneref *z; | ||
1846 | struct zone *zone; | ||
1847 | bool all_unreclaimable = true; | ||
1848 | |||
1849 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | ||
1850 | gfp_zone(sc->gfp_mask), sc->nodemask) { | ||
1851 | if (!populated_zone(zone)) | ||
1852 | continue; | ||
1853 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | ||
1854 | continue; | ||
1855 | if (zone_reclaimable(zone)) { | ||
1856 | all_unreclaimable = false; | ||
1857 | break; | ||
1858 | } | ||
1859 | } | ||
1860 | |||
1832 | return all_unreclaimable; | 1861 | return all_unreclaimable; |
1833 | } | 1862 | } |
1834 | 1863 | ||
@@ -1852,7 +1881,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1852 | struct scan_control *sc) | 1881 | struct scan_control *sc) |
1853 | { | 1882 | { |
1854 | int priority; | 1883 | int priority; |
1855 | bool all_unreclaimable; | ||
1856 | unsigned long total_scanned = 0; | 1884 | unsigned long total_scanned = 0; |
1857 | struct reclaim_state *reclaim_state = current->reclaim_state; | 1885 | struct reclaim_state *reclaim_state = current->reclaim_state; |
1858 | struct zoneref *z; | 1886 | struct zoneref *z; |
@@ -1869,7 +1897,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1869 | sc->nr_scanned = 0; | 1897 | sc->nr_scanned = 0; |
1870 | if (!priority) | 1898 | if (!priority) |
1871 | disable_swap_token(); | 1899 | disable_swap_token(); |
1872 | all_unreclaimable = shrink_zones(priority, zonelist, sc); | 1900 | shrink_zones(priority, zonelist, sc); |
1873 | /* | 1901 | /* |
1874 | * Don't shrink slabs when reclaiming memory from | 1902 | * Don't shrink slabs when reclaiming memory from |
1875 | * over limit cgroups | 1903 | * over limit cgroups |
@@ -1931,7 +1959,7 @@ out: | |||
1931 | return sc->nr_reclaimed; | 1959 | return sc->nr_reclaimed; |
1932 | 1960 | ||
1933 | /* top priority shrink_zones still had more to do? don't OOM, then */ | 1961 | /* top priority shrink_zones still had more to do? don't OOM, then */ |
1934 | if (scanning_global_lru(sc) && !all_unreclaimable) | 1962 | if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc)) |
1935 | return 1; | 1963 | return 1; |
1936 | 1964 | ||
1937 | return 0; | 1965 | return 0; |
@@ -2197,8 +2225,7 @@ loop_again: | |||
2197 | total_scanned += sc.nr_scanned; | 2225 | total_scanned += sc.nr_scanned; |
2198 | if (zone->all_unreclaimable) | 2226 | if (zone->all_unreclaimable) |
2199 | continue; | 2227 | continue; |
2200 | if (nr_slab == 0 && | 2228 | if (nr_slab == 0 && !zone_reclaimable(zone)) |
2201 | zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6)) | ||
2202 | zone->all_unreclaimable = 1; | 2229 | zone->all_unreclaimable = 1; |
2203 | /* | 2230 | /* |
2204 | * If we've done a decent amount of scanning and | 2231 | * If we've done a decent amount of scanning and |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 01ddb0472f86..0eb96f7e44be 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -24,8 +24,11 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
24 | 24 | ||
25 | if (vlan_dev) | 25 | if (vlan_dev) |
26 | skb->dev = vlan_dev; | 26 | skb->dev = vlan_dev; |
27 | else if (vlan_id) | 27 | else if (vlan_id) { |
28 | goto drop; | 28 | if (!(skb->dev->flags & IFF_PROMISC)) |
29 | goto drop; | ||
30 | skb->pkt_type = PACKET_OTHERHOST; | ||
31 | } | ||
29 | 32 | ||
30 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); | 33 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); |
31 | 34 | ||
@@ -102,8 +105,11 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
102 | 105 | ||
103 | if (vlan_dev) | 106 | if (vlan_dev) |
104 | skb->dev = vlan_dev; | 107 | skb->dev = vlan_dev; |
105 | else if (vlan_id) | 108 | else if (vlan_id) { |
106 | goto drop; | 109 | if (!(skb->dev->flags & IFF_PROMISC)) |
110 | goto drop; | ||
111 | skb->pkt_type = PACKET_OTHERHOST; | ||
112 | } | ||
107 | 113 | ||
108 | for (p = napi->gro_list; p; p = p->next) { | 114 | for (p = napi->gro_list; p; p = p->next) { |
109 | NAPI_GRO_CB(p)->same_flow = | 115 | NAPI_GRO_CB(p)->same_flow = |
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 0ea20c30466c..17c5ba7551a5 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
@@ -426,8 +426,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
426 | 426 | ||
427 | /* Allocate an fcall for the reply */ | 427 | /* Allocate an fcall for the reply */ |
428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); | 428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); |
429 | if (!rpl_context) | 429 | if (!rpl_context) { |
430 | err = -ENOMEM; | ||
430 | goto err_close; | 431 | goto err_close; |
432 | } | ||
431 | 433 | ||
432 | /* | 434 | /* |
433 | * If the request has a buffer, steal it, otherwise | 435 | * If the request has a buffer, steal it, otherwise |
@@ -445,8 +447,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
445 | } | 447 | } |
446 | rpl_context->rc = req->rc; | 448 | rpl_context->rc = req->rc; |
447 | if (!rpl_context->rc) { | 449 | if (!rpl_context->rc) { |
448 | kfree(rpl_context); | 450 | err = -ENOMEM; |
449 | goto err_close; | 451 | goto err_free2; |
450 | } | 452 | } |
451 | 453 | ||
452 | /* | 454 | /* |
@@ -458,11 +460,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
458 | */ | 460 | */ |
459 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { | 461 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { |
460 | err = post_recv(client, rpl_context); | 462 | err = post_recv(client, rpl_context); |
461 | if (err) { | 463 | if (err) |
462 | kfree(rpl_context->rc); | 464 | goto err_free1; |
463 | kfree(rpl_context); | ||
464 | goto err_close; | ||
465 | } | ||
466 | } else | 465 | } else |
467 | atomic_dec(&rdma->rq_count); | 466 | atomic_dec(&rdma->rq_count); |
468 | 467 | ||
@@ -471,8 +470,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
471 | 470 | ||
472 | /* Post the request */ | 471 | /* Post the request */ |
473 | c = kmalloc(sizeof *c, GFP_KERNEL); | 472 | c = kmalloc(sizeof *c, GFP_KERNEL); |
474 | if (!c) | 473 | if (!c) { |
475 | goto err_close; | 474 | err = -ENOMEM; |
475 | goto err_free1; | ||
476 | } | ||
476 | c->req = req; | 477 | c->req = req; |
477 | 478 | ||
478 | c->busa = ib_dma_map_single(rdma->cm_id->device, | 479 | c->busa = ib_dma_map_single(rdma->cm_id->device, |
@@ -499,9 +500,15 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
499 | return ib_post_send(rdma->qp, &wr, &bad_wr); | 500 | return ib_post_send(rdma->qp, &wr, &bad_wr); |
500 | 501 | ||
501 | error: | 502 | error: |
503 | kfree(c); | ||
504 | kfree(rpl_context->rc); | ||
505 | kfree(rpl_context); | ||
502 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); | 506 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); |
503 | return -EIO; | 507 | return -EIO; |
504 | 508 | err_free1: | |
509 | kfree(rpl_context->rc); | ||
510 | err_free2: | ||
511 | kfree(rpl_context); | ||
505 | err_close: | 512 | err_close: |
506 | spin_lock_irqsave(&rdma->req_lock, flags); | 513 | spin_lock_irqsave(&rdma->req_lock, flags); |
507 | if (rdma->state < P9_RDMA_CLOSING) { | 514 | if (rdma->state < P9_RDMA_CLOSING) { |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index dcfbe99ff81c..b88515936e4b 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
329 | 329 | ||
330 | mutex_lock(&virtio_9p_lock); | 330 | mutex_lock(&virtio_9p_lock); |
331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { | 331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { |
332 | if (!strncmp(devname, chan->tag, chan->tag_len)) { | 332 | if (!strncmp(devname, chan->tag, chan->tag_len) && |
333 | strlen(devname) == chan->tag_len) { | ||
333 | if (!chan->inuse) { | 334 | if (!chan->inuse) { |
334 | chan->inuse = true; | 335 | chan->inuse = true; |
335 | found = 1; | 336 | found = 1; |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 651babdfab38..ad2b232a2055 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -399,12 +399,6 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) | |||
399 | unregister_netdev(net_dev); | 399 | unregister_netdev(net_dev); |
400 | free_netdev(net_dev); | 400 | free_netdev(net_dev); |
401 | } | 401 | } |
402 | read_lock_irq(&devs_lock); | ||
403 | if (list_empty(&br2684_devs)) { | ||
404 | /* last br2684 device */ | ||
405 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
406 | } | ||
407 | read_unlock_irq(&devs_lock); | ||
408 | return; | 402 | return; |
409 | } | 403 | } |
410 | 404 | ||
@@ -675,7 +669,6 @@ static int br2684_create(void __user *arg) | |||
675 | 669 | ||
676 | if (list_empty(&br2684_devs)) { | 670 | if (list_empty(&br2684_devs)) { |
677 | /* 1st br2684 device */ | 671 | /* 1st br2684 device */ |
678 | register_atmdevice_notifier(&atm_dev_notifier); | ||
679 | brdev->number = 1; | 672 | brdev->number = 1; |
680 | } else | 673 | } else |
681 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; | 674 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; |
@@ -815,6 +808,7 @@ static int __init br2684_init(void) | |||
815 | return -ENOMEM; | 808 | return -ENOMEM; |
816 | #endif | 809 | #endif |
817 | register_atm_ioctl(&br2684_ioctl_ops); | 810 | register_atm_ioctl(&br2684_ioctl_ops); |
811 | register_atmdevice_notifier(&atm_dev_notifier); | ||
818 | return 0; | 812 | return 0; |
819 | } | 813 | } |
820 | 814 | ||
@@ -830,9 +824,7 @@ static void __exit br2684_exit(void) | |||
830 | #endif | 824 | #endif |
831 | 825 | ||
832 | 826 | ||
833 | /* if not already empty */ | 827 | unregister_atmdevice_notifier(&atm_dev_notifier); |
834 | if (!list_empty(&br2684_devs)) | ||
835 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
836 | 828 | ||
837 | while (!list_empty(&br2684_devs)) { | 829 | while (!list_empty(&br2684_devs)) { |
838 | net_dev = list_entry_brdev(br2684_devs.next); | 830 | net_dev = list_entry_brdev(br2684_devs.next); |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 251997a95483..282806ba7a57 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -243,6 +243,7 @@ void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) | |||
243 | unlock_sock_fast(sk, slow); | 243 | unlock_sock_fast(sk, slow); |
244 | 244 | ||
245 | /* skb is now orphaned, can be freed outside of locked section */ | 245 | /* skb is now orphaned, can be freed outside of locked section */ |
246 | trace_kfree_skb(skb, skb_free_datagram_locked); | ||
246 | __kfree_skb(skb); | 247 | __kfree_skb(skb); |
247 | } | 248 | } |
248 | EXPORT_SYMBOL(skb_free_datagram_locked); | 249 | EXPORT_SYMBOL(skb_free_datagram_locked); |
diff --git a/net/core/dev.c b/net/core/dev.c index 660dd41aaaa6..7ec85e27beed 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -128,6 +128,8 @@ | |||
128 | #include <linux/jhash.h> | 128 | #include <linux/jhash.h> |
129 | #include <linux/random.h> | 129 | #include <linux/random.h> |
130 | #include <trace/events/napi.h> | 130 | #include <trace/events/napi.h> |
131 | #include <trace/events/net.h> | ||
132 | #include <trace/events/skb.h> | ||
131 | #include <linux/pci.h> | 133 | #include <linux/pci.h> |
132 | 134 | ||
133 | #include "net-sysfs.h" | 135 | #include "net-sysfs.h" |
@@ -1978,6 +1980,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
1978 | } | 1980 | } |
1979 | 1981 | ||
1980 | rc = ops->ndo_start_xmit(skb, dev); | 1982 | rc = ops->ndo_start_xmit(skb, dev); |
1983 | trace_net_dev_xmit(skb, rc); | ||
1981 | if (rc == NETDEV_TX_OK) | 1984 | if (rc == NETDEV_TX_OK) |
1982 | txq_trans_update(txq); | 1985 | txq_trans_update(txq); |
1983 | return rc; | 1986 | return rc; |
@@ -1998,6 +2001,7 @@ gso: | |||
1998 | skb_dst_drop(nskb); | 2001 | skb_dst_drop(nskb); |
1999 | 2002 | ||
2000 | rc = ops->ndo_start_xmit(nskb, dev); | 2003 | rc = ops->ndo_start_xmit(nskb, dev); |
2004 | trace_net_dev_xmit(nskb, rc); | ||
2001 | if (unlikely(rc != NETDEV_TX_OK)) { | 2005 | if (unlikely(rc != NETDEV_TX_OK)) { |
2002 | if (rc & ~NETDEV_TX_MASK) | 2006 | if (rc & ~NETDEV_TX_MASK) |
2003 | goto out_kfree_gso_skb; | 2007 | goto out_kfree_gso_skb; |
@@ -2186,6 +2190,7 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
2186 | #ifdef CONFIG_NET_CLS_ACT | 2190 | #ifdef CONFIG_NET_CLS_ACT |
2187 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS); | 2191 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS); |
2188 | #endif | 2192 | #endif |
2193 | trace_net_dev_queue(skb); | ||
2189 | if (q->enqueue) { | 2194 | if (q->enqueue) { |
2190 | rc = __dev_xmit_skb(skb, q, dev, txq); | 2195 | rc = __dev_xmit_skb(skb, q, dev, txq); |
2191 | goto out; | 2196 | goto out; |
@@ -2512,6 +2517,7 @@ int netif_rx(struct sk_buff *skb) | |||
2512 | if (netdev_tstamp_prequeue) | 2517 | if (netdev_tstamp_prequeue) |
2513 | net_timestamp_check(skb); | 2518 | net_timestamp_check(skb); |
2514 | 2519 | ||
2520 | trace_netif_rx(skb); | ||
2515 | #ifdef CONFIG_RPS | 2521 | #ifdef CONFIG_RPS |
2516 | { | 2522 | { |
2517 | struct rps_dev_flow voidflow, *rflow = &voidflow; | 2523 | struct rps_dev_flow voidflow, *rflow = &voidflow; |
@@ -2571,6 +2577,7 @@ static void net_tx_action(struct softirq_action *h) | |||
2571 | clist = clist->next; | 2577 | clist = clist->next; |
2572 | 2578 | ||
2573 | WARN_ON(atomic_read(&skb->users)); | 2579 | WARN_ON(atomic_read(&skb->users)); |
2580 | trace_kfree_skb(skb, net_tx_action); | ||
2574 | __kfree_skb(skb); | 2581 | __kfree_skb(skb); |
2575 | } | 2582 | } |
2576 | } | 2583 | } |
@@ -2828,6 +2835,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
2828 | if (!netdev_tstamp_prequeue) | 2835 | if (!netdev_tstamp_prequeue) |
2829 | net_timestamp_check(skb); | 2836 | net_timestamp_check(skb); |
2830 | 2837 | ||
2838 | trace_netif_receive_skb(skb); | ||
2831 | if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb)) | 2839 | if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb)) |
2832 | return NET_RX_SUCCESS; | 2840 | return NET_RX_SUCCESS; |
2833 | 2841 | ||
diff --git a/net/core/iovec.c b/net/core/iovec.c index 1cd98df412df..e6b133b77ccb 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -35,9 +35,10 @@ | |||
35 | * in any case. | 35 | * in any case. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) |
39 | { | 39 | { |
40 | int size, err, ct; | 40 | int size, ct; |
41 | long err; | ||
41 | 42 | ||
42 | if (m->msg_namelen) { | 43 | if (m->msg_namelen) { |
43 | if (mode == VERIFY_READ) { | 44 | if (mode == VERIFY_READ) { |
diff --git a/net/core/net-traces.c b/net/core/net-traces.c index afa6380ed88a..7f1bb2aba03b 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #define CREATE_TRACE_POINTS | 27 | #define CREATE_TRACE_POINTS |
28 | #include <trace/events/skb.h> | 28 | #include <trace/events/skb.h> |
29 | #include <trace/events/net.h> | ||
29 | #include <trace/events/napi.h> | 30 | #include <trace/events/napi.h> |
30 | 31 | ||
31 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); | 32 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c83b421341c0..56ba3c4e4761 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -466,6 +466,7 @@ void consume_skb(struct sk_buff *skb) | |||
466 | smp_rmb(); | 466 | smp_rmb(); |
467 | else if (likely(!atomic_dec_and_test(&skb->users))) | 467 | else if (likely(!atomic_dec_and_test(&skb->users))) |
468 | return; | 468 | return; |
469 | trace_consume_skb(skb); | ||
469 | __kfree_skb(skb); | 470 | __kfree_skb(skb); |
470 | } | 471 | } |
471 | EXPORT_SYMBOL(consume_skb); | 472 | EXPORT_SYMBOL(consume_skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index b05b9b6ddb87..ef30e9d286e7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1351,9 +1351,9 @@ int sock_i_uid(struct sock *sk) | |||
1351 | { | 1351 | { |
1352 | int uid; | 1352 | int uid; |
1353 | 1353 | ||
1354 | read_lock(&sk->sk_callback_lock); | 1354 | read_lock_bh(&sk->sk_callback_lock); |
1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; | 1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; |
1356 | read_unlock(&sk->sk_callback_lock); | 1356 | read_unlock_bh(&sk->sk_callback_lock); |
1357 | return uid; | 1357 | return uid; |
1358 | } | 1358 | } |
1359 | EXPORT_SYMBOL(sock_i_uid); | 1359 | EXPORT_SYMBOL(sock_i_uid); |
@@ -1362,9 +1362,9 @@ unsigned long sock_i_ino(struct sock *sk) | |||
1362 | { | 1362 | { |
1363 | unsigned long ino; | 1363 | unsigned long ino; |
1364 | 1364 | ||
1365 | read_lock(&sk->sk_callback_lock); | 1365 | read_lock_bh(&sk->sk_callback_lock); |
1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; | 1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; |
1367 | read_unlock(&sk->sk_callback_lock); | 1367 | read_unlock_bh(&sk->sk_callback_lock); |
1368 | return ino; | 1368 | return ino; |
1369 | } | 1369 | } |
1370 | EXPORT_SYMBOL(sock_i_ino); | 1370 | EXPORT_SYMBOL(sock_i_ino); |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 571f8950ed06..72380a30d1c8 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -217,6 +217,7 @@ config NET_IPIP | |||
217 | 217 | ||
218 | config NET_IPGRE | 218 | config NET_IPGRE |
219 | tristate "IP: GRE tunnels over IP" | 219 | tristate "IP: GRE tunnels over IP" |
220 | depends on IPV6 || IPV6=n | ||
220 | help | 221 | help |
221 | Tunneling means encapsulating data of one protocol type within | 222 | Tunneling means encapsulating data of one protocol type within |
222 | another protocol and sending it over a channel that understands the | 223 | another protocol and sending it over a channel that understands the |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 945b20a5ad50..35c93e8b6a46 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <net/netns/generic.h> | 45 | #include <net/netns/generic.h> |
46 | #include <net/rtnetlink.h> | 46 | #include <net/rtnetlink.h> |
47 | 47 | ||
48 | #ifdef CONFIG_IPV6 | 48 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
49 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
50 | #include <net/ip6_fib.h> | 50 | #include <net/ip6_fib.h> |
51 | #include <net/ip6_route.h> | 51 | #include <net/ip6_route.h> |
@@ -699,7 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
699 | if ((dst = rt->rt_gateway) == 0) | 699 | if ((dst = rt->rt_gateway) == 0) |
700 | goto tx_error_icmp; | 700 | goto tx_error_icmp; |
701 | } | 701 | } |
702 | #ifdef CONFIG_IPV6 | 702 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
703 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 703 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
704 | struct in6_addr *addr6; | 704 | struct in6_addr *addr6; |
705 | int addr_type; | 705 | int addr_type; |
@@ -774,7 +774,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
774 | goto tx_error; | 774 | goto tx_error; |
775 | } | 775 | } |
776 | } | 776 | } |
777 | #ifdef CONFIG_IPV6 | 777 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
778 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 778 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); | 779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); |
780 | 780 | ||
@@ -850,7 +850,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
850 | if ((iph->ttl = tiph->ttl) == 0) { | 850 | if ((iph->ttl = tiph->ttl) == 0) { |
851 | if (skb->protocol == htons(ETH_P_IP)) | 851 | if (skb->protocol == htons(ETH_P_IP)) |
852 | iph->ttl = old_iph->ttl; | 852 | iph->ttl = old_iph->ttl; |
853 | #ifdef CONFIG_IPV6 | 853 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
854 | else if (skb->protocol == htons(ETH_P_IPV6)) | 854 | else if (skb->protocol == htons(ETH_P_IPV6)) |
855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; | 855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; |
856 | #endif | 856 | #endif |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 04b69896df5f..7649d7750075 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
488 | * we can switch to copy when see the first bad fragment. | 488 | * we can switch to copy when see the first bad fragment. |
489 | */ | 489 | */ |
490 | if (skb_has_frags(skb)) { | 490 | if (skb_has_frags(skb)) { |
491 | struct sk_buff *frag; | 491 | struct sk_buff *frag, *frag2; |
492 | int first_len = skb_pagelen(skb); | 492 | int first_len = skb_pagelen(skb); |
493 | int truesizes = 0; | ||
494 | 493 | ||
495 | if (first_len - hlen > mtu || | 494 | if (first_len - hlen > mtu || |
496 | ((first_len - hlen) & 7) || | 495 | ((first_len - hlen) & 7) || |
@@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
503 | if (frag->len > mtu || | 502 | if (frag->len > mtu || |
504 | ((frag->len & 7) && frag->next) || | 503 | ((frag->len & 7) && frag->next) || |
505 | skb_headroom(frag) < hlen) | 504 | skb_headroom(frag) < hlen) |
506 | goto slow_path; | 505 | goto slow_path_clean; |
507 | 506 | ||
508 | /* Partially cloned skb? */ | 507 | /* Partially cloned skb? */ |
509 | if (skb_shared(frag)) | 508 | if (skb_shared(frag)) |
510 | goto slow_path; | 509 | goto slow_path_clean; |
511 | 510 | ||
512 | BUG_ON(frag->sk); | 511 | BUG_ON(frag->sk); |
513 | if (skb->sk) { | 512 | if (skb->sk) { |
514 | frag->sk = skb->sk; | 513 | frag->sk = skb->sk; |
515 | frag->destructor = sock_wfree; | 514 | frag->destructor = sock_wfree; |
516 | } | 515 | } |
517 | truesizes += frag->truesize; | 516 | skb->truesize -= frag->truesize; |
518 | } | 517 | } |
519 | 518 | ||
520 | /* Everything is OK. Generate! */ | 519 | /* Everything is OK. Generate! */ |
@@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
524 | frag = skb_shinfo(skb)->frag_list; | 523 | frag = skb_shinfo(skb)->frag_list; |
525 | skb_frag_list_init(skb); | 524 | skb_frag_list_init(skb); |
526 | skb->data_len = first_len - skb_headlen(skb); | 525 | skb->data_len = first_len - skb_headlen(skb); |
527 | skb->truesize -= truesizes; | ||
528 | skb->len = first_len; | 526 | skb->len = first_len; |
529 | iph->tot_len = htons(first_len); | 527 | iph->tot_len = htons(first_len); |
530 | iph->frag_off = htons(IP_MF); | 528 | iph->frag_off = htons(IP_MF); |
@@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
576 | } | 574 | } |
577 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); | 575 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
578 | return err; | 576 | return err; |
577 | |||
578 | slow_path_clean: | ||
579 | skb_walk_frags(skb, frag2) { | ||
580 | if (frag2 == frag) | ||
581 | break; | ||
582 | frag2->sk = NULL; | ||
583 | frag2->destructor = NULL; | ||
584 | skb->truesize += frag2->truesize; | ||
585 | } | ||
579 | } | 586 | } |
580 | 587 | ||
581 | slow_path: | 588 | slow_path: |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index b254dafaf429..43eec80c0e7c 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -112,6 +112,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
112 | /* ip_route_me_harder expects skb->dst to be set */ | 112 | /* ip_route_me_harder expects skb->dst to be set */ |
113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); | 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); |
114 | 114 | ||
115 | nskb->protocol = htons(ETH_P_IP); | ||
115 | if (ip_route_me_harder(nskb, addr_type)) | 116 | if (ip_route_me_harder(nskb, addr_type)) |
116 | goto free_nskb; | 117 | goto free_nskb; |
117 | 118 | ||
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index eab8de32f200..f3a9b42b16c6 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -66,9 +66,11 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
66 | const struct net_device *out, | 66 | const struct net_device *out, |
67 | int (*okfn)(struct sk_buff *)) | 67 | int (*okfn)(struct sk_buff *)) |
68 | { | 68 | { |
69 | struct sock *sk = skb->sk; | ||
69 | struct inet_sock *inet = inet_sk(skb->sk); | 70 | struct inet_sock *inet = inet_sk(skb->sk); |
70 | 71 | ||
71 | if (inet && inet->nodefrag) | 72 | if (sk && (sk->sk_family == PF_INET) && |
73 | inet->nodefrag) | ||
72 | return NF_ACCEPT; | 74 | return NF_ACCEPT; |
73 | 75 | ||
74 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 76 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 1679e2c0963d..ee5f419d0a56 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -893,13 +893,15 @@ static void fast_csum(__sum16 *csum, | |||
893 | unsigned char s[4]; | 893 | unsigned char s[4]; |
894 | 894 | ||
895 | if (offset & 1) { | 895 | if (offset & 1) { |
896 | s[0] = s[2] = 0; | 896 | s[0] = ~0; |
897 | s[1] = ~*optr; | 897 | s[1] = ~*optr; |
898 | s[2] = 0; | ||
898 | s[3] = *nptr; | 899 | s[3] = *nptr; |
899 | } else { | 900 | } else { |
900 | s[1] = s[3] = 0; | ||
901 | s[0] = ~*optr; | 901 | s[0] = ~*optr; |
902 | s[1] = ~0; | ||
902 | s[2] = *nptr; | 903 | s[2] = *nptr; |
904 | s[3] = 0; | ||
903 | } | 905 | } |
904 | 906 | ||
905 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); | 907 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6298f75d5e93..ac6559cb54f9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1231,7 +1231,7 @@ restart: | |||
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | if (net_ratelimit()) | 1233 | if (net_ratelimit()) |
1234 | printk(KERN_WARNING "Neighbour table overflow.\n"); | 1234 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); |
1235 | rt_drop(rt); | 1235 | rt_drop(rt); |
1236 | return -ENOBUFS; | 1236 | return -ENOBUFS; |
1237 | } | 1237 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 3fb1428e526e..f115ea68a4ef 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -386,8 +386,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
386 | */ | 386 | */ |
387 | 387 | ||
388 | mask = 0; | 388 | mask = 0; |
389 | if (sk->sk_err) | ||
390 | mask = POLLERR; | ||
391 | 389 | ||
392 | /* | 390 | /* |
393 | * POLLHUP is certainly not done right. But poll() doesn't | 391 | * POLLHUP is certainly not done right. But poll() doesn't |
@@ -457,6 +455,11 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
457 | if (tp->urg_data & TCP_URG_VALID) | 455 | if (tp->urg_data & TCP_URG_VALID) |
458 | mask |= POLLPRI; | 456 | mask |= POLLPRI; |
459 | } | 457 | } |
458 | /* This barrier is coupled with smp_wmb() in tcp_reset() */ | ||
459 | smp_rmb(); | ||
460 | if (sk->sk_err) | ||
461 | mask |= POLLERR; | ||
462 | |||
460 | return mask; | 463 | return mask; |
461 | } | 464 | } |
462 | EXPORT_SYMBOL(tcp_poll); | 465 | EXPORT_SYMBOL(tcp_poll); |
@@ -940,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
940 | sg = sk->sk_route_caps & NETIF_F_SG; | 943 | sg = sk->sk_route_caps & NETIF_F_SG; |
941 | 944 | ||
942 | while (--iovlen >= 0) { | 945 | while (--iovlen >= 0) { |
943 | int seglen = iov->iov_len; | 946 | size_t seglen = iov->iov_len; |
944 | unsigned char __user *from = iov->iov_base; | 947 | unsigned char __user *from = iov->iov_base; |
945 | 948 | ||
946 | iov++; | 949 | iov++; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e663b78a2ef6..b55f60f6fcbe 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2545 | cnt += tcp_skb_pcount(skb); | 2545 | cnt += tcp_skb_pcount(skb); |
2546 | 2546 | ||
2547 | if (cnt > packets) { | 2547 | if (cnt > packets) { |
2548 | if (tcp_is_sack(tp) || (oldcnt >= packets)) | 2548 | if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) || |
2549 | (oldcnt >= packets)) | ||
2549 | break; | 2550 | break; |
2550 | 2551 | ||
2551 | mss = skb_shinfo(skb)->gso_size; | 2552 | mss = skb_shinfo(skb)->gso_size; |
@@ -4048,6 +4049,8 @@ static void tcp_reset(struct sock *sk) | |||
4048 | default: | 4049 | default: |
4049 | sk->sk_err = ECONNRESET; | 4050 | sk->sk_err = ECONNRESET; |
4050 | } | 4051 | } |
4052 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ | ||
4053 | smp_wmb(); | ||
4051 | 4054 | ||
4052 | if (!sock_flag(sk, SOCK_DEAD)) | 4055 | if (!sock_flag(sk, SOCK_DEAD)) |
4053 | sk->sk_error_report(sk); | 4056 | sk->sk_error_report(sk); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c35b469e851c..74c54b30600f 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -135,13 +135,16 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) | |||
135 | 135 | ||
136 | /* This function calculates a "timeout" which is equivalent to the timeout of a | 136 | /* This function calculates a "timeout" which is equivalent to the timeout of a |
137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off | 137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off |
138 | * retransmissions with an initial RTO of TCP_RTO_MIN. | 138 | * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if |
139 | * syn_set flag is set. | ||
139 | */ | 140 | */ |
140 | static bool retransmits_timed_out(struct sock *sk, | 141 | static bool retransmits_timed_out(struct sock *sk, |
141 | unsigned int boundary) | 142 | unsigned int boundary, |
143 | bool syn_set) | ||
142 | { | 144 | { |
143 | unsigned int timeout, linear_backoff_thresh; | 145 | unsigned int timeout, linear_backoff_thresh; |
144 | unsigned int start_ts; | 146 | unsigned int start_ts; |
147 | unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; | ||
145 | 148 | ||
146 | if (!inet_csk(sk)->icsk_retransmits) | 149 | if (!inet_csk(sk)->icsk_retransmits) |
147 | return false; | 150 | return false; |
@@ -151,12 +154,12 @@ static bool retransmits_timed_out(struct sock *sk, | |||
151 | else | 154 | else |
152 | start_ts = tcp_sk(sk)->retrans_stamp; | 155 | start_ts = tcp_sk(sk)->retrans_stamp; |
153 | 156 | ||
154 | linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); | 157 | linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); |
155 | 158 | ||
156 | if (boundary <= linear_backoff_thresh) | 159 | if (boundary <= linear_backoff_thresh) |
157 | timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; | 160 | timeout = ((2 << boundary) - 1) * rto_base; |
158 | else | 161 | else |
159 | timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + | 162 | timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + |
160 | (boundary - linear_backoff_thresh) * TCP_RTO_MAX; | 163 | (boundary - linear_backoff_thresh) * TCP_RTO_MAX; |
161 | 164 | ||
162 | return (tcp_time_stamp - start_ts) >= timeout; | 165 | return (tcp_time_stamp - start_ts) >= timeout; |
@@ -167,14 +170,15 @@ static int tcp_write_timeout(struct sock *sk) | |||
167 | { | 170 | { |
168 | struct inet_connection_sock *icsk = inet_csk(sk); | 171 | struct inet_connection_sock *icsk = inet_csk(sk); |
169 | int retry_until; | 172 | int retry_until; |
170 | bool do_reset; | 173 | bool do_reset, syn_set = 0; |
171 | 174 | ||
172 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { | 175 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { |
173 | if (icsk->icsk_retransmits) | 176 | if (icsk->icsk_retransmits) |
174 | dst_negative_advice(sk); | 177 | dst_negative_advice(sk); |
175 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; | 178 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; |
179 | syn_set = 1; | ||
176 | } else { | 180 | } else { |
177 | if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { | 181 | if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { |
178 | /* Black hole detection */ | 182 | /* Black hole detection */ |
179 | tcp_mtu_probing(icsk, sk); | 183 | tcp_mtu_probing(icsk, sk); |
180 | 184 | ||
@@ -187,14 +191,14 @@ static int tcp_write_timeout(struct sock *sk) | |||
187 | 191 | ||
188 | retry_until = tcp_orphan_retries(sk, alive); | 192 | retry_until = tcp_orphan_retries(sk, alive); |
189 | do_reset = alive || | 193 | do_reset = alive || |
190 | !retransmits_timed_out(sk, retry_until); | 194 | !retransmits_timed_out(sk, retry_until, 0); |
191 | 195 | ||
192 | if (tcp_out_of_resources(sk, do_reset)) | 196 | if (tcp_out_of_resources(sk, do_reset)) |
193 | return 1; | 197 | return 1; |
194 | } | 198 | } |
195 | } | 199 | } |
196 | 200 | ||
197 | if (retransmits_timed_out(sk, retry_until)) { | 201 | if (retransmits_timed_out(sk, retry_until, syn_set)) { |
198 | /* Has it gone just too far? */ | 202 | /* Has it gone just too far? */ |
199 | tcp_write_err(sk); | 203 | tcp_write_err(sk); |
200 | return 1; | 204 | return 1; |
@@ -436,7 +440,7 @@ out_reset_timer: | |||
436 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); | 440 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); |
437 | } | 441 | } |
438 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); | 442 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); |
439 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) | 443 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) |
440 | __sk_dst_reset(sk); | 444 | __sk_dst_reset(sk); |
441 | 445 | ||
442 | out:; | 446 | out:; |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 869078d4eeb9..a580349f0b8a 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *net, | |||
61 | 61 | ||
62 | static int xfrm4_get_tos(struct flowi *fl) | 62 | static int xfrm4_get_tos(struct flowi *fl) |
63 | { | 63 | { |
64 | return fl->fl4_tos; | 64 | return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ |
65 | } | 65 | } |
66 | 66 | ||
67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 1ef1366a0a03..47947624eccc 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
@@ -21,21 +21,25 @@ static int xfrm4_init_flags(struct xfrm_state *x) | |||
21 | } | 21 | } |
22 | 22 | ||
23 | static void | 23 | static void |
24 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 24 | __xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
25 | struct xfrm_tmpl *tmpl, | 25 | { |
26 | xfrm_address_t *daddr, xfrm_address_t *saddr) | 26 | sel->daddr.a4 = fl->fl4_dst; |
27 | sel->saddr.a4 = fl->fl4_src; | ||
28 | sel->dport = xfrm_flowi_dport(fl); | ||
29 | sel->dport_mask = htons(0xffff); | ||
30 | sel->sport = xfrm_flowi_sport(fl); | ||
31 | sel->sport_mask = htons(0xffff); | ||
32 | sel->family = AF_INET; | ||
33 | sel->prefixlen_d = 32; | ||
34 | sel->prefixlen_s = 32; | ||
35 | sel->proto = fl->proto; | ||
36 | sel->ifindex = fl->oif; | ||
37 | } | ||
38 | |||
39 | static void | ||
40 | xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
41 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
27 | { | 42 | { |
28 | x->sel.daddr.a4 = fl->fl4_dst; | ||
29 | x->sel.saddr.a4 = fl->fl4_src; | ||
30 | x->sel.dport = xfrm_flowi_dport(fl); | ||
31 | x->sel.dport_mask = htons(0xffff); | ||
32 | x->sel.sport = xfrm_flowi_sport(fl); | ||
33 | x->sel.sport_mask = htons(0xffff); | ||
34 | x->sel.family = AF_INET; | ||
35 | x->sel.prefixlen_d = 32; | ||
36 | x->sel.prefixlen_s = 32; | ||
37 | x->sel.proto = fl->proto; | ||
38 | x->sel.ifindex = fl->oif; | ||
39 | x->id = tmpl->id; | 43 | x->id = tmpl->id; |
40 | if (x->id.daddr.a4 == 0) | 44 | if (x->id.daddr.a4 == 0) |
41 | x->id.daddr.a4 = daddr->a4; | 45 | x->id.daddr.a4 = daddr->a4; |
@@ -70,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
70 | .owner = THIS_MODULE, | 74 | .owner = THIS_MODULE, |
71 | .init_flags = xfrm4_init_flags, | 75 | .init_flags = xfrm4_init_flags, |
72 | .init_tempsel = __xfrm4_init_tempsel, | 76 | .init_tempsel = __xfrm4_init_tempsel, |
77 | .init_temprop = xfrm4_init_temprop, | ||
73 | .output = xfrm4_output, | 78 | .output = xfrm4_output, |
74 | .extract_input = xfrm4_extract_input, | 79 | .extract_input = xfrm4_extract_input, |
75 | .extract_output = xfrm4_extract_output, | 80 | .extract_output = xfrm4_extract_output, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ab70a3fbcafa..324fac3b6c16 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4637,10 +4637,12 @@ int __init addrconf_init(void) | |||
4637 | if (err < 0) { | 4637 | if (err < 0) { |
4638 | printk(KERN_CRIT "IPv6 Addrconf:" | 4638 | printk(KERN_CRIT "IPv6 Addrconf:" |
4639 | " cannot initialize default policy table: %d.\n", err); | 4639 | " cannot initialize default policy table: %d.\n", err); |
4640 | return err; | 4640 | goto out; |
4641 | } | 4641 | } |
4642 | 4642 | ||
4643 | register_pernet_subsys(&addrconf_ops); | 4643 | err = register_pernet_subsys(&addrconf_ops); |
4644 | if (err < 0) | ||
4645 | goto out_addrlabel; | ||
4644 | 4646 | ||
4645 | /* The addrconf netdev notifier requires that loopback_dev | 4647 | /* The addrconf netdev notifier requires that loopback_dev |
4646 | * has it's ipv6 private information allocated and setup | 4648 | * has it's ipv6 private information allocated and setup |
@@ -4692,7 +4694,9 @@ errout: | |||
4692 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4694 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4693 | errlo: | 4695 | errlo: |
4694 | unregister_pernet_subsys(&addrconf_ops); | 4696 | unregister_pernet_subsys(&addrconf_ops); |
4695 | 4697 | out_addrlabel: | |
4698 | ipv6_addr_label_cleanup(); | ||
4699 | out: | ||
4696 | return err; | 4700 | return err; |
4697 | } | 4701 | } |
4698 | 4702 | ||
@@ -4703,6 +4707,7 @@ void addrconf_cleanup(void) | |||
4703 | 4707 | ||
4704 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4708 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4705 | unregister_pernet_subsys(&addrconf_ops); | 4709 | unregister_pernet_subsys(&addrconf_ops); |
4710 | ipv6_addr_label_cleanup(); | ||
4706 | 4711 | ||
4707 | rtnl_lock(); | 4712 | rtnl_lock(); |
4708 | 4713 | ||
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index f0e774cea386..8175f802651b 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -393,6 +393,11 @@ int __init ipv6_addr_label_init(void) | |||
393 | return register_pernet_subsys(&ipv6_addr_label_ops); | 393 | return register_pernet_subsys(&ipv6_addr_label_ops); |
394 | } | 394 | } |
395 | 395 | ||
396 | void ipv6_addr_label_cleanup(void) | ||
397 | { | ||
398 | unregister_pernet_subsys(&ipv6_addr_label_ops); | ||
399 | } | ||
400 | |||
396 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { | 401 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { |
397 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, | 402 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, |
398 | [IFAL_LABEL] = { .len = sizeof(u32), }, | 403 | [IFAL_LABEL] = { .len = sizeof(u32), }, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d40b330c0ee6..980912ed7a38 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
639 | 639 | ||
640 | if (skb_has_frags(skb)) { | 640 | if (skb_has_frags(skb)) { |
641 | int first_len = skb_pagelen(skb); | 641 | int first_len = skb_pagelen(skb); |
642 | int truesizes = 0; | 642 | struct sk_buff *frag2; |
643 | 643 | ||
644 | if (first_len - hlen > mtu || | 644 | if (first_len - hlen > mtu || |
645 | ((first_len - hlen) & 7) || | 645 | ((first_len - hlen) & 7) || |
@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
651 | if (frag->len > mtu || | 651 | if (frag->len > mtu || |
652 | ((frag->len & 7) && frag->next) || | 652 | ((frag->len & 7) && frag->next) || |
653 | skb_headroom(frag) < hlen) | 653 | skb_headroom(frag) < hlen) |
654 | goto slow_path; | 654 | goto slow_path_clean; |
655 | 655 | ||
656 | /* Partially cloned skb? */ | 656 | /* Partially cloned skb? */ |
657 | if (skb_shared(frag)) | 657 | if (skb_shared(frag)) |
658 | goto slow_path; | 658 | goto slow_path_clean; |
659 | 659 | ||
660 | BUG_ON(frag->sk); | 660 | BUG_ON(frag->sk); |
661 | if (skb->sk) { | 661 | if (skb->sk) { |
662 | frag->sk = skb->sk; | 662 | frag->sk = skb->sk; |
663 | frag->destructor = sock_wfree; | 663 | frag->destructor = sock_wfree; |
664 | truesizes += frag->truesize; | ||
665 | } | 664 | } |
665 | skb->truesize -= frag->truesize; | ||
666 | } | 666 | } |
667 | 667 | ||
668 | err = 0; | 668 | err = 0; |
@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
693 | 693 | ||
694 | first_len = skb_pagelen(skb); | 694 | first_len = skb_pagelen(skb); |
695 | skb->data_len = first_len - skb_headlen(skb); | 695 | skb->data_len = first_len - skb_headlen(skb); |
696 | skb->truesize -= truesizes; | ||
697 | skb->len = first_len; | 696 | skb->len = first_len; |
698 | ipv6_hdr(skb)->payload_len = htons(first_len - | 697 | ipv6_hdr(skb)->payload_len = htons(first_len - |
699 | sizeof(struct ipv6hdr)); | 698 | sizeof(struct ipv6hdr)); |
@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | IPSTATS_MIB_FRAGFAILS); | 755 | IPSTATS_MIB_FRAGFAILS); |
757 | dst_release(&rt->dst); | 756 | dst_release(&rt->dst); |
758 | return err; | 757 | return err; |
758 | |||
759 | slow_path_clean: | ||
760 | skb_walk_frags(skb, frag2) { | ||
761 | if (frag2 == frag) | ||
762 | break; | ||
763 | frag2->sk = NULL; | ||
764 | frag2->destructor = NULL; | ||
765 | skb->truesize += frag2->truesize; | ||
766 | } | ||
759 | } | 767 | } |
760 | 768 | ||
761 | slow_path: | 769 | slow_path: |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d126365ac046..8323136bdc54 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad | |||
670 | 670 | ||
671 | if (net_ratelimit()) | 671 | if (net_ratelimit()) |
672 | printk(KERN_WARNING | 672 | printk(KERN_WARNING |
673 | "Neighbour table overflow.\n"); | 673 | "ipv6: Neighbour table overflow.\n"); |
674 | dst_free(&rt->dst); | 674 | dst_free(&rt->dst); |
675 | return NULL; | 675 | return NULL; |
676 | } | 676 | } |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index f417b77fa0e1..a67575d472a3 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -20,23 +20,27 @@ | |||
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static void | 22 | static void |
23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
24 | struct xfrm_tmpl *tmpl, | ||
25 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
26 | { | 24 | { |
27 | /* Initialize temporary selector matching only | 25 | /* Initialize temporary selector matching only |
28 | * to current session. */ | 26 | * to current session. */ |
29 | ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst); | 27 | ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst); |
30 | ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src); | 28 | ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src); |
31 | x->sel.dport = xfrm_flowi_dport(fl); | 29 | sel->dport = xfrm_flowi_dport(fl); |
32 | x->sel.dport_mask = htons(0xffff); | 30 | sel->dport_mask = htons(0xffff); |
33 | x->sel.sport = xfrm_flowi_sport(fl); | 31 | sel->sport = xfrm_flowi_sport(fl); |
34 | x->sel.sport_mask = htons(0xffff); | 32 | sel->sport_mask = htons(0xffff); |
35 | x->sel.family = AF_INET6; | 33 | sel->family = AF_INET6; |
36 | x->sel.prefixlen_d = 128; | 34 | sel->prefixlen_d = 128; |
37 | x->sel.prefixlen_s = 128; | 35 | sel->prefixlen_s = 128; |
38 | x->sel.proto = fl->proto; | 36 | sel->proto = fl->proto; |
39 | x->sel.ifindex = fl->oif; | 37 | sel->ifindex = fl->oif; |
38 | } | ||
39 | |||
40 | static void | ||
41 | xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
42 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
43 | { | ||
40 | x->id = tmpl->id; | 44 | x->id = tmpl->id; |
41 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) | 45 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) |
42 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); | 46 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); |
@@ -168,6 +172,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
168 | .eth_proto = htons(ETH_P_IPV6), | 172 | .eth_proto = htons(ETH_P_IPV6), |
169 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
170 | .init_tempsel = __xfrm6_init_tempsel, | 174 | .init_tempsel = __xfrm6_init_tempsel, |
175 | .init_temprop = xfrm6_init_temprop, | ||
171 | .tmpl_sort = __xfrm6_tmpl_sort, | 176 | .tmpl_sort = __xfrm6_tmpl_sort, |
172 | .state_sort = __xfrm6_state_sort, | 177 | .state_sort = __xfrm6_state_sort, |
173 | .output = xfrm6_output, | 178 | .output = xfrm6_output, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa0f37e4afe4..28624282c5f3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2199,9 +2199,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2199 | struct net_device *prev_dev = NULL; | 2199 | struct net_device *prev_dev = NULL; |
2200 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2200 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2201 | 2201 | ||
2202 | if (status->flag & RX_FLAG_INTERNAL_CMTR) | ||
2203 | goto out_free_skb; | ||
2204 | |||
2205 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2202 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2206 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2203 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
2207 | goto out_free_skb; | 2204 | goto out_free_skb; |
@@ -2260,7 +2257,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2260 | } else | 2257 | } else |
2261 | goto out_free_skb; | 2258 | goto out_free_skb; |
2262 | 2259 | ||
2263 | status->flag |= RX_FLAG_INTERNAL_CMTR; | ||
2264 | return; | 2260 | return; |
2265 | 2261 | ||
2266 | out_free_skb: | 2262 | out_free_skb: |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 7dcf7a404190..8d9e4c949b96 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -48,15 +48,17 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) | |||
48 | { | 48 | { |
49 | unsigned int off, len; | 49 | unsigned int off, len; |
50 | struct nf_ct_ext_type *t; | 50 | struct nf_ct_ext_type *t; |
51 | size_t alloc_size; | ||
51 | 52 | ||
52 | rcu_read_lock(); | 53 | rcu_read_lock(); |
53 | t = rcu_dereference(nf_ct_ext_types[id]); | 54 | t = rcu_dereference(nf_ct_ext_types[id]); |
54 | BUG_ON(t == NULL); | 55 | BUG_ON(t == NULL); |
55 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); | 56 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); |
56 | len = off + t->len; | 57 | len = off + t->len; |
58 | alloc_size = t->alloc_size; | ||
57 | rcu_read_unlock(); | 59 | rcu_read_unlock(); |
58 | 60 | ||
59 | *ext = kzalloc(t->alloc_size, gfp); | 61 | *ext = kzalloc(alloc_size, gfp); |
60 | if (!*ext) | 62 | if (!*ext) |
61 | return NULL; | 63 | return NULL; |
62 | 64 | ||
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 53d892210a04..f64de9544866 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1376,7 +1376,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1376 | unsigned int msglen, origlen; | 1376 | unsigned int msglen, origlen; |
1377 | const char *dptr, *end; | 1377 | const char *dptr, *end; |
1378 | s16 diff, tdiff = 0; | 1378 | s16 diff, tdiff = 0; |
1379 | int ret; | 1379 | int ret = NF_ACCEPT; |
1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; | 1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; |
1381 | 1381 | ||
1382 | if (ctinfo != IP_CT_ESTABLISHED && | 1382 | if (ctinfo != IP_CT_ESTABLISHED && |
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 5490fc37c92d..daab8c4a903c 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c | |||
@@ -70,7 +70,11 @@ nf_tproxy_destructor(struct sk_buff *skb) | |||
70 | int | 70 | int |
71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) | 71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) |
72 | { | 72 | { |
73 | if (inet_sk(sk)->transparent) { | 73 | bool transparent = (sk->sk_state == TCP_TIME_WAIT) ? |
74 | inet_twsk(sk)->tw_transparent : | ||
75 | inet_sk(sk)->transparent; | ||
76 | |||
77 | if (transparent) { | ||
74 | skb_orphan(skb); | 78 | skb_orphan(skb); |
75 | skb->sk = sk; | 79 | skb->sk = sk; |
76 | skb->destructor = nf_tproxy_destructor; | 80 | skb->destructor = nf_tproxy_destructor; |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b2a3ae6cad78..15003021f4f0 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -225,12 +225,13 @@ static void pipe_grant_credits(struct sock *sk) | |||
225 | static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) | 225 | static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) |
226 | { | 226 | { |
227 | struct pep_sock *pn = pep_sk(sk); | 227 | struct pep_sock *pn = pep_sk(sk); |
228 | struct pnpipehdr *hdr = pnp_hdr(skb); | 228 | struct pnpipehdr *hdr; |
229 | int wake = 0; | 229 | int wake = 0; |
230 | 230 | ||
231 | if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) | 231 | if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) |
232 | return -EINVAL; | 232 | return -EINVAL; |
233 | 233 | ||
234 | hdr = pnp_hdr(skb); | ||
234 | if (hdr->data[0] != PN_PEP_TYPE_COMMON) { | 235 | if (hdr->data[0] != PN_PEP_TYPE_COMMON) { |
235 | LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", | 236 | LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", |
236 | (unsigned)hdr->data[0]); | 237 | (unsigned)hdr->data[0]); |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index c397524c039c..c519939e8da9 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
43 | struct rds_connection *conn; | 43 | struct rds_connection *conn; |
44 | struct rds_tcp_connection *tc; | 44 | struct rds_tcp_connection *tc; |
45 | 45 | ||
46 | read_lock(&sk->sk_callback_lock); | 46 | read_lock_bh(&sk->sk_callback_lock); |
47 | conn = sk->sk_user_data; | 47 | conn = sk->sk_user_data; |
48 | if (conn == NULL) { | 48 | if (conn == NULL) { |
49 | state_change = sk->sk_state_change; | 49 | state_change = sk->sk_state_change; |
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | out: | 70 | out: |
71 | read_unlock(&sk->sk_callback_lock); | 71 | read_unlock_bh(&sk->sk_callback_lock); |
72 | state_change(sk); | 72 | state_change(sk); |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 975183fe6950..27844f231d10 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -114,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
114 | 114 | ||
115 | rdsdebug("listen data ready sk %p\n", sk); | 115 | rdsdebug("listen data ready sk %p\n", sk); |
116 | 116 | ||
117 | read_lock(&sk->sk_callback_lock); | 117 | read_lock_bh(&sk->sk_callback_lock); |
118 | ready = sk->sk_user_data; | 118 | ready = sk->sk_user_data; |
119 | if (ready == NULL) { /* check for teardown race */ | 119 | if (ready == NULL) { /* check for teardown race */ |
120 | ready = sk->sk_data_ready; | 120 | ready = sk->sk_data_ready; |
@@ -131,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
131 | queue_work(rds_wq, &rds_tcp_listen_work); | 131 | queue_work(rds_wq, &rds_tcp_listen_work); |
132 | 132 | ||
133 | out: | 133 | out: |
134 | read_unlock(&sk->sk_callback_lock); | 134 | read_unlock_bh(&sk->sk_callback_lock); |
135 | ready(sk, bytes); | 135 | ready(sk, bytes); |
136 | } | 136 | } |
137 | 137 | ||
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 1aba6878fa5d..e43797404102 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -324,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
324 | 324 | ||
325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); | 325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); |
326 | 326 | ||
327 | read_lock(&sk->sk_callback_lock); | 327 | read_lock_bh(&sk->sk_callback_lock); |
328 | conn = sk->sk_user_data; | 328 | conn = sk->sk_user_data; |
329 | if (conn == NULL) { /* check for teardown race */ | 329 | if (conn == NULL) { /* check for teardown race */ |
330 | ready = sk->sk_data_ready; | 330 | ready = sk->sk_data_ready; |
@@ -338,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) | 338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) |
339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); | 339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); |
340 | out: | 340 | out: |
341 | read_unlock(&sk->sk_callback_lock); | 341 | read_unlock_bh(&sk->sk_callback_lock); |
342 | ready(sk, bytes); | 342 | ready(sk, bytes); |
343 | } | 343 | } |
344 | 344 | ||
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index a28b895ff0d1..2f012a07d94d 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
224 | struct rds_connection *conn; | 224 | struct rds_connection *conn; |
225 | struct rds_tcp_connection *tc; | 225 | struct rds_tcp_connection *tc; |
226 | 226 | ||
227 | read_lock(&sk->sk_callback_lock); | 227 | read_lock_bh(&sk->sk_callback_lock); |
228 | conn = sk->sk_user_data; | 228 | conn = sk->sk_user_data; |
229 | if (conn == NULL) { | 229 | if (conn == NULL) { |
230 | write_space = sk->sk_write_space; | 230 | write_space = sk->sk_write_space; |
@@ -244,7 +244,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
245 | 245 | ||
246 | out: | 246 | out: |
247 | read_unlock(&sk->sk_callback_lock); | 247 | read_unlock_bh(&sk->sk_callback_lock); |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * write_space is only called when data leaves tcp's send queue if | 250 | * write_space is only called when data leaves tcp's send queue if |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 8e45e76a95f5..d952e7eac188 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -679,7 +679,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
680 | return -EINVAL; | 680 | return -EINVAL; |
681 | 681 | ||
682 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 682 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
683 | return -EINVAL; | 683 | return -EINVAL; |
684 | 684 | ||
685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { | 685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { |
@@ -739,7 +739,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
740 | return -EINVAL; | 740 | return -EINVAL; |
741 | 741 | ||
742 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 742 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
743 | return -EINVAL; | 743 | return -EINVAL; |
744 | 744 | ||
745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ | 745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b6309db56226..fe9306bf10cc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
800 | u32 _xid; | 800 | u32 _xid; |
801 | __be32 *xp; | 801 | __be32 *xp; |
802 | 802 | ||
803 | read_lock(&sk->sk_callback_lock); | 803 | read_lock_bh(&sk->sk_callback_lock); |
804 | dprintk("RPC: xs_udp_data_ready...\n"); | 804 | dprintk("RPC: xs_udp_data_ready...\n"); |
805 | if (!(xprt = xprt_from_sock(sk))) | 805 | if (!(xprt = xprt_from_sock(sk))) |
806 | goto out; | 806 | goto out; |
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
852 | dropit: | 852 | dropit: |
853 | skb_free_datagram(sk, skb); | 853 | skb_free_datagram(sk, skb); |
854 | out: | 854 | out: |
855 | read_unlock(&sk->sk_callback_lock); | 855 | read_unlock_bh(&sk->sk_callback_lock); |
856 | } | 856 | } |
857 | 857 | ||
858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) | 858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) |
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1229 | 1229 | ||
1230 | dprintk("RPC: xs_tcp_data_ready...\n"); | 1230 | dprintk("RPC: xs_tcp_data_ready...\n"); |
1231 | 1231 | ||
1232 | read_lock(&sk->sk_callback_lock); | 1232 | read_lock_bh(&sk->sk_callback_lock); |
1233 | if (!(xprt = xprt_from_sock(sk))) | 1233 | if (!(xprt = xprt_from_sock(sk))) |
1234 | goto out; | 1234 | goto out; |
1235 | if (xprt->shutdown) | 1235 | if (xprt->shutdown) |
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | 1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); |
1249 | } while (read > 0); | 1249 | } while (read > 0); |
1250 | out: | 1250 | out: |
1251 | read_unlock(&sk->sk_callback_lock); | 1251 | read_unlock_bh(&sk->sk_callback_lock); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* | 1254 | /* |
@@ -1301,7 +1301,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1301 | { | 1301 | { |
1302 | struct rpc_xprt *xprt; | 1302 | struct rpc_xprt *xprt; |
1303 | 1303 | ||
1304 | read_lock(&sk->sk_callback_lock); | 1304 | read_lock_bh(&sk->sk_callback_lock); |
1305 | if (!(xprt = xprt_from_sock(sk))) | 1305 | if (!(xprt = xprt_from_sock(sk))) |
1306 | goto out; | 1306 | goto out; |
1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); | 1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); |
@@ -1313,7 +1313,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1313 | 1313 | ||
1314 | switch (sk->sk_state) { | 1314 | switch (sk->sk_state) { |
1315 | case TCP_ESTABLISHED: | 1315 | case TCP_ESTABLISHED: |
1316 | spin_lock_bh(&xprt->transport_lock); | 1316 | spin_lock(&xprt->transport_lock); |
1317 | if (!xprt_test_and_set_connected(xprt)) { | 1317 | if (!xprt_test_and_set_connected(xprt)) { |
1318 | struct sock_xprt *transport = container_of(xprt, | 1318 | struct sock_xprt *transport = container_of(xprt, |
1319 | struct sock_xprt, xprt); | 1319 | struct sock_xprt, xprt); |
@@ -1327,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1327 | 1327 | ||
1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1329 | } | 1329 | } |
1330 | spin_unlock_bh(&xprt->transport_lock); | 1330 | spin_unlock(&xprt->transport_lock); |
1331 | break; | 1331 | break; |
1332 | case TCP_FIN_WAIT1: | 1332 | case TCP_FIN_WAIT1: |
1333 | /* The client initiated a shutdown of the socket */ | 1333 | /* The client initiated a shutdown of the socket */ |
@@ -1365,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1365 | xs_sock_mark_closed(xprt); | 1365 | xs_sock_mark_closed(xprt); |
1366 | } | 1366 | } |
1367 | out: | 1367 | out: |
1368 | read_unlock(&sk->sk_callback_lock); | 1368 | read_unlock_bh(&sk->sk_callback_lock); |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | /** | 1371 | /** |
@@ -1376,7 +1376,7 @@ static void xs_error_report(struct sock *sk) | |||
1376 | { | 1376 | { |
1377 | struct rpc_xprt *xprt; | 1377 | struct rpc_xprt *xprt; |
1378 | 1378 | ||
1379 | read_lock(&sk->sk_callback_lock); | 1379 | read_lock_bh(&sk->sk_callback_lock); |
1380 | if (!(xprt = xprt_from_sock(sk))) | 1380 | if (!(xprt = xprt_from_sock(sk))) |
1381 | goto out; | 1381 | goto out; |
1382 | dprintk("RPC: %s client %p...\n" | 1382 | dprintk("RPC: %s client %p...\n" |
@@ -1384,7 +1384,7 @@ static void xs_error_report(struct sock *sk) | |||
1384 | __func__, xprt, sk->sk_err); | 1384 | __func__, xprt, sk->sk_err); |
1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1386 | out: | 1386 | out: |
1387 | read_unlock(&sk->sk_callback_lock); | 1387 | read_unlock_bh(&sk->sk_callback_lock); |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static void xs_write_space(struct sock *sk) | 1390 | static void xs_write_space(struct sock *sk) |
@@ -1416,13 +1416,13 @@ static void xs_write_space(struct sock *sk) | |||
1416 | */ | 1416 | */ |
1417 | static void xs_udp_write_space(struct sock *sk) | 1417 | static void xs_udp_write_space(struct sock *sk) |
1418 | { | 1418 | { |
1419 | read_lock(&sk->sk_callback_lock); | 1419 | read_lock_bh(&sk->sk_callback_lock); |
1420 | 1420 | ||
1421 | /* from net/core/sock.c:sock_def_write_space */ | 1421 | /* from net/core/sock.c:sock_def_write_space */ |
1422 | if (sock_writeable(sk)) | 1422 | if (sock_writeable(sk)) |
1423 | xs_write_space(sk); | 1423 | xs_write_space(sk); |
1424 | 1424 | ||
1425 | read_unlock(&sk->sk_callback_lock); | 1425 | read_unlock_bh(&sk->sk_callback_lock); |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | /** | 1428 | /** |
@@ -1437,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk) | |||
1437 | */ | 1437 | */ |
1438 | static void xs_tcp_write_space(struct sock *sk) | 1438 | static void xs_tcp_write_space(struct sock *sk) |
1439 | { | 1439 | { |
1440 | read_lock(&sk->sk_callback_lock); | 1440 | read_lock_bh(&sk->sk_callback_lock); |
1441 | 1441 | ||
1442 | /* from net/core/stream.c:sk_stream_write_space */ | 1442 | /* from net/core/stream.c:sk_stream_write_space */ |
1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
1444 | xs_write_space(sk); | 1444 | xs_write_space(sk); |
1445 | 1445 | ||
1446 | read_unlock(&sk->sk_callback_lock); | 1446 | read_unlock_bh(&sk->sk_callback_lock); |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) | 1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) |
diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c index 3feb28e41c53..674d426a9d24 100644 --- a/net/wireless/wext-priv.c +++ b/net/wireless/wext-priv.c | |||
@@ -152,7 +152,7 @@ static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
152 | } else if (!iwp->pointer) | 152 | } else if (!iwp->pointer) |
153 | return -EFAULT; | 153 | return -EFAULT; |
154 | 154 | ||
155 | extra = kmalloc(extra_size, GFP_KERNEL); | 155 | extra = kzalloc(extra_size, GFP_KERNEL); |
156 | if (!extra) | 156 | if (!extra) |
157 | return -ENOMEM; | 157 | return -ENOMEM; |
158 | 158 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2b3ed7ad4933..cbab6e1a8c9c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1175,9 +1175,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl, | |||
1175 | tmpl->mode == XFRM_MODE_BEET) { | 1175 | tmpl->mode == XFRM_MODE_BEET) { |
1176 | remote = &tmpl->id.daddr; | 1176 | remote = &tmpl->id.daddr; |
1177 | local = &tmpl->saddr; | 1177 | local = &tmpl->saddr; |
1178 | family = tmpl->encap_family; | 1178 | if (xfrm_addr_any(local, tmpl->encap_family)) { |
1179 | if (xfrm_addr_any(local, family)) { | 1179 | error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family); |
1180 | error = xfrm_get_saddr(net, &tmp, remote, family); | ||
1181 | if (error) | 1180 | if (error) |
1182 | goto fail; | 1181 | goto fail; |
1183 | local = &tmp; | 1182 | local = &tmp; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5208b12fbfb4..eb96ce52f178 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -656,15 +656,23 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) | |||
656 | EXPORT_SYMBOL(xfrm_sad_getinfo); | 656 | EXPORT_SYMBOL(xfrm_sad_getinfo); |
657 | 657 | ||
658 | static int | 658 | static int |
659 | xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 659 | xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl, |
660 | struct xfrm_tmpl *tmpl, | 660 | struct xfrm_tmpl *tmpl, |
661 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 661 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
662 | unsigned short family) | 662 | unsigned short family) |
663 | { | 663 | { |
664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); | 664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); |
665 | if (!afinfo) | 665 | if (!afinfo) |
666 | return -1; | 666 | return -1; |
667 | afinfo->init_tempsel(x, fl, tmpl, daddr, saddr); | 667 | afinfo->init_tempsel(&x->sel, fl); |
668 | |||
669 | if (family != tmpl->encap_family) { | ||
670 | xfrm_state_put_afinfo(afinfo); | ||
671 | afinfo = xfrm_state_get_afinfo(tmpl->encap_family); | ||
672 | if (!afinfo) | ||
673 | return -1; | ||
674 | } | ||
675 | afinfo->init_temprop(x, tmpl, daddr, saddr); | ||
668 | xfrm_state_put_afinfo(afinfo); | 676 | xfrm_state_put_afinfo(afinfo); |
669 | return 0; | 677 | return 0; |
670 | } | 678 | } |
@@ -790,37 +798,38 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
790 | int error = 0; | 798 | int error = 0; |
791 | struct xfrm_state *best = NULL; | 799 | struct xfrm_state *best = NULL; |
792 | u32 mark = pol->mark.v & pol->mark.m; | 800 | u32 mark = pol->mark.v & pol->mark.m; |
801 | unsigned short encap_family = tmpl->encap_family; | ||
793 | 802 | ||
794 | to_put = NULL; | 803 | to_put = NULL; |
795 | 804 | ||
796 | spin_lock_bh(&xfrm_state_lock); | 805 | spin_lock_bh(&xfrm_state_lock); |
797 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family); | 806 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); |
798 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { | 807 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
799 | if (x->props.family == family && | 808 | if (x->props.family == encap_family && |
800 | x->props.reqid == tmpl->reqid && | 809 | x->props.reqid == tmpl->reqid && |
801 | (mark & x->mark.m) == x->mark.v && | 810 | (mark & x->mark.m) == x->mark.v && |
802 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 811 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
803 | xfrm_state_addr_check(x, daddr, saddr, family) && | 812 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
804 | tmpl->mode == x->props.mode && | 813 | tmpl->mode == x->props.mode && |
805 | tmpl->id.proto == x->id.proto && | 814 | tmpl->id.proto == x->id.proto && |
806 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 815 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
807 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 816 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
808 | &best, &acquire_in_progress, &error); | 817 | &best, &acquire_in_progress, &error); |
809 | } | 818 | } |
810 | if (best) | 819 | if (best) |
811 | goto found; | 820 | goto found; |
812 | 821 | ||
813 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family); | 822 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family); |
814 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { | 823 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { |
815 | if (x->props.family == family && | 824 | if (x->props.family == encap_family && |
816 | x->props.reqid == tmpl->reqid && | 825 | x->props.reqid == tmpl->reqid && |
817 | (mark & x->mark.m) == x->mark.v && | 826 | (mark & x->mark.m) == x->mark.v && |
818 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 827 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
819 | xfrm_state_addr_check(x, daddr, saddr, family) && | 828 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
820 | tmpl->mode == x->props.mode && | 829 | tmpl->mode == x->props.mode && |
821 | tmpl->id.proto == x->id.proto && | 830 | tmpl->id.proto == x->id.proto && |
822 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 831 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
823 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 832 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
824 | &best, &acquire_in_progress, &error); | 833 | &best, &acquire_in_progress, &error); |
825 | } | 834 | } |
826 | 835 | ||
@@ -829,7 +838,7 @@ found: | |||
829 | if (!x && !error && !acquire_in_progress) { | 838 | if (!x && !error && !acquire_in_progress) { |
830 | if (tmpl->id.spi && | 839 | if (tmpl->id.spi && |
831 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, | 840 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, |
832 | tmpl->id.proto, family)) != NULL) { | 841 | tmpl->id.proto, encap_family)) != NULL) { |
833 | to_put = x0; | 842 | to_put = x0; |
834 | error = -EEXIST; | 843 | error = -EEXIST; |
835 | goto out; | 844 | goto out; |
@@ -839,9 +848,9 @@ found: | |||
839 | error = -ENOMEM; | 848 | error = -ENOMEM; |
840 | goto out; | 849 | goto out; |
841 | } | 850 | } |
842 | /* Initialize temporary selector matching only | 851 | /* Initialize temporary state matching only |
843 | * to current session. */ | 852 | * to current session. */ |
844 | xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family); | 853 | xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family); |
845 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); | 854 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); |
846 | 855 | ||
847 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); | 856 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); |
@@ -856,10 +865,10 @@ found: | |||
856 | x->km.state = XFRM_STATE_ACQ; | 865 | x->km.state = XFRM_STATE_ACQ; |
857 | list_add(&x->km.all, &net->xfrm.state_all); | 866 | list_add(&x->km.all, &net->xfrm.state_all); |
858 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); | 867 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
859 | h = xfrm_src_hash(net, daddr, saddr, family); | 868 | h = xfrm_src_hash(net, daddr, saddr, encap_family); |
860 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); | 869 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
861 | if (x->id.spi) { | 870 | if (x->id.spi) { |
862 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family); | 871 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family); |
863 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); | 872 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); |
864 | } | 873 | } |
865 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; | 874 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; |
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index ee03a4f0b64f..06473791c08a 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c | |||
@@ -24,6 +24,7 @@ static int __init example_init(void) | |||
24 | { | 24 | { |
25 | int i; | 25 | int i; |
26 | unsigned int ret; | 26 | unsigned int ret; |
27 | unsigned int nents; | ||
27 | struct scatterlist sg[10]; | 28 | struct scatterlist sg[10]; |
28 | 29 | ||
29 | printk(KERN_INFO "DMA fifo test start\n"); | 30 | printk(KERN_INFO "DMA fifo test start\n"); |
@@ -61,9 +62,9 @@ static int __init example_init(void) | |||
61 | * byte at the beginning, after the kfifo_skip(). | 62 | * byte at the beginning, after the kfifo_skip(). |
62 | */ | 63 | */ |
63 | sg_init_table(sg, ARRAY_SIZE(sg)); | 64 | sg_init_table(sg, ARRAY_SIZE(sg)); |
64 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); | 65 | nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); |
65 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 66 | printk(KERN_INFO "DMA sgl entries: %d\n", nents); |
66 | if (!ret) { | 67 | if (!nents) { |
67 | /* fifo is full and no sgl was created */ | 68 | /* fifo is full and no sgl was created */ |
68 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); | 69 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); |
69 | return -EIO; | 70 | return -EIO; |
@@ -71,7 +72,7 @@ static int __init example_init(void) | |||
71 | 72 | ||
72 | /* receive data */ | 73 | /* receive data */ |
73 | printk(KERN_INFO "scatterlist for receive:\n"); | 74 | printk(KERN_INFO "scatterlist for receive:\n"); |
74 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 75 | for (i = 0; i < nents; i++) { |
75 | printk(KERN_INFO | 76 | printk(KERN_INFO |
76 | "sg[%d] -> " | 77 | "sg[%d] -> " |
77 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 78 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
@@ -91,16 +92,16 @@ static int __init example_init(void) | |||
91 | kfifo_dma_in_finish(&fifo, ret); | 92 | kfifo_dma_in_finish(&fifo, ret); |
92 | 93 | ||
93 | /* Prepare to transmit data, example: 8 bytes */ | 94 | /* Prepare to transmit data, example: 8 bytes */ |
94 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); | 95 | nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); |
95 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 96 | printk(KERN_INFO "DMA sgl entries: %d\n", nents); |
96 | if (!ret) { | 97 | if (!nents) { |
97 | /* no data was available and no sgl was created */ | 98 | /* no data was available and no sgl was created */ |
98 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); | 99 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); |
99 | return -EIO; | 100 | return -EIO; |
100 | } | 101 | } |
101 | 102 | ||
102 | printk(KERN_INFO "scatterlist for transmit:\n"); | 103 | printk(KERN_INFO "scatterlist for transmit:\n"); |
103 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 104 | for (i = 0; i < nents; i++) { |
104 | printk(KERN_INFO | 105 | printk(KERN_INFO |
105 | "sg[%d] -> " | 106 | "sg[%d] -> " |
106 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 107 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
diff --git a/scripts/Makefile b/scripts/Makefile index 842dbc2d5aed..2e088109fbd5 100644 --- a/scripts/Makefile +++ b/scripts/Makefile | |||
@@ -11,6 +11,7 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms | |||
11 | hostprogs-$(CONFIG_LOGO) += pnmtologo | 11 | hostprogs-$(CONFIG_LOGO) += pnmtologo |
12 | hostprogs-$(CONFIG_VT) += conmakehash | 12 | hostprogs-$(CONFIG_VT) += conmakehash |
13 | hostprogs-$(CONFIG_IKCONFIG) += bin2c | 13 | hostprogs-$(CONFIG_IKCONFIG) += bin2c |
14 | hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount | ||
14 | 15 | ||
15 | always := $(hostprogs-y) $(hostprogs-m) | 16 | always := $(hostprogs-y) $(hostprogs-m) |
16 | 17 | ||
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a1a5cf95a68d..4d03a7efc689 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build | |||
@@ -209,12 +209,16 @@ cmd_modversions = \ | |||
209 | endif | 209 | endif |
210 | 210 | ||
211 | ifdef CONFIG_FTRACE_MCOUNT_RECORD | 211 | ifdef CONFIG_FTRACE_MCOUNT_RECORD |
212 | ifdef BUILD_C_RECORDMCOUNT | ||
213 | cmd_record_mcount = $(srctree)/scripts/recordmcount "$(@)"; | ||
214 | else | ||
212 | cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ | 215 | cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ |
213 | "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ | 216 | "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ |
214 | "$(if $(CONFIG_64BIT),64,32)" \ | 217 | "$(if $(CONFIG_64BIT),64,32)" \ |
215 | "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ | 218 | "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ |
216 | "$(if $(part-of-module),1,0)" "$(@)"; | 219 | "$(if $(part-of-module),1,0)" "$(@)"; |
217 | endif | 220 | endif |
221 | endif | ||
218 | 222 | ||
219 | define rule_cc_o_c | 223 | define rule_cc_o_c |
220 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ | 224 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 54fd1b700131..7bfcf1a09ac5 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -101,14 +101,6 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" | |||
101 | modname_flags = $(if $(filter 1,$(words $(modname))),\ | 101 | modname_flags = $(if $(filter 1,$(words $(modname))),\ |
102 | -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") | 102 | -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") |
103 | 103 | ||
104 | #hash values | ||
105 | ifdef CONFIG_DYNAMIC_DEBUG | ||
106 | debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ | ||
107 | -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" | ||
108 | else | ||
109 | debug_flags = | ||
110 | endif | ||
111 | |||
112 | orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ | 104 | orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ |
113 | $(ccflags-y) $(CFLAGS_$(basetarget).o) | 105 | $(ccflags-y) $(CFLAGS_$(basetarget).o) |
114 | _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) | 106 | _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) |
@@ -152,8 +144,7 @@ endif | |||
152 | 144 | ||
153 | c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ | 145 | c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ |
154 | $(__c_flags) $(modkern_cflags) \ | 146 | $(__c_flags) $(modkern_cflags) \ |
155 | -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ | 147 | -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) |
156 | $(debug_flags) | ||
157 | 148 | ||
158 | a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ | 149 | a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ |
159 | $(__a_flags) $(modkern_aflags) | 150 | $(__a_flags) $(modkern_aflags) |
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 09559951df12..4c324a1f1e0e 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile | |||
@@ -9,7 +9,7 @@ | |||
9 | # fixdep: Used to generate dependency information during build process | 9 | # fixdep: Used to generate dependency information during build process |
10 | # docproc: Used in Documentation/DocBook | 10 | # docproc: Used in Documentation/DocBook |
11 | 11 | ||
12 | hostprogs-y := fixdep docproc hash | 12 | hostprogs-y := fixdep docproc |
13 | always := $(hostprogs-y) | 13 | always := $(hostprogs-y) |
14 | 14 | ||
15 | # fixdep is needed to compile other host programs | 15 | # fixdep is needed to compile other host programs |
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c deleted file mode 100644 index 2ef5d3f666b8..000000000000 --- a/scripts/basic/hash.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com> | ||
3 | * | ||
4 | */ | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | #define DYNAMIC_DEBUG_HASH_BITS 6 | ||
11 | |||
12 | static const char *program; | ||
13 | |||
14 | static void usage(void) | ||
15 | { | ||
16 | printf("Usage: %s <djb2|r5> <modname>\n", program); | ||
17 | exit(1); | ||
18 | } | ||
19 | |||
20 | /* djb2 hashing algorithm by Dan Bernstein. From: | ||
21 | * http://www.cse.yorku.ca/~oz/hash.html | ||
22 | */ | ||
23 | |||
24 | static unsigned int djb2_hash(char *str) | ||
25 | { | ||
26 | unsigned long hash = 5381; | ||
27 | int c; | ||
28 | |||
29 | c = *str; | ||
30 | while (c) { | ||
31 | hash = ((hash << 5) + hash) + c; | ||
32 | c = *++str; | ||
33 | } | ||
34 | return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); | ||
35 | } | ||
36 | |||
37 | static unsigned int r5_hash(char *str) | ||
38 | { | ||
39 | unsigned long hash = 0; | ||
40 | int c; | ||
41 | |||
42 | c = *str; | ||
43 | while (c) { | ||
44 | hash = (hash + (c << 4) + (c >> 4)) * 11; | ||
45 | c = *++str; | ||
46 | } | ||
47 | return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1)); | ||
48 | } | ||
49 | |||
50 | int main(int argc, char *argv[]) | ||
51 | { | ||
52 | program = argv[0]; | ||
53 | |||
54 | if (argc != 3) | ||
55 | usage(); | ||
56 | if (!strcmp(argv[1], "djb2")) | ||
57 | printf("%d\n", djb2_hash(argv[2])); | ||
58 | else if (!strcmp(argv[1], "r5")) | ||
59 | printf("%d\n", r5_hash(argv[2])); | ||
60 | else | ||
61 | usage(); | ||
62 | exit(0); | ||
63 | } | ||
64 | |||
diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh new file mode 100644 index 000000000000..520d16b1ffaf --- /dev/null +++ b/scripts/gcc-goto.sh | |||
@@ -0,0 +1,5 @@ | |||
1 | #!/bin/sh | ||
2 | # Test for gcc 'asm goto' suport | ||
3 | # Copyright (C) 2010, Jason Baron <jbaron@redhat.com> | ||
4 | |||
5 | echo "int main(void) { entry: asm goto (\"\"::::entry); return 0; }" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" | ||
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c new file mode 100644 index 000000000000..7f7f7180fe24 --- /dev/null +++ b/scripts/recordmcount.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * recordmcount.c: construct a table of the locations of calls to 'mcount' | ||
3 | * so that ftrace can find them quickly. | ||
4 | * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved. | ||
5 | * Licensed under the GNU General Public License, version 2 (GPLv2). | ||
6 | * | ||
7 | * Restructured to fit Linux format, as well as other updates: | ||
8 | * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * Strategy: alter the .o file in-place. | ||
13 | * | ||
14 | * Append a new STRTAB that has the new section names, followed by a new array | ||
15 | * ElfXX_Shdr[] that has the new section headers, followed by the section | ||
16 | * contents for __mcount_loc and its relocations. The old shstrtab strings, | ||
17 | * and the old ElfXX_Shdr[] array, remain as "garbage" (commonly, a couple | ||
18 | * kilobytes.) Subsequent processing by /bin/ld (or the kernel module loader) | ||
19 | * will ignore the garbage regions, because they are not designated by the | ||
20 | * new .e_shoff nor the new ElfXX_Shdr[]. [In order to remove the garbage, | ||
21 | * then use "ld -r" to create a new file that omits the garbage.] | ||
22 | */ | ||
23 | |||
24 | #include <sys/types.h> | ||
25 | #include <sys/mman.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <elf.h> | ||
28 | #include <fcntl.h> | ||
29 | #include <setjmp.h> | ||
30 | #include <stdio.h> | ||
31 | #include <stdlib.h> | ||
32 | #include <string.h> | ||
33 | #include <unistd.h> | ||
34 | |||
35 | static int fd_map; /* File descriptor for file being modified. */ | ||
36 | static int mmap_failed; /* Boolean flag. */ | ||
37 | static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ | ||
38 | static char gpfx; /* prefix for global symbol name (sometimes '_') */ | ||
39 | static struct stat sb; /* Remember .st_size, etc. */ | ||
40 | static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ | ||
41 | |||
42 | /* setjmp() return values */ | ||
43 | enum { | ||
44 | SJ_SETJMP = 0, /* hardwired first return */ | ||
45 | SJ_FAIL, | ||
46 | SJ_SUCCEED | ||
47 | }; | ||
48 | |||
49 | /* Per-file resource cleanup when multiple files. */ | ||
50 | static void | ||
51 | cleanup(void) | ||
52 | { | ||
53 | if (!mmap_failed) | ||
54 | munmap(ehdr_curr, sb.st_size); | ||
55 | else | ||
56 | free(ehdr_curr); | ||
57 | close(fd_map); | ||
58 | } | ||
59 | |||
60 | static void __attribute__((noreturn)) | ||
61 | fail_file(void) | ||
62 | { | ||
63 | cleanup(); | ||
64 | longjmp(jmpenv, SJ_FAIL); | ||
65 | } | ||
66 | |||
67 | static void __attribute__((noreturn)) | ||
68 | succeed_file(void) | ||
69 | { | ||
70 | cleanup(); | ||
71 | longjmp(jmpenv, SJ_SUCCEED); | ||
72 | } | ||
73 | |||
74 | /* ulseek, uread, ...: Check return value for errors. */ | ||
75 | |||
76 | static off_t | ||
77 | ulseek(int const fd, off_t const offset, int const whence) | ||
78 | { | ||
79 | off_t const w = lseek(fd, offset, whence); | ||
80 | if ((off_t)-1 == w) { | ||
81 | perror("lseek"); | ||
82 | fail_file(); | ||
83 | } | ||
84 | return w; | ||
85 | } | ||
86 | |||
87 | static size_t | ||
88 | uread(int const fd, void *const buf, size_t const count) | ||
89 | { | ||
90 | size_t const n = read(fd, buf, count); | ||
91 | if (n != count) { | ||
92 | perror("read"); | ||
93 | fail_file(); | ||
94 | } | ||
95 | return n; | ||
96 | } | ||
97 | |||
98 | static size_t | ||
99 | uwrite(int const fd, void const *const buf, size_t const count) | ||
100 | { | ||
101 | size_t const n = write(fd, buf, count); | ||
102 | if (n != count) { | ||
103 | perror("write"); | ||
104 | fail_file(); | ||
105 | } | ||
106 | return n; | ||
107 | } | ||
108 | |||
109 | static void * | ||
110 | umalloc(size_t size) | ||
111 | { | ||
112 | void *const addr = malloc(size); | ||
113 | if (0 == addr) { | ||
114 | fprintf(stderr, "malloc failed: %zu bytes\n", size); | ||
115 | fail_file(); | ||
116 | } | ||
117 | return addr; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Get the whole file as a programming convenience in order to avoid | ||
122 | * malloc+lseek+read+free of many pieces. If successful, then mmap | ||
123 | * avoids copying unused pieces; else just read the whole file. | ||
124 | * Open for both read and write; new info will be appended to the file. | ||
125 | * Use MAP_PRIVATE so that a few changes to the in-memory ElfXX_Ehdr | ||
126 | * do not propagate to the file until an explicit overwrite at the last. | ||
127 | * This preserves most aspects of consistency (all except .st_size) | ||
128 | * for simultaneous readers of the file while we are appending to it. | ||
129 | * However, multiple writers still are bad. We choose not to use | ||
130 | * locking because it is expensive and the use case of kernel build | ||
131 | * makes multiple writers unlikely. | ||
132 | */ | ||
133 | static void *mmap_file(char const *fname) | ||
134 | { | ||
135 | void *addr; | ||
136 | |||
137 | fd_map = open(fname, O_RDWR); | ||
138 | if (0 > fd_map || 0 > fstat(fd_map, &sb)) { | ||
139 | perror(fname); | ||
140 | fail_file(); | ||
141 | } | ||
142 | if (!S_ISREG(sb.st_mode)) { | ||
143 | fprintf(stderr, "not a regular file: %s\n", fname); | ||
144 | fail_file(); | ||
145 | } | ||
146 | addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, | ||
147 | fd_map, 0); | ||
148 | mmap_failed = 0; | ||
149 | if (MAP_FAILED == addr) { | ||
150 | mmap_failed = 1; | ||
151 | addr = umalloc(sb.st_size); | ||
152 | uread(fd_map, addr, sb.st_size); | ||
153 | } | ||
154 | return addr; | ||
155 | } | ||
156 | |||
157 | /* w8rev, w8nat, ...: Handle endianness. */ | ||
158 | |||
159 | static uint64_t w8rev(uint64_t const x) | ||
160 | { | ||
161 | return ((0xff & (x >> (0 * 8))) << (7 * 8)) | ||
162 | | ((0xff & (x >> (1 * 8))) << (6 * 8)) | ||
163 | | ((0xff & (x >> (2 * 8))) << (5 * 8)) | ||
164 | | ((0xff & (x >> (3 * 8))) << (4 * 8)) | ||
165 | | ((0xff & (x >> (4 * 8))) << (3 * 8)) | ||
166 | | ((0xff & (x >> (5 * 8))) << (2 * 8)) | ||
167 | | ((0xff & (x >> (6 * 8))) << (1 * 8)) | ||
168 | | ((0xff & (x >> (7 * 8))) << (0 * 8)); | ||
169 | } | ||
170 | |||
171 | static uint32_t w4rev(uint32_t const x) | ||
172 | { | ||
173 | return ((0xff & (x >> (0 * 8))) << (3 * 8)) | ||
174 | | ((0xff & (x >> (1 * 8))) << (2 * 8)) | ||
175 | | ((0xff & (x >> (2 * 8))) << (1 * 8)) | ||
176 | | ((0xff & (x >> (3 * 8))) << (0 * 8)); | ||
177 | } | ||
178 | |||
179 | static uint32_t w2rev(uint16_t const x) | ||
180 | { | ||
181 | return ((0xff & (x >> (0 * 8))) << (1 * 8)) | ||
182 | | ((0xff & (x >> (1 * 8))) << (0 * 8)); | ||
183 | } | ||
184 | |||
185 | static uint64_t w8nat(uint64_t const x) | ||
186 | { | ||
187 | return x; | ||
188 | } | ||
189 | |||
190 | static uint32_t w4nat(uint32_t const x) | ||
191 | { | ||
192 | return x; | ||
193 | } | ||
194 | |||
195 | static uint32_t w2nat(uint16_t const x) | ||
196 | { | ||
197 | return x; | ||
198 | } | ||
199 | |||
200 | static uint64_t (*w8)(uint64_t); | ||
201 | static uint32_t (*w)(uint32_t); | ||
202 | static uint32_t (*w2)(uint16_t); | ||
203 | |||
204 | /* Names of the sections that could contain calls to mcount. */ | ||
205 | static int | ||
206 | is_mcounted_section_name(char const *const txtname) | ||
207 | { | ||
208 | return 0 == strcmp(".text", txtname) || | ||
209 | 0 == strcmp(".sched.text", txtname) || | ||
210 | 0 == strcmp(".spinlock.text", txtname) || | ||
211 | 0 == strcmp(".irqentry.text", txtname) || | ||
212 | 0 == strcmp(".text.unlikely", txtname); | ||
213 | } | ||
214 | |||
215 | /* 32 bit and 64 bit are very similar */ | ||
216 | #include "recordmcount.h" | ||
217 | #define RECORD_MCOUNT_64 | ||
218 | #include "recordmcount.h" | ||
219 | |||
220 | static void | ||
221 | do_file(char const *const fname) | ||
222 | { | ||
223 | Elf32_Ehdr *const ehdr = mmap_file(fname); | ||
224 | unsigned int reltype = 0; | ||
225 | |||
226 | ehdr_curr = ehdr; | ||
227 | w = w4nat; | ||
228 | w2 = w2nat; | ||
229 | w8 = w8nat; | ||
230 | switch (ehdr->e_ident[EI_DATA]) { | ||
231 | static unsigned int const endian = 1; | ||
232 | default: { | ||
233 | fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", | ||
234 | ehdr->e_ident[EI_DATA], fname); | ||
235 | fail_file(); | ||
236 | } break; | ||
237 | case ELFDATA2LSB: { | ||
238 | if (1 != *(unsigned char const *)&endian) { | ||
239 | /* main() is big endian, file.o is little endian. */ | ||
240 | w = w4rev; | ||
241 | w2 = w2rev; | ||
242 | w8 = w8rev; | ||
243 | } | ||
244 | } break; | ||
245 | case ELFDATA2MSB: { | ||
246 | if (0 != *(unsigned char const *)&endian) { | ||
247 | /* main() is little endian, file.o is big endian. */ | ||
248 | w = w4rev; | ||
249 | w2 = w2rev; | ||
250 | w8 = w8rev; | ||
251 | } | ||
252 | } break; | ||
253 | } /* end switch */ | ||
254 | if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG) | ||
255 | || ET_REL != w2(ehdr->e_type) | ||
256 | || EV_CURRENT != ehdr->e_ident[EI_VERSION]) { | ||
257 | fprintf(stderr, "unrecognized ET_REL file %s\n", fname); | ||
258 | fail_file(); | ||
259 | } | ||
260 | |||
261 | gpfx = 0; | ||
262 | switch (w2(ehdr->e_machine)) { | ||
263 | default: { | ||
264 | fprintf(stderr, "unrecognized e_machine %d %s\n", | ||
265 | w2(ehdr->e_machine), fname); | ||
266 | fail_file(); | ||
267 | } break; | ||
268 | case EM_386: reltype = R_386_32; break; | ||
269 | case EM_ARM: reltype = R_ARM_ABS32; break; | ||
270 | case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; | ||
271 | case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; | ||
272 | case EM_PPC64: reltype = R_PPC64_ADDR64; gpfx = '_'; break; | ||
273 | case EM_S390: /* reltype: e_class */ gpfx = '_'; break; | ||
274 | case EM_SH: reltype = R_SH_DIR32; break; | ||
275 | case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break; | ||
276 | case EM_X86_64: reltype = R_X86_64_64; break; | ||
277 | } /* end switch */ | ||
278 | |||
279 | switch (ehdr->e_ident[EI_CLASS]) { | ||
280 | default: { | ||
281 | fprintf(stderr, "unrecognized ELF class %d %s\n", | ||
282 | ehdr->e_ident[EI_CLASS], fname); | ||
283 | fail_file(); | ||
284 | } break; | ||
285 | case ELFCLASS32: { | ||
286 | if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize) | ||
287 | || sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) { | ||
288 | fprintf(stderr, | ||
289 | "unrecognized ET_REL file: %s\n", fname); | ||
290 | fail_file(); | ||
291 | } | ||
292 | if (EM_S390 == w2(ehdr->e_machine)) | ||
293 | reltype = R_390_32; | ||
294 | do32(ehdr, fname, reltype); | ||
295 | } break; | ||
296 | case ELFCLASS64: { | ||
297 | Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; | ||
298 | if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize) | ||
299 | || sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) { | ||
300 | fprintf(stderr, | ||
301 | "unrecognized ET_REL file: %s\n", fname); | ||
302 | fail_file(); | ||
303 | } | ||
304 | if (EM_S390 == w2(ghdr->e_machine)) | ||
305 | reltype = R_390_64; | ||
306 | do64(ghdr, fname, reltype); | ||
307 | } break; | ||
308 | } /* end switch */ | ||
309 | |||
310 | cleanup(); | ||
311 | } | ||
312 | |||
313 | int | ||
314 | main(int argc, char const *argv[]) | ||
315 | { | ||
316 | int n_error = 0; /* gcc-4.3.0 false positive complaint */ | ||
317 | if (argc <= 1) | ||
318 | fprintf(stderr, "usage: recordmcount file.o...\n"); | ||
319 | else /* Process each file in turn, allowing deep failure. */ | ||
320 | for (--argc, ++argv; 0 < argc; --argc, ++argv) { | ||
321 | int const sjval = setjmp(jmpenv); | ||
322 | switch (sjval) { | ||
323 | default: { | ||
324 | fprintf(stderr, "internal error: %s\n", argv[0]); | ||
325 | exit(1); | ||
326 | } break; | ||
327 | case SJ_SETJMP: { /* normal sequence */ | ||
328 | /* Avoid problems if early cleanup() */ | ||
329 | fd_map = -1; | ||
330 | ehdr_curr = NULL; | ||
331 | mmap_failed = 1; | ||
332 | do_file(argv[0]); | ||
333 | } break; | ||
334 | case SJ_FAIL: { /* error in do_file or below */ | ||
335 | ++n_error; | ||
336 | } break; | ||
337 | case SJ_SUCCEED: { /* premature success */ | ||
338 | /* do nothing */ | ||
339 | } break; | ||
340 | } /* end switch */ | ||
341 | } | ||
342 | return !!n_error; | ||
343 | } | ||
344 | |||
345 | |||
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h new file mode 100644 index 000000000000..7f39d0943d2d --- /dev/null +++ b/scripts/recordmcount.h | |||
@@ -0,0 +1,366 @@ | |||
1 | /* | ||
2 | * recordmcount.h | ||
3 | * | ||
4 | * This code was taken out of recordmcount.c written by | ||
5 | * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved. | ||
6 | * | ||
7 | * The original code had the same algorithms for both 32bit | ||
8 | * and 64bit ELF files, but the code was duplicated to support | ||
9 | * the difference in structures that were used. This | ||
10 | * file creates a macro of everything that is different between | ||
11 | * the 64 and 32 bit code, such that by including this header | ||
12 | * twice we can create both sets of functions by including this | ||
13 | * header once with RECORD_MCOUNT_64 undefined, and again with | ||
14 | * it defined. | ||
15 | * | ||
16 | * This conversion to macros was done by: | ||
17 | * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. | ||
18 | * | ||
19 | * Licensed under the GNU General Public License, version 2 (GPLv2). | ||
20 | */ | ||
21 | #undef append_func | ||
22 | #undef sift_rel_mcount | ||
23 | #undef find_secsym_ndx | ||
24 | #undef __has_rel_mcount | ||
25 | #undef has_rel_mcount | ||
26 | #undef tot_relsize | ||
27 | #undef do_func | ||
28 | #undef Elf_Ehdr | ||
29 | #undef Elf_Shdr | ||
30 | #undef Elf_Rel | ||
31 | #undef Elf_Rela | ||
32 | #undef Elf_Sym | ||
33 | #undef ELF_R_SYM | ||
34 | #undef ELF_R_INFO | ||
35 | #undef ELF_ST_BIND | ||
36 | #undef uint_t | ||
37 | #undef _w | ||
38 | #undef _align | ||
39 | #undef _size | ||
40 | |||
41 | #ifdef RECORD_MCOUNT_64 | ||
42 | # define append_func append64 | ||
43 | # define sift_rel_mcount sift64_rel_mcount | ||
44 | # define find_secsym_ndx find64_secsym_ndx | ||
45 | # define __has_rel_mcount __has64_rel_mcount | ||
46 | # define has_rel_mcount has64_rel_mcount | ||
47 | # define tot_relsize tot64_relsize | ||
48 | # define do_func do64 | ||
49 | # define Elf_Ehdr Elf64_Ehdr | ||
50 | # define Elf_Shdr Elf64_Shdr | ||
51 | # define Elf_Rel Elf64_Rel | ||
52 | # define Elf_Rela Elf64_Rela | ||
53 | # define Elf_Sym Elf64_Sym | ||
54 | # define ELF_R_SYM ELF64_R_SYM | ||
55 | # define ELF_R_INFO ELF64_R_INFO | ||
56 | # define ELF_ST_BIND ELF64_ST_BIND | ||
57 | # define uint_t uint64_t | ||
58 | # define _w w8 | ||
59 | # define _align 7u | ||
60 | # define _size 8 | ||
61 | #else | ||
62 | # define append_func append32 | ||
63 | # define sift_rel_mcount sift32_rel_mcount | ||
64 | # define find_secsym_ndx find32_secsym_ndx | ||
65 | # define __has_rel_mcount __has32_rel_mcount | ||
66 | # define has_rel_mcount has32_rel_mcount | ||
67 | # define tot_relsize tot32_relsize | ||
68 | # define do_func do32 | ||
69 | # define Elf_Ehdr Elf32_Ehdr | ||
70 | # define Elf_Shdr Elf32_Shdr | ||
71 | # define Elf_Rel Elf32_Rel | ||
72 | # define Elf_Rela Elf32_Rela | ||
73 | # define Elf_Sym Elf32_Sym | ||
74 | # define ELF_R_SYM ELF32_R_SYM | ||
75 | # define ELF_R_INFO ELF32_R_INFO | ||
76 | # define ELF_ST_BIND ELF32_ST_BIND | ||
77 | # define uint_t uint32_t | ||
78 | # define _w w | ||
79 | # define _align 3u | ||
80 | # define _size 4 | ||
81 | #endif | ||
82 | |||
83 | /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */ | ||
84 | static void append_func(Elf_Ehdr *const ehdr, | ||
85 | Elf_Shdr *const shstr, | ||
86 | uint_t const *const mloc0, | ||
87 | uint_t const *const mlocp, | ||
88 | Elf_Rel const *const mrel0, | ||
89 | Elf_Rel const *const mrelp, | ||
90 | unsigned int const rel_entsize, | ||
91 | unsigned int const symsec_sh_link) | ||
92 | { | ||
93 | /* Begin constructing output file */ | ||
94 | Elf_Shdr mcsec; | ||
95 | char const *mc_name = (sizeof(Elf_Rela) == rel_entsize) | ||
96 | ? ".rela__mcount_loc" | ||
97 | : ".rel__mcount_loc"; | ||
98 | unsigned const old_shnum = w2(ehdr->e_shnum); | ||
99 | uint_t const old_shoff = _w(ehdr->e_shoff); | ||
100 | uint_t const old_shstr_sh_size = _w(shstr->sh_size); | ||
101 | uint_t const old_shstr_sh_offset = _w(shstr->sh_offset); | ||
102 | uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size); | ||
103 | uint_t new_e_shoff; | ||
104 | |||
105 | shstr->sh_size = _w(t); | ||
106 | shstr->sh_offset = _w(sb.st_size); | ||
107 | t += sb.st_size; | ||
108 | t += (_align & -t); /* word-byte align */ | ||
109 | new_e_shoff = t; | ||
110 | |||
111 | /* body for new shstrtab */ | ||
112 | ulseek(fd_map, sb.st_size, SEEK_SET); | ||
113 | uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size); | ||
114 | uwrite(fd_map, mc_name, 1 + strlen(mc_name)); | ||
115 | |||
116 | /* old(modified) Elf_Shdr table, word-byte aligned */ | ||
117 | ulseek(fd_map, t, SEEK_SET); | ||
118 | t += sizeof(Elf_Shdr) * old_shnum; | ||
119 | uwrite(fd_map, old_shoff + (void *)ehdr, | ||
120 | sizeof(Elf_Shdr) * old_shnum); | ||
121 | |||
122 | /* new sections __mcount_loc and .rel__mcount_loc */ | ||
123 | t += 2*sizeof(mcsec); | ||
124 | mcsec.sh_name = w((sizeof(Elf_Rela) == rel_entsize) + strlen(".rel") | ||
125 | + old_shstr_sh_size); | ||
126 | mcsec.sh_type = w(SHT_PROGBITS); | ||
127 | mcsec.sh_flags = _w(SHF_ALLOC); | ||
128 | mcsec.sh_addr = 0; | ||
129 | mcsec.sh_offset = _w(t); | ||
130 | mcsec.sh_size = _w((void *)mlocp - (void *)mloc0); | ||
131 | mcsec.sh_link = 0; | ||
132 | mcsec.sh_info = 0; | ||
133 | mcsec.sh_addralign = _w(_size); | ||
134 | mcsec.sh_entsize = _w(_size); | ||
135 | uwrite(fd_map, &mcsec, sizeof(mcsec)); | ||
136 | |||
137 | mcsec.sh_name = w(old_shstr_sh_size); | ||
138 | mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize) | ||
139 | ? w(SHT_RELA) | ||
140 | : w(SHT_REL); | ||
141 | mcsec.sh_flags = 0; | ||
142 | mcsec.sh_addr = 0; | ||
143 | mcsec.sh_offset = _w((void *)mlocp - (void *)mloc0 + t); | ||
144 | mcsec.sh_size = _w((void *)mrelp - (void *)mrel0); | ||
145 | mcsec.sh_link = w(symsec_sh_link); | ||
146 | mcsec.sh_info = w(old_shnum); | ||
147 | mcsec.sh_addralign = _w(_size); | ||
148 | mcsec.sh_entsize = _w(rel_entsize); | ||
149 | uwrite(fd_map, &mcsec, sizeof(mcsec)); | ||
150 | |||
151 | uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0); | ||
152 | uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0); | ||
153 | |||
154 | ehdr->e_shoff = _w(new_e_shoff); | ||
155 | ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum)); /* {.rel,}__mcount_loc */ | ||
156 | ulseek(fd_map, 0, SEEK_SET); | ||
157 | uwrite(fd_map, ehdr, sizeof(*ehdr)); | ||
158 | } | ||
159 | |||
160 | |||
161 | /* | ||
162 | * Look at the relocations in order to find the calls to mcount. | ||
163 | * Accumulate the section offsets that are found, and their relocation info, | ||
164 | * onto the end of the existing arrays. | ||
165 | */ | ||
166 | static uint_t *sift_rel_mcount(uint_t *mlocp, | ||
167 | unsigned const offbase, | ||
168 | Elf_Rel **const mrelpp, | ||
169 | Elf_Shdr const *const relhdr, | ||
170 | Elf_Ehdr const *const ehdr, | ||
171 | unsigned const recsym, | ||
172 | uint_t const recval, | ||
173 | unsigned const reltype) | ||
174 | { | ||
175 | uint_t *const mloc0 = mlocp; | ||
176 | Elf_Rel *mrelp = *mrelpp; | ||
177 | Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) | ||
178 | + (void *)ehdr); | ||
179 | unsigned const symsec_sh_link = w(relhdr->sh_link); | ||
180 | Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; | ||
181 | Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset) | ||
182 | + (void *)ehdr); | ||
183 | |||
184 | Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)]; | ||
185 | char const *const str0 = (char const *)(_w(strsec->sh_offset) | ||
186 | + (void *)ehdr); | ||
187 | |||
188 | Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset) | ||
189 | + (void *)ehdr); | ||
190 | unsigned rel_entsize = _w(relhdr->sh_entsize); | ||
191 | unsigned const nrel = _w(relhdr->sh_size) / rel_entsize; | ||
192 | Elf_Rel const *relp = rel0; | ||
193 | |||
194 | unsigned mcountsym = 0; | ||
195 | unsigned t; | ||
196 | |||
197 | for (t = nrel; t; --t) { | ||
198 | if (!mcountsym) { | ||
199 | Elf_Sym const *const symp = | ||
200 | &sym0[ELF_R_SYM(_w(relp->r_info))]; | ||
201 | char const *symname = &str0[w(symp->st_name)]; | ||
202 | |||
203 | if ('.' == symname[0]) | ||
204 | ++symname; /* ppc64 hack */ | ||
205 | if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), | ||
206 | symname)) | ||
207 | mcountsym = ELF_R_SYM(_w(relp->r_info)); | ||
208 | } | ||
209 | |||
210 | if (mcountsym == ELF_R_SYM(_w(relp->r_info))) { | ||
211 | uint_t const addend = _w(_w(relp->r_offset) - recval); | ||
212 | |||
213 | mrelp->r_offset = _w(offbase | ||
214 | + ((void *)mlocp - (void *)mloc0)); | ||
215 | mrelp->r_info = _w(ELF_R_INFO(recsym, reltype)); | ||
216 | if (sizeof(Elf_Rela) == rel_entsize) { | ||
217 | ((Elf_Rela *)mrelp)->r_addend = addend; | ||
218 | *mlocp++ = 0; | ||
219 | } else | ||
220 | *mlocp++ = addend; | ||
221 | |||
222 | mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp); | ||
223 | } | ||
224 | relp = (Elf_Rel const *)(rel_entsize + (void *)relp); | ||
225 | } | ||
226 | *mrelpp = mrelp; | ||
227 | return mlocp; | ||
228 | } | ||
229 | |||
230 | |||
231 | /* | ||
232 | * Find a symbol in the given section, to be used as the base for relocating | ||
233 | * the table of offsets of calls to mcount. A local or global symbol suffices, | ||
234 | * but avoid a Weak symbol because it may be overridden; the change in value | ||
235 | * would invalidate the relocations of the offsets of the calls to mcount. | ||
236 | * Often the found symbol will be the unnamed local symbol generated by | ||
237 | * GNU 'as' for the start of each section. For example: | ||
238 | * Num: Value Size Type Bind Vis Ndx Name | ||
239 | * 2: 00000000 0 SECTION LOCAL DEFAULT 1 | ||
240 | */ | ||
241 | static unsigned find_secsym_ndx(unsigned const txtndx, | ||
242 | char const *const txtname, | ||
243 | uint_t *const recvalp, | ||
244 | Elf_Shdr const *const symhdr, | ||
245 | Elf_Ehdr const *const ehdr) | ||
246 | { | ||
247 | Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset) | ||
248 | + (void *)ehdr); | ||
249 | unsigned const nsym = _w(symhdr->sh_size) / _w(symhdr->sh_entsize); | ||
250 | Elf_Sym const *symp; | ||
251 | unsigned t; | ||
252 | |||
253 | for (symp = sym0, t = nsym; t; --t, ++symp) { | ||
254 | unsigned int const st_bind = ELF_ST_BIND(symp->st_info); | ||
255 | |||
256 | if (txtndx == w2(symp->st_shndx) | ||
257 | /* avoid STB_WEAK */ | ||
258 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { | ||
259 | *recvalp = _w(symp->st_value); | ||
260 | return symp - sym0; | ||
261 | } | ||
262 | } | ||
263 | fprintf(stderr, "Cannot find symbol for section %d: %s.\n", | ||
264 | txtndx, txtname); | ||
265 | fail_file(); | ||
266 | } | ||
267 | |||
268 | |||
269 | /* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */ | ||
270 | static char const * | ||
271 | __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */ | ||
272 | Elf_Shdr const *const shdr0, | ||
273 | char const *const shstrtab, | ||
274 | char const *const fname) | ||
275 | { | ||
276 | /* .sh_info depends on .sh_type == SHT_REL[,A] */ | ||
277 | Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)]; | ||
278 | char const *const txtname = &shstrtab[w(txthdr->sh_name)]; | ||
279 | |||
280 | if (0 == strcmp("__mcount_loc", txtname)) { | ||
281 | fprintf(stderr, "warning: __mcount_loc already exists: %s\n", | ||
282 | fname); | ||
283 | succeed_file(); | ||
284 | } | ||
285 | if (SHT_PROGBITS != w(txthdr->sh_type) || | ||
286 | !is_mcounted_section_name(txtname)) | ||
287 | return NULL; | ||
288 | return txtname; | ||
289 | } | ||
290 | |||
291 | static char const *has_rel_mcount(Elf_Shdr const *const relhdr, | ||
292 | Elf_Shdr const *const shdr0, | ||
293 | char const *const shstrtab, | ||
294 | char const *const fname) | ||
295 | { | ||
296 | if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) | ||
297 | return NULL; | ||
298 | return __has_rel_mcount(relhdr, shdr0, shstrtab, fname); | ||
299 | } | ||
300 | |||
301 | |||
302 | static unsigned tot_relsize(Elf_Shdr const *const shdr0, | ||
303 | unsigned nhdr, | ||
304 | const char *const shstrtab, | ||
305 | const char *const fname) | ||
306 | { | ||
307 | unsigned totrelsz = 0; | ||
308 | Elf_Shdr const *shdrp = shdr0; | ||
309 | |||
310 | for (; nhdr; --nhdr, ++shdrp) { | ||
311 | if (has_rel_mcount(shdrp, shdr0, shstrtab, fname)) | ||
312 | totrelsz += _w(shdrp->sh_size); | ||
313 | } | ||
314 | return totrelsz; | ||
315 | } | ||
316 | |||
317 | |||
318 | /* Overall supervision for Elf32 ET_REL file. */ | ||
319 | static void | ||
320 | do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) | ||
321 | { | ||
322 | Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) | ||
323 | + (void *)ehdr); | ||
324 | unsigned const nhdr = w2(ehdr->e_shnum); | ||
325 | Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)]; | ||
326 | char const *const shstrtab = (char const *)(_w(shstr->sh_offset) | ||
327 | + (void *)ehdr); | ||
328 | |||
329 | Elf_Shdr const *relhdr; | ||
330 | unsigned k; | ||
331 | |||
332 | /* Upper bound on space: assume all relevant relocs are for mcount. */ | ||
333 | unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname); | ||
334 | Elf_Rel *const mrel0 = umalloc(totrelsz); | ||
335 | Elf_Rel * mrelp = mrel0; | ||
336 | |||
337 | /* 2*sizeof(address) <= sizeof(Elf_Rel) */ | ||
338 | uint_t *const mloc0 = umalloc(totrelsz>>1); | ||
339 | uint_t * mlocp = mloc0; | ||
340 | |||
341 | unsigned rel_entsize = 0; | ||
342 | unsigned symsec_sh_link = 0; | ||
343 | |||
344 | for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) { | ||
345 | char const *const txtname = has_rel_mcount(relhdr, shdr0, | ||
346 | shstrtab, fname); | ||
347 | if (txtname) { | ||
348 | uint_t recval = 0; | ||
349 | unsigned const recsym = find_secsym_ndx( | ||
350 | w(relhdr->sh_info), txtname, &recval, | ||
351 | &shdr0[symsec_sh_link = w(relhdr->sh_link)], | ||
352 | ehdr); | ||
353 | |||
354 | rel_entsize = _w(relhdr->sh_entsize); | ||
355 | mlocp = sift_rel_mcount(mlocp, | ||
356 | (void *)mlocp - (void *)mloc0, &mrelp, | ||
357 | relhdr, ehdr, recsym, recval, reltype); | ||
358 | } | ||
359 | } | ||
360 | if (mloc0 != mlocp) { | ||
361 | append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp, | ||
362 | rel_entsize, symsec_sh_link); | ||
363 | } | ||
364 | free(mrel0); | ||
365 | free(mloc0); | ||
366 | } | ||
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ef43995119a4..c668b447c725 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1416,15 +1416,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
1416 | const pid_t gpid = task_pid_nr(current); | 1416 | const pid_t gpid = task_pid_nr(current); |
1417 | static const int tomoyo_buffer_len = 4096; | 1417 | static const int tomoyo_buffer_len = 4096; |
1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); | 1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); |
1419 | pid_t ppid; | ||
1419 | if (!buffer) | 1420 | if (!buffer) |
1420 | return NULL; | 1421 | return NULL; |
1421 | do_gettimeofday(&tv); | 1422 | do_gettimeofday(&tv); |
1423 | rcu_read_lock(); | ||
1424 | ppid = task_tgid_vnr(current->real_parent); | ||
1425 | rcu_read_unlock(); | ||
1422 | snprintf(buffer, tomoyo_buffer_len - 1, | 1426 | snprintf(buffer, tomoyo_buffer_len - 1, |
1423 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" | 1427 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" |
1424 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" | 1428 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" |
1425 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", | 1429 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", |
1426 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, | 1430 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, |
1427 | (pid_t) sys_getpid(), (pid_t) sys_getppid(), | 1431 | task_tgid_vnr(current), ppid, |
1428 | current_uid(), current_gid(), current_euid(), | 1432 | current_uid(), current_gid(), current_euid(), |
1429 | current_egid(), current_suid(), current_sgid(), | 1433 | current_egid(), current_suid(), current_sgid(), |
1430 | current_fsuid(), current_fsgid()); | 1434 | current_fsuid(), current_fsgid()); |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 04454cb7b24a..7c66bd898782 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -689,9 +689,6 @@ struct tomoyo_profile { | |||
689 | 689 | ||
690 | /********** Function prototypes. **********/ | 690 | /********** Function prototypes. **********/ |
691 | 691 | ||
692 | extern asmlinkage long sys_getpid(void); | ||
693 | extern asmlinkage long sys_getppid(void); | ||
694 | |||
695 | /* Check whether the given string starts with the given keyword. */ | 692 | /* Check whether the given string starts with the given keyword. */ |
696 | bool tomoyo_str_starts(char **src, const char *find); | 693 | bool tomoyo_str_starts(char **src, const char *find); |
697 | /* Get tomoyo_realpath() of current process. */ | 694 | /* Get tomoyo_realpath() of current process. */ |
diff --git a/sound/core/control.c b/sound/core/control.c index 070aab490191..45a818002d99 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | /* max number of user-defined controls */ | 32 | /* max number of user-defined controls */ |
33 | #define MAX_USER_CONTROLS 32 | 33 | #define MAX_USER_CONTROLS 32 |
34 | #define MAX_CONTROL_COUNT 1028 | ||
34 | 35 | ||
35 | struct snd_kctl_ioctl { | 36 | struct snd_kctl_ioctl { |
36 | struct list_head list; /* list of all ioctls */ | 37 | struct list_head list; /* list of all ioctls */ |
@@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, | |||
195 | 196 | ||
196 | if (snd_BUG_ON(!control || !control->count)) | 197 | if (snd_BUG_ON(!control || !control->count)) |
197 | return NULL; | 198 | return NULL; |
199 | |||
200 | if (control->count > MAX_CONTROL_COUNT) | ||
201 | return NULL; | ||
202 | |||
198 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); | 203 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); |
199 | if (kctl == NULL) { | 204 | if (kctl == NULL) { |
200 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); | 205 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); |
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 1adb8a3c2b62..42d7844ecd0b 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -900,7 +900,7 @@ static int proc_init(struct snd_akm4xxx *ak) | |||
900 | return 0; | 900 | return 0; |
901 | } | 901 | } |
902 | #else /* !CONFIG_PROC_FS */ | 902 | #else /* !CONFIG_PROC_FS */ |
903 | static int proc_init(struct snd_akm4xxx *ak) {} | 903 | static int proc_init(struct snd_akm4xxx *ak) { return 0; } |
904 | #endif | 904 | #endif |
905 | 905 | ||
906 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | 906 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index b697fd2a6f8b..10bbbaf6ebc3 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3641,6 +3641,7 @@ static struct snd_pci_quirk ad1984_cfg_tbl[] = { | |||
3641 | /* Lenovo Thinkpad T61/X61 */ | 3641 | /* Lenovo Thinkpad T61/X61 */ |
3642 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), | 3642 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), |
3643 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), | 3643 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), |
3644 | SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP), | ||
3644 | {} | 3645 | {} |
3645 | }; | 3646 | }; |
3646 | 3647 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a1312a6c8af2..a432e6efd19b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1594,12 +1594,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec) | |||
1594 | } | 1594 | } |
1595 | 1595 | ||
1596 | if (spec->autocfg.dig_in_pin) { | 1596 | if (spec->autocfg.dig_in_pin) { |
1597 | hda_nid_t dig_nid; | 1597 | dig_nid = codec->start_nid; |
1598 | err = snd_hda_get_connections(codec, | 1598 | for (i = 0; i < codec->num_nodes; i++, dig_nid++) { |
1599 | spec->autocfg.dig_in_pin, | 1599 | unsigned int wcaps = get_wcaps(codec, dig_nid); |
1600 | &dig_nid, 1); | 1600 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) |
1601 | if (err > 0) | 1601 | continue; |
1602 | spec->dig_in_nid = dig_nid; | 1602 | if (!(wcaps & AC_WCAP_DIGITAL)) |
1603 | continue; | ||
1604 | if (!(wcaps & AC_WCAP_CONN_LIST)) | ||
1605 | continue; | ||
1606 | err = get_connection_index(codec, dig_nid, | ||
1607 | spec->autocfg.dig_in_pin); | ||
1608 | if (err >= 0) { | ||
1609 | spec->dig_in_nid = dig_nid; | ||
1610 | break; | ||
1611 | } | ||
1612 | } | ||
1603 | } | 1613 | } |
1604 | } | 1614 | } |
1605 | 1615 | ||
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 289cb4dacfc7..6c0a11adb2a8 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -543,6 +543,10 @@ static int __devinit get_oxygen_model(struct oxygen *chip, | |||
543 | chip->model.suspend = claro_suspend; | 543 | chip->model.suspend = claro_suspend; |
544 | chip->model.resume = claro_resume; | 544 | chip->model.resume = claro_resume; |
545 | chip->model.set_adc_params = set_ak5385_params; | 545 | chip->model.set_adc_params = set_ak5385_params; |
546 | chip->model.device_config = PLAYBACK_0_TO_I2S | | ||
547 | PLAYBACK_1_TO_SPDIF | | ||
548 | CAPTURE_0_FROM_I2S_2 | | ||
549 | CAPTURE_1_FROM_SPDIF; | ||
546 | break; | 550 | break; |
547 | } | 551 | } |
548 | if (id->driver_data == MODEL_MERIDIAN || | 552 | if (id->driver_data == MODEL_MERIDIAN || |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index b92adef8e81e..d6fa7bfd9aa1 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -4609,6 +4609,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
4609 | if (err < 0) | 4609 | if (err < 0) |
4610 | return err; | 4610 | return err; |
4611 | 4611 | ||
4612 | memset(&info, 0, sizeof(info)); | ||
4612 | spin_lock_irqsave(&hdsp->lock, flags); | 4613 | spin_lock_irqsave(&hdsp->lock, flags); |
4613 | info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); | 4614 | info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); |
4614 | info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); | 4615 | info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 547b713d7204..0c98ef9156d8 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -4127,6 +4127,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | |||
4127 | 4127 | ||
4128 | case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: | 4128 | case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: |
4129 | 4129 | ||
4130 | memset(&info, 0, sizeof(info)); | ||
4130 | spin_lock_irq(&hdspm->lock); | 4131 | spin_lock_irq(&hdspm->lock); |
4131 | info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); | 4132 | info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); |
4132 | info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); | 4133 | info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); |
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index b823a5c9b9bc..87e2b7fcbf17 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/firmware.h> | 12 | #include <linux/firmware.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | 14 | ||
15 | #include <asm/clkdev.h> | ||
15 | #include <asm/clock.h> | 16 | #include <asm/clock.h> |
16 | 17 | ||
17 | #include <cpu/sh7722.h> | 18 | #include <cpu/sh7722.h> |
@@ -40,12 +41,12 @@ static struct clk_ops siumckb_clk_ops = { | |||
40 | }; | 41 | }; |
41 | 42 | ||
42 | static struct clk siumckb_clk = { | 43 | static struct clk siumckb_clk = { |
43 | .name = "siumckb_clk", | ||
44 | .id = -1, | ||
45 | .ops = &siumckb_clk_ops, | 44 | .ops = &siumckb_clk_ops, |
46 | .rate = 0, /* initialised at run-time */ | 45 | .rate = 0, /* initialised at run-time */ |
47 | }; | 46 | }; |
48 | 47 | ||
48 | static struct clk_lookup *siumckb_lookup; | ||
49 | |||
49 | static int migor_hw_params(struct snd_pcm_substream *substream, | 50 | static int migor_hw_params(struct snd_pcm_substream *substream, |
50 | struct snd_pcm_hw_params *params) | 51 | struct snd_pcm_hw_params *params) |
51 | { | 52 | { |
@@ -180,6 +181,13 @@ static int __init migor_init(void) | |||
180 | if (ret < 0) | 181 | if (ret < 0) |
181 | return ret; | 182 | return ret; |
182 | 183 | ||
184 | siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL); | ||
185 | if (!siumckb_lookup) { | ||
186 | ret = -ENOMEM; | ||
187 | goto eclkdevalloc; | ||
188 | } | ||
189 | clkdev_add(siumckb_lookup); | ||
190 | |||
183 | /* Port number used on this machine: port B */ | 191 | /* Port number used on this machine: port B */ |
184 | migor_snd_device = platform_device_alloc("soc-audio", 1); | 192 | migor_snd_device = platform_device_alloc("soc-audio", 1); |
185 | if (!migor_snd_device) { | 193 | if (!migor_snd_device) { |
@@ -200,12 +208,15 @@ static int __init migor_init(void) | |||
200 | epdevadd: | 208 | epdevadd: |
201 | platform_device_put(migor_snd_device); | 209 | platform_device_put(migor_snd_device); |
202 | epdevalloc: | 210 | epdevalloc: |
211 | clkdev_drop(siumckb_lookup); | ||
212 | eclkdevalloc: | ||
203 | clk_unregister(&siumckb_clk); | 213 | clk_unregister(&siumckb_clk); |
204 | return ret; | 214 | return ret; |
205 | } | 215 | } |
206 | 216 | ||
207 | static void __exit migor_exit(void) | 217 | static void __exit migor_exit(void) |
208 | { | 218 | { |
219 | clkdev_drop(siumckb_lookup); | ||
209 | clk_unregister(&siumckb_clk); | 220 | clk_unregister(&siumckb_clk); |
210 | platform_device_unregister(migor_snd_device); | 221 | platform_device_unregister(migor_snd_device); |
211 | } | 222 | } |
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index adbc68ce9050..f6b0d2829ea9 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -203,8 +203,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
203 | data[1] = (value >> 8) & 0xff; | 203 | data[1] = (value >> 8) & 0xff; |
204 | data[2] = value & 0xff; | 204 | data[2] = value & 0xff; |
205 | 205 | ||
206 | if (!snd_soc_codec_volatile_register(codec, reg)) | 206 | if (!snd_soc_codec_volatile_register(codec, reg) |
207 | reg_cache[reg] = value; | 207 | && reg < codec->reg_cache_size) |
208 | reg_cache[reg] = value; | ||
208 | 209 | ||
209 | if (codec->cache_only) { | 210 | if (codec->cache_only) { |
210 | codec->cache_sync = 1; | 211 | codec->cache_sync = 1; |
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 5164a655c39f..b2c63309a651 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt | |||
@@ -8,7 +8,7 @@ perf-annotate - Read perf.data (created by perf record) and display annotated co | |||
8 | SYNOPSIS | 8 | SYNOPSIS |
9 | -------- | 9 | -------- |
10 | [verse] | 10 | [verse] |
11 | 'perf annotate' [-i <file> | --input=file] symbol_name | 11 | 'perf annotate' [-i <file> | --input=file] [symbol_name] |
12 | 12 | ||
13 | DESCRIPTION | 13 | DESCRIPTION |
14 | ----------- | 14 | ----------- |
@@ -24,6 +24,13 @@ OPTIONS | |||
24 | --input=:: | 24 | --input=:: |
25 | Input file name. (default: perf.data) | 25 | Input file name. (default: perf.data) |
26 | 26 | ||
27 | --stdio:: Use the stdio interface. | ||
28 | |||
29 | --tui:: Use the TUI interface Use of --tui requires a tty, if one is not | ||
30 | present, as when piping to other commands, the stdio interface is | ||
31 | used. This interfaces starts by centering on the line with more | ||
32 | samples, TAB/UNTAB cycles thru the lines with more samples. | ||
33 | |||
27 | SEE ALSO | 34 | SEE ALSO |
28 | -------- | 35 | -------- |
29 | linkperf:perf-record[1] | 36 | linkperf:perf-record[1], linkperf:perf-report[1] |
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index abfabe9147a4..12052c9ed0ba 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -65,6 +65,13 @@ OPTIONS | |||
65 | the tree is considered as a new profiled object. + | 65 | the tree is considered as a new profiled object. + |
66 | Default: fractal,0.5. | 66 | Default: fractal,0.5. |
67 | 67 | ||
68 | --stdio:: Use the stdio interface. | ||
69 | |||
70 | --tui:: Use the TUI interface, that is integrated with annotate and allows | ||
71 | zooming into DSOs or threads, among other features. Use of --tui | ||
72 | requires a tty, if one is not present, as when piping to other | ||
73 | commands, the stdio interface is used. | ||
74 | |||
68 | SEE ALSO | 75 | SEE ALSO |
69 | -------- | 76 | -------- |
70 | linkperf:perf-stat[1] | 77 | linkperf:perf-stat[1] |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 4f1fa77c1feb..d1db0f676a4b 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -313,6 +313,9 @@ TEST_PROGRAMS = | |||
313 | 313 | ||
314 | SCRIPT_SH += perf-archive.sh | 314 | SCRIPT_SH += perf-archive.sh |
315 | 315 | ||
316 | grep-libs = $(filter -l%,$(1)) | ||
317 | strip-libs = $(filter-out -l%,$(1)) | ||
318 | |||
316 | # | 319 | # |
317 | # No Perl scripts right now: | 320 | # No Perl scripts right now: |
318 | # | 321 | # |
@@ -588,14 +591,17 @@ endif | |||
588 | ifdef NO_LIBPERL | 591 | ifdef NO_LIBPERL |
589 | BASIC_CFLAGS += -DNO_LIBPERL | 592 | BASIC_CFLAGS += -DNO_LIBPERL |
590 | else | 593 | else |
591 | PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` | 594 | PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) |
595 | PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) | ||
596 | PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) | ||
592 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` | 597 | PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` |
593 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) | 598 | FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) |
594 | 599 | ||
595 | ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) | 600 | ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) |
596 | BASIC_CFLAGS += -DNO_LIBPERL | 601 | BASIC_CFLAGS += -DNO_LIBPERL |
597 | else | 602 | else |
598 | ALL_LDFLAGS += $(PERL_EMBED_LDOPTS) | 603 | ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS) |
604 | EXTLIBS += $(PERL_EMBED_LIBADD) | ||
599 | LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o | 605 | LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o |
600 | LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o | 606 | LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o |
601 | endif | 607 | endif |
@@ -604,13 +610,16 @@ endif | |||
604 | ifdef NO_LIBPYTHON | 610 | ifdef NO_LIBPYTHON |
605 | BASIC_CFLAGS += -DNO_LIBPYTHON | 611 | BASIC_CFLAGS += -DNO_LIBPYTHON |
606 | else | 612 | else |
607 | PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null` | 613 | PYTHON_EMBED_LDOPTS = $(shell python-config --ldflags 2>/dev/null) |
614 | PYTHON_EMBED_LDFLAGS = $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) | ||
615 | PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) | ||
608 | PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` | 616 | PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` |
609 | FLAGS_PYTHON_EMBED=$(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) | 617 | FLAGS_PYTHON_EMBED=$(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) |
610 | ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) | 618 | ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) |
611 | BASIC_CFLAGS += -DNO_LIBPYTHON | 619 | BASIC_CFLAGS += -DNO_LIBPYTHON |
612 | else | 620 | else |
613 | ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS) | 621 | ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS) |
622 | EXTLIBS += $(PYTHON_EMBED_LIBADD) | ||
614 | LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o | 623 | LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o |
615 | LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o | 624 | LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o |
616 | endif | 625 | endif |
@@ -653,6 +662,15 @@ else | |||
653 | endif | 662 | endif |
654 | endif | 663 | endif |
655 | 664 | ||
665 | |||
666 | ifdef NO_STRLCPY | ||
667 | BASIC_CFLAGS += -DNO_STRLCPY | ||
668 | else | ||
669 | ifneq ($(call try-cc,$(SOURCE_STRLCPY),),y) | ||
670 | BASIC_CFLAGS += -DNO_STRLCPY | ||
671 | endif | ||
672 | endif | ||
673 | |||
656 | ifndef CC_LD_DYNPATH | 674 | ifndef CC_LD_DYNPATH |
657 | ifdef NO_R_TO_GCC_LINKER | 675 | ifdef NO_R_TO_GCC_LINKER |
658 | # Some gcc does not accept and pass -R to the linker to specify | 676 | # Some gcc does not accept and pass -R to the linker to specify |
@@ -910,8 +928,8 @@ $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS | |||
910 | $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@ | 928 | $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@ |
911 | 929 | ||
912 | $(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) | 930 | $(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) |
913 | $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(OUTPUT)perf.o \ | 931 | $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \ |
914 | $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) | 932 | $(BUILTIN_OBJS) $(LIBS) -o $@ |
915 | 933 | ||
916 | $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS | 934 | $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS |
917 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ | 935 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ |
@@ -1017,7 +1035,7 @@ builtin-revert.o wt-status.o: wt-status.h | |||
1017 | # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So | 1035 | # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So |
1018 | # we depend the various files onto their directories. | 1036 | # we depend the various files onto their directories. |
1019 | DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h | 1037 | DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h |
1020 | $(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS))) | 1038 | $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) |
1021 | # In the second step, we make a rule to actually create these directories | 1039 | # In the second step, we make a rule to actually create these directories |
1022 | $(sort $(dir $(DIRECTORY_DEPS))): | 1040 | $(sort $(dir $(DIRECTORY_DEPS))): |
1023 | $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null | 1041 | $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1478dc64bf15..6d5604d8df95 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | static char const *input_name = "perf.data"; | 29 | static char const *input_name = "perf.data"; |
30 | 30 | ||
31 | static bool force; | 31 | static bool force, use_tui, use_stdio; |
32 | 32 | ||
33 | static bool full_paths; | 33 | static bool full_paths; |
34 | 34 | ||
@@ -321,7 +321,7 @@ static int hist_entry__tty_annotate(struct hist_entry *he) | |||
321 | 321 | ||
322 | static void hists__find_annotations(struct hists *self) | 322 | static void hists__find_annotations(struct hists *self) |
323 | { | 323 | { |
324 | struct rb_node *first = rb_first(&self->entries), *nd = first; | 324 | struct rb_node *nd = rb_first(&self->entries), *next; |
325 | int key = KEY_RIGHT; | 325 | int key = KEY_RIGHT; |
326 | 326 | ||
327 | while (nd) { | 327 | while (nd) { |
@@ -343,20 +343,19 @@ find_next: | |||
343 | 343 | ||
344 | if (use_browser > 0) { | 344 | if (use_browser > 0) { |
345 | key = hist_entry__tui_annotate(he); | 345 | key = hist_entry__tui_annotate(he); |
346 | if (is_exit_key(key)) | ||
347 | break; | ||
348 | switch (key) { | 346 | switch (key) { |
349 | case KEY_RIGHT: | 347 | case KEY_RIGHT: |
350 | case '\t': | 348 | next = rb_next(nd); |
351 | nd = rb_next(nd); | ||
352 | break; | 349 | break; |
353 | case KEY_LEFT: | 350 | case KEY_LEFT: |
354 | if (nd == first) | 351 | next = rb_prev(nd); |
355 | continue; | ||
356 | nd = rb_prev(nd); | ||
357 | default: | ||
358 | break; | 352 | break; |
353 | default: | ||
354 | return; | ||
359 | } | 355 | } |
356 | |||
357 | if (next != NULL) | ||
358 | nd = next; | ||
360 | } else { | 359 | } else { |
361 | hist_entry__tty_annotate(he); | 360 | hist_entry__tty_annotate(he); |
362 | nd = rb_next(nd); | 361 | nd = rb_next(nd); |
@@ -428,6 +427,8 @@ static const struct option options[] = { | |||
428 | "be more verbose (show symbol address, etc)"), | 427 | "be more verbose (show symbol address, etc)"), |
429 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 428 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
430 | "dump raw trace in ASCII"), | 429 | "dump raw trace in ASCII"), |
430 | OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), | ||
431 | OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), | ||
431 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, | 432 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
432 | "file", "vmlinux pathname"), | 433 | "file", "vmlinux pathname"), |
433 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, | 434 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, |
@@ -443,6 +444,11 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
443 | { | 444 | { |
444 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 445 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
445 | 446 | ||
447 | if (use_stdio) | ||
448 | use_browser = 0; | ||
449 | else if (use_tui) | ||
450 | use_browser = 1; | ||
451 | |||
446 | setup_browser(); | 452 | setup_browser(); |
447 | 453 | ||
448 | symbol_conf.priv_size = sizeof(struct sym_priv); | 454 | symbol_conf.priv_size = sizeof(struct sym_priv); |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 55fc1f46892a..5de405d45230 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | static char const *input_name = "perf.data"; | 33 | static char const *input_name = "perf.data"; |
34 | 34 | ||
35 | static bool force; | 35 | static bool force, use_tui, use_stdio; |
36 | static bool hide_unresolved; | 36 | static bool hide_unresolved; |
37 | static bool dont_use_callchains; | 37 | static bool dont_use_callchains; |
38 | 38 | ||
@@ -107,7 +107,8 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
107 | goto out_free_syms; | 107 | goto out_free_syms; |
108 | err = 0; | 108 | err = 0; |
109 | if (symbol_conf.use_callchain) { | 109 | if (symbol_conf.use_callchain) { |
110 | err = append_chain(he->callchain, data->callchain, syms, data->period); | 110 | err = callchain_append(he->callchain, data->callchain, syms, |
111 | data->period); | ||
111 | if (err) | 112 | if (err) |
112 | goto out_free_syms; | 113 | goto out_free_syms; |
113 | } | 114 | } |
@@ -450,6 +451,8 @@ static const struct option options[] = { | |||
450 | "Show per-thread event counters"), | 451 | "Show per-thread event counters"), |
451 | OPT_STRING(0, "pretty", &pretty_printing_style, "key", | 452 | OPT_STRING(0, "pretty", &pretty_printing_style, "key", |
452 | "pretty printing style key: normal raw"), | 453 | "pretty printing style key: normal raw"), |
454 | OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), | ||
455 | OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), | ||
453 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", | 456 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", |
454 | "sort by key(s): pid, comm, dso, symbol, parent"), | 457 | "sort by key(s): pid, comm, dso, symbol, parent"), |
455 | OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, | 458 | OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, |
@@ -482,8 +485,15 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
482 | { | 485 | { |
483 | argc = parse_options(argc, argv, options, report_usage, 0); | 486 | argc = parse_options(argc, argv, options, report_usage, 0); |
484 | 487 | ||
488 | if (use_stdio) | ||
489 | use_browser = 0; | ||
490 | else if (use_tui) | ||
491 | use_browser = 1; | ||
492 | |||
485 | if (strcmp(input_name, "-") != 0) | 493 | if (strcmp(input_name, "-") != 0) |
486 | setup_browser(); | 494 | setup_browser(); |
495 | else | ||
496 | use_browser = 0; | ||
487 | /* | 497 | /* |
488 | * Only in the newt browser we are doing integrated annotation, | 498 | * Only in the newt browser we are doing integrated annotation, |
489 | * so don't allocate extra space that won't be used in the stdio | 499 | * so don't allocate extra space that won't be used in the stdio |
diff --git a/tools/perf/feature-tests.mak b/tools/perf/feature-tests.mak index 7a7b60859053..b253db634f04 100644 --- a/tools/perf/feature-tests.mak +++ b/tools/perf/feature-tests.mak | |||
@@ -110,6 +110,17 @@ int main(void) | |||
110 | } | 110 | } |
111 | endef | 111 | endef |
112 | 112 | ||
113 | define SOURCE_STRLCPY | ||
114 | #include <stdlib.h> | ||
115 | extern size_t strlcpy(char *dest, const char *src, size_t size); | ||
116 | |||
117 | int main(void) | ||
118 | { | ||
119 | strlcpy(NULL, NULL, 0); | ||
120 | return 0; | ||
121 | } | ||
122 | endef | ||
123 | |||
113 | # try-cc | 124 | # try-cc |
114 | # Usage: option = $(call try-cc, source-to-build, cc-options) | 125 | # Usage: option = $(call try-cc, source-to-build, cc-options) |
115 | try-cc = $(shell sh -c \ | 126 | try-cc = $(shell sh -c \ |
diff --git a/tools/perf/scripts/python/bin/netdev-times-record b/tools/perf/scripts/python/bin/netdev-times-record new file mode 100644 index 000000000000..d931a828126b --- /dev/null +++ b/tools/perf/scripts/python/bin/netdev-times-record | |||
@@ -0,0 +1,8 @@ | |||
1 | #!/bin/bash | ||
2 | perf record -a -e net:net_dev_xmit -e net:net_dev_queue \ | ||
3 | -e net:netif_receive_skb -e net:netif_rx \ | ||
4 | -e skb:consume_skb -e skb:kfree_skb \ | ||
5 | -e skb:skb_copy_datagram_iovec -e napi:napi_poll \ | ||
6 | -e irq:irq_handler_entry -e irq:irq_handler_exit \ | ||
7 | -e irq:softirq_entry -e irq:softirq_exit \ | ||
8 | -e irq:softirq_raise $@ | ||
diff --git a/tools/perf/scripts/python/bin/netdev-times-report b/tools/perf/scripts/python/bin/netdev-times-report new file mode 100644 index 000000000000..c3d0a638123d --- /dev/null +++ b/tools/perf/scripts/python/bin/netdev-times-report | |||
@@ -0,0 +1,5 @@ | |||
1 | #!/bin/bash | ||
2 | # description: display a process of packet and processing time | ||
3 | # args: [tx] [rx] [dev=] [debug] | ||
4 | |||
5 | perf trace -s ~/libexec/perf-core/scripts/python/netdev-times.py $@ | ||
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py new file mode 100644 index 000000000000..9aa0a32972e8 --- /dev/null +++ b/tools/perf/scripts/python/netdev-times.py | |||
@@ -0,0 +1,464 @@ | |||
1 | # Display a process of packets and processed time. | ||
2 | # It helps us to investigate networking or network device. | ||
3 | # | ||
4 | # options | ||
5 | # tx: show only tx chart | ||
6 | # rx: show only rx chart | ||
7 | # dev=: show only thing related to specified device | ||
8 | # debug: work with debug mode. It shows buffer status. | ||
9 | |||
10 | import os | ||
11 | import sys | ||
12 | |||
13 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
14 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
15 | |||
16 | from perf_trace_context import * | ||
17 | from Core import * | ||
18 | from Util import * | ||
19 | |||
20 | all_event_list = []; # insert all tracepoint event related with this script | ||
21 | irq_dic = {}; # key is cpu and value is a list which stacks irqs | ||
22 | # which raise NET_RX softirq | ||
23 | net_rx_dic = {}; # key is cpu and value include time of NET_RX softirq-entry | ||
24 | # and a list which stacks receive | ||
25 | receive_hunk_list = []; # a list which include a sequence of receive events | ||
26 | rx_skb_list = []; # received packet list for matching | ||
27 | # skb_copy_datagram_iovec | ||
28 | |||
29 | buffer_budget = 65536; # the budget of rx_skb_list, tx_queue_list and | ||
30 | # tx_xmit_list | ||
31 | of_count_rx_skb_list = 0; # overflow count | ||
32 | |||
33 | tx_queue_list = []; # list of packets which pass through dev_queue_xmit | ||
34 | of_count_tx_queue_list = 0; # overflow count | ||
35 | |||
36 | tx_xmit_list = []; # list of packets which pass through dev_hard_start_xmit | ||
37 | of_count_tx_xmit_list = 0; # overflow count | ||
38 | |||
39 | tx_free_list = []; # list of packets which is freed | ||
40 | |||
41 | # options | ||
42 | show_tx = 0; | ||
43 | show_rx = 0; | ||
44 | dev = 0; # store a name of device specified by option "dev=" | ||
45 | debug = 0; | ||
46 | |||
47 | # indices of event_info tuple | ||
48 | EINFO_IDX_NAME= 0 | ||
49 | EINFO_IDX_CONTEXT=1 | ||
50 | EINFO_IDX_CPU= 2 | ||
51 | EINFO_IDX_TIME= 3 | ||
52 | EINFO_IDX_PID= 4 | ||
53 | EINFO_IDX_COMM= 5 | ||
54 | |||
55 | # Calculate a time interval(msec) from src(nsec) to dst(nsec) | ||
56 | def diff_msec(src, dst): | ||
57 | return (dst - src) / 1000000.0 | ||
58 | |||
59 | # Display a process of transmitting a packet | ||
60 | def print_transmit(hunk): | ||
61 | if dev != 0 and hunk['dev'].find(dev) < 0: | ||
62 | return | ||
63 | print "%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % \ | ||
64 | (hunk['dev'], hunk['len'], | ||
65 | nsecs_secs(hunk['queue_t']), | ||
66 | nsecs_nsecs(hunk['queue_t'])/1000, | ||
67 | diff_msec(hunk['queue_t'], hunk['xmit_t']), | ||
68 | diff_msec(hunk['xmit_t'], hunk['free_t'])) | ||
69 | |||
70 | # Format for displaying rx packet processing | ||
71 | PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)" | ||
72 | PF_SOFT_ENTRY=" softirq_entry(+%.3fmsec)" | ||
73 | PF_NAPI_POLL= " napi_poll_exit(+%.3fmsec %s)" | ||
74 | PF_JOINT= " |" | ||
75 | PF_WJOINT= " | |" | ||
76 | PF_NET_RECV= " |---netif_receive_skb(+%.3fmsec skb=%x len=%d)" | ||
77 | PF_NET_RX= " |---netif_rx(+%.3fmsec skb=%x)" | ||
78 | PF_CPY_DGRAM= " | skb_copy_datagram_iovec(+%.3fmsec %d:%s)" | ||
79 | PF_KFREE_SKB= " | kfree_skb(+%.3fmsec location=%x)" | ||
80 | PF_CONS_SKB= " | consume_skb(+%.3fmsec)" | ||
81 | |||
82 | # Display a process of received packets and interrputs associated with | ||
83 | # a NET_RX softirq | ||
84 | def print_receive(hunk): | ||
85 | show_hunk = 0 | ||
86 | irq_list = hunk['irq_list'] | ||
87 | cpu = irq_list[0]['cpu'] | ||
88 | base_t = irq_list[0]['irq_ent_t'] | ||
89 | # check if this hunk should be showed | ||
90 | if dev != 0: | ||
91 | for i in range(len(irq_list)): | ||
92 | if irq_list[i]['name'].find(dev) >= 0: | ||
93 | show_hunk = 1 | ||
94 | break | ||
95 | else: | ||
96 | show_hunk = 1 | ||
97 | if show_hunk == 0: | ||
98 | return | ||
99 | |||
100 | print "%d.%06dsec cpu=%d" % \ | ||
101 | (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu) | ||
102 | for i in range(len(irq_list)): | ||
103 | print PF_IRQ_ENTRY % \ | ||
104 | (diff_msec(base_t, irq_list[i]['irq_ent_t']), | ||
105 | irq_list[i]['irq'], irq_list[i]['name']) | ||
106 | print PF_JOINT | ||
107 | irq_event_list = irq_list[i]['event_list'] | ||
108 | for j in range(len(irq_event_list)): | ||
109 | irq_event = irq_event_list[j] | ||
110 | if irq_event['event'] == 'netif_rx': | ||
111 | print PF_NET_RX % \ | ||
112 | (diff_msec(base_t, irq_event['time']), | ||
113 | irq_event['skbaddr']) | ||
114 | print PF_JOINT | ||
115 | print PF_SOFT_ENTRY % \ | ||
116 | diff_msec(base_t, hunk['sirq_ent_t']) | ||
117 | print PF_JOINT | ||
118 | event_list = hunk['event_list'] | ||
119 | for i in range(len(event_list)): | ||
120 | event = event_list[i] | ||
121 | if event['event_name'] == 'napi_poll': | ||
122 | print PF_NAPI_POLL % \ | ||
123 | (diff_msec(base_t, event['event_t']), event['dev']) | ||
124 | if i == len(event_list) - 1: | ||
125 | print "" | ||
126 | else: | ||
127 | print PF_JOINT | ||
128 | else: | ||
129 | print PF_NET_RECV % \ | ||
130 | (diff_msec(base_t, event['event_t']), event['skbaddr'], | ||
131 | event['len']) | ||
132 | if 'comm' in event.keys(): | ||
133 | print PF_WJOINT | ||
134 | print PF_CPY_DGRAM % \ | ||
135 | (diff_msec(base_t, event['comm_t']), | ||
136 | event['pid'], event['comm']) | ||
137 | elif 'handle' in event.keys(): | ||
138 | print PF_WJOINT | ||
139 | if event['handle'] == "kfree_skb": | ||
140 | print PF_KFREE_SKB % \ | ||
141 | (diff_msec(base_t, | ||
142 | event['comm_t']), | ||
143 | event['location']) | ||
144 | elif event['handle'] == "consume_skb": | ||
145 | print PF_CONS_SKB % \ | ||
146 | diff_msec(base_t, | ||
147 | event['comm_t']) | ||
148 | print PF_JOINT | ||
149 | |||
150 | def trace_begin(): | ||
151 | global show_tx | ||
152 | global show_rx | ||
153 | global dev | ||
154 | global debug | ||
155 | |||
156 | for i in range(len(sys.argv)): | ||
157 | if i == 0: | ||
158 | continue | ||
159 | arg = sys.argv[i] | ||
160 | if arg == 'tx': | ||
161 | show_tx = 1 | ||
162 | elif arg =='rx': | ||
163 | show_rx = 1 | ||
164 | elif arg.find('dev=',0, 4) >= 0: | ||
165 | dev = arg[4:] | ||
166 | elif arg == 'debug': | ||
167 | debug = 1 | ||
168 | if show_tx == 0 and show_rx == 0: | ||
169 | show_tx = 1 | ||
170 | show_rx = 1 | ||
171 | |||
172 | def trace_end(): | ||
173 | # order all events in time | ||
174 | all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME], | ||
175 | b[EINFO_IDX_TIME])) | ||
176 | # process all events | ||
177 | for i in range(len(all_event_list)): | ||
178 | event_info = all_event_list[i] | ||
179 | name = event_info[EINFO_IDX_NAME] | ||
180 | if name == 'irq__softirq_exit': | ||
181 | handle_irq_softirq_exit(event_info) | ||
182 | elif name == 'irq__softirq_entry': | ||
183 | handle_irq_softirq_entry(event_info) | ||
184 | elif name == 'irq__softirq_raise': | ||
185 | handle_irq_softirq_raise(event_info) | ||
186 | elif name == 'irq__irq_handler_entry': | ||
187 | handle_irq_handler_entry(event_info) | ||
188 | elif name == 'irq__irq_handler_exit': | ||
189 | handle_irq_handler_exit(event_info) | ||
190 | elif name == 'napi__napi_poll': | ||
191 | handle_napi_poll(event_info) | ||
192 | elif name == 'net__netif_receive_skb': | ||
193 | handle_netif_receive_skb(event_info) | ||
194 | elif name == 'net__netif_rx': | ||
195 | handle_netif_rx(event_info) | ||
196 | elif name == 'skb__skb_copy_datagram_iovec': | ||
197 | handle_skb_copy_datagram_iovec(event_info) | ||
198 | elif name == 'net__net_dev_queue': | ||
199 | handle_net_dev_queue(event_info) | ||
200 | elif name == 'net__net_dev_xmit': | ||
201 | handle_net_dev_xmit(event_info) | ||
202 | elif name == 'skb__kfree_skb': | ||
203 | handle_kfree_skb(event_info) | ||
204 | elif name == 'skb__consume_skb': | ||
205 | handle_consume_skb(event_info) | ||
206 | # display receive hunks | ||
207 | if show_rx: | ||
208 | for i in range(len(receive_hunk_list)): | ||
209 | print_receive(receive_hunk_list[i]) | ||
210 | # display transmit hunks | ||
211 | if show_tx: | ||
212 | print " dev len Qdisc " \ | ||
213 | " netdevice free" | ||
214 | for i in range(len(tx_free_list)): | ||
215 | print_transmit(tx_free_list[i]) | ||
216 | if debug: | ||
217 | print "debug buffer status" | ||
218 | print "----------------------------" | ||
219 | print "xmit Qdisc:remain:%d overflow:%d" % \ | ||
220 | (len(tx_queue_list), of_count_tx_queue_list) | ||
221 | print "xmit netdevice:remain:%d overflow:%d" % \ | ||
222 | (len(tx_xmit_list), of_count_tx_xmit_list) | ||
223 | print "receive:remain:%d overflow:%d" % \ | ||
224 | (len(rx_skb_list), of_count_rx_skb_list) | ||
225 | |||
226 | # called from perf, when it finds a correspoinding event | ||
227 | def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, vec): | ||
228 | if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": | ||
229 | return | ||
230 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) | ||
231 | all_event_list.append(event_info) | ||
232 | |||
233 | def irq__softirq_exit(name, context, cpu, sec, nsec, pid, comm, vec): | ||
234 | if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": | ||
235 | return | ||
236 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) | ||
237 | all_event_list.append(event_info) | ||
238 | |||
239 | def irq__softirq_raise(name, context, cpu, sec, nsec, pid, comm, vec): | ||
240 | if symbol_str("irq__softirq_entry", "vec", vec) != "NET_RX": | ||
241 | return | ||
242 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, vec) | ||
243 | all_event_list.append(event_info) | ||
244 | |||
245 | def irq__irq_handler_entry(name, context, cpu, sec, nsec, pid, comm, | ||
246 | irq, irq_name): | ||
247 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
248 | irq, irq_name) | ||
249 | all_event_list.append(event_info) | ||
250 | |||
251 | def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, irq, ret): | ||
252 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) | ||
253 | all_event_list.append(event_info) | ||
254 | |||
255 | def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, napi, dev_name): | ||
256 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
257 | napi, dev_name) | ||
258 | all_event_list.append(event_info) | ||
259 | |||
260 | def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, skbaddr, | ||
261 | skblen, dev_name): | ||
262 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
263 | skbaddr, skblen, dev_name) | ||
264 | all_event_list.append(event_info) | ||
265 | |||
266 | def net__netif_rx(name, context, cpu, sec, nsec, pid, comm, skbaddr, | ||
267 | skblen, dev_name): | ||
268 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
269 | skbaddr, skblen, dev_name) | ||
270 | all_event_list.append(event_info) | ||
271 | |||
272 | def net__net_dev_queue(name, context, cpu, sec, nsec, pid, comm, | ||
273 | skbaddr, skblen, dev_name): | ||
274 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
275 | skbaddr, skblen, dev_name) | ||
276 | all_event_list.append(event_info) | ||
277 | |||
278 | def net__net_dev_xmit(name, context, cpu, sec, nsec, pid, comm, | ||
279 | skbaddr, skblen, rc, dev_name): | ||
280 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
281 | skbaddr, skblen, rc ,dev_name) | ||
282 | all_event_list.append(event_info) | ||
283 | |||
284 | def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm, | ||
285 | skbaddr, protocol, location): | ||
286 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
287 | skbaddr, protocol, location) | ||
288 | all_event_list.append(event_info) | ||
289 | |||
290 | def skb__consume_skb(name, context, cpu, sec, nsec, pid, comm, skbaddr): | ||
291 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
292 | skbaddr) | ||
293 | all_event_list.append(event_info) | ||
294 | |||
295 | def skb__skb_copy_datagram_iovec(name, context, cpu, sec, nsec, pid, comm, | ||
296 | skbaddr, skblen): | ||
297 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | ||
298 | skbaddr, skblen) | ||
299 | all_event_list.append(event_info) | ||
300 | |||
301 | def handle_irq_handler_entry(event_info): | ||
302 | (name, context, cpu, time, pid, comm, irq, irq_name) = event_info | ||
303 | if cpu not in irq_dic.keys(): | ||
304 | irq_dic[cpu] = [] | ||
305 | irq_record = {'irq':irq, 'name':irq_name, 'cpu':cpu, 'irq_ent_t':time} | ||
306 | irq_dic[cpu].append(irq_record) | ||
307 | |||
308 | def handle_irq_handler_exit(event_info): | ||
309 | (name, context, cpu, time, pid, comm, irq, ret) = event_info | ||
310 | if cpu not in irq_dic.keys(): | ||
311 | return | ||
312 | irq_record = irq_dic[cpu].pop() | ||
313 | if irq != irq_record['irq']: | ||
314 | return | ||
315 | irq_record.update({'irq_ext_t':time}) | ||
316 | # if an irq doesn't include NET_RX softirq, drop. | ||
317 | if 'event_list' in irq_record.keys(): | ||
318 | irq_dic[cpu].append(irq_record) | ||
319 | |||
320 | def handle_irq_softirq_raise(event_info): | ||
321 | (name, context, cpu, time, pid, comm, vec) = event_info | ||
322 | if cpu not in irq_dic.keys() \ | ||
323 | or len(irq_dic[cpu]) == 0: | ||
324 | return | ||
325 | irq_record = irq_dic[cpu].pop() | ||
326 | if 'event_list' in irq_record.keys(): | ||
327 | irq_event_list = irq_record['event_list'] | ||
328 | else: | ||
329 | irq_event_list = [] | ||
330 | irq_event_list.append({'time':time, 'event':'sirq_raise'}) | ||
331 | irq_record.update({'event_list':irq_event_list}) | ||
332 | irq_dic[cpu].append(irq_record) | ||
333 | |||
334 | def handle_irq_softirq_entry(event_info): | ||
335 | (name, context, cpu, time, pid, comm, vec) = event_info | ||
336 | net_rx_dic[cpu] = {'sirq_ent_t':time, 'event_list':[]} | ||
337 | |||
338 | def handle_irq_softirq_exit(event_info): | ||
339 | (name, context, cpu, time, pid, comm, vec) = event_info | ||
340 | irq_list = [] | ||
341 | event_list = 0 | ||
342 | if cpu in irq_dic.keys(): | ||
343 | irq_list = irq_dic[cpu] | ||
344 | del irq_dic[cpu] | ||
345 | if cpu in net_rx_dic.keys(): | ||
346 | sirq_ent_t = net_rx_dic[cpu]['sirq_ent_t'] | ||
347 | event_list = net_rx_dic[cpu]['event_list'] | ||
348 | del net_rx_dic[cpu] | ||
349 | if irq_list == [] or event_list == 0: | ||
350 | return | ||
351 | rec_data = {'sirq_ent_t':sirq_ent_t, 'sirq_ext_t':time, | ||
352 | 'irq_list':irq_list, 'event_list':event_list} | ||
353 | # merge information realted to a NET_RX softirq | ||
354 | receive_hunk_list.append(rec_data) | ||
355 | |||
356 | def handle_napi_poll(event_info): | ||
357 | (name, context, cpu, time, pid, comm, napi, dev_name) = event_info | ||
358 | if cpu in net_rx_dic.keys(): | ||
359 | event_list = net_rx_dic[cpu]['event_list'] | ||
360 | rec_data = {'event_name':'napi_poll', | ||
361 | 'dev':dev_name, 'event_t':time} | ||
362 | event_list.append(rec_data) | ||
363 | |||
364 | def handle_netif_rx(event_info): | ||
365 | (name, context, cpu, time, pid, comm, | ||
366 | skbaddr, skblen, dev_name) = event_info | ||
367 | if cpu not in irq_dic.keys() \ | ||
368 | or len(irq_dic[cpu]) == 0: | ||
369 | return | ||
370 | irq_record = irq_dic[cpu].pop() | ||
371 | if 'event_list' in irq_record.keys(): | ||
372 | irq_event_list = irq_record['event_list'] | ||
373 | else: | ||
374 | irq_event_list = [] | ||
375 | irq_event_list.append({'time':time, 'event':'netif_rx', | ||
376 | 'skbaddr':skbaddr, 'skblen':skblen, 'dev_name':dev_name}) | ||
377 | irq_record.update({'event_list':irq_event_list}) | ||
378 | irq_dic[cpu].append(irq_record) | ||
379 | |||
380 | def handle_netif_receive_skb(event_info): | ||
381 | global of_count_rx_skb_list | ||
382 | |||
383 | (name, context, cpu, time, pid, comm, | ||
384 | skbaddr, skblen, dev_name) = event_info | ||
385 | if cpu in net_rx_dic.keys(): | ||
386 | rec_data = {'event_name':'netif_receive_skb', | ||
387 | 'event_t':time, 'skbaddr':skbaddr, 'len':skblen} | ||
388 | event_list = net_rx_dic[cpu]['event_list'] | ||
389 | event_list.append(rec_data) | ||
390 | rx_skb_list.insert(0, rec_data) | ||
391 | if len(rx_skb_list) > buffer_budget: | ||
392 | rx_skb_list.pop() | ||
393 | of_count_rx_skb_list += 1 | ||
394 | |||
395 | def handle_net_dev_queue(event_info): | ||
396 | global of_count_tx_queue_list | ||
397 | |||
398 | (name, context, cpu, time, pid, comm, | ||
399 | skbaddr, skblen, dev_name) = event_info | ||
400 | skb = {'dev':dev_name, 'skbaddr':skbaddr, 'len':skblen, 'queue_t':time} | ||
401 | tx_queue_list.insert(0, skb) | ||
402 | if len(tx_queue_list) > buffer_budget: | ||
403 | tx_queue_list.pop() | ||
404 | of_count_tx_queue_list += 1 | ||
405 | |||
406 | def handle_net_dev_xmit(event_info): | ||
407 | global of_count_tx_xmit_list | ||
408 | |||
409 | (name, context, cpu, time, pid, comm, | ||
410 | skbaddr, skblen, rc, dev_name) = event_info | ||
411 | if rc == 0: # NETDEV_TX_OK | ||
412 | for i in range(len(tx_queue_list)): | ||
413 | skb = tx_queue_list[i] | ||
414 | if skb['skbaddr'] == skbaddr: | ||
415 | skb['xmit_t'] = time | ||
416 | tx_xmit_list.insert(0, skb) | ||
417 | del tx_queue_list[i] | ||
418 | if len(tx_xmit_list) > buffer_budget: | ||
419 | tx_xmit_list.pop() | ||
420 | of_count_tx_xmit_list += 1 | ||
421 | return | ||
422 | |||
423 | def handle_kfree_skb(event_info): | ||
424 | (name, context, cpu, time, pid, comm, | ||
425 | skbaddr, protocol, location) = event_info | ||
426 | for i in range(len(tx_queue_list)): | ||
427 | skb = tx_queue_list[i] | ||
428 | if skb['skbaddr'] == skbaddr: | ||
429 | del tx_queue_list[i] | ||
430 | return | ||
431 | for i in range(len(tx_xmit_list)): | ||
432 | skb = tx_xmit_list[i] | ||
433 | if skb['skbaddr'] == skbaddr: | ||
434 | skb['free_t'] = time | ||
435 | tx_free_list.append(skb) | ||
436 | del tx_xmit_list[i] | ||
437 | return | ||
438 | for i in range(len(rx_skb_list)): | ||
439 | rec_data = rx_skb_list[i] | ||
440 | if rec_data['skbaddr'] == skbaddr: | ||
441 | rec_data.update({'handle':"kfree_skb", | ||
442 | 'comm':comm, 'pid':pid, 'comm_t':time}) | ||
443 | del rx_skb_list[i] | ||
444 | return | ||
445 | |||
446 | def handle_consume_skb(event_info): | ||
447 | (name, context, cpu, time, pid, comm, skbaddr) = event_info | ||
448 | for i in range(len(tx_xmit_list)): | ||
449 | skb = tx_xmit_list[i] | ||
450 | if skb['skbaddr'] == skbaddr: | ||
451 | skb['free_t'] = time | ||
452 | tx_free_list.append(skb) | ||
453 | del tx_xmit_list[i] | ||
454 | return | ||
455 | |||
456 | def handle_skb_copy_datagram_iovec(event_info): | ||
457 | (name, context, cpu, time, pid, comm, skbaddr, skblen) = event_info | ||
458 | for i in range(len(rx_skb_list)): | ||
459 | rec_data = rx_skb_list[i] | ||
460 | if skbaddr == rec_data['skbaddr']: | ||
461 | rec_data.update({'handle':"skb_copy_datagram_iovec", | ||
462 | 'comm':comm, 'pid':pid, 'comm_t':time}) | ||
463 | del rx_skb_list[i] | ||
464 | return | ||
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 27e9ebe4076e..a7729797fd96 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -82,6 +82,8 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2 | |||
82 | extern char *perf_pathdup(const char *fmt, ...) | 82 | extern char *perf_pathdup(const char *fmt, ...) |
83 | __attribute__((format (printf, 1, 2))); | 83 | __attribute__((format (printf, 1, 2))); |
84 | 84 | ||
85 | #ifdef NO_STRLCPY | ||
85 | extern size_t strlcpy(char *dest, const char *src, size_t size); | 86 | extern size_t strlcpy(char *dest, const char *src, size_t size); |
87 | #endif | ||
86 | 88 | ||
87 | #endif /* __PERF_CACHE_H */ | 89 | #endif /* __PERF_CACHE_H */ |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index f231f43424d2..e12d539417b2 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -28,6 +28,9 @@ bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event) | |||
28 | #define chain_for_each_child(child, parent) \ | 28 | #define chain_for_each_child(child, parent) \ |
29 | list_for_each_entry(child, &parent->children, brothers) | 29 | list_for_each_entry(child, &parent->children, brothers) |
30 | 30 | ||
31 | #define chain_for_each_child_safe(child, next, parent) \ | ||
32 | list_for_each_entry_safe(child, next, &parent->children, brothers) | ||
33 | |||
31 | static void | 34 | static void |
32 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | 35 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, |
33 | enum chain_mode mode) | 36 | enum chain_mode mode) |
@@ -86,10 +89,10 @@ __sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, | |||
86 | * sort them by hit | 89 | * sort them by hit |
87 | */ | 90 | */ |
88 | static void | 91 | static void |
89 | sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, | 92 | sort_chain_flat(struct rb_root *rb_root, struct callchain_root *root, |
90 | u64 min_hit, struct callchain_param *param __used) | 93 | u64 min_hit, struct callchain_param *param __used) |
91 | { | 94 | { |
92 | __sort_chain_flat(rb_root, node, min_hit); | 95 | __sort_chain_flat(rb_root, &root->node, min_hit); |
93 | } | 96 | } |
94 | 97 | ||
95 | static void __sort_chain_graph_abs(struct callchain_node *node, | 98 | static void __sort_chain_graph_abs(struct callchain_node *node, |
@@ -108,11 +111,11 @@ static void __sort_chain_graph_abs(struct callchain_node *node, | |||
108 | } | 111 | } |
109 | 112 | ||
110 | static void | 113 | static void |
111 | sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_node *chain_root, | 114 | sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_root *chain_root, |
112 | u64 min_hit, struct callchain_param *param __used) | 115 | u64 min_hit, struct callchain_param *param __used) |
113 | { | 116 | { |
114 | __sort_chain_graph_abs(chain_root, min_hit); | 117 | __sort_chain_graph_abs(&chain_root->node, min_hit); |
115 | rb_root->rb_node = chain_root->rb_root.rb_node; | 118 | rb_root->rb_node = chain_root->node.rb_root.rb_node; |
116 | } | 119 | } |
117 | 120 | ||
118 | static void __sort_chain_graph_rel(struct callchain_node *node, | 121 | static void __sort_chain_graph_rel(struct callchain_node *node, |
@@ -133,11 +136,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node, | |||
133 | } | 136 | } |
134 | 137 | ||
135 | static void | 138 | static void |
136 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, | 139 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_root *chain_root, |
137 | u64 min_hit __used, struct callchain_param *param) | 140 | u64 min_hit __used, struct callchain_param *param) |
138 | { | 141 | { |
139 | __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); | 142 | __sort_chain_graph_rel(&chain_root->node, param->min_percent / 100.0); |
140 | rb_root->rb_node = chain_root->rb_root.rb_node; | 143 | rb_root->rb_node = chain_root->node.rb_root.rb_node; |
141 | } | 144 | } |
142 | 145 | ||
143 | int register_callchain_param(struct callchain_param *param) | 146 | int register_callchain_param(struct callchain_param *param) |
@@ -284,19 +287,18 @@ split_add_child(struct callchain_node *parent, struct resolved_chain *chain, | |||
284 | } | 287 | } |
285 | 288 | ||
286 | static int | 289 | static int |
287 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, | 290 | append_chain(struct callchain_node *root, struct resolved_chain *chain, |
288 | unsigned int start, u64 period); | 291 | unsigned int start, u64 period); |
289 | 292 | ||
290 | static void | 293 | static void |
291 | __append_chain_children(struct callchain_node *root, | 294 | append_chain_children(struct callchain_node *root, struct resolved_chain *chain, |
292 | struct resolved_chain *chain, | 295 | unsigned int start, u64 period) |
293 | unsigned int start, u64 period) | ||
294 | { | 296 | { |
295 | struct callchain_node *rnode; | 297 | struct callchain_node *rnode; |
296 | 298 | ||
297 | /* lookup in childrens */ | 299 | /* lookup in childrens */ |
298 | chain_for_each_child(rnode, root) { | 300 | chain_for_each_child(rnode, root) { |
299 | unsigned int ret = __append_chain(rnode, chain, start, period); | 301 | unsigned int ret = append_chain(rnode, chain, start, period); |
300 | 302 | ||
301 | if (!ret) | 303 | if (!ret) |
302 | goto inc_children_hit; | 304 | goto inc_children_hit; |
@@ -309,8 +311,8 @@ inc_children_hit: | |||
309 | } | 311 | } |
310 | 312 | ||
311 | static int | 313 | static int |
312 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, | 314 | append_chain(struct callchain_node *root, struct resolved_chain *chain, |
313 | unsigned int start, u64 period) | 315 | unsigned int start, u64 period) |
314 | { | 316 | { |
315 | struct callchain_list *cnode; | 317 | struct callchain_list *cnode; |
316 | unsigned int i = start; | 318 | unsigned int i = start; |
@@ -357,7 +359,7 @@ __append_chain(struct callchain_node *root, struct resolved_chain *chain, | |||
357 | } | 359 | } |
358 | 360 | ||
359 | /* We match the node and still have a part remaining */ | 361 | /* We match the node and still have a part remaining */ |
360 | __append_chain_children(root, chain, i, period); | 362 | append_chain_children(root, chain, i, period); |
361 | 363 | ||
362 | return 0; | 364 | return 0; |
363 | } | 365 | } |
@@ -380,8 +382,8 @@ static void filter_context(struct ip_callchain *old, struct resolved_chain *new, | |||
380 | } | 382 | } |
381 | 383 | ||
382 | 384 | ||
383 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, | 385 | int callchain_append(struct callchain_root *root, struct ip_callchain *chain, |
384 | struct map_symbol *syms, u64 period) | 386 | struct map_symbol *syms, u64 period) |
385 | { | 387 | { |
386 | struct resolved_chain *filtered; | 388 | struct resolved_chain *filtered; |
387 | 389 | ||
@@ -398,9 +400,65 @@ int append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
398 | if (!filtered->nr) | 400 | if (!filtered->nr) |
399 | goto end; | 401 | goto end; |
400 | 402 | ||
401 | __append_chain_children(root, filtered, 0, period); | 403 | append_chain_children(&root->node, filtered, 0, period); |
404 | |||
405 | if (filtered->nr > root->max_depth) | ||
406 | root->max_depth = filtered->nr; | ||
402 | end: | 407 | end: |
403 | free(filtered); | 408 | free(filtered); |
404 | 409 | ||
405 | return 0; | 410 | return 0; |
406 | } | 411 | } |
412 | |||
413 | static int | ||
414 | merge_chain_branch(struct callchain_node *dst, struct callchain_node *src, | ||
415 | struct resolved_chain *chain) | ||
416 | { | ||
417 | struct callchain_node *child, *next_child; | ||
418 | struct callchain_list *list, *next_list; | ||
419 | int old_pos = chain->nr; | ||
420 | int err = 0; | ||
421 | |||
422 | list_for_each_entry_safe(list, next_list, &src->val, list) { | ||
423 | chain->ips[chain->nr].ip = list->ip; | ||
424 | chain->ips[chain->nr].ms = list->ms; | ||
425 | chain->nr++; | ||
426 | list_del(&list->list); | ||
427 | free(list); | ||
428 | } | ||
429 | |||
430 | if (src->hit) | ||
431 | append_chain_children(dst, chain, 0, src->hit); | ||
432 | |||
433 | chain_for_each_child_safe(child, next_child, src) { | ||
434 | err = merge_chain_branch(dst, child, chain); | ||
435 | if (err) | ||
436 | break; | ||
437 | |||
438 | list_del(&child->brothers); | ||
439 | free(child); | ||
440 | } | ||
441 | |||
442 | chain->nr = old_pos; | ||
443 | |||
444 | return err; | ||
445 | } | ||
446 | |||
447 | int callchain_merge(struct callchain_root *dst, struct callchain_root *src) | ||
448 | { | ||
449 | struct resolved_chain *chain; | ||
450 | int err; | ||
451 | |||
452 | chain = malloc(sizeof(*chain) + | ||
453 | src->max_depth * sizeof(struct resolved_ip)); | ||
454 | if (!chain) | ||
455 | return -ENOMEM; | ||
456 | |||
457 | chain->nr = 0; | ||
458 | |||
459 | err = merge_chain_branch(&dst->node, &src->node, chain); | ||
460 | |||
461 | free(chain); | ||
462 | |||
463 | return err; | ||
464 | } | ||
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 6de4313924fb..c15fb8c24ad2 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -26,9 +26,14 @@ struct callchain_node { | |||
26 | u64 children_hit; | 26 | u64 children_hit; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct callchain_root { | ||
30 | u64 max_depth; | ||
31 | struct callchain_node node; | ||
32 | }; | ||
33 | |||
29 | struct callchain_param; | 34 | struct callchain_param; |
30 | 35 | ||
31 | typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, | 36 | typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *, |
32 | u64, struct callchain_param *); | 37 | u64, struct callchain_param *); |
33 | 38 | ||
34 | struct callchain_param { | 39 | struct callchain_param { |
@@ -44,15 +49,16 @@ struct callchain_list { | |||
44 | struct list_head list; | 49 | struct list_head list; |
45 | }; | 50 | }; |
46 | 51 | ||
47 | static inline void callchain_init(struct callchain_node *node) | 52 | static inline void callchain_init(struct callchain_root *root) |
48 | { | 53 | { |
49 | INIT_LIST_HEAD(&node->brothers); | 54 | INIT_LIST_HEAD(&root->node.brothers); |
50 | INIT_LIST_HEAD(&node->children); | 55 | INIT_LIST_HEAD(&root->node.children); |
51 | INIT_LIST_HEAD(&node->val); | 56 | INIT_LIST_HEAD(&root->node.val); |
52 | 57 | ||
53 | node->children_hit = 0; | 58 | root->node.parent = NULL; |
54 | node->parent = NULL; | 59 | root->node.hit = 0; |
55 | node->hit = 0; | 60 | root->node.children_hit = 0; |
61 | root->max_depth = 0; | ||
56 | } | 62 | } |
57 | 63 | ||
58 | static inline u64 cumul_hits(struct callchain_node *node) | 64 | static inline u64 cumul_hits(struct callchain_node *node) |
@@ -61,8 +67,9 @@ static inline u64 cumul_hits(struct callchain_node *node) | |||
61 | } | 67 | } |
62 | 68 | ||
63 | int register_callchain_param(struct callchain_param *param); | 69 | int register_callchain_param(struct callchain_param *param); |
64 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, | 70 | int callchain_append(struct callchain_root *root, struct ip_callchain *chain, |
65 | struct map_symbol *syms, u64 period); | 71 | struct map_symbol *syms, u64 period); |
72 | int callchain_merge(struct callchain_root *dst, struct callchain_root *src); | ||
66 | 73 | ||
67 | bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); | 74 | bool ip_callchain__valid(struct ip_callchain *chain, const event_t *event); |
68 | #endif /* __PERF_CALLCHAIN_H */ | 75 | #endif /* __PERF_CALLCHAIN_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index be22ae6ef055..2022e8740994 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -87,7 +87,7 @@ static void hist_entry__add_cpumode_period(struct hist_entry *self, | |||
87 | 87 | ||
88 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | 88 | static struct hist_entry *hist_entry__new(struct hist_entry *template) |
89 | { | 89 | { |
90 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0; | 90 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0; |
91 | struct hist_entry *self = malloc(sizeof(*self) + callchain_size); | 91 | struct hist_entry *self = malloc(sizeof(*self) + callchain_size); |
92 | 92 | ||
93 | if (self != NULL) { | 93 | if (self != NULL) { |
@@ -226,6 +226,8 @@ static bool collapse__insert_entry(struct rb_root *root, struct hist_entry *he) | |||
226 | 226 | ||
227 | if (!cmp) { | 227 | if (!cmp) { |
228 | iter->period += he->period; | 228 | iter->period += he->period; |
229 | if (symbol_conf.use_callchain) | ||
230 | callchain_merge(iter->callchain, he->callchain); | ||
229 | hist_entry__free(he); | 231 | hist_entry__free(he); |
230 | return false; | 232 | return false; |
231 | } | 233 | } |
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index 58a470d036dd..bd7497711424 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c | |||
@@ -22,6 +22,7 @@ static const char *get_perf_dir(void) | |||
22 | return "."; | 22 | return "."; |
23 | } | 23 | } |
24 | 24 | ||
25 | #ifdef NO_STRLCPY | ||
25 | size_t strlcpy(char *dest, const char *src, size_t size) | 26 | size_t strlcpy(char *dest, const char *src, size_t size) |
26 | { | 27 | { |
27 | size_t ret = strlen(src); | 28 | size_t ret = strlen(src); |
@@ -33,7 +34,7 @@ size_t strlcpy(char *dest, const char *src, size_t size) | |||
33 | } | 34 | } |
34 | return ret; | 35 | return ret; |
35 | } | 36 | } |
36 | 37 | #endif | |
37 | 38 | ||
38 | static char *get_pathname(void) | 39 | static char *get_pathname(void) |
39 | { | 40 | { |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 46e531d09e8b..0b91053a7d11 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -70,7 +70,7 @@ struct hist_entry { | |||
70 | struct hist_entry *pair; | 70 | struct hist_entry *pair; |
71 | struct rb_root sorted_chain; | 71 | struct rb_root sorted_chain; |
72 | }; | 72 | }; |
73 | struct callchain_node callchain[0]; | 73 | struct callchain_root callchain[0]; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | enum sort_type { | 76 | enum sort_type { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b2f5ae97f33d..b39f499e575a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -388,6 +388,20 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp) | |||
388 | return fprintf(fp, "%s", sbuild_id); | 388 | return fprintf(fp, "%s", sbuild_id); |
389 | } | 389 | } |
390 | 390 | ||
391 | size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp) | ||
392 | { | ||
393 | size_t ret = 0; | ||
394 | struct rb_node *nd; | ||
395 | struct symbol_name_rb_node *pos; | ||
396 | |||
397 | for (nd = rb_first(&self->symbol_names[type]); nd; nd = rb_next(nd)) { | ||
398 | pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); | ||
399 | fprintf(fp, "%s\n", pos->sym.name); | ||
400 | } | ||
401 | |||
402 | return ret; | ||
403 | } | ||
404 | |||
391 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) | 405 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) |
392 | { | 406 | { |
393 | struct rb_node *nd; | 407 | struct rb_node *nd; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index ea95c2756f05..038f2201ee09 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -182,6 +182,7 @@ size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); | |||
182 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); | 182 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); |
183 | 183 | ||
184 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); | 184 | size_t dso__fprintf_buildid(struct dso *self, FILE *fp); |
185 | size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp); | ||
185 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); | 186 | size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); |
186 | 187 | ||
187 | enum dso_origin { | 188 | enum dso_origin { |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 7ea983acfaea..f7af2fca965d 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
@@ -97,7 +97,7 @@ void setup_python_scripting(void) | |||
97 | register_python_scripting(&python_scripting_unsupported_ops); | 97 | register_python_scripting(&python_scripting_unsupported_ops); |
98 | } | 98 | } |
99 | #else | 99 | #else |
100 | struct scripting_ops python_scripting_ops; | 100 | extern struct scripting_ops python_scripting_ops; |
101 | 101 | ||
102 | void setup_python_scripting(void) | 102 | void setup_python_scripting(void) |
103 | { | 103 | { |
@@ -158,7 +158,7 @@ void setup_perl_scripting(void) | |||
158 | register_perl_scripting(&perl_scripting_unsupported_ops); | 158 | register_perl_scripting(&perl_scripting_unsupported_ops); |
159 | } | 159 | } |
160 | #else | 160 | #else |
161 | struct scripting_ops perl_scripting_ops; | 161 | extern struct scripting_ops perl_scripting_ops; |
162 | 162 | ||
163 | void setup_perl_scripting(void) | 163 | void setup_perl_scripting(void) |
164 | { | 164 | { |
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 66f2d583d8c4..6d0df809a2ed 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c | |||
@@ -1,16 +1,6 @@ | |||
1 | #define _GNU_SOURCE | ||
2 | #include <stdio.h> | ||
3 | #undef _GNU_SOURCE | ||
4 | /* | ||
5 | * slang versions <= 2.0.6 have a "#if HAVE_LONG_LONG" that breaks | ||
6 | * the build if it isn't defined. Use the equivalent one that glibc | ||
7 | * has on features.h. | ||
8 | */ | ||
9 | #include <features.h> | ||
10 | #ifndef HAVE_LONG_LONG | ||
11 | #define HAVE_LONG_LONG __GLIBC_HAVE_LONG_LONG | ||
12 | #endif | ||
13 | #include <slang.h> | 1 | #include <slang.h> |
2 | #include "libslang.h" | ||
3 | #include <linux/compiler.h> | ||
14 | #include <linux/list.h> | 4 | #include <linux/list.h> |
15 | #include <linux/rbtree.h> | 5 | #include <linux/rbtree.h> |
16 | #include <stdlib.h> | 6 | #include <stdlib.h> |
@@ -19,17 +9,9 @@ | |||
19 | #include "helpline.h" | 9 | #include "helpline.h" |
20 | #include "../color.h" | 10 | #include "../color.h" |
21 | #include "../util.h" | 11 | #include "../util.h" |
12 | #include <stdio.h> | ||
22 | 13 | ||
23 | #if SLANG_VERSION < 20104 | 14 | static int ui_browser__percent_color(double percent, bool current) |
24 | #define sltt_set_color(obj, name, fg, bg) \ | ||
25 | SLtt_set_color(obj,(char *)name, (char *)fg, (char *)bg) | ||
26 | #else | ||
27 | #define sltt_set_color SLtt_set_color | ||
28 | #endif | ||
29 | |||
30 | newtComponent newt_form__new(void); | ||
31 | |||
32 | int ui_browser__percent_color(double percent, bool current) | ||
33 | { | 15 | { |
34 | if (current) | 16 | if (current) |
35 | return HE_COLORSET_SELECTED; | 17 | return HE_COLORSET_SELECTED; |
@@ -40,6 +22,23 @@ int ui_browser__percent_color(double percent, bool current) | |||
40 | return HE_COLORSET_NORMAL; | 22 | return HE_COLORSET_NORMAL; |
41 | } | 23 | } |
42 | 24 | ||
25 | void ui_browser__set_color(struct ui_browser *self __used, int color) | ||
26 | { | ||
27 | SLsmg_set_color(color); | ||
28 | } | ||
29 | |||
30 | void ui_browser__set_percent_color(struct ui_browser *self, | ||
31 | double percent, bool current) | ||
32 | { | ||
33 | int color = ui_browser__percent_color(percent, current); | ||
34 | ui_browser__set_color(self, color); | ||
35 | } | ||
36 | |||
37 | void ui_browser__gotorc(struct ui_browser *self, int y, int x) | ||
38 | { | ||
39 | SLsmg_gotorc(self->y + y, self->x + x); | ||
40 | } | ||
41 | |||
43 | void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence) | 42 | void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence) |
44 | { | 43 | { |
45 | struct list_head *head = self->entries; | 44 | struct list_head *head = self->entries; |
@@ -111,7 +110,7 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self) | |||
111 | nd = self->top; | 110 | nd = self->top; |
112 | 111 | ||
113 | while (nd != NULL) { | 112 | while (nd != NULL) { |
114 | SLsmg_gotorc(self->y + row, self->x); | 113 | ui_browser__gotorc(self, row, 0); |
115 | self->write(self, nd, row); | 114 | self->write(self, nd, row); |
116 | if (++row == self->height) | 115 | if (++row == self->height) |
117 | break; | 116 | break; |
@@ -131,13 +130,10 @@ void ui_browser__refresh_dimensions(struct ui_browser *self) | |||
131 | int cols, rows; | 130 | int cols, rows; |
132 | newtGetScreenSize(&cols, &rows); | 131 | newtGetScreenSize(&cols, &rows); |
133 | 132 | ||
134 | if (self->width > cols - 4) | 133 | self->width = cols - 1; |
135 | self->width = cols - 4; | 134 | self->height = rows - 2; |
136 | self->height = rows - 5; | 135 | self->y = 1; |
137 | if (self->height > self->nr_entries) | 136 | self->x = 0; |
138 | self->height = self->nr_entries; | ||
139 | self->y = (rows - self->height) / 2; | ||
140 | self->x = (cols - self->width) / 2; | ||
141 | } | 137 | } |
142 | 138 | ||
143 | void ui_browser__reset_index(struct ui_browser *self) | 139 | void ui_browser__reset_index(struct ui_browser *self) |
@@ -146,34 +142,48 @@ void ui_browser__reset_index(struct ui_browser *self) | |||
146 | self->seek(self, 0, SEEK_SET); | 142 | self->seek(self, 0, SEEK_SET); |
147 | } | 143 | } |
148 | 144 | ||
145 | void ui_browser__add_exit_key(struct ui_browser *self, int key) | ||
146 | { | ||
147 | newtFormAddHotKey(self->form, key); | ||
148 | } | ||
149 | |||
150 | void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]) | ||
151 | { | ||
152 | int i = 0; | ||
153 | |||
154 | while (keys[i] && i < 64) { | ||
155 | ui_browser__add_exit_key(self, keys[i]); | ||
156 | ++i; | ||
157 | } | ||
158 | } | ||
159 | |||
149 | int ui_browser__show(struct ui_browser *self, const char *title, | 160 | int ui_browser__show(struct ui_browser *self, const char *title, |
150 | const char *helpline, ...) | 161 | const char *helpline, ...) |
151 | { | 162 | { |
152 | va_list ap; | 163 | va_list ap; |
164 | int keys[] = { NEWT_KEY_UP, NEWT_KEY_DOWN, NEWT_KEY_PGUP, | ||
165 | NEWT_KEY_PGDN, NEWT_KEY_HOME, NEWT_KEY_END, ' ', | ||
166 | NEWT_KEY_LEFT, NEWT_KEY_ESCAPE, 'q', CTRL('c'), 0 }; | ||
153 | 167 | ||
154 | if (self->form != NULL) { | 168 | if (self->form != NULL) |
155 | newtFormDestroy(self->form); | 169 | newtFormDestroy(self->form); |
156 | newtPopWindow(); | 170 | |
157 | } | ||
158 | ui_browser__refresh_dimensions(self); | 171 | ui_browser__refresh_dimensions(self); |
159 | newtCenteredWindow(self->width, self->height, title); | 172 | self->form = newtForm(NULL, NULL, 0); |
160 | self->form = newt_form__new(); | ||
161 | if (self->form == NULL) | 173 | if (self->form == NULL) |
162 | return -1; | 174 | return -1; |
163 | 175 | ||
164 | self->sb = newtVerticalScrollbar(self->width, 0, self->height, | 176 | self->sb = newtVerticalScrollbar(self->width, 1, self->height, |
165 | HE_COLORSET_NORMAL, | 177 | HE_COLORSET_NORMAL, |
166 | HE_COLORSET_SELECTED); | 178 | HE_COLORSET_SELECTED); |
167 | if (self->sb == NULL) | 179 | if (self->sb == NULL) |
168 | return -1; | 180 | return -1; |
169 | 181 | ||
170 | newtFormAddHotKey(self->form, NEWT_KEY_UP); | 182 | SLsmg_gotorc(0, 0); |
171 | newtFormAddHotKey(self->form, NEWT_KEY_DOWN); | 183 | ui_browser__set_color(self, NEWT_COLORSET_ROOT); |
172 | newtFormAddHotKey(self->form, NEWT_KEY_PGUP); | 184 | slsmg_write_nstring(title, self->width); |
173 | newtFormAddHotKey(self->form, NEWT_KEY_PGDN); | 185 | |
174 | newtFormAddHotKey(self->form, NEWT_KEY_HOME); | 186 | ui_browser__add_exit_keys(self, keys); |
175 | newtFormAddHotKey(self->form, NEWT_KEY_END); | ||
176 | newtFormAddHotKey(self->form, ' '); | ||
177 | newtFormAddComponent(self->form, self->sb); | 187 | newtFormAddComponent(self->form, self->sb); |
178 | 188 | ||
179 | va_start(ap, helpline); | 189 | va_start(ap, helpline); |
@@ -185,7 +195,6 @@ int ui_browser__show(struct ui_browser *self, const char *title, | |||
185 | void ui_browser__hide(struct ui_browser *self) | 195 | void ui_browser__hide(struct ui_browser *self) |
186 | { | 196 | { |
187 | newtFormDestroy(self->form); | 197 | newtFormDestroy(self->form); |
188 | newtPopWindow(); | ||
189 | self->form = NULL; | 198 | self->form = NULL; |
190 | ui_helpline__pop(); | 199 | ui_helpline__pop(); |
191 | } | 200 | } |
@@ -196,28 +205,28 @@ int ui_browser__refresh(struct ui_browser *self) | |||
196 | 205 | ||
197 | newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); | 206 | newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); |
198 | row = self->refresh(self); | 207 | row = self->refresh(self); |
199 | SLsmg_set_color(HE_COLORSET_NORMAL); | 208 | ui_browser__set_color(self, HE_COLORSET_NORMAL); |
200 | SLsmg_fill_region(self->y + row, self->x, | 209 | SLsmg_fill_region(self->y + row, self->x, |
201 | self->height - row, self->width, ' '); | 210 | self->height - row, self->width, ' '); |
202 | 211 | ||
203 | return 0; | 212 | return 0; |
204 | } | 213 | } |
205 | 214 | ||
206 | int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) | 215 | int ui_browser__run(struct ui_browser *self) |
207 | { | 216 | { |
217 | struct newtExitStruct es; | ||
218 | |||
208 | if (ui_browser__refresh(self) < 0) | 219 | if (ui_browser__refresh(self) < 0) |
209 | return -1; | 220 | return -1; |
210 | 221 | ||
211 | while (1) { | 222 | while (1) { |
212 | off_t offset; | 223 | off_t offset; |
213 | 224 | ||
214 | newtFormRun(self->form, es); | 225 | newtFormRun(self->form, &es); |
215 | 226 | ||
216 | if (es->reason != NEWT_EXIT_HOTKEY) | 227 | if (es.reason != NEWT_EXIT_HOTKEY) |
217 | break; | 228 | break; |
218 | if (is_exit_key(es->u.key)) | 229 | switch (es.u.key) { |
219 | return es->u.key; | ||
220 | switch (es->u.key) { | ||
221 | case NEWT_KEY_DOWN: | 230 | case NEWT_KEY_DOWN: |
222 | if (self->index == self->nr_entries - 1) | 231 | if (self->index == self->nr_entries - 1) |
223 | break; | 232 | break; |
@@ -274,12 +283,12 @@ int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) | |||
274 | self->seek(self, -offset, SEEK_END); | 283 | self->seek(self, -offset, SEEK_END); |
275 | break; | 284 | break; |
276 | default: | 285 | default: |
277 | return es->u.key; | 286 | return es.u.key; |
278 | } | 287 | } |
279 | if (ui_browser__refresh(self) < 0) | 288 | if (ui_browser__refresh(self) < 0) |
280 | return -1; | 289 | return -1; |
281 | } | 290 | } |
282 | return 0; | 291 | return -1; |
283 | } | 292 | } |
284 | 293 | ||
285 | unsigned int ui_browser__list_head_refresh(struct ui_browser *self) | 294 | unsigned int ui_browser__list_head_refresh(struct ui_browser *self) |
@@ -294,7 +303,7 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self) | |||
294 | pos = self->top; | 303 | pos = self->top; |
295 | 304 | ||
296 | list_for_each_from(pos, head) { | 305 | list_for_each_from(pos, head) { |
297 | SLsmg_gotorc(self->y + row, self->x); | 306 | ui_browser__gotorc(self, row, 0); |
298 | self->write(self, pos, row); | 307 | self->write(self, pos, row); |
299 | if (++row == self->height) | 308 | if (++row == self->height) |
300 | break; | 309 | break; |
diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index 0b9f829214f7..0dc7e4da36f5 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h | |||
@@ -25,16 +25,21 @@ struct ui_browser { | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | 27 | ||
28 | int ui_browser__percent_color(double percent, bool current); | 28 | void ui_browser__set_color(struct ui_browser *self, int color); |
29 | void ui_browser__set_percent_color(struct ui_browser *self, | ||
30 | double percent, bool current); | ||
29 | bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row); | 31 | bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row); |
30 | void ui_browser__refresh_dimensions(struct ui_browser *self); | 32 | void ui_browser__refresh_dimensions(struct ui_browser *self); |
31 | void ui_browser__reset_index(struct ui_browser *self); | 33 | void ui_browser__reset_index(struct ui_browser *self); |
32 | 34 | ||
35 | void ui_browser__gotorc(struct ui_browser *self, int y, int x); | ||
36 | void ui_browser__add_exit_key(struct ui_browser *self, int key); | ||
37 | void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]); | ||
33 | int ui_browser__show(struct ui_browser *self, const char *title, | 38 | int ui_browser__show(struct ui_browser *self, const char *title, |
34 | const char *helpline, ...); | 39 | const char *helpline, ...); |
35 | void ui_browser__hide(struct ui_browser *self); | 40 | void ui_browser__hide(struct ui_browser *self); |
36 | int ui_browser__refresh(struct ui_browser *self); | 41 | int ui_browser__refresh(struct ui_browser *self); |
37 | int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es); | 42 | int ui_browser__run(struct ui_browser *self); |
38 | 43 | ||
39 | void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); | 44 | void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); |
40 | unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); | 45 | unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); |
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index a90273e63f4f..82b78f99251b 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -40,14 +40,12 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
40 | 40 | ||
41 | if (ol->offset != -1) { | 41 | if (ol->offset != -1) { |
42 | struct objdump_line_rb_node *olrb = objdump_line__rb(ol); | 42 | struct objdump_line_rb_node *olrb = objdump_line__rb(ol); |
43 | int color = ui_browser__percent_color(olrb->percent, current_entry); | 43 | ui_browser__set_percent_color(self, olrb->percent, current_entry); |
44 | SLsmg_set_color(color); | ||
45 | slsmg_printf(" %7.2f ", olrb->percent); | 44 | slsmg_printf(" %7.2f ", olrb->percent); |
46 | if (!current_entry) | 45 | if (!current_entry) |
47 | SLsmg_set_color(HE_COLORSET_CODE); | 46 | ui_browser__set_color(self, HE_COLORSET_CODE); |
48 | } else { | 47 | } else { |
49 | int color = ui_browser__percent_color(0, current_entry); | 48 | ui_browser__set_percent_color(self, 0, current_entry); |
50 | SLsmg_set_color(color); | ||
51 | slsmg_write_nstring(" ", 9); | 49 | slsmg_write_nstring(" ", 9); |
52 | } | 50 | } |
53 | 51 | ||
@@ -135,32 +133,31 @@ static void annotate_browser__set_top(struct annotate_browser *self, | |||
135 | self->curr_hot = nd; | 133 | self->curr_hot = nd; |
136 | } | 134 | } |
137 | 135 | ||
138 | static int annotate_browser__run(struct annotate_browser *self, | 136 | static int annotate_browser__run(struct annotate_browser *self) |
139 | struct newtExitStruct *es) | ||
140 | { | 137 | { |
141 | struct rb_node *nd; | 138 | struct rb_node *nd; |
142 | struct hist_entry *he = self->b.priv; | 139 | struct hist_entry *he = self->b.priv; |
140 | int key; | ||
143 | 141 | ||
144 | if (ui_browser__show(&self->b, he->ms.sym->name, | 142 | if (ui_browser__show(&self->b, he->ms.sym->name, |
145 | "<- or ESC: exit, TAB/shift+TAB: cycle thru samples") < 0) | 143 | "<-, -> or ESC: exit, TAB/shift+TAB: cycle thru samples") < 0) |
146 | return -1; | 144 | return -1; |
147 | 145 | /* | |
148 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); | 146 | * To allow builtin-annotate to cycle thru multiple symbols by |
149 | newtFormAddHotKey(self->b.form, NEWT_KEY_RIGHT); | 147 | * examining the exit key for this function. |
148 | */ | ||
149 | ui_browser__add_exit_key(&self->b, NEWT_KEY_RIGHT); | ||
150 | 150 | ||
151 | nd = self->curr_hot; | 151 | nd = self->curr_hot; |
152 | if (nd) { | 152 | if (nd) { |
153 | newtFormAddHotKey(self->b.form, NEWT_KEY_TAB); | 153 | int tabs[] = { NEWT_KEY_TAB, NEWT_KEY_UNTAB, 0 }; |
154 | newtFormAddHotKey(self->b.form, NEWT_KEY_UNTAB); | 154 | ui_browser__add_exit_keys(&self->b, tabs); |
155 | } | 155 | } |
156 | 156 | ||
157 | while (1) { | 157 | while (1) { |
158 | ui_browser__run(&self->b, es); | 158 | key = ui_browser__run(&self->b); |
159 | |||
160 | if (es->reason != NEWT_EXIT_HOTKEY) | ||
161 | break; | ||
162 | 159 | ||
163 | switch (es->u.key) { | 160 | switch (key) { |
164 | case NEWT_KEY_TAB: | 161 | case NEWT_KEY_TAB: |
165 | nd = rb_prev(nd); | 162 | nd = rb_prev(nd); |
166 | if (nd == NULL) | 163 | if (nd == NULL) |
@@ -179,12 +176,11 @@ static int annotate_browser__run(struct annotate_browser *self, | |||
179 | } | 176 | } |
180 | out: | 177 | out: |
181 | ui_browser__hide(&self->b); | 178 | ui_browser__hide(&self->b); |
182 | return es->u.key; | 179 | return key; |
183 | } | 180 | } |
184 | 181 | ||
185 | int hist_entry__tui_annotate(struct hist_entry *self) | 182 | int hist_entry__tui_annotate(struct hist_entry *self) |
186 | { | 183 | { |
187 | struct newtExitStruct es; | ||
188 | struct objdump_line *pos, *n; | 184 | struct objdump_line *pos, *n; |
189 | struct objdump_line_rb_node *rbpos; | 185 | struct objdump_line_rb_node *rbpos; |
190 | LIST_HEAD(head); | 186 | LIST_HEAD(head); |
@@ -232,7 +228,7 @@ int hist_entry__tui_annotate(struct hist_entry *self) | |||
232 | annotate_browser__set_top(&browser, browser.curr_hot); | 228 | annotate_browser__set_top(&browser, browser.curr_hot); |
233 | 229 | ||
234 | browser.b.width += 18; /* Percentage */ | 230 | browser.b.width += 18; /* Percentage */ |
235 | ret = annotate_browser__run(&browser, &es); | 231 | ret = annotate_browser__run(&browser); |
236 | list_for_each_entry_safe(pos, n, &head, node) { | 232 | list_for_each_entry_safe(pos, n, &head, node) { |
237 | list_del(&pos->node); | 233 | list_del(&pos->node); |
238 | objdump_line__free(pos); | 234 | objdump_line__free(pos); |
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index dafdf6775d77..ebda8c3fde9e 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
@@ -58,6 +58,11 @@ static char callchain_list__folded(const struct callchain_list *self) | |||
58 | return map_symbol__folded(&self->ms); | 58 | return map_symbol__folded(&self->ms); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void map_symbol__set_folding(struct map_symbol *self, bool unfold) | ||
62 | { | ||
63 | self->unfolded = unfold ? self->has_children : false; | ||
64 | } | ||
65 | |||
61 | static int callchain_node__count_rows_rb_tree(struct callchain_node *self) | 66 | static int callchain_node__count_rows_rb_tree(struct callchain_node *self) |
62 | { | 67 | { |
63 | int n = 0; | 68 | int n = 0; |
@@ -129,16 +134,16 @@ static void callchain_node__init_have_children_rb_tree(struct callchain_node *se | |||
129 | for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { | 134 | for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { |
130 | struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); | 135 | struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); |
131 | struct callchain_list *chain; | 136 | struct callchain_list *chain; |
132 | int first = true; | 137 | bool first = true; |
133 | 138 | ||
134 | list_for_each_entry(chain, &child->val, list) { | 139 | list_for_each_entry(chain, &child->val, list) { |
135 | if (first) { | 140 | if (first) { |
136 | first = false; | 141 | first = false; |
137 | chain->ms.has_children = chain->list.next != &child->val || | 142 | chain->ms.has_children = chain->list.next != &child->val || |
138 | rb_first(&child->rb_root) != NULL; | 143 | !RB_EMPTY_ROOT(&child->rb_root); |
139 | } else | 144 | } else |
140 | chain->ms.has_children = chain->list.next == &child->val && | 145 | chain->ms.has_children = chain->list.next == &child->val && |
141 | rb_first(&child->rb_root) != NULL; | 146 | !RB_EMPTY_ROOT(&child->rb_root); |
142 | } | 147 | } |
143 | 148 | ||
144 | callchain_node__init_have_children_rb_tree(child); | 149 | callchain_node__init_have_children_rb_tree(child); |
@@ -150,7 +155,7 @@ static void callchain_node__init_have_children(struct callchain_node *self) | |||
150 | struct callchain_list *chain; | 155 | struct callchain_list *chain; |
151 | 156 | ||
152 | list_for_each_entry(chain, &self->val, list) | 157 | list_for_each_entry(chain, &self->val, list) |
153 | chain->ms.has_children = rb_first(&self->rb_root) != NULL; | 158 | chain->ms.has_children = !RB_EMPTY_ROOT(&self->rb_root); |
154 | 159 | ||
155 | callchain_node__init_have_children_rb_tree(self); | 160 | callchain_node__init_have_children_rb_tree(self); |
156 | } | 161 | } |
@@ -168,6 +173,7 @@ static void callchain__init_have_children(struct rb_root *self) | |||
168 | static void hist_entry__init_have_children(struct hist_entry *self) | 173 | static void hist_entry__init_have_children(struct hist_entry *self) |
169 | { | 174 | { |
170 | if (!self->init_have_children) { | 175 | if (!self->init_have_children) { |
176 | self->ms.has_children = !RB_EMPTY_ROOT(&self->sorted_chain); | ||
171 | callchain__init_have_children(&self->sorted_chain); | 177 | callchain__init_have_children(&self->sorted_chain); |
172 | self->init_have_children = true; | 178 | self->init_have_children = true; |
173 | } | 179 | } |
@@ -195,43 +201,114 @@ static bool hist_browser__toggle_fold(struct hist_browser *self) | |||
195 | return false; | 201 | return false; |
196 | } | 202 | } |
197 | 203 | ||
198 | static int hist_browser__run(struct hist_browser *self, const char *title, | 204 | static int callchain_node__set_folding_rb_tree(struct callchain_node *self, bool unfold) |
199 | struct newtExitStruct *es) | 205 | { |
206 | int n = 0; | ||
207 | struct rb_node *nd; | ||
208 | |||
209 | for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { | ||
210 | struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); | ||
211 | struct callchain_list *chain; | ||
212 | bool has_children = false; | ||
213 | |||
214 | list_for_each_entry(chain, &child->val, list) { | ||
215 | ++n; | ||
216 | map_symbol__set_folding(&chain->ms, unfold); | ||
217 | has_children = chain->ms.has_children; | ||
218 | } | ||
219 | |||
220 | if (has_children) | ||
221 | n += callchain_node__set_folding_rb_tree(child, unfold); | ||
222 | } | ||
223 | |||
224 | return n; | ||
225 | } | ||
226 | |||
227 | static int callchain_node__set_folding(struct callchain_node *node, bool unfold) | ||
228 | { | ||
229 | struct callchain_list *chain; | ||
230 | bool has_children = false; | ||
231 | int n = 0; | ||
232 | |||
233 | list_for_each_entry(chain, &node->val, list) { | ||
234 | ++n; | ||
235 | map_symbol__set_folding(&chain->ms, unfold); | ||
236 | has_children = chain->ms.has_children; | ||
237 | } | ||
238 | |||
239 | if (has_children) | ||
240 | n += callchain_node__set_folding_rb_tree(node, unfold); | ||
241 | |||
242 | return n; | ||
243 | } | ||
244 | |||
245 | static int callchain__set_folding(struct rb_root *chain, bool unfold) | ||
246 | { | ||
247 | struct rb_node *nd; | ||
248 | int n = 0; | ||
249 | |||
250 | for (nd = rb_first(chain); nd; nd = rb_next(nd)) { | ||
251 | struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); | ||
252 | n += callchain_node__set_folding(node, unfold); | ||
253 | } | ||
254 | |||
255 | return n; | ||
256 | } | ||
257 | |||
258 | static void hist_entry__set_folding(struct hist_entry *self, bool unfold) | ||
259 | { | ||
260 | hist_entry__init_have_children(self); | ||
261 | map_symbol__set_folding(&self->ms, unfold); | ||
262 | |||
263 | if (self->ms.has_children) { | ||
264 | int n = callchain__set_folding(&self->sorted_chain, unfold); | ||
265 | self->nr_rows = unfold ? n : 0; | ||
266 | } else | ||
267 | self->nr_rows = 0; | ||
268 | } | ||
269 | |||
270 | static void hists__set_folding(struct hists *self, bool unfold) | ||
271 | { | ||
272 | struct rb_node *nd; | ||
273 | |||
274 | self->nr_entries = 0; | ||
275 | |||
276 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | ||
277 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | ||
278 | hist_entry__set_folding(he, unfold); | ||
279 | self->nr_entries += 1 + he->nr_rows; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static void hist_browser__set_folding(struct hist_browser *self, bool unfold) | ||
284 | { | ||
285 | hists__set_folding(self->hists, unfold); | ||
286 | self->b.nr_entries = self->hists->nr_entries; | ||
287 | /* Go to the start, we may be way after valid entries after a collapse */ | ||
288 | ui_browser__reset_index(&self->b); | ||
289 | } | ||
290 | |||
291 | static int hist_browser__run(struct hist_browser *self, const char *title) | ||
200 | { | 292 | { |
201 | char str[256], unit; | 293 | int key; |
202 | unsigned long nr_events = self->hists->stats.nr_events[PERF_RECORD_SAMPLE]; | 294 | int exit_keys[] = { 'a', '?', 'h', 'C', 'd', 'D', 'E', 't', |
295 | NEWT_KEY_ENTER, NEWT_KEY_RIGHT, NEWT_KEY_LEFT, 0, }; | ||
203 | 296 | ||
204 | self->b.entries = &self->hists->entries; | 297 | self->b.entries = &self->hists->entries; |
205 | self->b.nr_entries = self->hists->nr_entries; | 298 | self->b.nr_entries = self->hists->nr_entries; |
206 | 299 | ||
207 | hist_browser__refresh_dimensions(self); | 300 | hist_browser__refresh_dimensions(self); |
208 | 301 | ||
209 | nr_events = convert_unit(nr_events, &unit); | ||
210 | snprintf(str, sizeof(str), "Events: %lu%c ", | ||
211 | nr_events, unit); | ||
212 | newtDrawRootText(0, 0, str); | ||
213 | |||
214 | if (ui_browser__show(&self->b, title, | 302 | if (ui_browser__show(&self->b, title, |
215 | "Press '?' for help on key bindings") < 0) | 303 | "Press '?' for help on key bindings") < 0) |
216 | return -1; | 304 | return -1; |
217 | 305 | ||
218 | newtFormAddHotKey(self->b.form, 'a'); | 306 | ui_browser__add_exit_keys(&self->b, exit_keys); |
219 | newtFormAddHotKey(self->b.form, '?'); | ||
220 | newtFormAddHotKey(self->b.form, 'h'); | ||
221 | newtFormAddHotKey(self->b.form, 'd'); | ||
222 | newtFormAddHotKey(self->b.form, 'D'); | ||
223 | newtFormAddHotKey(self->b.form, 't'); | ||
224 | |||
225 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); | ||
226 | newtFormAddHotKey(self->b.form, NEWT_KEY_RIGHT); | ||
227 | newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); | ||
228 | 307 | ||
229 | while (1) { | 308 | while (1) { |
230 | ui_browser__run(&self->b, es); | 309 | key = ui_browser__run(&self->b); |
231 | 310 | ||
232 | if (es->reason != NEWT_EXIT_HOTKEY) | 311 | switch (key) { |
233 | break; | ||
234 | switch (es->u.key) { | ||
235 | case 'D': { /* Debug */ | 312 | case 'D': { /* Debug */ |
236 | static int seq; | 313 | static int seq; |
237 | struct hist_entry *h = rb_entry(self->b.top, | 314 | struct hist_entry *h = rb_entry(self->b.top, |
@@ -245,18 +322,26 @@ static int hist_browser__run(struct hist_browser *self, const char *title, | |||
245 | self->b.top_idx, | 322 | self->b.top_idx, |
246 | h->row_offset, h->nr_rows); | 323 | h->row_offset, h->nr_rows); |
247 | } | 324 | } |
248 | continue; | 325 | break; |
326 | case 'C': | ||
327 | /* Collapse the whole world. */ | ||
328 | hist_browser__set_folding(self, false); | ||
329 | break; | ||
330 | case 'E': | ||
331 | /* Expand the whole world. */ | ||
332 | hist_browser__set_folding(self, true); | ||
333 | break; | ||
249 | case NEWT_KEY_ENTER: | 334 | case NEWT_KEY_ENTER: |
250 | if (hist_browser__toggle_fold(self)) | 335 | if (hist_browser__toggle_fold(self)) |
251 | break; | 336 | break; |
252 | /* fall thru */ | 337 | /* fall thru */ |
253 | default: | 338 | default: |
254 | return 0; | 339 | goto out; |
255 | } | 340 | } |
256 | } | 341 | } |
257 | 342 | out: | |
258 | ui_browser__hide(&self->b); | 343 | ui_browser__hide(&self->b); |
259 | return 0; | 344 | return key; |
260 | } | 345 | } |
261 | 346 | ||
262 | static char *callchain_list__sym_name(struct callchain_list *self, | 347 | static char *callchain_list__sym_name(struct callchain_list *self, |
@@ -306,15 +391,10 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *self, | |||
306 | int color; | 391 | int color; |
307 | bool was_first = first; | 392 | bool was_first = first; |
308 | 393 | ||
309 | if (first) { | 394 | if (first) |
310 | first = false; | 395 | first = false; |
311 | chain->ms.has_children = chain->list.next != &child->val || | 396 | else |
312 | rb_first(&child->rb_root) != NULL; | ||
313 | } else { | ||
314 | extra_offset = LEVEL_OFFSET_STEP; | 397 | extra_offset = LEVEL_OFFSET_STEP; |
315 | chain->ms.has_children = chain->list.next == &child->val && | ||
316 | rb_first(&child->rb_root) != NULL; | ||
317 | } | ||
318 | 398 | ||
319 | folded_sign = callchain_list__folded(chain); | 399 | folded_sign = callchain_list__folded(chain); |
320 | if (*row_offset != 0) { | 400 | if (*row_offset != 0) { |
@@ -341,8 +421,8 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *self, | |||
341 | *is_current_entry = true; | 421 | *is_current_entry = true; |
342 | } | 422 | } |
343 | 423 | ||
344 | SLsmg_set_color(color); | 424 | ui_browser__set_color(&self->b, color); |
345 | SLsmg_gotorc(self->b.y + row, self->b.x); | 425 | ui_browser__gotorc(&self->b, row, 0); |
346 | slsmg_write_nstring(" ", offset + extra_offset); | 426 | slsmg_write_nstring(" ", offset + extra_offset); |
347 | slsmg_printf("%c ", folded_sign); | 427 | slsmg_printf("%c ", folded_sign); |
348 | slsmg_write_nstring(str, width); | 428 | slsmg_write_nstring(str, width); |
@@ -384,12 +464,7 @@ static int hist_browser__show_callchain_node(struct hist_browser *self, | |||
384 | list_for_each_entry(chain, &node->val, list) { | 464 | list_for_each_entry(chain, &node->val, list) { |
385 | char ipstr[BITS_PER_LONG / 4 + 1], *s; | 465 | char ipstr[BITS_PER_LONG / 4 + 1], *s; |
386 | int color; | 466 | int color; |
387 | /* | 467 | |
388 | * FIXME: This should be moved to somewhere else, | ||
389 | * probably when the callchain is created, so as not to | ||
390 | * traverse it all over again | ||
391 | */ | ||
392 | chain->ms.has_children = rb_first(&node->rb_root) != NULL; | ||
393 | folded_sign = callchain_list__folded(chain); | 468 | folded_sign = callchain_list__folded(chain); |
394 | 469 | ||
395 | if (*row_offset != 0) { | 470 | if (*row_offset != 0) { |
@@ -405,8 +480,8 @@ static int hist_browser__show_callchain_node(struct hist_browser *self, | |||
405 | } | 480 | } |
406 | 481 | ||
407 | s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); | 482 | s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); |
408 | SLsmg_gotorc(self->b.y + row, self->b.x); | 483 | ui_browser__gotorc(&self->b, row, 0); |
409 | SLsmg_set_color(color); | 484 | ui_browser__set_color(&self->b, color); |
410 | slsmg_write_nstring(" ", offset); | 485 | slsmg_write_nstring(" ", offset); |
411 | slsmg_printf("%c ", folded_sign); | 486 | slsmg_printf("%c ", folded_sign); |
412 | slsmg_write_nstring(s, width - 2); | 487 | slsmg_write_nstring(s, width - 2); |
@@ -465,7 +540,7 @@ static int hist_browser__show_entry(struct hist_browser *self, | |||
465 | } | 540 | } |
466 | 541 | ||
467 | if (symbol_conf.use_callchain) { | 542 | if (symbol_conf.use_callchain) { |
468 | entry->ms.has_children = !RB_EMPTY_ROOT(&entry->sorted_chain); | 543 | hist_entry__init_have_children(entry); |
469 | folded_sign = hist_entry__folded(entry); | 544 | folded_sign = hist_entry__folded(entry); |
470 | } | 545 | } |
471 | 546 | ||
@@ -484,8 +559,8 @@ static int hist_browser__show_entry(struct hist_browser *self, | |||
484 | color = HE_COLORSET_NORMAL; | 559 | color = HE_COLORSET_NORMAL; |
485 | } | 560 | } |
486 | 561 | ||
487 | SLsmg_set_color(color); | 562 | ui_browser__set_color(&self->b, color); |
488 | SLsmg_gotorc(self->b.y + row, self->b.x); | 563 | ui_browser__gotorc(&self->b, row, 0); |
489 | if (symbol_conf.use_callchain) { | 564 | if (symbol_conf.use_callchain) { |
490 | slsmg_printf("%c ", folded_sign); | 565 | slsmg_printf("%c ", folded_sign); |
491 | width -= 2; | 566 | width -= 2; |
@@ -687,8 +762,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists) | |||
687 | 762 | ||
688 | static void hist_browser__delete(struct hist_browser *self) | 763 | static void hist_browser__delete(struct hist_browser *self) |
689 | { | 764 | { |
690 | newtFormDestroy(self->b.form); | ||
691 | newtPopWindow(); | ||
692 | free(self); | 765 | free(self); |
693 | } | 766 | } |
694 | 767 | ||
@@ -702,21 +775,26 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *self) | |||
702 | return self->he_selection->thread; | 775 | return self->he_selection->thread; |
703 | } | 776 | } |
704 | 777 | ||
705 | static int hist_browser__title(char *bf, size_t size, const char *ev_name, | 778 | static int hists__browser_title(struct hists *self, char *bf, size_t size, |
706 | const struct dso *dso, const struct thread *thread) | 779 | const char *ev_name, const struct dso *dso, |
780 | const struct thread *thread) | ||
707 | { | 781 | { |
708 | int printed = 0; | 782 | char unit; |
783 | int printed; | ||
784 | unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE]; | ||
785 | |||
786 | nr_events = convert_unit(nr_events, &unit); | ||
787 | printed = snprintf(bf, size, "Events: %lu%c %s", nr_events, unit, ev_name); | ||
709 | 788 | ||
710 | if (thread) | 789 | if (thread) |
711 | printed += snprintf(bf + printed, size - printed, | 790 | printed += snprintf(bf + printed, size - printed, |
712 | "Thread: %s(%d)", | 791 | ", Thread: %s(%d)", |
713 | (thread->comm_set ? thread->comm : ""), | 792 | (thread->comm_set ? thread->comm : ""), |
714 | thread->pid); | 793 | thread->pid); |
715 | if (dso) | 794 | if (dso) |
716 | printed += snprintf(bf + printed, size - printed, | 795 | printed += snprintf(bf + printed, size - printed, |
717 | "%sDSO: %s", thread ? " " : "", | 796 | ", DSO: %s", dso->short_name); |
718 | dso->short_name); | 797 | return printed; |
719 | return printed ?: snprintf(bf, size, "Event: %s", ev_name); | ||
720 | } | 798 | } |
721 | 799 | ||
722 | int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | 800 | int hists__browse(struct hists *self, const char *helpline, const char *ev_name) |
@@ -725,7 +803,6 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | |||
725 | struct pstack *fstack; | 803 | struct pstack *fstack; |
726 | const struct thread *thread_filter = NULL; | 804 | const struct thread *thread_filter = NULL; |
727 | const struct dso *dso_filter = NULL; | 805 | const struct dso *dso_filter = NULL; |
728 | struct newtExitStruct es; | ||
729 | char msg[160]; | 806 | char msg[160]; |
730 | int key = -1; | 807 | int key = -1; |
731 | 808 | ||
@@ -738,9 +815,8 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | |||
738 | 815 | ||
739 | ui_helpline__push(helpline); | 816 | ui_helpline__push(helpline); |
740 | 817 | ||
741 | hist_browser__title(msg, sizeof(msg), ev_name, | 818 | hists__browser_title(self, msg, sizeof(msg), ev_name, |
742 | dso_filter, thread_filter); | 819 | dso_filter, thread_filter); |
743 | |||
744 | while (1) { | 820 | while (1) { |
745 | const struct thread *thread; | 821 | const struct thread *thread; |
746 | const struct dso *dso; | 822 | const struct dso *dso; |
@@ -749,70 +825,63 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | |||
749 | annotate = -2, zoom_dso = -2, zoom_thread = -2, | 825 | annotate = -2, zoom_dso = -2, zoom_thread = -2, |
750 | browse_map = -2; | 826 | browse_map = -2; |
751 | 827 | ||
752 | if (hist_browser__run(browser, msg, &es)) | 828 | key = hist_browser__run(browser, msg); |
753 | break; | ||
754 | 829 | ||
755 | thread = hist_browser__selected_thread(browser); | 830 | thread = hist_browser__selected_thread(browser); |
756 | dso = browser->selection->map ? browser->selection->map->dso : NULL; | 831 | dso = browser->selection->map ? browser->selection->map->dso : NULL; |
757 | 832 | ||
758 | if (es.reason == NEWT_EXIT_HOTKEY) { | 833 | switch (key) { |
759 | key = es.u.key; | 834 | case NEWT_KEY_TAB: |
760 | 835 | case NEWT_KEY_UNTAB: | |
761 | switch (key) { | 836 | /* |
762 | case NEWT_KEY_F1: | 837 | * Exit the browser, let hists__browser_tree |
763 | goto do_help; | 838 | * go to the next or previous |
764 | case NEWT_KEY_TAB: | 839 | */ |
765 | case NEWT_KEY_UNTAB: | 840 | goto out_free_stack; |
766 | /* | 841 | case 'a': |
767 | * Exit the browser, let hists__browser_tree | 842 | if (browser->selection->map == NULL && |
768 | * go to the next or previous | 843 | browser->selection->map->dso->annotate_warned) |
769 | */ | ||
770 | goto out_free_stack; | ||
771 | default:; | ||
772 | } | ||
773 | |||
774 | switch (key) { | ||
775 | case 'a': | ||
776 | if (browser->selection->map == NULL && | ||
777 | browser->selection->map->dso->annotate_warned) | ||
778 | continue; | ||
779 | goto do_annotate; | ||
780 | case 'd': | ||
781 | goto zoom_dso; | ||
782 | case 't': | ||
783 | goto zoom_thread; | ||
784 | case 'h': | ||
785 | case '?': | ||
786 | do_help: | ||
787 | ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n" | ||
788 | "<- Zoom out\n" | ||
789 | "a Annotate current symbol\n" | ||
790 | "h/?/F1 Show this window\n" | ||
791 | "d Zoom into current DSO\n" | ||
792 | "t Zoom into current Thread\n" | ||
793 | "q/CTRL+C Exit browser"); | ||
794 | continue; | 844 | continue; |
795 | default:; | 845 | goto do_annotate; |
796 | } | 846 | case 'd': |
797 | if (is_exit_key(key)) { | 847 | goto zoom_dso; |
798 | if (key == NEWT_KEY_ESCAPE && | 848 | case 't': |
799 | !ui__dialog_yesno("Do you really want to exit?")) | 849 | goto zoom_thread; |
800 | continue; | 850 | case NEWT_KEY_F1: |
801 | break; | 851 | case 'h': |
802 | } | 852 | case '?': |
803 | 853 | ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n" | |
804 | if (es.u.key == NEWT_KEY_LEFT) { | 854 | "<- Zoom out\n" |
805 | const void *top; | 855 | "a Annotate current symbol\n" |
856 | "h/?/F1 Show this window\n" | ||
857 | "C Collapse all callchains\n" | ||
858 | "E Expand all callchains\n" | ||
859 | "d Zoom into current DSO\n" | ||
860 | "t Zoom into current Thread\n" | ||
861 | "q/CTRL+C Exit browser"); | ||
862 | continue; | ||
863 | case NEWT_KEY_ENTER: | ||
864 | case NEWT_KEY_RIGHT: | ||
865 | /* menu */ | ||
866 | break; | ||
867 | case NEWT_KEY_LEFT: { | ||
868 | const void *top; | ||
806 | 869 | ||
807 | if (pstack__empty(fstack)) | 870 | if (pstack__empty(fstack)) |
808 | continue; | ||
809 | top = pstack__pop(fstack); | ||
810 | if (top == &dso_filter) | ||
811 | goto zoom_out_dso; | ||
812 | if (top == &thread_filter) | ||
813 | goto zoom_out_thread; | ||
814 | continue; | 871 | continue; |
815 | } | 872 | top = pstack__pop(fstack); |
873 | if (top == &dso_filter) | ||
874 | goto zoom_out_dso; | ||
875 | if (top == &thread_filter) | ||
876 | goto zoom_out_thread; | ||
877 | continue; | ||
878 | } | ||
879 | case NEWT_KEY_ESCAPE: | ||
880 | if (!ui__dialog_yesno("Do you really want to exit?")) | ||
881 | continue; | ||
882 | /* Fall thru */ | ||
883 | default: | ||
884 | goto out_free_stack; | ||
816 | } | 885 | } |
817 | 886 | ||
818 | if (browser->selection->sym != NULL && | 887 | if (browser->selection->sym != NULL && |
@@ -885,8 +954,8 @@ zoom_out_dso: | |||
885 | pstack__push(fstack, &dso_filter); | 954 | pstack__push(fstack, &dso_filter); |
886 | } | 955 | } |
887 | hists__filter_by_dso(self, dso_filter); | 956 | hists__filter_by_dso(self, dso_filter); |
888 | hist_browser__title(msg, sizeof(msg), ev_name, | 957 | hists__browser_title(self, msg, sizeof(msg), ev_name, |
889 | dso_filter, thread_filter); | 958 | dso_filter, thread_filter); |
890 | hist_browser__reset(browser); | 959 | hist_browser__reset(browser); |
891 | } else if (choice == zoom_thread) { | 960 | } else if (choice == zoom_thread) { |
892 | zoom_thread: | 961 | zoom_thread: |
@@ -903,8 +972,8 @@ zoom_out_thread: | |||
903 | pstack__push(fstack, &thread_filter); | 972 | pstack__push(fstack, &thread_filter); |
904 | } | 973 | } |
905 | hists__filter_by_thread(self, thread_filter); | 974 | hists__filter_by_thread(self, thread_filter); |
906 | hist_browser__title(msg, sizeof(msg), ev_name, | 975 | hists__browser_title(self, msg, sizeof(msg), ev_name, |
907 | dso_filter, thread_filter); | 976 | dso_filter, thread_filter); |
908 | hist_browser__reset(browser); | 977 | hist_browser__reset(browser); |
909 | } | 978 | } |
910 | } | 979 | } |
@@ -925,10 +994,6 @@ int hists__tui_browse_tree(struct rb_root *self, const char *help) | |||
925 | const char *ev_name = __event_name(hists->type, hists->config); | 994 | const char *ev_name = __event_name(hists->type, hists->config); |
926 | 995 | ||
927 | key = hists__browse(hists, help, ev_name); | 996 | key = hists__browse(hists, help, ev_name); |
928 | |||
929 | if (is_exit_key(key)) | ||
930 | break; | ||
931 | |||
932 | switch (key) { | 997 | switch (key) { |
933 | case NEWT_KEY_TAB: | 998 | case NEWT_KEY_TAB: |
934 | next = rb_next(nd); | 999 | next = rb_next(nd); |
@@ -940,7 +1005,7 @@ int hists__tui_browse_tree(struct rb_root *self, const char *help) | |||
940 | continue; | 1005 | continue; |
941 | nd = rb_prev(nd); | 1006 | nd = rb_prev(nd); |
942 | default: | 1007 | default: |
943 | break; | 1008 | return key; |
944 | } | 1009 | } |
945 | } | 1010 | } |
946 | 1011 | ||
diff --git a/tools/perf/util/ui/browsers/map.c b/tools/perf/util/ui/browsers/map.c index 142b825b42bf..e35437dfa5b4 100644 --- a/tools/perf/util/ui/browsers/map.c +++ b/tools/perf/util/ui/browsers/map.c | |||
@@ -1,6 +1,5 @@ | |||
1 | #include "../libslang.h" | 1 | #include "../libslang.h" |
2 | #include <elf.h> | 2 | #include <elf.h> |
3 | #include <newt.h> | ||
4 | #include <sys/ttydefaults.h> | 3 | #include <sys/ttydefaults.h> |
5 | #include <ctype.h> | 4 | #include <ctype.h> |
6 | #include <string.h> | 5 | #include <string.h> |
@@ -47,7 +46,6 @@ out_free_form: | |||
47 | struct map_browser { | 46 | struct map_browser { |
48 | struct ui_browser b; | 47 | struct ui_browser b; |
49 | struct map *map; | 48 | struct map *map; |
50 | u16 namelen; | ||
51 | u8 addrlen; | 49 | u8 addrlen; |
52 | }; | 50 | }; |
53 | 51 | ||
@@ -56,14 +54,16 @@ static void map_browser__write(struct ui_browser *self, void *nd, int row) | |||
56 | struct symbol *sym = rb_entry(nd, struct symbol, rb_node); | 54 | struct symbol *sym = rb_entry(nd, struct symbol, rb_node); |
57 | struct map_browser *mb = container_of(self, struct map_browser, b); | 55 | struct map_browser *mb = container_of(self, struct map_browser, b); |
58 | bool current_entry = ui_browser__is_current_entry(self, row); | 56 | bool current_entry = ui_browser__is_current_entry(self, row); |
59 | int color = ui_browser__percent_color(0, current_entry); | 57 | int width; |
60 | 58 | ||
61 | SLsmg_set_color(color); | 59 | ui_browser__set_percent_color(self, 0, current_entry); |
62 | slsmg_printf("%*llx %*llx %c ", | 60 | slsmg_printf("%*llx %*llx %c ", |
63 | mb->addrlen, sym->start, mb->addrlen, sym->end, | 61 | mb->addrlen, sym->start, mb->addrlen, sym->end, |
64 | sym->binding == STB_GLOBAL ? 'g' : | 62 | sym->binding == STB_GLOBAL ? 'g' : |
65 | sym->binding == STB_LOCAL ? 'l' : 'w'); | 63 | sym->binding == STB_LOCAL ? 'l' : 'w'); |
66 | slsmg_write_nstring(sym->name, mb->namelen); | 64 | width = self->width - ((mb->addrlen * 2) + 4); |
65 | if (width > 0) | ||
66 | slsmg_write_nstring(sym->name, width); | ||
67 | } | 67 | } |
68 | 68 | ||
69 | /* FIXME uber-kludgy, see comment on cmd_report... */ | 69 | /* FIXME uber-kludgy, see comment on cmd_report... */ |
@@ -98,31 +98,29 @@ static int map_browser__search(struct map_browser *self) | |||
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
100 | 100 | ||
101 | static int map_browser__run(struct map_browser *self, struct newtExitStruct *es) | 101 | static int map_browser__run(struct map_browser *self) |
102 | { | 102 | { |
103 | int key; | ||
104 | |||
103 | if (ui_browser__show(&self->b, self->map->dso->long_name, | 105 | if (ui_browser__show(&self->b, self->map->dso->long_name, |
104 | "Press <- or ESC to exit, %s / to search", | 106 | "Press <- or ESC to exit, %s / to search", |
105 | verbose ? "" : "restart with -v to use") < 0) | 107 | verbose ? "" : "restart with -v to use") < 0) |
106 | return -1; | 108 | return -1; |
107 | 109 | ||
108 | newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); | ||
109 | newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); | ||
110 | if (verbose) | 110 | if (verbose) |
111 | newtFormAddHotKey(self->b.form, '/'); | 111 | ui_browser__add_exit_key(&self->b, '/'); |
112 | 112 | ||
113 | while (1) { | 113 | while (1) { |
114 | ui_browser__run(&self->b, es); | 114 | key = ui_browser__run(&self->b); |
115 | 115 | ||
116 | if (es->reason != NEWT_EXIT_HOTKEY) | 116 | if (verbose && key == '/') |
117 | break; | ||
118 | if (verbose && es->u.key == '/') | ||
119 | map_browser__search(self); | 117 | map_browser__search(self); |
120 | else | 118 | else |
121 | break; | 119 | break; |
122 | } | 120 | } |
123 | 121 | ||
124 | ui_browser__hide(&self->b); | 122 | ui_browser__hide(&self->b); |
125 | return 0; | 123 | return key; |
126 | } | 124 | } |
127 | 125 | ||
128 | int map__browse(struct map *self) | 126 | int map__browse(struct map *self) |
@@ -136,7 +134,6 @@ int map__browse(struct map *self) | |||
136 | }, | 134 | }, |
137 | .map = self, | 135 | .map = self, |
138 | }; | 136 | }; |
139 | struct newtExitStruct es; | ||
140 | struct rb_node *nd; | 137 | struct rb_node *nd; |
141 | char tmp[BITS_PER_LONG / 4]; | 138 | char tmp[BITS_PER_LONG / 4]; |
142 | u64 maxaddr = 0; | 139 | u64 maxaddr = 0; |
@@ -144,8 +141,6 @@ int map__browse(struct map *self) | |||
144 | for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) { | 141 | for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) { |
145 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | 142 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
146 | 143 | ||
147 | if (mb.namelen < pos->namelen) | ||
148 | mb.namelen = pos->namelen; | ||
149 | if (maxaddr < pos->end) | 144 | if (maxaddr < pos->end) |
150 | maxaddr = pos->end; | 145 | maxaddr = pos->end; |
151 | if (verbose) { | 146 | if (verbose) { |
@@ -156,6 +151,5 @@ int map__browse(struct map *self) | |||
156 | } | 151 | } |
157 | 152 | ||
158 | mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); | 153 | mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); |
159 | mb.b.width += mb.addrlen * 2 + 4 + mb.namelen; | 154 | return map_browser__run(&mb); |
160 | return map_browser__run(&mb, &es); | ||
161 | } | 155 | } |
diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c index 04600e26ceea..9706d9d40279 100644 --- a/tools/perf/util/ui/util.c +++ b/tools/perf/util/ui/util.c | |||
@@ -11,8 +11,6 @@ | |||
11 | #include "helpline.h" | 11 | #include "helpline.h" |
12 | #include "util.h" | 12 | #include "util.h" |
13 | 13 | ||
14 | newtComponent newt_form__new(void); | ||
15 | |||
16 | static void newt_form__set_exit_keys(newtComponent self) | 14 | static void newt_form__set_exit_keys(newtComponent self) |
17 | { | 15 | { |
18 | newtFormAddHotKey(self, NEWT_KEY_LEFT); | 16 | newtFormAddHotKey(self, NEWT_KEY_LEFT); |
@@ -22,7 +20,7 @@ static void newt_form__set_exit_keys(newtComponent self) | |||
22 | newtFormAddHotKey(self, CTRL('c')); | 20 | newtFormAddHotKey(self, CTRL('c')); |
23 | } | 21 | } |
24 | 22 | ||
25 | newtComponent newt_form__new(void) | 23 | static newtComponent newt_form__new(void) |
26 | { | 24 | { |
27 | newtComponent self = newtForm(NULL, NULL, 0); | 25 | newtComponent self = newtForm(NULL, NULL, 0); |
28 | if (self) | 26 | if (self) |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index f380fed74359..7562707ddd1c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -266,19 +266,6 @@ bool strglobmatch(const char *str, const char *pat); | |||
266 | bool strlazymatch(const char *str, const char *pat); | 266 | bool strlazymatch(const char *str, const char *pat); |
267 | unsigned long convert_unit(unsigned long value, char *unit); | 267 | unsigned long convert_unit(unsigned long value, char *unit); |
268 | 268 | ||
269 | #ifndef ESC | ||
270 | #define ESC 27 | ||
271 | #endif | ||
272 | |||
273 | static inline bool is_exit_key(int key) | ||
274 | { | ||
275 | char up; | ||
276 | if (key == CTRL('c') || key == ESC) | ||
277 | return true; | ||
278 | up = toupper(key); | ||
279 | return up == 'Q'; | ||
280 | } | ||
281 | |||
282 | #define _STR(x) #x | 269 | #define _STR(x) #x |
283 | #define STR(x) _STR(x) | 270 | #define STR(x) _STR(x) |
284 | 271 | ||
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 66cf65b510b1..c1f1e3c62984 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -218,7 +218,6 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
218 | events = file->f_op->poll(file, &irqfd->pt); | 218 | events = file->f_op->poll(file, &irqfd->pt); |
219 | 219 | ||
220 | list_add_tail(&irqfd->list, &kvm->irqfds.items); | 220 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
221 | spin_unlock_irq(&kvm->irqfds.lock); | ||
222 | 221 | ||
223 | /* | 222 | /* |
224 | * Check if there was an event already pending on the eventfd | 223 | * Check if there was an event already pending on the eventfd |
@@ -227,6 +226,8 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
227 | if (events & POLLIN) | 226 | if (events & POLLIN) |
228 | schedule_work(&irqfd->inject); | 227 | schedule_work(&irqfd->inject); |
229 | 228 | ||
229 | spin_unlock_irq(&kvm->irqfds.lock); | ||
230 | |||
230 | /* | 231 | /* |
231 | * do not drop the file until the irqfd is fully initialized, otherwise | 232 | * do not drop the file until the irqfd is fully initialized, otherwise |
232 | * we might race against the POLLHUP | 233 | * we might race against the POLLHUP |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d4853a54771a..5186e728c53e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1970,10 +1970,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
1970 | 1970 | ||
1971 | asmlinkage void kvm_handle_fault_on_reboot(void) | 1971 | asmlinkage void kvm_handle_fault_on_reboot(void) |
1972 | { | 1972 | { |
1973 | if (kvm_rebooting) | 1973 | if (kvm_rebooting) { |
1974 | /* spin while reset goes on */ | 1974 | /* spin while reset goes on */ |
1975 | local_irq_enable(); | ||
1975 | while (true) | 1976 | while (true) |
1976 | ; | 1977 | ; |
1978 | } | ||
1977 | /* Fault while not rebooting. We want the trace. */ | 1979 | /* Fault while not rebooting. We want the trace. */ |
1978 | BUG(); | 1980 | BUG(); |
1979 | } | 1981 | } |