diff --git a/[refs] b/[refs] index 0e3dd12e15c8..dc72c53a3627 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7334219c44826ae0ebe6f07555c6b97f978ce266 +refs/heads/master: c8c00a6915a2e3d10416e8bdd3138429beb96210 diff --git a/trunk/Documentation/ioctl/ioctl-number.txt b/trunk/Documentation/ioctl/ioctl-number.txt index dbea4f95fc85..7bb0d934b6d8 100644 --- a/trunk/Documentation/ioctl/ioctl-number.txt +++ b/trunk/Documentation/ioctl/ioctl-number.txt @@ -139,7 +139,6 @@ Code Seq# Include File Comments 'm' all linux/synclink.h conflict! 'm' 00-1F net/irda/irmod.h conflict! 'n' 00-7F linux/ncp_fs.h -'n' 80-8F linux/nilfs2_fs.h NILFS2 'n' E0-FF video/matrox.h matroxfb 'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 'o' 00-03 include/mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 7936b801fe6a..dd1a6d4bb747 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1115,10 +1115,6 @@ and is between 256 and 4096 characters. It is defined in the file libata.dma=4 Compact Flash DMA only Combinations also work, so libata.dma=3 enables DMA for disks and CDROMs, but not CFs. - - libata.ignore_hpa= [LIBATA] Ignore HPA limit - libata.ignore_hpa=0 keep BIOS limits (default) - libata.ignore_hpa=1 ignore limits, using full disk libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume when set. diff --git a/trunk/Documentation/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index abf768c681e2..e20d913d5914 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -30,9 +30,9 @@ State The validator tracks lock-class usage history into 4n + 1 separate state bits: - 'ever held in STATE context' -- 'ever held as readlock in STATE context' -- 'ever held with STATE enabled' -- 'ever held as readlock with STATE enabled' +- 'ever head as readlock in STATE context' +- 'ever head with STATE enabled' +- 'ever head as readlock with STATE enabled' Where STATE can be either one of (kernel/lockdep_states.h) - hardirq diff --git a/trunk/arch/ia64/Makefile b/trunk/arch/ia64/Makefile index e7cbaa02cd0b..58a7e46affda 100644 --- a/trunk/arch/ia64/Makefile +++ b/trunk/arch/ia64/Makefile @@ -41,6 +41,11 @@ $(error Sorry, you need a newer version of the assember, one that is built from ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) endif +ifeq ($(call cc-version),0304) + cflags-$(CONFIG_ITANIUM) += -mtune=merced + cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley +endif + KBUILD_CFLAGS += $(cflags-y) head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o diff --git a/trunk/arch/ia64/include/asm/bitops.h b/trunk/arch/ia64/include/asm/bitops.h index 57a2787bc9fb..e2ca80037335 100644 --- a/trunk/arch/ia64/include/asm/bitops.h +++ b/trunk/arch/ia64/include/asm/bitops.h @@ -286,7 +286,7 @@ __test_and_clear_bit(int nr, volatile void * addr) { __u32 *p = (__u32 *) addr + (nr >> 5); __u32 m = 1 << (nr & 31); - int oldbitset = (*p & m) != 0; + int oldbitset = *p & m; *p &= ~m; return oldbitset; diff --git a/trunk/arch/ia64/include/asm/pgtable.h b/trunk/arch/ia64/include/asm/pgtable.h index 8840a690d1e7..0a9cc73d35c7 100644 --- a/trunk/arch/ia64/include/asm/pgtable.h +++ b/trunk/arch/ia64/include/asm/pgtable.h @@ -155,6 +155,7 @@ #include #include #include +#include /* * Next come the mappings that determine how mmap() protection bits diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c index 8ebccb589e1c..2d311864e359 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -21,7 +21,6 @@ EXPORT_SYMBOL(csum_ipv6_magic); #include EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); #ifdef CONFIG_VIRTUAL_MEM_MAP #include @@ -61,6 +60,9 @@ EXPORT_SYMBOL(__udivdi3); EXPORT_SYMBOL(__moddi3); EXPORT_SYMBOL(__umoddi3); +#include +EXPORT_SYMBOL(copy_page); + #if defined(CONFIG_MD_RAID456) || defined(CONFIG_MD_RAID456_MODULE) extern void xor_ia64_2(void); extern void xor_ia64_3(void); diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index dab4d393908c..c48b03f2b61d 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -1072,10 +1072,6 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) } addr = ioremap(phys_addr, 0); - if (addr == NULL) { - spin_unlock_irqrestore(&iosapic_lock, flags); - return -ENOMEM; - } ver = iosapic_version(addr); if ((err = iosapic_check_gsi_range(gsi_base, ver))) { iounmap(addr); diff --git a/trunk/arch/ia64/kernel/pci-dma.c b/trunk/arch/ia64/kernel/pci-dma.c index f6b1ff0aea76..05695962fe44 100644 --- a/trunk/arch/ia64/kernel/pci-dma.c +++ b/trunk/arch/ia64/kernel/pci-dma.c @@ -69,6 +69,11 @@ iommu_dma_init(void) int iommu_dma_supported(struct device *dev, u64 mask) { + struct dma_map_ops *ops = platform_dma_get_ops(dev); + + if (ops->dma_supported) + return ops->dma_supported(dev, mask); + /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. The caller just has to use GFP_DMA in this case. */ diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 8f060352e129..bc80dff1df7a 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -372,10 +372,6 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj, &cache_ktype_percpu_entry, &sys_dev->kobj, "%s", "cache"); - if (unlikely(retval < 0)) { - cpu_cache_sysfs_exit(cpu); - return retval; - } for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) { this_object = LEAF_KOBJECT_PTR(cpu,i); @@ -389,7 +385,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) } kobject_put(&all_cpu_cache_info[cpu].kobj); cpu_cache_sysfs_exit(cpu); - return retval; + break; } kobject_uevent(&(this_object->kobj), KOBJ_ADD); } diff --git a/trunk/arch/ia64/kvm/mmio.c b/trunk/arch/ia64/kvm/mmio.c index 9bf55afd08d0..21f63fffc379 100644 --- a/trunk/arch/ia64/kvm/mmio.c +++ b/trunk/arch/ia64/kvm/mmio.c @@ -247,8 +247,7 @@ void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma) vcpu_get_fpreg(vcpu, inst.M9.f2, &v); /* Write high word. FIXME: this is a kludge! */ v.u.bits[1] &= 0x3ffff; - mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], 8, - ma, IOREQ_WRITE); + mmio_access(vcpu, padr + 8, &v.u.bits[1], 8, ma, IOREQ_WRITE); data = v.u.bits[0]; size = 3; } else if (inst.M10.major == 7 && inst.M10.x6 == 0x3B) { @@ -266,8 +265,7 @@ void emulate_io_inst(struct kvm_vcpu *vcpu, u64 padr, u64 ma) /* Write high word.FIXME: this is a kludge! */ v.u.bits[1] &= 0x3ffff; - mmio_access(vcpu, padr + 8, (u64 *)&v.u.bits[1], - 8, ma, IOREQ_WRITE); + mmio_access(vcpu, padr + 8, &v.u.bits[1], 8, ma, IOREQ_WRITE); data = v.u.bits[0]; size = 3; } else if (inst.M10.major == 7 && inst.M10.x6 == 0x31) { diff --git a/trunk/arch/ia64/kvm/vcpu.c b/trunk/arch/ia64/kvm/vcpu.c index cc406d064a09..46b02cbcc874 100644 --- a/trunk/arch/ia64/kvm/vcpu.c +++ b/trunk/arch/ia64/kvm/vcpu.c @@ -461,7 +461,7 @@ void setreg(unsigned long regnum, unsigned long val, u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg) { struct kvm_pt_regs *regs = vcpu_regs(vcpu); - unsigned long val; + u64 val; if (!reg) return 0; @@ -469,7 +469,7 @@ u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg) return val; } -void vcpu_set_gr(struct kvm_vcpu *vcpu, unsigned long reg, u64 value, int nat) +void vcpu_set_gr(struct kvm_vcpu *vcpu, u64 reg, u64 value, int nat) { struct kvm_pt_regs *regs = vcpu_regs(vcpu); long sof = (regs->cr_ifs) & 0x7f; @@ -1072,7 +1072,7 @@ void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst) vcpu_set_gr(vcpu, inst.M46.r1, tag, 0); } -int vcpu_tpa(struct kvm_vcpu *vcpu, u64 vadr, unsigned long *padr) +int vcpu_tpa(struct kvm_vcpu *vcpu, u64 vadr, u64 *padr) { struct thash_data *data; union ia64_isr visr, pt_isr; diff --git a/trunk/arch/ia64/kvm/vcpu.h b/trunk/arch/ia64/kvm/vcpu.h index 360724d3ae69..042af92ced83 100644 --- a/trunk/arch/ia64/kvm/vcpu.h +++ b/trunk/arch/ia64/kvm/vcpu.h @@ -686,15 +686,14 @@ static inline int highest_inservice_irq(struct kvm_vcpu *vcpu) return highest_bits((int *)&(VMX(vcpu, insvc[0]))); } -extern void vcpu_get_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, +extern void vcpu_get_fpreg(struct kvm_vcpu *vcpu, u64 reg, struct ia64_fpreg *val); -extern void vcpu_set_fpreg(struct kvm_vcpu *vcpu, unsigned long reg, +extern void vcpu_set_fpreg(struct kvm_vcpu *vcpu, u64 reg, struct ia64_fpreg *val); -extern u64 vcpu_get_gr(struct kvm_vcpu *vcpu, unsigned long reg); -extern void vcpu_set_gr(struct kvm_vcpu *vcpu, unsigned long reg, - u64 val, int nat); -extern unsigned long vcpu_get_psr(struct kvm_vcpu *vcpu); -extern void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val); +extern u64 vcpu_get_gr(struct kvm_vcpu *vcpu, u64 reg); +extern void vcpu_set_gr(struct kvm_vcpu *vcpu, u64 reg, u64 val, int nat); +extern u64 vcpu_get_psr(struct kvm_vcpu *vcpu); +extern void vcpu_set_psr(struct kvm_vcpu *vcpu, u64 val); extern u64 vcpu_thash(struct kvm_vcpu *vcpu, u64 vadr); extern void vcpu_bsw0(struct kvm_vcpu *vcpu); extern void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, diff --git a/trunk/arch/mn10300/include/asm/pci.h b/trunk/arch/mn10300/include/asm/pci.h index 19aecc90f7a4..35d2ed6396f6 100644 --- a/trunk/arch/mn10300/include/asm/pci.h +++ b/trunk/arch/mn10300/include/asm/pci.h @@ -59,6 +59,7 @@ void pcibios_penalize_isa_irq(int irq); #include #include #include +#include #include struct pci_dev; diff --git a/trunk/arch/powerpc/include/asm/kvm_host.h b/trunk/arch/powerpc/include/asm/kvm_host.h index fddc3ed715fa..dfdf13c9fefd 100644 --- a/trunk/arch/powerpc/include/asm/kvm_host.h +++ b/trunk/arch/powerpc/include/asm/kvm_host.h @@ -34,7 +34,7 @@ #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 /* We don't currently support large pages. */ -#define KVM_PAGES_PER_HPAGE (1UL << 31) +#define KVM_PAGES_PER_HPAGE (1<<31) struct kvm; struct kvm_run; diff --git a/trunk/arch/powerpc/kernel/dma.c b/trunk/arch/powerpc/kernel/dma.c index ccf129d47d84..20a60d661ba8 100644 --- a/trunk/arch/powerpc/kernel/dma.c +++ b/trunk/arch/powerpc/kernel/dma.c @@ -7,7 +7,6 @@ #include #include -#include #include #include @@ -91,10 +90,11 @@ static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, static int dma_direct_dma_supported(struct device *dev, u64 mask) { #ifdef CONFIG_PPC64 - /* Could be improved so platforms can set the limit in case + /* Could be improved to check for memory though it better be + * done via some global so platforms can set the limit in case * they have limited DMA windows */ - return mask >= (lmb_end_of_DRAM() - 1); + return mask >= DMA_BIT_MASK(32); #else return 1; #endif diff --git a/trunk/arch/powerpc/kernel/perf_counter.c b/trunk/arch/powerpc/kernel/perf_counter.c index 70e1f57f7dd8..809fdf94b95f 100644 --- a/trunk/arch/powerpc/kernel/perf_counter.c +++ b/trunk/arch/powerpc/kernel/perf_counter.c @@ -518,8 +518,6 @@ void hw_perf_disable(void) struct cpu_hw_counters *cpuhw; unsigned long flags; - if (!ppmu) - return; local_irq_save(flags); cpuhw = &__get_cpu_var(cpu_hw_counters); @@ -574,8 +572,6 @@ void hw_perf_enable(void) int n_lim; int idx; - if (!ppmu) - return; local_irq_save(flags); cpuhw = &__get_cpu_var(cpu_hw_counters); if (!cpuhw->disabled) { @@ -741,8 +737,6 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, long i, n, n0; struct perf_counter *sub; - if (!ppmu) - return 0; cpuhw = &__get_cpu_var(cpu_hw_counters); n0 = cpuhw->n_counters; n = collect_events(group_leader, ppmu->n_counter - n0, @@ -1287,8 +1281,6 @@ void hw_perf_counter_setup(int cpu) { struct cpu_hw_counters *cpuhw = &per_cpu(cpu_hw_counters, cpu); - if (!ppmu) - return; memset(cpuhw, 0, sizeof(*cpuhw)); cpuhw->mmcr[0] = MMCR0_FC; } diff --git a/trunk/arch/s390/kvm/interrupt.c b/trunk/arch/s390/kvm/interrupt.c index 4d613415c435..f04f5301b1b4 100644 --- a/trunk/arch/s390/kvm/interrupt.c +++ b/trunk/arch/s390/kvm/interrupt.c @@ -386,7 +386,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) } __unset_cpu_idle(vcpu); __set_current_state(TASK_RUNNING); - remove_wait_queue(&vcpu->arch.local_int.wq, &wait); + remove_wait_queue(&vcpu->wq, &wait); spin_unlock_bh(&vcpu->arch.local_int.lock); spin_unlock(&vcpu->arch.local_int.float_int->lock); hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); diff --git a/trunk/arch/sh/boards/board-ap325rxa.c b/trunk/arch/sh/boards/board-ap325rxa.c index b9c88cc519e2..7ffd1b4315bd 100644 --- a/trunk/arch/sh/boards/board-ap325rxa.c +++ b/trunk/arch/sh/boards/board-ap325rxa.c @@ -547,7 +547,7 @@ static int __init ap325rxa_devices_setup(void) return platform_add_devices(ap325rxa_devices, ARRAY_SIZE(ap325rxa_devices)); } -arch_initcall(ap325rxa_devices_setup); +device_initcall(ap325rxa_devices_setup); /* Return the board specific boot mode pin configuration */ static int ap325rxa_mode_pins(void) diff --git a/trunk/arch/sh/boards/mach-migor/setup.c b/trunk/arch/sh/boards/mach-migor/setup.c index f9b2e4df35b9..f70f4644deb4 100644 --- a/trunk/arch/sh/boards/mach-migor/setup.c +++ b/trunk/arch/sh/boards/mach-migor/setup.c @@ -608,7 +608,7 @@ static int __init migor_devices_setup(void) return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); } -arch_initcall(migor_devices_setup); +__initcall(migor_devices_setup); /* Return the board specific boot mode pin configuration */ static int migor_mode_pins(void) diff --git a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 8555c05e8667..13798733f2db 100644 --- a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -187,7 +187,7 @@ static int __init sh7619_devices_setup(void) return platform_add_devices(sh7619_devices, ARRAY_SIZE(sh7619_devices)); } -arch_initcall(sh7619_devices_setup); +__initcall(sh7619_devices_setup); void __init plat_irq_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-mxg.c index b67376445315..869c2da4820b 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -238,7 +238,7 @@ static int __init mxg_devices_setup(void) return platform_add_devices(mxg_devices, ARRAY_SIZE(mxg_devices)); } -arch_initcall(mxg_devices_setup); +__initcall(mxg_devices_setup); void __init plat_irq_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index fbde5b75deb9..d8febe128066 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -357,7 +357,7 @@ static int __init sh7201_devices_setup(void) return platform_add_devices(sh7201_devices, ARRAY_SIZE(sh7201_devices)); } -arch_initcall(sh7201_devices_setup); +__initcall(sh7201_devices_setup); void __init plat_irq_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index d3fd536c9a84..62e3039d2398 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -367,7 +367,7 @@ static int __init sh7203_devices_setup(void) return platform_add_devices(sh7203_devices, ARRAY_SIZE(sh7203_devices)); } -arch_initcall(sh7203_devices_setup); +__initcall(sh7203_devices_setup); void __init plat_irq_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index a9ccc5e8d9e9..3e6f3d7a58be 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -338,7 +338,7 @@ static int __init sh7206_devices_setup(void) return platform_add_devices(sh7206_devices, ARRAY_SIZE(sh7206_devices)); } -arch_initcall(sh7206_devices_setup); +__initcall(sh7206_devices_setup); void __init plat_irq_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c index c23105983878..88f742fed9ed 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -222,7 +222,7 @@ static int __init sh7705_devices_setup(void) return platform_add_devices(sh7705_devices, ARRAY_SIZE(sh7705_devices)); } -arch_initcall(sh7705_devices_setup); +__initcall(sh7705_devices_setup); static struct platform_device *sh7705_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 347ab35d0697..c56306798584 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -250,7 +250,7 @@ static int __init sh770x_devices_setup(void) return platform_add_devices(sh770x_devices, ARRAY_SIZE(sh770x_devices)); } -arch_initcall(sh770x_devices_setup); +__initcall(sh770x_devices_setup); static struct platform_device *sh770x_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 717e90ae1097..efa76c8148f4 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -226,7 +226,7 @@ static int __init sh7710_devices_setup(void) return platform_add_devices(sh7710_devices, ARRAY_SIZE(sh7710_devices)); } -arch_initcall(sh7710_devices_setup); +__initcall(sh7710_devices_setup); static struct platform_device *sh7710_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 74d8baaf8e96..5b2107798edb 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -388,7 +388,7 @@ static int __init sh7720_devices_setup(void) return platform_add_devices(sh7720_devices, ARRAY_SIZE(sh7720_devices)); } -arch_initcall(sh7720_devices_setup); +__initcall(sh7720_devices_setup); static struct platform_device *sh7720_early_devices[] __initdata = { &cmt0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index de4827df19aa..6d088d123591 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -138,7 +138,7 @@ static int __init sh4202_devices_setup(void) return platform_add_devices(sh4202_devices, ARRAY_SIZE(sh4202_devices)); } -arch_initcall(sh4202_devices_setup); +__initcall(sh4202_devices_setup); static struct platform_device *sh4202_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 1b8b122e8f3d..851672d15cf4 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -239,7 +239,7 @@ static int __init sh7750_devices_setup(void) return platform_add_devices(sh7750_devices, ARRAY_SIZE(sh7750_devices)); } -arch_initcall(sh7750_devices_setup); +__initcall(sh7750_devices_setup); static struct platform_device *sh7750_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 7fbb7be9284c..5b822519bd90 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -265,7 +265,7 @@ static int __init sh7760_devices_setup(void) return platform_add_devices(sh7760_devices, ARRAY_SIZE(sh7760_devices)); } -arch_initcall(sh7760_devices_setup); +__initcall(sh7760_devices_setup); static struct platform_device *sh7760_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index ac4d5672ec1a..6307e087c864 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -325,7 +325,7 @@ static int __init sh7343_devices_setup(void) return platform_add_devices(sh7343_devices, ARRAY_SIZE(sh7343_devices)); } -arch_initcall(sh7343_devices_setup); +__initcall(sh7343_devices_setup); static struct platform_device *sh7343_early_devices[] __initdata = { &cmt_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 1a956b1beccc..c18f7d09281b 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -318,7 +318,7 @@ static int __init sh7366_devices_setup(void) return platform_add_devices(sh7366_devices, ARRAY_SIZE(sh7366_devices)); } -arch_initcall(sh7366_devices_setup); +__initcall(sh7366_devices_setup); static struct platform_device *sh7366_early_devices[] __initdata = { &cmt_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index cda76ebf87c3..ea524a2da3e4 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -359,7 +359,7 @@ static int __init sh7722_devices_setup(void) return platform_add_devices(sh7722_devices, ARRAY_SIZE(sh7722_devices)); } -arch_initcall(sh7722_devices_setup); +__initcall(sh7722_devices_setup); static struct platform_device *sh7722_early_devices[] __initdata = { &cmt_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index b45dace9539f..e1bb80b2a27b 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -473,7 +473,7 @@ static int __init sh7723_devices_setup(void) return platform_add_devices(sh7723_devices, ARRAY_SIZE(sh7723_devices)); } -arch_initcall(sh7723_devices_setup); +__initcall(sh7723_devices_setup); static struct platform_device *sh7723_early_devices[] __initdata = { &cmt_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index a04edaab9a29..e5ac9eb11c63 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -508,7 +508,7 @@ static int __init sh7724_devices_setup(void) return platform_add_devices(sh7724_devices, ARRAY_SIZE(sh7724_devices)); } -arch_initcall(sh7724_devices_setup); +device_initcall(sh7724_devices_setup); static struct platform_device *sh7724_early_devices[] __initdata = { &cmt_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 4659fff6b842..f1e0c0d36da7 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -314,7 +314,7 @@ static int __init sh7763_devices_setup(void) return platform_add_devices(sh7763_devices, ARRAY_SIZE(sh7763_devices)); } -arch_initcall(sh7763_devices_setup); +__initcall(sh7763_devices_setup); static struct platform_device *sh7763_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index eead08d89d32..1e86209db284 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -368,7 +368,7 @@ static int __init sh7770_devices_setup(void) return platform_add_devices(sh7770_devices, ARRAY_SIZE(sh7770_devices)); } -arch_initcall(sh7770_devices_setup); +__initcall(sh7770_devices_setup); static struct platform_device *sh7770_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 2c901f446959..715e05b431e5 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -256,7 +256,7 @@ static int __init sh7780_devices_setup(void) return platform_add_devices(sh7780_devices, ARRAY_SIZE(sh7780_devices)); } -arch_initcall(sh7780_devices_setup); +__initcall(sh7780_devices_setup); static struct platform_device *sh7780_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 7f6c718b6c36..af561402570b 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -263,7 +263,7 @@ static int __init sh7785_devices_setup(void) return platform_add_devices(sh7785_devices, ARRAY_SIZE(sh7785_devices)); } -arch_initcall(sh7785_devices_setup); +__initcall(sh7785_devices_setup); static struct platform_device *sh7785_early_devices[] __initdata = { &tmu0_device, diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 0104a8ec5369..b70049470a0b 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -547,7 +547,7 @@ static int __init sh7786_devices_setup(void) return platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices)); } -arch_initcall(sh7786_devices_setup); +device_initcall(sh7786_devices_setup); void __init plat_early_device_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 07f078961c71..53c65fd9ccef 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -256,7 +256,7 @@ static int __init shx3_devices_setup(void) return platform_add_devices(shx3_devices, ARRAY_SIZE(shx3_devices)); } -arch_initcall(shx3_devices_setup); +__initcall(shx3_devices_setup); void __init plat_early_device_setup(void) { diff --git a/trunk/arch/sh/kernel/cpu/sh5/setup-sh5.c b/trunk/arch/sh/kernel/cpu/sh5/setup-sh5.c index 6a0f82f70032..f5ff1ac57fc2 100644 --- a/trunk/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/trunk/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -186,7 +186,7 @@ static int __init sh5_devices_setup(void) return platform_add_devices(sh5_devices, ARRAY_SIZE(sh5_devices)); } -arch_initcall(sh5_devices_setup); +__initcall(sh5_devices_setup); void __init plat_early_device_setup(void) { diff --git a/trunk/arch/x86/kernel/apic/x2apic_cluster.c b/trunk/arch/x86/kernel/apic/x2apic_cluster.c index a5371ec36776..2ed4e2bb3b32 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_cluster.c +++ b/trunk/arch/x86/kernel/apic/x2apic_cluster.c @@ -17,13 +17,11 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return x2apic_enabled(); } -/* - * need to use more than cpu 0, because we need more vectors when - * MSI-X are used. - */ +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + static const struct cpumask *x2apic_target_cpus(void) { - return cpu_online_mask; + return cpumask_of(0); } /* diff --git a/trunk/arch/x86/kernel/apic/x2apic_phys.c b/trunk/arch/x86/kernel/apic/x2apic_phys.c index a8989aadc99a..0b631c6a2e00 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_phys.c +++ b/trunk/arch/x86/kernel/apic/x2apic_phys.c @@ -27,13 +27,11 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } -/* - * need to use more than cpu 0, because we need more vectors when - * MSI-X are used. - */ +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + static const struct cpumask *x2apic_target_cpus(void) { - return cpu_online_mask; + return cpumask_of(0); } static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) diff --git a/trunk/arch/x86/kernel/efi.c b/trunk/arch/x86/kernel/efi.c index fe26ba3e3451..19ccf6d0dccf 100644 --- a/trunk/arch/x86/kernel/efi.c +++ b/trunk/arch/x86/kernel/efi.c @@ -354,7 +354,7 @@ void __init efi_init(void) */ c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2); if (c16) { - for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i) + for (i = 0; i < sizeof(vendor) && *c16; ++i) vendor[i] = *c16++; vendor[i] = '\0'; } else diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index 9eb897603705..834c9da8bf9d 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -405,7 +405,7 @@ EXPORT_SYMBOL(machine_real_restart); #endif /* CONFIG_X86_32 */ /* - * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot + * Apple MacBook5,2 (2009 MacBook) needs reboot=p */ static int __init set_pci_reboot(const struct dmi_system_id *d) { @@ -426,14 +426,6 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"), }, }, - { /* Handle problems with rebooting on Apple MacBookPro5,1 */ - .callback = set_pci_reboot, - .ident = "Apple MacBookPro5,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"), - }, - }, { } }; diff --git a/trunk/arch/x86/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c index 71f4368b357e..6e1a368d21d4 100644 --- a/trunk/arch/x86/kernel/tsc.c +++ b/trunk/arch/x86/kernel/tsc.c @@ -275,20 +275,15 @@ static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin) * use the TSC value at the transitions to calculate a pretty * good value for the TSC frequencty. */ -static inline int pit_verify_msb(unsigned char val) -{ - /* Ignore LSB */ - inb(0x42); - return inb(0x42) == val; -} - static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap) { int count; u64 tsc = 0; for (count = 0; count < 50000; count++) { - if (!pit_verify_msb(val)) + /* Ignore LSB */ + inb(0x42); + if (inb(0x42) != val) break; tsc = get_cycles(); } @@ -341,7 +336,8 @@ static unsigned long quick_pit_calibrate(void) * to do that is to just read back the 16-bit counter * once from the PIT. */ - pit_verify_msb(0); + inb(0x42); + inb(0x42); if (pit_expect_msb(0xff, &tsc, &d1)) { for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) { @@ -352,19 +348,8 @@ static unsigned long quick_pit_calibrate(void) * Iterate until the error is less than 500 ppm */ delta -= tsc; - if (d1+d2 >= delta >> 11) - continue; - - /* - * Check the PIT one more time to verify that - * all TSC reads were stable wrt the PIT. - * - * This also guarantees serialization of the - * last cycle read ('d2') in pit_expect_msb. - */ - if (!pit_verify_msb(0xfe - i)) - break; - goto success; + if (d1+d2 < delta >> 11) + goto success; } } printk("Fast TSC calibration failed\n"); diff --git a/trunk/arch/x86/kernel/vmi_32.c b/trunk/arch/x86/kernel/vmi_32.c index 95a7289e4b0c..b263423fbe2a 100644 --- a/trunk/arch/x86/kernel/vmi_32.c +++ b/trunk/arch/x86/kernel/vmi_32.c @@ -441,7 +441,7 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, ap.ds = __USER_DS; ap.es = __USER_DS; ap.fs = __KERNEL_PERCPU; - ap.gs = __KERNEL_STACK_CANARY; + ap.gs = 0; ap.eflags = 0; diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 21f68e00524f..4d6f0d293ee2 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -104,9 +104,6 @@ static s64 __kpit_elapsed(struct kvm *kvm) ktime_t remaining; struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state; - if (!ps->pit_timer.period) - return 0; - /* * The Counter does not stop when it reaches zero. In * Modes 0, 1, 4, and 5 the Counter ``wraps around'' to diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 0ef5bb2b4043..7030b5f911bf 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -489,20 +489,16 @@ static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) * * If rmapp bit zero is one, (then rmap & ~1) points to a struct kvm_rmap_desc * containing more mappings. - * - * Returns the number of rmap entries before the spte was added or zero if - * the spte was not added. - * */ -static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) +static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) { struct kvm_mmu_page *sp; struct kvm_rmap_desc *desc; unsigned long *rmapp; - int i, count = 0; + int i; if (!is_rmap_pte(*spte)) - return count; + return; gfn = unalias_gfn(vcpu->kvm, gfn); sp = page_header(__pa(spte)); sp->gfns[spte - sp->spt] = gfn; @@ -519,10 +515,8 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) } else { rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); - while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) { + while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) desc = desc->more; - count += RMAP_EXT; - } if (desc->shadow_ptes[RMAP_EXT-1]) { desc->more = mmu_alloc_rmap_desc(vcpu); desc = desc->more; @@ -531,7 +525,6 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) ; desc->shadow_ptes[i] = spte; } - return count; } static void rmap_desc_remove_entry(unsigned long *rmapp, @@ -761,19 +754,6 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp) return young; } -#define RMAP_RECYCLE_THRESHOLD 1000 - -static void rmap_recycle(struct kvm_vcpu *vcpu, gfn_t gfn, int lpage) -{ - unsigned long *rmapp; - - gfn = unalias_gfn(vcpu->kvm, gfn); - rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); - - kvm_unmap_rmapp(vcpu->kvm, rmapp); - kvm_flush_remote_tlbs(vcpu->kvm); -} - int kvm_age_hva(struct kvm *kvm, unsigned long hva) { return kvm_handle_hva(kvm, hva, kvm_age_rmapp); @@ -1427,25 +1407,24 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) */ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages) { - int used_pages; - - used_pages = kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages; - used_pages = max(0, used_pages); - /* * If we set the number of mmu pages to be smaller be than the * number of actived pages , we must to free some mmu pages before we * change the value */ - if (used_pages > kvm_nr_mmu_pages) { - while (used_pages > kvm_nr_mmu_pages) { + if ((kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages) > + kvm_nr_mmu_pages) { + int n_used_mmu_pages = kvm->arch.n_alloc_mmu_pages + - kvm->arch.n_free_mmu_pages; + + while (n_used_mmu_pages > kvm_nr_mmu_pages) { struct kvm_mmu_page *page; page = container_of(kvm->arch.active_mmu_pages.prev, struct kvm_mmu_page, link); kvm_mmu_zap_page(kvm, page); - used_pages--; + n_used_mmu_pages--; } kvm->arch.n_free_mmu_pages = 0; } @@ -1761,7 +1740,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, { int was_rmapped = 0; int was_writeble = is_writeble_pte(*shadow_pte); - int rmap_count; pgprintk("%s: spte %llx access %x write_fault %d" " user_fault %d gfn %lx\n", @@ -1803,11 +1781,9 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, page_header_update_slot(vcpu->kvm, shadow_pte, gfn); if (!was_rmapped) { - rmap_count = rmap_add(vcpu, shadow_pte, gfn, largepage); + rmap_add(vcpu, shadow_pte, gfn, largepage); if (!is_rmap_pte(*shadow_pte)) kvm_release_pfn_clean(pfn); - if (rmap_count > RMAP_RECYCLE_THRESHOLD) - rmap_recycle(vcpu, gfn, largepage); } else { if (was_writeble) kvm_release_pfn_dirty(pfn); diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index b1f658ad2f06..71510e07e69e 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -711,7 +711,6 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) svm->vmcb->control.tsc_offset += delta; vcpu->cpu = cpu; kvm_migrate_timers(vcpu); - svm->asid_generation = 0; } for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) @@ -1032,6 +1031,7 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data) svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; } + svm->vcpu.cpu = svm_data->cpu; svm->asid_generation = svm_data->asid_generation; svm->vmcb->control.asid = svm_data->next_asid++; } @@ -2300,8 +2300,8 @@ static void pre_svm_run(struct vcpu_svm *svm) struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu); svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING; - /* FIXME: handle wraparound of asid_generation */ - if (svm->asid_generation != svm_data->asid_generation) + if (svm->vcpu.cpu != cpu || + svm->asid_generation != svm_data->asid_generation) new_asid(svm, svm_data); } diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 29f912927a58..356a0ce85c68 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -3157,8 +3157,8 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu, struct vcpu_vmx *vmx = to_vmx(vcpu); enum emulation_result err = EMULATE_DONE; - local_irq_enable(); preempt_enable(); + local_irq_enable(); while (!guest_state_valid(vcpu)) { err = emulate_instruction(vcpu, kvm_run, 0, 0, 0); @@ -3168,7 +3168,7 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu, if (err != EMULATE_DONE) { kvm_report_emulation_failure(vcpu, "emulation failure"); - break; + return; } if (signal_pending(current)) @@ -3177,8 +3177,8 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu, schedule(); } - preempt_disable(); local_irq_disable(); + preempt_disable(); vmx->invalid_state_emulation_result = err; } diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 3d4529011828..fe5474aec41a 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -704,48 +704,11 @@ static bool msr_mtrr_valid(unsigned msr) return false; } -static bool valid_pat_type(unsigned t) -{ - return t < 8 && (1 << t) & 0xf3; /* 0, 1, 4, 5, 6, 7 */ -} - -static bool valid_mtrr_type(unsigned t) -{ - return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */ -} - -static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) -{ - int i; - - if (!msr_mtrr_valid(msr)) - return false; - - if (msr == MSR_IA32_CR_PAT) { - for (i = 0; i < 8; i++) - if (!valid_pat_type((data >> (i * 8)) & 0xff)) - return false; - return true; - } else if (msr == MSR_MTRRdefType) { - if (data & ~0xcff) - return false; - return valid_mtrr_type(data & 0xff); - } else if (msr >= MSR_MTRRfix64K_00000 && msr <= MSR_MTRRfix4K_F8000) { - for (i = 0; i < 8 ; i++) - if (!valid_mtrr_type((data >> (i * 8)) & 0xff)) - return false; - return true; - } - - /* variable MTRRs */ - return valid_mtrr_type(data & 0xff); -} - static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data) { u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges; - if (!mtrr_valid(vcpu, msr, data)) + if (!msr_mtrr_valid(msr)) return 1; if (msr == MSR_MTRRdefType) { @@ -1116,13 +1079,14 @@ long kvm_arch_dev_ioctl(struct file *filp, if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) goto out; r = -E2BIG; - if (n < msr_list.nmsrs) + if (n < num_msrs_to_save) goto out; r = -EFAULT; if (copy_to_user(user_msr_list->indices, &msrs_to_save, num_msrs_to_save * sizeof(u32))) goto out; - if (copy_to_user(user_msr_list->indices + num_msrs_to_save, + if (copy_to_user(user_msr_list->indices + + num_msrs_to_save * sizeof(u32), &emulated_msrs, ARRAY_SIZE(emulated_msrs) * sizeof(u32))) goto out; diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index fe3eba5d6b3e..958c1fa41900 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -219,8 +219,6 @@ enum { AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ - AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as - link offline */ /* ap->flags bits */ @@ -1665,7 +1663,6 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, int (*check_ready)(struct ata_link *link)) { struct ata_port *ap = link->ap; - struct ahci_host_priv *hpriv = ap->host->private_data; const char *reason = NULL; unsigned long now, msecs; struct ata_taskfile tf; @@ -1704,21 +1701,12 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, /* wait for link to become ready */ rc = ata_wait_after_reset(link, deadline, check_ready); - if (rc == -EBUSY && hpriv->flags & AHCI_HFLAG_SRST_TOUT_IS_OFFLINE) { - /* - * Workaround for cases where link online status can't - * be trusted. Treat device readiness timeout as link - * offline. - */ - ata_link_printk(link, KERN_INFO, - "device not ready, treating as offline\n"); - *class = ATA_DEV_NONE; - } else if (rc) { - /* link occupied, -ENODEV too is an error */ + /* link occupied, -ENODEV too is an error */ + if (rc) { reason = "device not ready"; goto fail; - } else - *class = ahci_dev_classify(ap); + } + *class = ahci_dev_classify(ap); DPRINTK("EXIT, class=%u\n", *class); return 0; @@ -1785,8 +1773,7 @@ static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, irq_sts = readl(port_mmio + PORT_IRQ_STAT); if (irq_sts & PORT_IRQ_BAD_PMP) { ata_link_printk(link, KERN_WARNING, - "applying SB600 PMP SRST workaround " - "and retrying\n"); + "failed due to HW bug, retry pmp=0\n"); rc = ahci_do_softreset(link, class, 0, deadline, ahci_check_ready); } @@ -2739,56 +2726,6 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) return !ver || strcmp(ver, dmi->driver_data) < 0; } -static bool ahci_broken_online(struct pci_dev *pdev) -{ -#define ENCODE_BUSDEVFN(bus, slot, func) \ - (void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func))) - static const struct dmi_system_id sysids[] = { - /* - * There are several gigabyte boards which use - * SIMG5723s configured as hardware RAID. Certain - * 5723 firmware revisions shipped there keep the link - * online but fail to answer properly to SRST or - * IDENTIFY when no device is attached downstream - * causing libata to retry quite a few times leading - * to excessive detection delay. - * - * As these firmwares respond to the second reset try - * with invalid device signature, considering unknown - * sig as offline works around the problem acceptably. - */ - { - .ident = "EP45-DQ6", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, - "Gigabyte Technology Co., Ltd."), - DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"), - }, - .driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0), - }, - { - .ident = "EP45-DS5", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, - "Gigabyte Technology Co., Ltd."), - DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"), - }, - .driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0), - }, - { } /* terminate list */ - }; -#undef ENCODE_BUSDEVFN - const struct dmi_system_id *dmi = dmi_first_match(sysids); - unsigned int val; - - if (!dmi) - return false; - - val = (unsigned long)dmi->driver_data; - - return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); -} - static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; @@ -2904,12 +2841,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "BIOS update required for suspend/resume\n"); } - if (ahci_broken_online(pdev)) { - hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE; - dev_info(&pdev->dev, - "online status unreliable, applying workaround\n"); - } - /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 072ba5ea138f..8ac98ff16d7d 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -4302,9 +4302,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA }, { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA }, - /* this one allows HPA unlocking but fails IOs on the area */ - { "OCZ-VERTEX", "1.30", ATA_HORKAGE_BROKEN_HPA }, - /* Devices which report 1 sector over size HPA */ { "ST340823A", NULL, ATA_HORKAGE_HPA_SIZE, }, { "ST320413A", NULL, ATA_HORKAGE_HPA_SIZE, }, diff --git a/trunk/drivers/ata/pata_at91.c b/trunk/drivers/ata/pata_at91.c index 41c94b1ae493..5702affcb325 100644 --- a/trunk/drivers/ata/pata_at91.c +++ b/trunk/drivers/ata/pata_at91.c @@ -250,7 +250,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) ata_port_desc(ap, "no IRQ, using PIO polling"); } - info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { dev_err(dev, "failed to allocate memory for private data\n"); @@ -275,7 +275,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) if (!info->ide_addr) { dev_err(dev, "failed to map IO base\n"); ret = -ENOMEM; - goto err_put; + goto err_ide_ioremap; } info->alt_addr = devm_ioremap(dev, @@ -284,7 +284,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) if (!info->alt_addr) { dev_err(dev, "failed to map CTL base\n"); ret = -ENOMEM; - goto err_put; + goto err_alt_ioremap; } ap->ioaddr.cmd_addr = info->ide_addr; @@ -303,8 +303,13 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) irq ? ata_sff_interrupt : NULL, irq_flags, &pata_at91_sht); -err_put: +err_alt_ioremap: + devm_iounmap(dev, info->ide_addr); + +err_ide_ioremap: clk_put(info->mck); + kfree(info); + return ret; } @@ -312,6 +317,7 @@ static int __devexit pata_at91_remove(struct platform_device *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); struct at91_ide_info *info; + struct device *dev = &pdev->dev; if (!host) return 0; @@ -322,8 +328,11 @@ static int __devexit pata_at91_remove(struct platform_device *pdev) if (!info) return 0; + devm_iounmap(dev, info->ide_addr); + devm_iounmap(dev, info->alt_addr); clk_put(info->mck); + kfree(info); return 0; } diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c index 45915566e4e9..bec0b8ade66d 100644 --- a/trunk/drivers/ata/pata_atiixp.c +++ b/trunk/drivers/ata/pata_atiixp.c @@ -1,7 +1,6 @@ /* * pata_atiixp.c - ATI PATA for new ATA layer * (C) 2005 Red Hat Inc - * (C) 2009 Bartlomiej Zolnierkiewicz * * Based on * @@ -62,19 +61,20 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, struct pci_dev *pdev = to_pci_dev(ap->host->dev); int dn = 2 * ap->port_no + adev->devno; + + /* Check this is correct - the order is odd in both drivers */ int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1); - u32 pio_timing_data; - u16 pio_mode_data; + u16 pio_mode_data, pio_timing_data; pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); pio_mode_data &= ~(0x7 << (4 * dn)); pio_mode_data |= pio << (4 * dn); pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data); - pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); + pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data); pio_timing_data &= ~(0xFF << timing_shift); pio_timing_data |= (pio_timings[pio] << timing_shift); - pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); + pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); } /** @@ -119,17 +119,16 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) udma_mode_data |= dma << (4 * dn); pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data); } else { + u16 mwdma_timing_data; + /* Check this is correct - the order is odd in both drivers */ int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1); - u32 mwdma_timing_data; dma -= XFER_MW_DMA_0; - pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING, - &mwdma_timing_data); + pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data); mwdma_timing_data &= ~(0xFF << timing_shift); mwdma_timing_data |= (mwdma_timings[dma] << timing_shift); - pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING, - mwdma_timing_data); + pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data); } /* * We must now look at the PIO mode situation. We may need to diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index 86a40582999c..b2d11f300c39 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -602,7 +602,6 @@ MODULE_VERSION(DRV_VERSION); static int adma_enabled; static int swncq_enabled = 1; -static int msi_enabled; static void nv_adma_register_mode(struct ata_port *ap) { @@ -2460,11 +2459,6 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } else if (type == SWNCQ) nv_swncq_host_init(host); - if (msi_enabled) { - dev_printk(KERN_NOTICE, &pdev->dev, "Using MSI\n"); - pci_enable_msi(pdev); - } - pci_set_master(pdev); return ata_host_activate(host, pdev->irq, ipriv->irq_handler, IRQF_SHARED, ipriv->sht); @@ -2564,6 +2558,4 @@ module_param_named(adma, adma_enabled, bool, 0444); MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: false)"); module_param_named(swncq, swncq_enabled, bool, 0444); MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: true)"); -module_param_named(msi, msi_enabled, bool, 0444); -MODULE_PARM_DESC(msi, "Enable use of MSI (Default: false)"); diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 456594bd97bc..81cb01bfc356 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -483,6 +483,9 @@ int platform_driver_register(struct platform_driver *drv) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; + if (drv->suspend || drv->resume) + pr_warning("Platform driver '%s' needs updating - please use " + "dev_pm_ops\n", drv->driver.name); return driver_register(&drv->driver); } diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index d083c73d784a..6e6942c45f5b 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -144,8 +144,6 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, static int pty_write_room(struct tty_struct *tty) { - if (tty->stopped) - return 0; return pty_space(tty->link); } diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index f85aaf21e783..b4a3dbcebe9b 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -566,7 +566,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, ret = drm_vblank_get(dev, crtc); if (ret) { - DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); + DRM_ERROR("failed to acquire vblank counter, %d\n", ret); return ret; } seq = drm_vblank_count(dev, crtc); diff --git a/trunk/drivers/gpu/drm/drm_modes.c b/trunk/drivers/gpu/drm/drm_modes.c index 7914097b09c6..54f492a488a9 100644 --- a/trunk/drivers/gpu/drm/drm_modes.c +++ b/trunk/drivers/gpu/drm/drm_modes.c @@ -566,8 +566,6 @@ void drm_mode_connector_list_update(struct drm_connector *connector) found_it = 1; /* if equal delete the probed mode */ mode->status = pmode->status; - /* Merge type bits together */ - mode->type |= pmode->type; list_del(&pmode->head); drm_mode_destroy(connector->dev, pmode); break; diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 7ebc84c2881e..83aee80e77a6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -190,7 +190,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); + DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); return 0; } @@ -219,7 +219,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); + DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); return 0; } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 5b98bea4ff9b..5614500092e3 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -359,6 +359,7 @@ static mddev_t * mddev_find(dev_t unit) else new->md_minor = MINOR(unit) >> MdpMinorShift; + mutex_init(&new->open_mutex); mutex_init(&new->reconfig_mutex); INIT_LIST_HEAD(&new->disks); INIT_LIST_HEAD(&new->all_mddevs); @@ -4304,12 +4305,11 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) struct gendisk *disk = mddev->gendisk; mdk_rdev_t *rdev; + mutex_lock(&mddev->open_mutex); if (atomic_read(&mddev->openers) > is_open) { printk("md: %s still in use.\n",mdname(mddev)); - return -EBUSY; - } - - if (mddev->pers) { + err = -EBUSY; + } else if (mddev->pers) { if (mddev->sync_thread) { set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); @@ -4367,7 +4367,10 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) set_disk_ro(disk, 1); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } - +out: + mutex_unlock(&mddev->open_mutex); + if (err) + return err; /* * Free resources if final stop */ @@ -4433,7 +4436,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) blk_integrity_unregister(disk); md_new_event(mddev); sysfs_notify_dirent(mddev->sysfs_state); -out: return err; } @@ -5518,12 +5520,12 @@ static int md_open(struct block_device *bdev, fmode_t mode) } BUG_ON(mddev != bdev->bd_disk->private_data); - if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1))) + if ((err = mutex_lock_interruptible(&mddev->open_mutex))) goto out; err = 0; atomic_inc(&mddev->openers); - mddev_unlock(mddev); + mutex_unlock(&mddev->open_mutex); check_disk_change(bdev); out: diff --git a/trunk/drivers/md/md.h b/trunk/drivers/md/md.h index 78f03168baf9..f8fc188bc762 100644 --- a/trunk/drivers/md/md.h +++ b/trunk/drivers/md/md.h @@ -223,6 +223,16 @@ struct mddev_s * so we don't loop trying */ int in_sync; /* know to not need resync */ + /* 'open_mutex' avoids races between 'md_open' and 'do_md_stop', so + * that we are never stopping an array while it is open. + * 'reconfig_mutex' protects all other reconfiguration. + * These locks are separate due to conflicting interactions + * with bdev->bd_mutex. + * Lock ordering is: + * reconfig_mutex -> bd_mutex : e.g. do_md_run -> revalidate_disk + * bd_mutex -> open_mutex: e.g. __blkdev_get -> md_open + */ + struct mutex open_mutex; struct mutex reconfig_mutex; atomic_t active; /* general refcount */ atomic_t openers; /* number of active opens */ diff --git a/trunk/drivers/mtd/maps/sbc8240.c b/trunk/drivers/mtd/maps/sbc8240.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/drivers/mtd/ubi/eba.c b/trunk/drivers/mtd/ubi/eba.c index e4d9ef0c965a..0f2034c3ed2f 100644 --- a/trunk/drivers/mtd/ubi/eba.c +++ b/trunk/drivers/mtd/ubi/eba.c @@ -1254,7 +1254,6 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) if (!ubi->volumes[i]) continue; kfree(ubi->volumes[i]->eba_tbl); - ubi->volumes[i]->eba_tbl = NULL; } return err; } diff --git a/trunk/drivers/mtd/ubi/scan.c b/trunk/drivers/mtd/ubi/scan.c index b847745394b4..a423131b6171 100644 --- a/trunk/drivers/mtd/ubi/scan.c +++ b/trunk/drivers/mtd/ubi/scan.c @@ -781,22 +781,11 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, return -EINVAL; } - /* - * Make sure that all PEBs have the same image sequence number. - * This allows us to detect situations when users flash UBI - * images incorrectly, so that the flash has the new UBI image - * and leftovers from the old one. This feature was added - * relatively recently, and the sequence number was always - * zero, because old UBI implementations always set it to zero. - * For this reasons, we do not panic if some PEBs have zero - * sequence number, while other PEBs have non-zero sequence - * number. - */ image_seq = be32_to_cpu(ech->image_seq); if (!si->image_seq_set) { ubi->image_seq = image_seq; si->image_seq_set = 1; - } else if (ubi->image_seq && ubi->image_seq != image_seq) { + } else if (ubi->image_seq != image_seq) { ubi_err("bad image sequence number %d in PEB %d, " "expected %d", image_seq, pnum, ubi->image_seq); ubi_dbg_dump_ec_hdr(ech); diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index 8aebe1e9d3d6..a4494d78e7c2 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -90,10 +90,11 @@ static struct hotplug_slot_ops sn_hotplug_slot_ops = { static DEFINE_MUTEX(sn_hotplug_mutex); -static ssize_t path_show(struct pci_slot *pci_slot, char *buf) +static ssize_t path_show (struct hotplug_slot *bss_hotplug_slot, + char *buf) { int retval = -ENOENT; - struct slot *slot = pci_slot->hotplug->private; + struct slot *slot = bss_hotplug_slot->private; if (!slot) return retval; @@ -102,7 +103,7 @@ static ssize_t path_show(struct pci_slot *pci_slot, char *buf) return retval; } -static struct pci_slot_attribute sn_slot_path_attr = __ATTR_RO(path); +static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path); static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) { diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index e4e089a8f294..489fc01a3204 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -255,7 +255,7 @@ static void nfs_direct_read_release(void *calldata) if (put_dreq(dreq)) nfs_direct_complete(dreq); - nfs_readdata_free(data); + nfs_readdata_release(calldata); } static const struct rpc_call_ops nfs_read_direct_ops = { @@ -314,14 +314,14 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, data->npages, 1, 0, data->pagevec, NULL); up_read(¤t->mm->mmap_sem); if (result < 0) { - nfs_readdata_free(data); + nfs_readdata_release(data); break; } if ((unsigned)result < data->npages) { bytes = result * PAGE_SIZE; if (bytes <= pgbase) { nfs_direct_release_pages(data->pagevec, result); - nfs_readdata_free(data); + nfs_readdata_release(data); break; } bytes -= pgbase; @@ -334,7 +334,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, data->inode = inode; data->cred = msg.rpc_cred; data->args.fh = NFS_FH(inode); - data->args.context = ctx; + data->args.context = get_nfs_open_context(ctx); data->args.offset = pos; data->args.pgbase = pgbase; data->args.pages = data->pagevec; @@ -441,7 +441,7 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq) struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages); list_del(&data->pages); nfs_direct_release_pages(data->pagevec, data->npages); - nfs_writedata_free(data); + nfs_writedata_release(data); } } @@ -534,7 +534,7 @@ static void nfs_direct_commit_release(void *calldata) dprintk("NFS: %5u commit returned %d\n", data->task.tk_pid, status); nfs_direct_write_complete(dreq, data->inode); - nfs_commit_free(data); + nfs_commitdata_release(calldata); } static const struct rpc_call_ops nfs_commit_direct_ops = { @@ -570,7 +570,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) data->args.fh = NFS_FH(data->inode); data->args.offset = 0; data->args.count = 0; - data->args.context = dreq->ctx; + data->args.context = get_nfs_open_context(dreq->ctx); data->res.count = 0; data->res.fattr = &data->fattr; data->res.verf = &data->verf; @@ -734,14 +734,14 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, data->npages, 0, 0, data->pagevec, NULL); up_read(¤t->mm->mmap_sem); if (result < 0) { - nfs_writedata_free(data); + nfs_writedata_release(data); break; } if ((unsigned)result < data->npages) { bytes = result * PAGE_SIZE; if (bytes <= pgbase) { nfs_direct_release_pages(data->pagevec, result); - nfs_writedata_free(data); + nfs_writedata_release(data); break; } bytes -= pgbase; @@ -756,7 +756,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, data->inode = inode; data->cred = msg.rpc_cred; data->args.fh = NFS_FH(inode); - data->args.context = ctx; + data->args.context = get_nfs_open_context(ctx); data->args.offset = pos; data->args.pgbase = pgbase; data->args.pages = data->pagevec; diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 12c9e66d3f1d..73ea5e8d66ce 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -60,15 +60,17 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) return p; } -void nfs_readdata_free(struct nfs_read_data *p) +static void nfs_readdata_free(struct nfs_read_data *p) { if (p && (p->pagevec != &p->page_array[0])) kfree(p->pagevec); mempool_free(p, nfs_rdata_mempool); } -static void nfs_readdata_release(struct nfs_read_data *rdata) +void nfs_readdata_release(void *data) { + struct nfs_read_data *rdata = data; + put_nfs_open_context(rdata->args.context); nfs_readdata_free(rdata); } diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index a34fae21fe10..0a0a2ff767c3 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -87,15 +87,17 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) return p; } -void nfs_writedata_free(struct nfs_write_data *p) +static void nfs_writedata_free(struct nfs_write_data *p) { if (p && (p->pagevec != &p->page_array[0])) kfree(p->pagevec); mempool_free(p, nfs_wdata_mempool); } -static void nfs_writedata_release(struct nfs_write_data *wdata) +void nfs_writedata_release(void *data) { + struct nfs_write_data *wdata = data; + put_nfs_open_context(wdata->args.context); nfs_writedata_free(wdata); } diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 175db258942f..3ce5ae9e3d2d 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -234,20 +234,23 @@ static int check_mem_permission(struct task_struct *task) struct mm_struct *mm_for_maps(struct task_struct *task) { - struct mm_struct *mm; - - if (mutex_lock_killable(&task->cred_guard_mutex)) + struct mm_struct *mm = get_task_mm(task); + if (!mm) return NULL; - - mm = get_task_mm(task); - if (mm && mm != current->mm && - !ptrace_may_access(task, PTRACE_MODE_READ)) { - mmput(mm); - mm = NULL; - } - mutex_unlock(&task->cred_guard_mutex); - + down_read(&mm->mmap_sem); + task_lock(task); + if (task->mm != mm) + goto out; + if (task->mm != current->mm && + __ptrace_may_access(task, PTRACE_MODE_READ) < 0) + goto out; + task_unlock(task); return mm; +out: + task_unlock(task); + up_read(&mm->mmap_sem); + mmput(mm); + return NULL; } static int proc_pid_cmdline(struct task_struct *task, char * buffer) diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 9bd8be1d235c..6f61b7cc32e0 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -119,7 +119,6 @@ static void *m_start(struct seq_file *m, loff_t *pos) mm = mm_for_maps(priv->task); if (!mm) return NULL; - down_read(&mm->mmap_sem); tail_vma = get_gate_vma(priv->task); priv->tail_vma = tail_vma; diff --git a/trunk/fs/proc/task_nommu.c b/trunk/fs/proc/task_nommu.c index 8f5c05d3dbd3..64a72e2e7650 100644 --- a/trunk/fs/proc/task_nommu.c +++ b/trunk/fs/proc/task_nommu.c @@ -189,7 +189,6 @@ static void *m_start(struct seq_file *m, loff_t *pos) priv->task = NULL; return NULL; } - down_read(&mm->mmap_sem); /* start from the Nth VMA */ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index 965df1227d64..0c93c7ef3d18 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -770,7 +770,7 @@ xfs_buf_associate_memory( bp->b_pages = NULL; bp->b_addr = mem; - rval = _xfs_buf_get_pages(bp, page_count, XBF_DONT_BLOCK); + rval = _xfs_buf_get_pages(bp, page_count, 0); if (rval) return rval; diff --git a/trunk/fs/xfs/xfs_attr.c b/trunk/fs/xfs/xfs_attr.c index 4ece1906bd41..db15feb906ff 100644 --- a/trunk/fs/xfs/xfs_attr.c +++ b/trunk/fs/xfs/xfs_attr.c @@ -2010,9 +2010,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args) dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock); blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount); error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno, - blkcnt, - XFS_BUF_LOCK | XBF_DONT_BLOCK, - &bp); + blkcnt, XFS_BUF_LOCK, &bp); if (error) return(error); @@ -2143,8 +2141,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); - bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno, blkcnt, - XFS_BUF_LOCK | XBF_DONT_BLOCK); + bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno, + blkcnt, XFS_BUF_LOCK); ASSERT(bp); ASSERT(!XFS_BUF_GETERROR(bp)); diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 8ee5b5a76a2a..7928b9983c1d 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -6009,7 +6009,7 @@ xfs_getbmap( */ error = ENOMEM; subnex = 16; - map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL | KM_NOFS); + map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL); if (!map) goto out_unlock_ilock; diff --git a/trunk/fs/xfs/xfs_btree.c b/trunk/fs/xfs/xfs_btree.c index 26717388acf5..e9df99574829 100644 --- a/trunk/fs/xfs/xfs_btree.c +++ b/trunk/fs/xfs/xfs_btree.c @@ -120,8 +120,8 @@ xfs_btree_check_sblock( XFS_RANDOM_BTREE_CHECK_SBLOCK))) { if (bp) xfs_buftrace("SBTREE ERROR", bp); - XFS_CORRUPTION_ERROR("xfs_btree_check_sblock", - XFS_ERRLEVEL_LOW, cur->bc_mp, block); + XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW, + cur->bc_mp); return XFS_ERROR(EFSCORRUPTED); } return 0; diff --git a/trunk/fs/xfs/xfs_da_btree.c b/trunk/fs/xfs/xfs_da_btree.c index 2847bbc1c534..9ff6e57a5075 100644 --- a/trunk/fs/xfs/xfs_da_btree.c +++ b/trunk/fs/xfs/xfs_da_btree.c @@ -2201,7 +2201,7 @@ kmem_zone_t *xfs_dabuf_zone; /* dabuf zone */ xfs_da_state_t * xfs_da_state_alloc(void) { - return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS); + return kmem_zone_zalloc(xfs_da_state_zone, KM_SLEEP); } /* @@ -2261,9 +2261,9 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) int off; if (nbuf == 1) - dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS); + dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_SLEEP); else - dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); + dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_SLEEP); dabuf->dirty = 0; #ifdef XFS_DABUF_DEBUG dabuf->ra = ra; diff --git a/trunk/fs/xfs/xfs_dir2.c b/trunk/fs/xfs/xfs_dir2.c index bb1d58eb3982..c657bec6d951 100644 --- a/trunk/fs/xfs/xfs_dir2.c +++ b/trunk/fs/xfs/xfs_dir2.c @@ -256,7 +256,7 @@ xfs_dir_cilookup_result( !(args->op_flags & XFS_DA_OP_CILOOKUP)) return EEXIST; - args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); + args->value = kmem_alloc(len, KM_MAYFAIL); if (!args->value) return ENOMEM; diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 2d0b3e1da9e6..cbd451bb4848 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -167,25 +167,17 @@ xfs_growfs_data_private( new = nb - mp->m_sb.sb_dblocks; oagcount = mp->m_sb.sb_agcount; if (nagcount > oagcount) { - void *new_perag, *old_perag; - xfs_filestream_flush(mp); - - new_perag = kmem_zalloc(sizeof(xfs_perag_t) * nagcount, - KM_MAYFAIL); - if (!new_perag) - return XFS_ERROR(ENOMEM); - down_write(&mp->m_peraglock); - memcpy(new_perag, mp->m_perag, sizeof(xfs_perag_t) * oagcount); - old_perag = mp->m_perag; - mp->m_perag = new_perag; - + mp->m_perag = kmem_realloc(mp->m_perag, + sizeof(xfs_perag_t) * nagcount, + sizeof(xfs_perag_t) * oagcount, + KM_SLEEP); + memset(&mp->m_perag[oagcount], 0, + (nagcount - oagcount) * sizeof(xfs_perag_t)); mp->m_flags |= XFS_MOUNT_32BITINODES; nagimax = xfs_initialize_perag(mp, nagcount); up_write(&mp->m_peraglock); - - kmem_free(old_perag); } tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); tp->t_flags |= XFS_TRANS_RESERVE; diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index da428b3fe0f5..1f22d65fed0a 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -343,16 +343,6 @@ xfs_iformat( return XFS_ERROR(EFSCORRUPTED); } - if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && - !ip->i_mount->m_rtdev_targp)) { - xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, - "corrupt dinode %Lu, has realtime flag set.", - ip->i_ino); - XFS_CORRUPTION_ERROR("xfs_iformat(realtime)", - XFS_ERRLEVEL_LOW, ip->i_mount, dip); - return XFS_ERROR(EFSCORRUPTED); - } - switch (ip->i_d.di_mode & S_IFMT) { case S_IFIFO: case S_IFCHR: diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 9dbdff3ea484..3750f04ede0b 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -3180,7 +3180,7 @@ xlog_state_sync(xlog_t *log, STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) { - assert_spin_locked(&log->l_icloglock); + ASSERT(spin_is_locked(&log->l_icloglock)); if (iclog->ic_state == XLOG_STATE_ACTIVE) { xlog_state_switch_iclogs(log, iclog, 0); diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index 492d75bae2bf..c4eca5ed5dab 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -538,9 +538,7 @@ xfs_readlink_bmap( d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); - bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt), - XBF_LOCK | XBF_MAPPED | - XBF_DONT_BLOCK); + bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); error = XFS_BUF_GETERROR(bp); if (error) { xfs_ioerror_alert("xfs_readlink", diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index a81170de7f6b..d7cd193c2277 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -89,9 +89,7 @@ enum print_line_t { TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ }; -void tracing_generic_entry_update(struct trace_entry *entry, - unsigned long flags, - int pc); + struct ring_buffer_event * trace_current_buffer_lock_reserve(int type, unsigned long len, unsigned long flags, int pc); diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 3060bdc35ffe..16713dc672e4 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -110,7 +110,6 @@ struct kvm_memory_slot { struct kvm_kernel_irq_routing_entry { u32 gsi; - u32 type; int (*set)(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, int level); union { diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index f6b90240dd41..fdffb413b192 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -473,6 +473,7 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *); extern int nfs_flush_incompatible(struct file *file, struct page *page); extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); +extern void nfs_writedata_release(void *); /* * Try to write back everything synchronously (but check the @@ -487,6 +488,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_write_data *nfs_commitdata_alloc(void); extern void nfs_commit_free(struct nfs_write_data *wdata); +extern void nfs_commitdata_release(void *wdata); #else static inline int nfs_commit_inode(struct inode *inode, int how) @@ -505,7 +507,6 @@ nfs_have_writebacks(struct inode *inode) * Allocate nfs_write_data structures */ extern struct nfs_write_data *nfs_writedata_alloc(unsigned int npages); -extern void nfs_writedata_free(struct nfs_write_data *); /* * linux/fs/nfs/read.c @@ -514,6 +515,7 @@ extern int nfs_readpage(struct file *, struct page *); extern int nfs_readpages(struct file *, struct address_space *, struct list_head *, unsigned); extern int nfs_readpage_result(struct rpc_task *, struct nfs_read_data *); +extern void nfs_readdata_release(void *data); extern int nfs_readpage_async(struct nfs_open_context *, struct inode *, struct page *); @@ -521,7 +523,6 @@ extern int nfs_readpage_async(struct nfs_open_context *, struct inode *, * Allocate nfs_read_data structures */ extern struct nfs_read_data *nfs_readdata_alloc(unsigned int npages); -extern void nfs_readdata_free(struct nfs_read_data *); /* * linux/fs/nfs3proc.c diff --git a/trunk/include/linux/perf_counter.h b/trunk/include/linux/perf_counter.h index a9d823a93fe8..e604e6ef72dd 100644 --- a/trunk/include/linux/perf_counter.h +++ b/trunk/include/linux/perf_counter.h @@ -121,9 +121,8 @@ enum perf_counter_sample_format { PERF_SAMPLE_CPU = 1U << 7, PERF_SAMPLE_PERIOD = 1U << 8, PERF_SAMPLE_STREAM_ID = 1U << 9, - PERF_SAMPLE_RAW = 1U << 10, - PERF_SAMPLE_MAX = 1U << 11, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 10, /* non-ABI */ }; /* @@ -369,8 +368,6 @@ enum perf_event_type { * * { u64 nr, * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN - * { u32 size; - * char data[size];}&& PERF_SAMPLE_RAW * }; */ PERF_EVENT_SAMPLE = 9, @@ -416,11 +413,6 @@ struct perf_callchain_entry { __u64 ip[PERF_MAX_STACK_DEPTH]; }; -struct perf_raw_record { - u32 size; - void *data; -}; - struct task_struct; /** @@ -689,7 +681,6 @@ struct perf_sample_data { struct pt_regs *regs; u64 addr; u64 period; - struct perf_raw_record *raw; }; extern int perf_counter_overflow(struct perf_counter *counter, int nmi, diff --git a/trunk/include/trace/ftrace.h b/trunk/include/trace/ftrace.h index f64fbaae781a..1867553c61e5 100644 --- a/trunk/include/trace/ftrace.h +++ b/trunk/include/trace/ftrace.h @@ -144,9 +144,6 @@ #undef TP_fast_assign #define TP_fast_assign(args...) args -#undef TP_perf_assign -#define TP_perf_assign(args...) - #undef TRACE_EVENT #define TRACE_EVENT(call, proto, args, tstruct, func, print) \ static int \ @@ -348,56 +345,6 @@ static inline int ftrace_get_offsets_##call( \ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -#ifdef CONFIG_EVENT_PROFILE - -/* - * Generate the functions needed for tracepoint perf_counter support. - * - * NOTE: The insertion profile callback (ftrace_profile_) is defined later - * - * static int ftrace_profile_enable_(struct ftrace_event_call *event_call) - * { - * int ret = 0; - * - * if (!atomic_inc_return(&event_call->profile_count)) - * ret = register_trace_(ftrace_profile_); - * - * return ret; - * } - * - * static void ftrace_profile_disable_(struct ftrace_event_call *event_call) - * { - * if (atomic_add_negative(-1, &event->call->profile_count)) - * unregister_trace_(ftrace_profile_); - * } - * - */ - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ - \ -static void ftrace_profile_##call(proto); \ - \ -static int ftrace_profile_enable_##call(struct ftrace_event_call *event_call) \ -{ \ - int ret = 0; \ - \ - if (!atomic_inc_return(&event_call->profile_count)) \ - ret = register_trace_##call(ftrace_profile_##call); \ - \ - return ret; \ -} \ - \ -static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ -{ \ - if (atomic_add_negative(-1, &event_call->profile_count)) \ - unregister_trace_##call(ftrace_profile_##call); \ -} - -#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) - -#endif - /* * Stage 4 of the trace events. * @@ -500,6 +447,28 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ #define TP_FMT(fmt, args...) fmt "\n", ##args #ifdef CONFIG_EVENT_PROFILE +#define _TRACE_PROFILE(call, proto, args) \ +static void ftrace_profile_##call(proto) \ +{ \ + extern void perf_tpcounter_event(int); \ + perf_tpcounter_event(event_##call.id); \ +} \ + \ +static int ftrace_profile_enable_##call(struct ftrace_event_call *event_call) \ +{ \ + int ret = 0; \ + \ + if (!atomic_inc_return(&event_call->profile_count)) \ + ret = register_trace_##call(ftrace_profile_##call); \ + \ + return ret; \ +} \ + \ +static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ +{ \ + if (atomic_add_negative(-1, &event_call->profile_count)) \ + unregister_trace_##call(ftrace_profile_##call); \ +} #define _TRACE_PROFILE_INIT(call) \ .profile_count = ATOMIC_INIT(-1), \ @@ -507,6 +476,7 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ .profile_disable = ftrace_profile_disable_##call, #else +#define _TRACE_PROFILE(call, proto, args) #define _TRACE_PROFILE_INIT(call) #endif @@ -532,6 +502,7 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\ #undef TRACE_EVENT #define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ +_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \ \ static struct ftrace_event_call event_##call; \ \ @@ -615,110 +586,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -/* - * Define the insertion callback to profile events - * - * The job is very similar to ftrace_raw_event_ except that we don't - * insert in the ring buffer but in a perf counter. - * - * static void ftrace_profile_(proto) - * { - * struct ftrace_data_offsets_ __maybe_unused __data_offsets; - * struct ftrace_event_call *event_call = &event_; - * extern void perf_tpcounter_event(int, u64, u64, void *, int); - * struct ftrace_raw_##call *entry; - * u64 __addr = 0, __count = 1; - * unsigned long irq_flags; - * int __entry_size; - * int __data_size; - * int pc; - * - * local_save_flags(irq_flags); - * pc = preempt_count(); - * - * __data_size = ftrace_get_offsets_(&__data_offsets, args); - * - * // Below we want to get the aligned size by taking into account - * // the u32 field that will later store the buffer size - * __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32), - * sizeof(u64)); - * __entry_size -= sizeof(u32); - * - * do { - * char raw_data[__entry_size]; <- allocate our sample in the stack - * struct trace_entry *ent; - * - * zero dead bytes from alignment to avoid stack leak to userspace: - * - * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; - * entry = (struct ftrace_raw_ *)raw_data; - * ent = &entry->ent; - * tracing_generic_entry_update(ent, irq_flags, pc); - * ent->type = event_call->id; - * - * <- do some jobs with dynamic arrays - * - * <- affect our values - * - * perf_tpcounter_event(event_call->id, __addr, __count, entry, - * __entry_size); <- submit them to perf counter - * } while (0); - * - * } - */ - -#ifdef CONFIG_EVENT_PROFILE - -#undef __perf_addr -#define __perf_addr(a) __addr = (a) - -#undef __perf_count -#define __perf_count(c) __count = (c) - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \ -static void ftrace_profile_##call(proto) \ -{ \ - struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ - struct ftrace_event_call *event_call = &event_##call; \ - extern void perf_tpcounter_event(int, u64, u64, void *, int); \ - struct ftrace_raw_##call *entry; \ - u64 __addr = 0, __count = 1; \ - unsigned long irq_flags; \ - int __entry_size; \ - int __data_size; \ - int pc; \ - \ - local_save_flags(irq_flags); \ - pc = preempt_count(); \ - \ - __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ - __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ - sizeof(u64)); \ - __entry_size -= sizeof(u32); \ - \ - do { \ - char raw_data[__entry_size]; \ - struct trace_entry *ent; \ - \ - *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; \ - entry = (struct ftrace_raw_##call *)raw_data; \ - ent = &entry->ent; \ - tracing_generic_entry_update(ent, irq_flags, pc); \ - ent->type = event_call->id; \ - \ - tstruct \ - \ - { assign; } \ - \ - perf_tpcounter_event(event_call->id, __addr, __count, entry,\ - __entry_size); \ - } while (0); \ - \ -} - -#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -#endif /* CONFIG_EVENT_PROFILE */ - +#undef _TRACE_PROFILE #undef _TRACE_PROFILE_INIT diff --git a/trunk/kernel/irq/numa_migrate.c b/trunk/kernel/irq/numa_migrate.c index 3fd30197da2e..2f69bee57bf2 100644 --- a/trunk/kernel/irq/numa_migrate.c +++ b/trunk/kernel/irq/numa_migrate.c @@ -107,8 +107,8 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc, struct irq_desc *move_irq_desc(struct irq_desc *desc, int node) { - /* those static or target node is -1, do not move them */ - if (desc->irq < NR_IRQS_LEGACY || node == -1) + /* those all static, do move them */ + if (desc->irq < NR_IRQS_LEGACY) return desc; if (desc->node != node) diff --git a/trunk/kernel/lockdep_proc.c b/trunk/kernel/lockdep_proc.c index e94caa666dba..d7135aa2d2c4 100644 --- a/trunk/kernel/lockdep_proc.c +++ b/trunk/kernel/lockdep_proc.c @@ -758,8 +758,7 @@ static int __init lockdep_proc_init(void) &proc_lockdep_stats_operations); #ifdef CONFIG_LOCK_STAT - proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL, - &proc_lock_stat_operations); + proc_create("lock_stat", S_IRUSR, NULL, &proc_lock_stat_operations); #endif return 0; diff --git a/trunk/kernel/perf_counter.c b/trunk/kernel/perf_counter.c index b0b20a07f394..673c1aaf7332 100644 --- a/trunk/kernel/perf_counter.c +++ b/trunk/kernel/perf_counter.c @@ -2714,18 +2714,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, header.size += sizeof(u64); } - if (sample_type & PERF_SAMPLE_RAW) { - int size = sizeof(u32); - - if (data->raw) - size += data->raw->size; - else - size += sizeof(u32); - - WARN_ON_ONCE(size & (sizeof(u64)-1)); - header.size += size; - } - ret = perf_output_begin(&handle, counter, header.size, nmi, 1); if (ret) return; @@ -2789,22 +2777,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, } } - if (sample_type & PERF_SAMPLE_RAW) { - if (data->raw) { - perf_output_put(&handle, data->raw->size); - perf_output_copy(&handle, data->raw->data, data->raw->size); - } else { - struct { - u32 size; - u32 data; - } raw = { - .size = sizeof(u32), - .data = 0, - }; - perf_output_put(&handle, raw); - } - } - perf_output_end(&handle); } @@ -2868,8 +2840,7 @@ perf_counter_read_event(struct perf_counter *counter, */ struct perf_task_event { - struct task_struct *task; - struct perf_counter_context *task_ctx; + struct task_struct *task; struct { struct perf_event_header header; @@ -2929,23 +2900,24 @@ static void perf_counter_task_ctx(struct perf_counter_context *ctx, static void perf_counter_task_event(struct perf_task_event *task_event) { struct perf_cpu_context *cpuctx; - struct perf_counter_context *ctx = task_event->task_ctx; + struct perf_counter_context *ctx; cpuctx = &get_cpu_var(perf_cpu_context); perf_counter_task_ctx(&cpuctx->ctx, task_event); put_cpu_var(perf_cpu_context); rcu_read_lock(); - if (!ctx) - ctx = rcu_dereference(task_event->task->perf_counter_ctxp); + /* + * doesn't really matter which of the child contexts the + * events ends up in. + */ + ctx = rcu_dereference(current->perf_counter_ctxp); if (ctx) perf_counter_task_ctx(ctx, task_event); rcu_read_unlock(); } -static void perf_counter_task(struct task_struct *task, - struct perf_counter_context *task_ctx, - int new) +static void perf_counter_task(struct task_struct *task, int new) { struct perf_task_event task_event; @@ -2955,9 +2927,8 @@ static void perf_counter_task(struct task_struct *task, return; task_event = (struct perf_task_event){ - .task = task, - .task_ctx = task_ctx, - .event = { + .task = task, + .event = { .header = { .type = new ? PERF_EVENT_FORK : PERF_EVENT_EXIT, .misc = 0, @@ -2975,7 +2946,7 @@ static void perf_counter_task(struct task_struct *task, void perf_counter_fork(struct task_struct *task) { - perf_counter_task(task, NULL, 1); + perf_counter_task(task, 1); } /* @@ -3364,81 +3335,87 @@ int perf_counter_overflow(struct perf_counter *counter, int nmi, * Generic software counter infrastructure */ -/* - * We directly increment counter->count and keep a second value in - * counter->hw.period_left to count intervals. This period counter - * is kept in the range [-sample_period, 0] so that we can use the - * sign as trigger. - */ - -static u64 perf_swcounter_set_period(struct perf_counter *counter) +static void perf_swcounter_update(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; - u64 period = hwc->last_period; - u64 nr, offset; - s64 old, val; - - hwc->last_period = hwc->sample_period; + u64 prev, now; + s64 delta; again: - old = val = atomic64_read(&hwc->period_left); - if (val < 0) - return 0; - - nr = div64_u64(period + val, period); - offset = nr * period; - val -= offset; - if (atomic64_cmpxchg(&hwc->period_left, old, val) != old) + prev = atomic64_read(&hwc->prev_count); + now = atomic64_read(&hwc->count); + if (atomic64_cmpxchg(&hwc->prev_count, prev, now) != prev) goto again; - return nr; + delta = now - prev; + + atomic64_add(delta, &counter->count); + atomic64_sub(delta, &hwc->period_left); } -static void perf_swcounter_overflow(struct perf_counter *counter, - int nmi, struct perf_sample_data *data) +static void perf_swcounter_set_period(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; - u64 overflow; - - data->period = counter->hw.last_period; - overflow = perf_swcounter_set_period(counter); + s64 left = atomic64_read(&hwc->period_left); + s64 period = hwc->sample_period; - if (hwc->interrupts == MAX_INTERRUPTS) - return; + if (unlikely(left <= -period)) { + left = period; + atomic64_set(&hwc->period_left, left); + hwc->last_period = period; + } - for (; overflow; overflow--) { - if (perf_counter_overflow(counter, nmi, data)) { - /* - * We inhibit the overflow from happening when - * hwc->interrupts == MAX_INTERRUPTS. - */ - break; - } + if (unlikely(left <= 0)) { + left += period; + atomic64_add(period, &hwc->period_left); + hwc->last_period = period; } + + atomic64_set(&hwc->prev_count, -left); + atomic64_set(&hwc->count, -left); } -static void perf_swcounter_unthrottle(struct perf_counter *counter) +static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) { + enum hrtimer_restart ret = HRTIMER_RESTART; + struct perf_sample_data data; + struct perf_counter *counter; + u64 period; + + counter = container_of(hrtimer, struct perf_counter, hw.hrtimer); + counter->pmu->read(counter); + + data.addr = 0; + data.regs = get_irq_regs(); /* - * Nothing to do, we already reset hwc->interrupts. + * In case we exclude kernel IPs or are somehow not in interrupt + * context, provide the next best thing, the user IP. */ -} + if ((counter->attr.exclude_kernel || !data.regs) && + !counter->attr.exclude_user) + data.regs = task_pt_regs(current); -static void perf_swcounter_add(struct perf_counter *counter, u64 nr, - int nmi, struct perf_sample_data *data) -{ - struct hw_perf_counter *hwc = &counter->hw; + if (data.regs) { + if (perf_counter_overflow(counter, 0, &data)) + ret = HRTIMER_NORESTART; + } - atomic64_add(nr, &counter->count); + period = max_t(u64, 10000, counter->hw.sample_period); + hrtimer_forward_now(hrtimer, ns_to_ktime(period)); - if (!hwc->sample_period) - return; + return ret; +} - if (!data->regs) - return; +static void perf_swcounter_overflow(struct perf_counter *counter, + int nmi, struct perf_sample_data *data) +{ + data->period = counter->hw.last_period; - if (!atomic64_add_negative(nr, &hwc->period_left)) - perf_swcounter_overflow(counter, nmi, data); + perf_swcounter_update(counter); + perf_swcounter_set_period(counter); + if (perf_counter_overflow(counter, nmi, data)) + /* soft-disable the counter */ + ; } static int perf_swcounter_is_counting(struct perf_counter *counter) @@ -3502,6 +3479,15 @@ static int perf_swcounter_match(struct perf_counter *counter, return 1; } +static void perf_swcounter_add(struct perf_counter *counter, u64 nr, + int nmi, struct perf_sample_data *data) +{ + int neg = atomic64_add_negative(nr, &counter->hw.count); + + if (counter->hw.sample_period && !neg && data->regs) + perf_swcounter_overflow(counter, nmi, data); +} + static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, enum perf_type_id type, u32 event, u64 nr, int nmi, @@ -3580,65 +3566,26 @@ void __perf_swcounter_event(u32 event, u64 nr, int nmi, static void perf_swcounter_read(struct perf_counter *counter) { + perf_swcounter_update(counter); } static int perf_swcounter_enable(struct perf_counter *counter) { - struct hw_perf_counter *hwc = &counter->hw; - - if (hwc->sample_period) { - hwc->last_period = hwc->sample_period; - perf_swcounter_set_period(counter); - } + perf_swcounter_set_period(counter); return 0; } static void perf_swcounter_disable(struct perf_counter *counter) { + perf_swcounter_update(counter); } static const struct pmu perf_ops_generic = { .enable = perf_swcounter_enable, .disable = perf_swcounter_disable, .read = perf_swcounter_read, - .unthrottle = perf_swcounter_unthrottle, }; -/* - * hrtimer based swcounter callback - */ - -static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) -{ - enum hrtimer_restart ret = HRTIMER_RESTART; - struct perf_sample_data data; - struct perf_counter *counter; - u64 period; - - counter = container_of(hrtimer, struct perf_counter, hw.hrtimer); - counter->pmu->read(counter); - - data.addr = 0; - data.regs = get_irq_regs(); - /* - * In case we exclude kernel IPs or are somehow not in interrupt - * context, provide the next best thing, the user IP. - */ - if ((counter->attr.exclude_kernel || !data.regs) && - !counter->attr.exclude_user) - data.regs = task_pt_regs(current); - - if (data.regs) { - if (perf_counter_overflow(counter, 0, &data)) - ret = HRTIMER_NORESTART; - } - - period = max_t(u64, 10000, counter->hw.sample_period); - hrtimer_forward_now(hrtimer, ns_to_ktime(period)); - - return ret; -} - /* * Software counter: cpu wall time clock */ @@ -3756,24 +3703,17 @@ static const struct pmu perf_ops_task_clock = { }; #ifdef CONFIG_EVENT_PROFILE -void perf_tpcounter_event(int event_id, u64 addr, u64 count, void *record, - int entry_size) +void perf_tpcounter_event(int event_id) { - struct perf_raw_record raw = { - .size = entry_size, - .data = record, - }; - struct perf_sample_data data = { .regs = get_irq_regs(), - .addr = addr, - .raw = &raw, + .addr = 0, }; if (!data.regs) data.regs = task_pt_regs(current); - do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, &data); + do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, &data); } EXPORT_SYMBOL_GPL(perf_tpcounter_event); @@ -3787,14 +3727,6 @@ static void tp_perf_counter_destroy(struct perf_counter *counter) static const struct pmu *tp_perf_counter_init(struct perf_counter *counter) { - /* - * Raw tracepoint data is a severe data leak, only allow root to - * have these. - */ - if ((counter->attr.sample_type & PERF_SAMPLE_RAW) && - !capable(CAP_SYS_ADMIN)) - return ERR_PTR(-EPERM); - if (ftrace_profile_enable(counter->attr.config)) return NULL; @@ -4337,7 +4269,7 @@ void perf_counter_exit_task(struct task_struct *child) unsigned long flags; if (likely(!child->perf_counter_ctxp)) { - perf_counter_task(child, NULL, 0); + perf_counter_task(child, 0); return; } @@ -4357,7 +4289,6 @@ void perf_counter_exit_task(struct task_struct *child) * incremented the context's refcount before we do put_ctx below. */ spin_lock(&child_ctx->lock); - child->perf_counter_ctxp = NULL; /* * If this context is a clone; unclone it so it can't get * swapped to another process while we're removing all @@ -4371,7 +4302,9 @@ void perf_counter_exit_task(struct task_struct *child) * won't get any samples after PERF_EVENT_EXIT. We can however still * get a few PERF_EVENT_READ events. */ - perf_counter_task(child, child_ctx, 0); + perf_counter_task(child, 0); + + child->perf_counter_ctxp = NULL; /* * We can recurse on the same lock type through: diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index e33a21cb9407..bece7c0b67b2 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -521,12 +521,11 @@ void posix_cpu_timers_exit(struct task_struct *tsk) } void posix_cpu_timers_exit_group(struct task_struct *tsk) { - struct signal_struct *const sig = tsk->signal; + struct task_cputime cputime; + thread_group_cputimer(tsk, &cputime); cleanup_timers(tsk->signal->cpu_timers, - cputime_add(tsk->utime, sig->utime), - cputime_add(tsk->stime, sig->stime), - tsk->se.sum_exec_runtime + sig->sum_sched_runtime); + cputime.utime, cputime.stime, cputime.sum_exec_runtime); } static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now) diff --git a/trunk/kernel/rtmutex.c b/trunk/kernel/rtmutex.c index 29bd4baf9e75..fcd107a78c5a 100644 --- a/trunk/kernel/rtmutex.c +++ b/trunk/kernel/rtmutex.c @@ -1039,14 +1039,16 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, if (!rt_mutex_owner(lock) || try_to_steal_lock(lock, task)) { /* We got the lock for task. */ debug_rt_mutex_lock(lock); + rt_mutex_set_owner(lock, task, 0); - spin_unlock(&lock->wait_lock); + rt_mutex_deadlock_account_lock(lock, task); return 1; } ret = task_blocks_on_rt_mutex(lock, waiter, task, detect_deadlock); + if (ret && !waiter->task) { /* * Reset the return value. We might have diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index 7a34cb563fec..1090b0aed9ba 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -267,8 +267,8 @@ static void blk_trace_free(struct blk_trace *bt) { debugfs_remove(bt->msg_file); debugfs_remove(bt->dropped_file); - relay_close(bt->rchan); debugfs_remove(bt->dir); + relay_close(bt->rchan); free_percpu(bt->sequence); free_percpu(bt->msg_data); kfree(bt); @@ -378,8 +378,18 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf, static int blk_remove_buf_file_callback(struct dentry *dentry) { + struct dentry *parent = dentry->d_parent; debugfs_remove(dentry); + /* + * this will fail for all but the last file, but that is ok. what we + * care about is the top level buts->name directory going away, when + * the last trace file is gone. Then we don't have to rmdir() that + * manually on trace stop, so it nicely solves the issue with + * force killing of running traces. + */ + + debugfs_remove(parent); return 0; } diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c index a330513d96ce..bf27bb7a63e2 100644 --- a/trunk/kernel/trace/ring_buffer.c +++ b/trunk/kernel/trace/ring_buffer.c @@ -735,7 +735,6 @@ ring_buffer_free(struct ring_buffer *buffer) put_online_cpus(); - kfree(buffer->buffers); free_cpumask_var(buffer->cpumask); kfree(buffer); @@ -1786,7 +1785,7 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer, */ RB_WARN_ON(buffer, !local_read(&cpu_buffer->committing)); - if (rb_try_to_discard(cpu_buffer, event)) + if (!rb_try_to_discard(cpu_buffer, event)) goto out; /* @@ -2384,6 +2383,7 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) * the box. Return the padding, and we will release * the current locks, and try again. */ + rb_advance_reader(cpu_buffer); return event; case RINGBUF_TYPE_TIME_EXTEND: @@ -2486,7 +2486,7 @@ static inline int rb_ok_to_lock(void) * buffer too. A one time deal is all you get from reading * the ring buffer from an NMI. */ - if (likely(!in_nmi())) + if (likely(!in_nmi() && !oops_in_progress)) return 1; tracing_off_permanent(); @@ -2519,8 +2519,6 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) if (dolock) spin_lock(&cpu_buffer->reader_lock); event = rb_buffer_peek(buffer, cpu, ts); - if (event && event->type_len == RINGBUF_TYPE_PADDING) - rb_advance_reader(cpu_buffer); if (dolock) spin_unlock(&cpu_buffer->reader_lock); local_irq_restore(flags); @@ -2592,9 +2590,12 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts) spin_lock(&cpu_buffer->reader_lock); event = rb_buffer_peek(buffer, cpu, ts); - if (event) - rb_advance_reader(cpu_buffer); + if (!event) + goto out_unlock; + rb_advance_reader(cpu_buffer); + + out_unlock: if (dolock) spin_unlock(&cpu_buffer->reader_lock); local_irq_restore(flags); diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index c22b40f8f576..8930e39b9d8c 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -848,7 +848,6 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0); } -EXPORT_SYMBOL_GPL(tracing_generic_entry_update); struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, int type, diff --git a/trunk/kernel/trace/trace.h b/trunk/kernel/trace/trace.h index 8b9f4f6e9559..3548ae5cc780 100644 --- a/trunk/kernel/trace/trace.h +++ b/trunk/kernel/trace/trace.h @@ -438,6 +438,10 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts); +void tracing_generic_entry_update(struct trace_entry *entry, + unsigned long flags, + int pc); + void default_wait_pipe(struct trace_iterator *iter); void poll_wait_pipe(struct trace_iterator *iter); diff --git a/trunk/kernel/trace/trace_events_filter.c b/trunk/kernel/trace/trace_events_filter.c index f32dc9d1ea7b..936c621bbf46 100644 --- a/trunk/kernel/trace/trace_events_filter.c +++ b/trunk/kernel/trace/trace_events_filter.c @@ -624,6 +624,9 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps, return -ENOSPC; } + filter->preds[filter->n_preds] = pred; + filter->n_preds++; + list_for_each_entry(call, &ftrace_events, list) { if (!call->define_fields) @@ -640,9 +643,6 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps, } replace_filter_string(call->filter, filter_string); } - - filter->preds[filter->n_preds] = pred; - filter->n_preds++; out: return err; } @@ -1029,17 +1029,12 @@ static int replace_preds(struct event_subsystem *system, if (elt->op == OP_AND || elt->op == OP_OR) { pred = create_logical_pred(elt->op); - if (!pred) - return -ENOMEM; if (call) { err = filter_add_pred(ps, call, pred); filter_free_pred(pred); - } else { + } else err = filter_add_subsystem_pred(ps, system, pred, filter_string); - if (err) - filter_free_pred(pred); - } if (err) return err; @@ -1053,17 +1048,12 @@ static int replace_preds(struct event_subsystem *system, } pred = create_pred(elt->op, operand1, operand2); - if (!pred) - return -ENOMEM; if (call) { err = filter_add_pred(ps, call, pred); filter_free_pred(pred); - } else { + } else err = filter_add_subsystem_pred(ps, system, pred, filter_string); - if (err) - filter_free_pred(pred); - } if (err) return err; diff --git a/trunk/mm/mempool.c b/trunk/mm/mempool.c index 32e75d400503..a46eb1b4bb66 100644 --- a/trunk/mm/mempool.c +++ b/trunk/mm/mempool.c @@ -303,14 +303,14 @@ EXPORT_SYMBOL(mempool_free_slab); */ void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data) { - size_t size = (size_t)pool_data; + size_t size = (size_t)(long)pool_data; return kmalloc(size, gfp_mask); } EXPORT_SYMBOL(mempool_kmalloc); void *mempool_kzalloc(gfp_t gfp_mask, void *pool_data) { - size_t size = (size_t)pool_data; + size_t size = (size_t) pool_data; return kzalloc(size, gfp_mask); } EXPORT_SYMBOL(mempool_kzalloc); diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 6d4716559047..791d71a36a93 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -736,7 +736,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, if (more) flags |= MSG_MORE; - return kernel_sendpage(sock, page, offset, size, flags); + return sock->ops->sendpage(sock, page, offset, size, flags); } static ssize_t sock_splice_read(struct file *file, loff_t *ppos, diff --git a/trunk/scripts/recordmcount.pl b/trunk/scripts/recordmcount.pl index 911ba7ffab84..d29baa2e063a 100755 --- a/trunk/scripts/recordmcount.pl +++ b/trunk/scripts/recordmcount.pl @@ -393,7 +393,7 @@ sub update_funcs $read_function = 0; } # print out any recorded offsets - update_funcs() if (defined($ref_func)); + update_funcs() if ($text_found); # reset all markers and arrays $text_found = 0; @@ -414,10 +414,7 @@ sub update_funcs $offset = hex $1; } else { # if we already have a function, and this is weak, skip it - if (!defined($ref_func) && !defined($weak{$text}) && - # PPC64 can have symbols that start with .L and - # gcc considers these special. Don't use them! - $text !~ /^\.L/) { + if (!defined($ref_func) && !defined($weak{$text})) { $ref_func = $text; $offset = hex $1; } @@ -444,7 +441,7 @@ sub update_funcs } # dump out anymore offsets that may have been found -update_funcs() if (defined($ref_func)); +update_funcs() if ($text_found); # If we did not find any mcount callers, we are done (do nothing). if (!$opened) { diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 1e8cfc4c2ed6..15c2a08a66f1 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1285,8 +1285,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, context, len); if (rc == -ERANGE) { - kfree(context); - /* Need a larger buffer. Query for the right size. */ rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, NULL, 0); @@ -1294,6 +1292,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent dput(dentry); goto out_unlock; } + kfree(context); len = rc; context = kmalloc(len+1, GFP_NOFS); if (!context) { diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index fea976793ae5..51c44fdbc0f0 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -13563,8 +13563,6 @@ static int patch_alc269(struct hda_codec *codec) set_capture_mixer(spec); set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); - spec->vmaster_nid = 0x02; - codec->patch_ops = alc_patch_ops; if (board_config == ALC269_AUTO) spec->init_hook = alc269_auto_init; @@ -15579,12 +15577,9 @@ static int patch_alc861vd(struct hda_codec *codec) spec->stream_digital_playback = &alc861vd_pcm_digital_playback; spec->stream_digital_capture = &alc861vd_pcm_digital_capture; - if (!spec->adc_nids) { - spec->adc_nids = alc861vd_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); - } - if (!spec->capsrc_nids) - spec->capsrc_nids = alc861vd_capsrc_nids; + spec->adc_nids = alc861vd_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); + spec->capsrc_nids = alc861vd_capsrc_nids; set_capture_mixer(spec); set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); @@ -17501,12 +17496,9 @@ static int patch_alc662(struct hda_codec *codec) spec->stream_digital_playback = &alc662_pcm_digital_playback; spec->stream_digital_capture = &alc662_pcm_digital_capture; - if (!spec->adc_nids) { - spec->adc_nids = alc662_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); - } - if (!spec->capsrc_nids) - spec->capsrc_nids = alc662_capsrc_nids; + spec->adc_nids = alc662_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); + spec->capsrc_nids = alc662_capsrc_nids; if (!spec->cap_mixer) set_capture_mixer(spec); diff --git a/trunk/sound/soc/fsl/efika-audio-fabric.c b/trunk/sound/soc/fsl/efika-audio-fabric.c index 3326e2a1e863..85b0e7569504 100644 --- a/trunk/sound/soc/fsl/efika-audio-fabric.c +++ b/trunk/sound/soc/fsl/efika-audio-fabric.c @@ -30,8 +30,6 @@ #include "mpc5200_psc_ac97.h" #include "../codecs/stac9766.h" -#define DRV_NAME "efika-audio-fabric" - static struct snd_soc_device device; static struct snd_soc_card card; diff --git a/trunk/sound/soc/fsl/pcm030-audio-fabric.c b/trunk/sound/soc/fsl/pcm030-audio-fabric.c index b928ef7d28eb..8766f7a3893d 100644 --- a/trunk/sound/soc/fsl/pcm030-audio-fabric.c +++ b/trunk/sound/soc/fsl/pcm030-audio-fabric.c @@ -30,8 +30,6 @@ #include "mpc5200_psc_ac97.h" #include "../codecs/wm9712.h" -#define DRV_NAME "pcm030-audio-fabric" - static struct snd_soc_device device; static struct snd_soc_card card; diff --git a/trunk/tools/perf/Documentation/perf-examples.txt b/trunk/tools/perf/Documentation/perf-examples.txt deleted file mode 100644 index 8eb6c489fb15..000000000000 --- a/trunk/tools/perf/Documentation/perf-examples.txt +++ /dev/null @@ -1,225 +0,0 @@ - - ------------------------------ - ****** perf by examples ****** - ------------------------------ - -[ From an e-mail by Ingo Molnar, http://lkml.org/lkml/2009/8/4/346 ] - - -First, discovery/enumeration of available counters can be done via -'perf list': - -titan:~> perf list - [...] - kmem:kmalloc [Tracepoint event] - kmem:kmem_cache_alloc [Tracepoint event] - kmem:kmalloc_node [Tracepoint event] - kmem:kmem_cache_alloc_node [Tracepoint event] - kmem:kfree [Tracepoint event] - kmem:kmem_cache_free [Tracepoint event] - kmem:mm_page_free_direct [Tracepoint event] - kmem:mm_pagevec_free [Tracepoint event] - kmem:mm_page_alloc [Tracepoint event] - kmem:mm_page_alloc_zone_locked [Tracepoint event] - kmem:mm_page_pcpu_drain [Tracepoint event] - kmem:mm_page_alloc_extfrag [Tracepoint event] - -Then any (or all) of the above event sources can be activated and -measured. For example the page alloc/free properties of a 'hackbench -run' are: - - titan:~> perf stat -e kmem:mm_page_pcpu_drain -e kmem:mm_page_alloc - -e kmem:mm_pagevec_free -e kmem:mm_page_free_direct ./hackbench 10 - Time: 0.575 - - Performance counter stats for './hackbench 10': - - 13857 kmem:mm_page_pcpu_drain - 27576 kmem:mm_page_alloc - 6025 kmem:mm_pagevec_free - 20934 kmem:mm_page_free_direct - - 0.613972165 seconds time elapsed - -You can observe the statistical properties as well, by using the -'repeat the workload N times' feature of perf stat: - - titan:~> perf stat --repeat 5 -e kmem:mm_page_pcpu_drain -e - kmem:mm_page_alloc -e kmem:mm_pagevec_free -e - kmem:mm_page_free_direct ./hackbench 10 - Time: 0.627 - Time: 0.644 - Time: 0.564 - Time: 0.559 - Time: 0.626 - - Performance counter stats for './hackbench 10' (5 runs): - - 12920 kmem:mm_page_pcpu_drain ( +- 3.359% ) - 25035 kmem:mm_page_alloc ( +- 3.783% ) - 6104 kmem:mm_pagevec_free ( +- 0.934% ) - 18376 kmem:mm_page_free_direct ( +- 4.941% ) - - 0.643954516 seconds time elapsed ( +- 2.363% ) - -Furthermore, these tracepoints can be used to sample the workload as -well. For example the page allocations done by a 'git gc' can be -captured the following way: - - titan:~/git> perf record -f -e kmem:mm_page_alloc -c 1 ./git gc - Counting objects: 1148, done. - Delta compression using up to 2 threads. - Compressing objects: 100% (450/450), done. - Writing objects: 100% (1148/1148), done. - Total 1148 (delta 690), reused 1148 (delta 690) - [ perf record: Captured and wrote 0.267 MB perf.data (~11679 samples) ] - -To check which functions generated page allocations: - - titan:~/git> perf report - # Samples: 10646 - # - # Overhead Command Shared Object - # ........ ............... .......................... - # - 23.57% git-repack /lib64/libc-2.5.so - 21.81% git /lib64/libc-2.5.so - 14.59% git ./git - 11.79% git-repack ./git - 7.12% git /lib64/ld-2.5.so - 3.16% git-repack /lib64/libpthread-2.5.so - 2.09% git-repack /bin/bash - 1.97% rm /lib64/libc-2.5.so - 1.39% mv /lib64/ld-2.5.so - 1.37% mv /lib64/libc-2.5.so - 1.12% git-repack /lib64/ld-2.5.so - 0.95% rm /lib64/ld-2.5.so - 0.90% git-update-serv /lib64/libc-2.5.so - 0.73% git-update-serv /lib64/ld-2.5.so - 0.68% perf /lib64/libpthread-2.5.so - 0.64% git-repack /usr/lib64/libz.so.1.2.3 - -Or to see it on a more finegrained level: - -titan:~/git> perf report --sort comm,dso,symbol -# Samples: 10646 -# -# Overhead Command Shared Object Symbol -# ........ ............... .......................... ...... -# - 9.35% git-repack ./git [.] insert_obj_hash - 9.12% git ./git [.] insert_obj_hash - 7.31% git /lib64/libc-2.5.so [.] memcpy - 6.34% git-repack /lib64/libc-2.5.so [.] _int_malloc - 6.24% git-repack /lib64/libc-2.5.so [.] memcpy - 5.82% git-repack /lib64/libc-2.5.so [.] __GI___fork - 5.47% git /lib64/libc-2.5.so [.] _int_malloc - 2.99% git /lib64/libc-2.5.so [.] memset - -Furthermore, call-graph sampling can be done too, of page -allocations - to see precisely what kind of page allocations there -are: - - titan:~/git> perf record -f -g -e kmem:mm_page_alloc -c 1 ./git gc - Counting objects: 1148, done. - Delta compression using up to 2 threads. - Compressing objects: 100% (450/450), done. - Writing objects: 100% (1148/1148), done. - Total 1148 (delta 690), reused 1148 (delta 690) - [ perf record: Captured and wrote 0.963 MB perf.data (~42069 samples) ] - - titan:~/git> perf report -g - # Samples: 10686 - # - # Overhead Command Shared Object - # ........ ............... .......................... - # - 23.25% git-repack /lib64/libc-2.5.so - | - |--50.00%-- _int_free - | - |--37.50%-- __GI___fork - | make_child - | - |--12.50%-- ptmalloc_unlock_all2 - | make_child - | - --6.25%-- __GI_strcpy - 21.61% git /lib64/libc-2.5.so - | - |--30.00%-- __GI_read - | | - | --83.33%-- git_config_from_file - | git_config - | | - [...] - -Or you can observe the whole system's page allocations for 10 -seconds: - -titan:~/git> perf stat -a -e kmem:mm_page_pcpu_drain -e -kmem:mm_page_alloc -e kmem:mm_pagevec_free -e -kmem:mm_page_free_direct sleep 10 - - Performance counter stats for 'sleep 10': - - 171585 kmem:mm_page_pcpu_drain - 322114 kmem:mm_page_alloc - 73623 kmem:mm_pagevec_free - 254115 kmem:mm_page_free_direct - - 10.000591410 seconds time elapsed - -Or observe how fluctuating the page allocations are, via statistical -analysis done over ten 1-second intervals: - - titan:~/git> perf stat --repeat 10 -a -e kmem:mm_page_pcpu_drain -e - kmem:mm_page_alloc -e kmem:mm_pagevec_free -e - kmem:mm_page_free_direct sleep 1 - - Performance counter stats for 'sleep 1' (10 runs): - - 17254 kmem:mm_page_pcpu_drain ( +- 3.709% ) - 34394 kmem:mm_page_alloc ( +- 4.617% ) - 7509 kmem:mm_pagevec_free ( +- 4.820% ) - 25653 kmem:mm_page_free_direct ( +- 3.672% ) - - 1.058135029 seconds time elapsed ( +- 3.089% ) - -Or you can annotate the recorded 'git gc' run on a per symbol basis -and check which instructions/source-code generated page allocations: - - titan:~/git> perf annotate __GI___fork - ------------------------------------------------ - Percent | Source code & Disassembly of libc-2.5.so - ------------------------------------------------ - : - : - : Disassembly of section .plt: - : Disassembly of section .text: - : - : 00000031a2e95560 <__fork>: - [...] - 0.00 : 31a2e95602: b8 38 00 00 00 mov $0x38,%eax - 0.00 : 31a2e95607: 0f 05 syscall - 83.42 : 31a2e95609: 48 3d 00 f0 ff ff cmp $0xfffffffffffff000,%rax - 0.00 : 31a2e9560f: 0f 87 4d 01 00 00 ja 31a2e95762 <__fork+0x202> - 0.00 : 31a2e95615: 85 c0 test %eax,%eax - -( this shows that 83.42% of __GI___fork's page allocations come from - the 0x38 system call it performs. ) - -etc. etc. - a lot more is possible. I could list a dozen of -other different usecases straight away - neither of which is -possible via /proc/vmstat. - -/proc/vmstat is not in the same league really, in terms of -expressive power of system analysis and performance -analysis. - -All that the above results needed were those new tracepoints -in include/tracing/events/kmem.h. - - Ingo - - diff --git a/trunk/tools/perf/Documentation/perf-stat.txt b/trunk/tools/perf/Documentation/perf-stat.txt index 484080dd5b6f..0d74346d21ab 100644 --- a/trunk/tools/perf/Documentation/perf-stat.txt +++ b/trunk/tools/perf/Documentation/perf-stat.txt @@ -40,7 +40,7 @@ OPTIONS -a:: system-wide collection --c:: +-S:: scale counter values EXAMPLES diff --git a/trunk/tools/perf/Documentation/perf-top.txt b/trunk/tools/perf/Documentation/perf-top.txt index 4a7d558dc309..539d01289725 100644 --- a/trunk/tools/perf/Documentation/perf-top.txt +++ b/trunk/tools/perf/Documentation/perf-top.txt @@ -3,122 +3,36 @@ perf-top(1) NAME ---- -perf-top - System profiling tool. +perf-top - Run a command and profile it SYNOPSIS -------- [verse] -'perf top' [-e | --event=EVENT] [] +'perf top' [-e | --event=EVENT] [-l] [-a] DESCRIPTION ----------- -This command generates and displays a performance counter profile in realtime. +This command runs a command and gathers a performance counter profile +from it. OPTIONS ------- --a:: ---all-cpus:: - System-wide collection. (default) - --c :: ---count=:: - Event period to sample. - --C :: ---CPU=:: - CPU to profile. - --d :: ---delay=:: - Number of seconds to delay between refreshes. +...:: + Any command you can specify in a shell. --e :: ---event=:: +-e:: +--event=:: Select the PMU event. Selection can be a symbolic event name (use 'perf list' to list all events) or a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a - hexadecimal event descriptor. - --E :: ---entries=:: - Display this many functions. - --f :: ---count-filter=:: - Only display functions with more events than this. - --F :: ---freq=:: - Profile at this frequency. - --i:: ---inherit:: - Child tasks inherit counters, only makes sens with -p option. - --k :: ---vmlinux=:: - Path to vmlinux. Required for annotation functionality. - --m :: ---mmap-pages=:: - Number of mmapped data pages. - --p :: ---pid=:: - Profile events on existing pid. - --r :: ---realtime=:: - Collect data with this RT SCHED_FIFO priority. - --s :: ---sym-annotate=:: - Annotate this symbol. Requires -k option. - --v:: ---verbose:: - Be more verbose (show counter open errors, etc). + hexadecimal event descriptor. --z:: ---zero:: - Zero history across display updates. - -INTERACTIVE PROMPTING KEYS --------------------------- - -[d]:: - Display refresh delay. - -[e]:: - Number of entries to display. - -[E]:: - Event to display when multiple counters are active. - -[f]:: - Profile display filter (>= hit count). - -[F]:: - Annotation display filter (>= % of total). - -[s]:: - Annotate symbol. - -[S]:: - Stop annotation, return to full profile display. - -[w]:: - Toggle between weighted sum and individual count[E]r profile. - -[z]:: - Toggle event count zeroing across display updates. - -[qQ]:: - Quit. - -Pressing any unmapped key displays a menu, and prompts for input. +-a:: + system-wide collection +-l:: + scale counter values SEE ALSO -------- diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 60411e94113b..1916e44b9bb0 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -387,14 +387,10 @@ else has_bfd_iberty := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y") - has_bfd_iberty_z := $(shell sh -c "(echo '\#include '; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y") - ifeq ($(has_bfd),y) EXTLIBS += -lbfd else ifeq ($(has_bfd_iberty),y) EXTLIBS += -lbfd -liberty - else ifeq ($(has_bfd_iberty_z),y) - EXTLIBS += -lbfd -liberty -lz else msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling) BASIC_CFLAGS += -DNO_DEMANGLE diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index 0345aad8eba5..6da09928130f 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -412,7 +412,6 @@ static void create_counter(int counter, int cpu, pid_t pid) if (call_graph) attr->sample_type |= PERF_SAMPLE_CALLCHAIN; - attr->mmap = track; attr->comm = track; attr->inherit = (cpu < 0) && inherit; @@ -525,14 +524,10 @@ static int __cmd_record(int argc, const char **argv) signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); - if (!stat(output_name, &st) && st.st_size) { - if (!force && !append_file) { - fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", - output_name); - exit(-1); - } - } else { - append_file = 0; + if (!stat(output_name, &st) && !force && !append_file) { + fprintf(stderr, "Error, output file %s exists, use -A to append or -f to overwrite.\n", + output_name); + exit(-1); } flags = O_CREAT|O_RDWR; diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index 99274cec0adb..8cb58d68a006 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -68,7 +68,7 @@ static int callchain; static struct callchain_param callchain_param = { - .mode = CHAIN_GRAPH_REL, + .mode = CHAIN_GRAPH_ABS, .min_percent = 0.5 }; @@ -112,9 +112,7 @@ struct read_event { struct perf_event_header header; u32 pid,tid; u64 value; - u64 time_enabled; - u64 time_running; - u64 id; + u64 format[3]; }; typedef union event_union { @@ -700,8 +698,7 @@ sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used) size_t ret = 0; if (verbose) - ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, - dso__symtab_origin(self->dso)); + ret += repsep_fprintf(fp, "%#018llx ", (u64)self->ip); ret += repsep_fprintf(fp, "[%c] ", self->level); if (self->sym) { @@ -891,21 +888,6 @@ ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth, return ret; } -static struct symbol *rem_sq_bracket; -static struct callchain_list rem_hits; - -static void init_rem_hits(void) -{ - rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6); - if (!rem_sq_bracket) { - fprintf(stderr, "Not enough memory to display remaining hits\n"); - return; - } - - strcpy(rem_sq_bracket->name, "[...]"); - rem_hits.sym = rem_sq_bracket; -} - static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, u64 total_samples, int depth, int depth_mask) @@ -915,34 +897,25 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self, struct callchain_list *chain; int new_depth_mask = depth_mask; u64 new_total; - u64 remaining; size_t ret = 0; int i; if (callchain_param.mode == CHAIN_GRAPH_REL) - new_total = self->children_hit; + new_total = self->cumul_hit; else new_total = total_samples; - remaining = new_total; - node = rb_first(&self->rb_root); while (node) { - u64 cumul; - child = rb_entry(node, struct callchain_node, rb_node); - cumul = cumul_hits(child); - remaining -= cumul; /* * The depth mask manages the output of pipes that show * the depth. We don't want to keep the pipes of the current - * level for the last child of this depth. - * Except if we have remaining filtered hits. They will - * supersede the last child + * level for the last child of this depth */ next = rb_next(node); - if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || !remaining)) + if (!next) new_depth_mask &= ~(1 << (depth - 1)); /* @@ -957,7 +930,7 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self, ret += ipchain__fprintf_graph(fp, chain, depth, new_depth_mask, i++, new_total, - cumul); + child->cumul_hit); } ret += callchain__fprintf_graph(fp, child, new_total, depth + 1, @@ -965,19 +938,6 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self, node = next; } - if (callchain_param.mode == CHAIN_GRAPH_REL && - remaining && remaining != new_total) { - - if (!rem_sq_bracket) - return ret; - - new_depth_mask &= ~(1 << (depth - 1)); - - ret += ipchain__fprintf_graph(fp, &rem_hits, depth, - new_depth_mask, 0, new_total, - remaining); - } - return ret; } @@ -1398,8 +1358,6 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) unsigned int width; char *col_width = col_width_list_str; - init_rem_hits(); - fprintf(fp, "# Samples: %Ld\n", (u64)total_samples); fprintf(fp, "#\n"); @@ -1471,8 +1429,6 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) } fprintf(fp, "\n"); - free(rem_sq_bracket); - return ret; } @@ -1734,37 +1690,14 @@ static void trace_event(event_t *event) dprintf(".\n"); } -static struct perf_header *header; - -static struct perf_counter_attr *perf_header__find_attr(u64 id) -{ - int i; - - for (i = 0; i < header->attrs; i++) { - struct perf_header_attr *attr = header->attr[i]; - int j; - - for (j = 0; j < attr->ids; j++) { - if (attr->id[j] == id) - return &attr->attr; - } - } - - return NULL; -} - static int process_read_event(event_t *event, unsigned long offset, unsigned long head) { - struct perf_counter_attr *attr = perf_header__find_attr(event->read.id); - - dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n", + dprintf("%p [%p]: PERF_EVENT_READ: %d %d %Lu\n", (void *)(offset + head), (void *)(long)(event->header.size), event->read.pid, event->read.tid, - attr ? __event_name(attr->type, attr->config) - : "FAIL", event->read.value); return 0; @@ -1810,6 +1743,8 @@ process_event(event_t *event, unsigned long offset, unsigned long head) return 0; } +static struct perf_header *header; + static u64 perf_header__sample_type(void) { u64 sample_type = 0; @@ -1877,13 +1812,6 @@ static int __cmd_report(void) " -g?\n"); exit(-1); } - } else if (callchain_param.mode != CHAIN_NONE && !callchain) { - callchain = 1; - if (register_callchain_param(&callchain_param) < 0) { - fprintf(stderr, "Can't register callchain" - " params\n"); - exit(-1); - } } if (load_kernel() < 0) { @@ -2022,13 +1950,6 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, else if (!strncmp(tok, "fractal", strlen(arg))) callchain_param.mode = CHAIN_GRAPH_REL; - else if (!strncmp(tok, "none", strlen(arg))) { - callchain_param.mode = CHAIN_NONE; - callchain = 0; - - return 0; - } - else return -1; diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index b4b06c7903e1..f9510eeeb6c7 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -496,7 +496,7 @@ static const struct option options[] = { "stat events on existing pid"), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), - OPT_BOOLEAN('c', "scale", &scale, + OPT_BOOLEAN('S', "scale", &scale, "scale/normalize counters"), OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 7de28ce9ca26..f139f1ab9333 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -31,8 +31,6 @@ #include #include -#include -#include #include #include @@ -56,7 +54,7 @@ static int system_wide = 0; static int default_interval = 100000; -static int count_filter = 5; +static u64 count_filter = 5; static int print_entries = 15; static int target_pid = -1; @@ -71,27 +69,14 @@ static int freq = 0; static int verbose = 0; static char *vmlinux = NULL; +static char *sym_filter; +static unsigned long filter_start; +static unsigned long filter_end; + static int delay_secs = 2; static int zero; static int dump_symtab; -/* - * Source - */ - -struct source_line { - u64 eip; - unsigned long count[MAX_COUNTERS]; - char *line; - struct source_line *next; -}; - -static char *sym_filter = NULL; -struct sym_entry *sym_filter_entry = NULL; -static int sym_pcnt_filter = 5; -static int sym_counter = 0; -static int display_weighted = -1; - /* * Symbols */ @@ -106,237 +91,9 @@ struct sym_entry { unsigned long snap_count; double weight; int skip; - struct source_line *source; - struct source_line *lines; - struct source_line **lines_tail; - pthread_mutex_t source_lock; }; -/* - * Source functions - */ - -static void parse_source(struct sym_entry *syme) -{ - struct symbol *sym; - struct module *module; - struct section *section = NULL; - FILE *file; - char command[PATH_MAX*2], *path = vmlinux; - u64 start, end, len; - - if (!syme) - return; - - if (syme->lines) { - pthread_mutex_lock(&syme->source_lock); - goto out_assign; - } - - sym = (struct symbol *)(syme + 1); - module = sym->module; - - if (module) - path = module->path; - if (!path) - return; - - start = sym->obj_start; - if (!start) - start = sym->start; - - if (module) { - section = module->sections->find_section(module->sections, ".text"); - if (section) - start -= section->vma; - } - - end = start + sym->end - sym->start + 1; - len = sym->end - sym->start; - - sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", start, end, path); - - file = popen(command, "r"); - if (!file) - return; - - pthread_mutex_lock(&syme->source_lock); - syme->lines_tail = &syme->lines; - while (!feof(file)) { - struct source_line *src; - size_t dummy = 0; - char *c; - - src = malloc(sizeof(struct source_line)); - assert(src != NULL); - memset(src, 0, sizeof(struct source_line)); - - if (getline(&src->line, &dummy, file) < 0) - break; - if (!src->line) - break; - - c = strchr(src->line, '\n'); - if (c) - *c = 0; - - src->next = NULL; - *syme->lines_tail = src; - syme->lines_tail = &src->next; - - if (strlen(src->line)>8 && src->line[8] == ':') { - src->eip = strtoull(src->line, NULL, 16); - if (section) - src->eip += section->vma; - } - if (strlen(src->line)>8 && src->line[16] == ':') { - src->eip = strtoull(src->line, NULL, 16); - if (section) - src->eip += section->vma; - } - } - pclose(file); -out_assign: - sym_filter_entry = syme; - pthread_mutex_unlock(&syme->source_lock); -} - -static void __zero_source_counters(struct sym_entry *syme) -{ - int i; - struct source_line *line; - - line = syme->lines; - while (line) { - for (i = 0; i < nr_counters; i++) - line->count[i] = 0; - line = line->next; - } -} - -static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) -{ - struct source_line *line; - - if (syme != sym_filter_entry) - return; - - if (pthread_mutex_trylock(&syme->source_lock)) - return; - - if (!syme->source) - goto out_unlock; - - for (line = syme->lines; line; line = line->next) { - if (line->eip == ip) { - line->count[counter]++; - break; - } - if (line->eip > ip) - break; - } -out_unlock: - pthread_mutex_unlock(&syme->source_lock); -} - -static void lookup_sym_source(struct sym_entry *syme) -{ - struct symbol *symbol = (struct symbol *)(syme + 1); - struct source_line *line; - char pattern[PATH_MAX]; - char *idx; - - sprintf(pattern, "<%s>:", symbol->name); - - if (symbol->module) { - idx = strstr(pattern, "\t"); - if (idx) - *idx = 0; - } - - pthread_mutex_lock(&syme->source_lock); - for (line = syme->lines; line; line = line->next) { - if (strstr(line->line, pattern)) { - syme->source = line; - break; - } - } - pthread_mutex_unlock(&syme->source_lock); -} - -static void show_lines(struct source_line *queue, int count, int total) -{ - int i; - struct source_line *line; - - line = queue; - for (i = 0; i < count; i++) { - float pcnt = 100.0*(float)line->count[sym_counter]/(float)total; - - printf("%8li %4.1f%%\t%s\n", line->count[sym_counter], pcnt, line->line); - line = line->next; - } -} - -#define TRACE_COUNT 3 - -static void show_details(struct sym_entry *syme) -{ - struct symbol *symbol; - struct source_line *line; - struct source_line *line_queue = NULL; - int displayed = 0; - int line_queue_count = 0, total = 0, more = 0; - - if (!syme) - return; - - if (!syme->source) - lookup_sym_source(syme); - - if (!syme->source) - return; - - symbol = (struct symbol *)(syme + 1); - printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); - printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); - - pthread_mutex_lock(&syme->source_lock); - line = syme->source; - while (line) { - total += line->count[sym_counter]; - line = line->next; - } - - line = syme->source; - while (line) { - float pcnt = 0.0; - - if (!line_queue_count) - line_queue = line; - line_queue_count++; - - if (line->count[sym_counter]) - pcnt = 100.0 * line->count[sym_counter] / (float)total; - if (pcnt >= (float)sym_pcnt_filter) { - if (displayed <= print_entries) - show_lines(line_queue, line_queue_count, total); - else more++; - displayed += line_queue_count; - line_queue_count = 0; - line_queue = NULL; - } else if (line_queue_count > TRACE_COUNT) { - line_queue = line_queue->next; - line_queue_count--; - } - - line->count[sym_counter] = zero ? 0 : line->count[sym_counter] * 7 / 8; - line = line->next; - } - pthread_mutex_unlock(&syme->source_lock); - if (more) - printf("%d lines not displayed, maybe increase display entries [e]\n", more); -} +struct sym_entry *sym_filter_entry; struct dso *kernel_dso; @@ -355,9 +112,6 @@ static double sym_weight(const struct sym_entry *sym) double weight = sym->snap_count; int counter; - if (!display_weighted) - return weight; - for (counter = 1; counter < nr_counters-1; counter++) weight *= sym->count[counter]; @@ -405,7 +159,7 @@ static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se) static void print_sym_table(void) { int printed = 0, j; - int counter, snap = !display_weighted ? sym_counter : 0; + int counter; float samples_per_sec = samples/delay_secs; float ksamples_per_sec = (samples-userspace_samples)/delay_secs; float sum_ksamples = 0.0; @@ -421,7 +175,7 @@ static void print_sym_table(void) pthread_mutex_unlock(&active_symbols_lock); list_for_each_entry_safe_from(syme, n, &active_symbols, node) { - syme->snap_count = syme->count[snap]; + syme->snap_count = syme->count[0]; if (syme->snap_count != 0) { syme->weight = sym_weight(syme); rb_insert_active_sym(&tmp, syme); @@ -441,7 +195,7 @@ static void print_sym_table(void) samples_per_sec, 100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec))); - if (nr_counters == 1 || !display_weighted) { + if (nr_counters == 1) { printf("%Ld", (u64)attrs[0].sample_period); if (freq) printf("Hz "); @@ -449,9 +203,7 @@ static void print_sym_table(void) printf(" "); } - if (!display_weighted) - printf("%s", event_name(sym_counter)); - else for (counter = 0; counter < nr_counters; counter++) { + for (counter = 0; counter < nr_counters; counter++) { if (counter) printf("/"); @@ -476,11 +228,6 @@ static void print_sym_table(void) printf("------------------------------------------------------------------------------\n\n"); - if (sym_filter_entry) { - show_details(sym_filter_entry); - return; - } - if (nr_counters == 1) printf(" samples pcnt"); else @@ -495,13 +242,13 @@ static void print_sym_table(void) struct symbol *sym = (struct symbol *)(syme + 1); double pcnt; - if (++printed > print_entries || (int)syme->snap_count < count_filter) + if (++printed > print_entries || syme->snap_count < count_filter) continue; pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / sum_ksamples)); - if (nr_counters == 1 || !display_weighted) + if (nr_counters == 1) printf("%20.2f - ", syme->weight); else printf("%9.1f %10ld - ", syme->weight, syme->snap_count); @@ -514,250 +261,19 @@ static void print_sym_table(void) } } -static void prompt_integer(int *target, const char *msg) -{ - char *buf = malloc(0), *p; - size_t dummy = 0; - int tmp; - - fprintf(stdout, "\n%s: ", msg); - if (getline(&buf, &dummy, stdin) < 0) - return; - - p = strchr(buf, '\n'); - if (p) - *p = 0; - - p = buf; - while(*p) { - if (!isdigit(*p)) - goto out_free; - p++; - } - tmp = strtoul(buf, NULL, 10); - *target = tmp; -out_free: - free(buf); -} - -static void prompt_percent(int *target, const char *msg) -{ - int tmp = 0; - - prompt_integer(&tmp, msg); - if (tmp >= 0 && tmp <= 100) - *target = tmp; -} - -static void prompt_symbol(struct sym_entry **target, const char *msg) -{ - char *buf = malloc(0), *p; - struct sym_entry *syme = *target, *n, *found = NULL; - size_t dummy = 0; - - /* zero counters of active symbol */ - if (syme) { - pthread_mutex_lock(&syme->source_lock); - __zero_source_counters(syme); - *target = NULL; - pthread_mutex_unlock(&syme->source_lock); - } - - fprintf(stdout, "\n%s: ", msg); - if (getline(&buf, &dummy, stdin) < 0) - goto out_free; - - p = strchr(buf, '\n'); - if (p) - *p = 0; - - pthread_mutex_lock(&active_symbols_lock); - syme = list_entry(active_symbols.next, struct sym_entry, node); - pthread_mutex_unlock(&active_symbols_lock); - - list_for_each_entry_safe_from(syme, n, &active_symbols, node) { - struct symbol *sym = (struct symbol *)(syme + 1); - - if (!strcmp(buf, sym->name)) { - found = syme; - break; - } - } - - if (!found) { - fprintf(stderr, "Sorry, %s is not active.\n", sym_filter); - sleep(1); - return; - } else - parse_source(found); - -out_free: - free(buf); -} - -static void print_mapped_keys(void) -{ - char *name = NULL; - - if (sym_filter_entry) { - struct symbol *sym = (struct symbol *)(sym_filter_entry+1); - name = sym->name; - } - - fprintf(stdout, "\nMapped keys:\n"); - fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); - fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); - - if (nr_counters > 1) - fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter)); - - fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); - - if (vmlinux) { - fprintf(stdout, "\t[F] annotate display filter (percent). \t(%d%%)\n", sym_pcnt_filter); - fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); - fprintf(stdout, "\t[S] stop annotation.\n"); - } - - if (nr_counters > 1) - fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); - - fprintf(stdout, "\t[z] toggle sample zeroing. \t(%d)\n", zero ? 1 : 0); - fprintf(stdout, "\t[qQ] quit.\n"); -} - -static int key_mapped(int c) -{ - switch (c) { - case 'd': - case 'e': - case 'f': - case 'z': - case 'q': - case 'Q': - return 1; - case 'E': - case 'w': - return nr_counters > 1 ? 1 : 0; - case 'F': - case 's': - case 'S': - return vmlinux ? 1 : 0; - } - - return 0; -} - -static void handle_keypress(int c) -{ - if (!key_mapped(c)) { - struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; - struct termios tc, save; - - print_mapped_keys(); - fprintf(stdout, "\nEnter selection, or unmapped key to continue: "); - fflush(stdout); - - tcgetattr(0, &save); - tc = save; - tc.c_lflag &= ~(ICANON | ECHO); - tc.c_cc[VMIN] = 0; - tc.c_cc[VTIME] = 0; - tcsetattr(0, TCSANOW, &tc); - - poll(&stdin_poll, 1, -1); - c = getc(stdin); - - tcsetattr(0, TCSAFLUSH, &save); - if (!key_mapped(c)) - return; - } - - switch (c) { - case 'd': - prompt_integer(&delay_secs, "Enter display delay"); - break; - case 'e': - prompt_integer(&print_entries, "Enter display entries (lines)"); - break; - case 'E': - if (nr_counters > 1) { - int i; - - fprintf(stderr, "\nAvailable events:"); - for (i = 0; i < nr_counters; i++) - fprintf(stderr, "\n\t%d %s", i, event_name(i)); - - prompt_integer(&sym_counter, "Enter details event counter"); - - if (sym_counter >= nr_counters) { - fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0)); - sym_counter = 0; - sleep(1); - } - } else sym_counter = 0; - break; - case 'f': - prompt_integer(&count_filter, "Enter display event count filter"); - break; - case 'F': - prompt_percent(&sym_pcnt_filter, "Enter details display event filter (percent)"); - break; - case 'q': - case 'Q': - printf("exiting.\n"); - exit(0); - case 's': - prompt_symbol(&sym_filter_entry, "Enter details symbol"); - break; - case 'S': - if (!sym_filter_entry) - break; - else { - struct sym_entry *syme = sym_filter_entry; - - pthread_mutex_lock(&syme->source_lock); - sym_filter_entry = NULL; - __zero_source_counters(syme); - pthread_mutex_unlock(&syme->source_lock); - } - break; - case 'w': - display_weighted = ~display_weighted; - break; - case 'z': - zero = ~zero; - break; - } -} - static void *display_thread(void *arg __used) { struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; - struct termios tc, save; - int delay_msecs, c; - - tcgetattr(0, &save); - tc = save; - tc.c_lflag &= ~(ICANON | ECHO); - tc.c_cc[VMIN] = 0; - tc.c_cc[VTIME] = 0; + int delay_msecs = delay_secs * 1000; -repeat: - delay_msecs = delay_secs * 1000; - tcsetattr(0, TCSANOW, &tc); - /* trash return*/ - getc(stdin); + printf("PerfTop refresh period: %d seconds\n", delay_secs); do { print_sym_table(); } while (!poll(&stdin_poll, 1, delay_msecs) == 1); - c = getc(stdin); - tcsetattr(0, TCSAFLUSH, &save); - - handle_keypress(c); - goto repeat; + printf("key pressed - exiting.\n"); + exit(0); return NULL; } @@ -777,6 +293,7 @@ static const char *skip_symbols[] = { static int symbol_filter(struct dso *self, struct symbol *sym) { + static int filter_match; struct sym_entry *syme; const char *name = sym->name; int i; @@ -798,10 +315,6 @@ static int symbol_filter(struct dso *self, struct symbol *sym) return 1; syme = dso__sym_priv(self, sym); - pthread_mutex_init(&syme->source_lock, NULL); - if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) - sym_filter_entry = syme; - for (i = 0; skip_symbols[i]; i++) { if (!strcmp(skip_symbols[i], name)) { syme->skip = 1; @@ -809,6 +322,29 @@ static int symbol_filter(struct dso *self, struct symbol *sym) } } + if (filter_match == 1) { + filter_end = sym->start; + filter_match = -1; + if (filter_end - filter_start > 10000) { + fprintf(stderr, + "hm, too large filter symbol <%s> - skipping.\n", + sym_filter); + fprintf(stderr, "symbol filter start: %016lx\n", + filter_start); + fprintf(stderr, " end: %016lx\n", + filter_end); + filter_end = filter_start = 0; + sym_filter = NULL; + sleep(1); + } + } + + if (filter_match == 0 && sym_filter && !strcmp(name, sym_filter)) { + filter_match = 1; + filter_start = sym->start; + } + + return 0; } @@ -844,6 +380,8 @@ static int parse_symbols(void) return -1; } +#define TRACE_COUNT 3 + /* * Binary search in the histogram table and record the hit: */ @@ -856,7 +394,6 @@ static void record_ip(u64 ip, int counter) if (!syme->skip) { syme->count[counter]++; - record_precise_ip(syme, counter, ip); pthread_mutex_lock(&active_symbols_lock); if (list_empty(&syme->node) || !syme->node.next) __list_insert_active_sym(syme); @@ -1153,8 +690,8 @@ static const struct option options[] = { "put the counters into a counter group"), OPT_BOOLEAN('i', "inherit", &inherit, "child tasks inherit counters"), - OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", - "symbol to annotate - requires -k option"), + OPT_STRING('s', "sym-filter", &sym_filter, "pattern", + "only display symbols matchig this pattern"), OPT_BOOLEAN('z', "zero", &zero, "zero history across updates"), OPT_INTEGER('F', "freq", &freq, @@ -1197,7 +734,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) delay_secs = 1; parse_symbols(); - parse_source(sym_filter_entry); /* * Fill in the ones not specifically initialized via -c: diff --git a/trunk/tools/perf/util/callchain.c b/trunk/tools/perf/util/callchain.c index 011473411642..9d3c8141b8c1 100644 --- a/trunk/tools/perf/util/callchain.c +++ b/trunk/tools/perf/util/callchain.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "callchain.h" @@ -27,14 +26,10 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct callchain_node *rnode; - u64 chain_cumul = cumul_hits(chain); while (*p) { - u64 rnode_cumul; - parent = *p; rnode = rb_entry(parent, struct callchain_node, rb_node); - rnode_cumul = cumul_hits(rnode); switch (mode) { case CHAIN_FLAT: @@ -45,7 +40,7 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, break; case CHAIN_GRAPH_ABS: /* Falldown */ case CHAIN_GRAPH_REL: - if (rnode_cumul < chain_cumul) + if (rnode->cumul_hit < chain->cumul_hit) p = &(*p)->rb_left; else p = &(*p)->rb_right; @@ -92,7 +87,7 @@ static void __sort_chain_graph_abs(struct callchain_node *node, chain_for_each_child(child, node) { __sort_chain_graph_abs(child, min_hit); - if (cumul_hits(child) >= min_hit) + if (child->cumul_hit >= min_hit) rb_insert_callchain(&node->rb_root, child, CHAIN_GRAPH_ABS); } @@ -113,11 +108,11 @@ static void __sort_chain_graph_rel(struct callchain_node *node, u64 min_hit; node->rb_root = RB_ROOT; - min_hit = ceil(node->children_hit * min_percent); + min_hit = node->cumul_hit * min_percent / 100.0; chain_for_each_child(child, node) { __sort_chain_graph_rel(child, min_percent); - if (cumul_hits(child) >= min_hit) + if (child->cumul_hit >= min_hit) rb_insert_callchain(&node->rb_root, child, CHAIN_GRAPH_REL); } @@ -127,7 +122,7 @@ static void sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, u64 min_hit __used, struct callchain_param *param) { - __sort_chain_graph_rel(chain_root, param->min_percent / 100.0); + __sort_chain_graph_rel(chain_root, param->min_percent); rb_root->rb_node = chain_root->rb_root.rb_node; } @@ -216,8 +211,7 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain, new = create_child(parent, false); fill_node(new, chain, start, syms); - new->children_hit = 0; - new->hit = 1; + new->cumul_hit = new->hit = 1; } /* @@ -247,8 +241,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, /* split the hits */ new->hit = parent->hit; - new->children_hit = parent->children_hit; - parent->children_hit = cumul_hits(new); + new->cumul_hit = parent->cumul_hit; new->val_nr = parent->val_nr - idx_local; parent->val_nr = idx_local; @@ -256,7 +249,6 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, if (idx_total < chain->nr) { parent->hit = 0; add_child(parent, chain, idx_total, syms); - parent->children_hit++; } else { parent->hit = 1; } @@ -277,13 +269,13 @@ __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, unsigned int ret = __append_chain(rnode, chain, start, syms); if (!ret) - goto inc_children_hit; + goto cumul; } /* nothing in children, add to the current node */ add_child(root, chain, start, syms); -inc_children_hit: - root->children_hit++; +cumul: + root->cumul_hit++; } static int @@ -325,6 +317,8 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, /* we match 100% of the path, increment the hit */ if (i - start == root->val_nr && i == chain->nr) { root->hit++; + root->cumul_hit++; + return 0; } @@ -337,7 +331,5 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, void append_chain(struct callchain_node *root, struct ip_callchain *chain, struct symbol **syms) { - if (!chain->nr) - return; __append_chain_children(root, chain, syms, 0); } diff --git a/trunk/tools/perf/util/callchain.h b/trunk/tools/perf/util/callchain.h index a926ae4f5a16..7812122bea1d 100644 --- a/trunk/tools/perf/util/callchain.h +++ b/trunk/tools/perf/util/callchain.h @@ -7,7 +7,6 @@ #include "symbol.h" enum chain_mode { - CHAIN_NONE, CHAIN_FLAT, CHAIN_GRAPH_ABS, CHAIN_GRAPH_REL @@ -22,7 +21,7 @@ struct callchain_node { struct rb_root rb_root; /* sorted tree of children */ unsigned int val_nr; u64 hit; - u64 children_hit; + u64 cumul_hit; /* hit + hits of children */ }; struct callchain_param; @@ -49,11 +48,6 @@ static inline void callchain_init(struct callchain_node *node) INIT_LIST_HEAD(&node->val); } -static inline u64 cumul_hits(struct callchain_node *node) -{ - return node->hit + node->children_hit; -} - int register_callchain_param(struct callchain_param *param); void append_chain(struct callchain_node *root, struct ip_callchain *chain, struct symbol **syms); diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index b92a457ca32e..450384b3bbe5 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -185,8 +185,6 @@ static void do_read(int fd, void *buf, size_t size) if (ret < 0) die("failed to read"); - if (ret == 0) - die("failed to read: missing data"); size -= ret; buf += ret; @@ -215,10 +213,9 @@ struct perf_header *perf_header__read(int fd) for (i = 0; i < nr_attrs; i++) { struct perf_header_attr *attr; - off_t tmp; + off_t tmp = lseek(fd, 0, SEEK_CUR); do_read(fd, &f_attr, sizeof(f_attr)); - tmp = lseek(fd, 0, SEEK_CUR); attr = perf_header_attr__new(&f_attr.attr); diff --git a/trunk/tools/perf/util/parse-events.c b/trunk/tools/perf/util/parse-events.c index 4858d83b3b67..7bdad8df22a6 100644 --- a/trunk/tools/perf/util/parse-events.c +++ b/trunk/tools/perf/util/parse-events.c @@ -121,29 +121,13 @@ static unsigned long hw_cache_stat[C(MAX)] = { (strcmp(sys_dirent.d_name, ".")) && \ (strcmp(sys_dirent.d_name, ".."))) -static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir) -{ - char evt_path[MAXPATHLEN]; - int fd; - - snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path, - sys_dir->d_name, evt_dir->d_name); - fd = open(evt_path, O_RDONLY); - if (fd < 0) - return -EINVAL; - close(fd); - - return 0; -} - #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next, file, st) \ while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ if (snprintf(file, MAXPATHLEN, "%s/%s/%s", debugfs_path, \ sys_dirent.d_name, evt_dirent.d_name) && \ (!stat(file, &st)) && (S_ISDIR(st.st_mode)) && \ (strcmp(evt_dirent.d_name, ".")) && \ - (strcmp(evt_dirent.d_name, "..")) && \ - (!tp_event_has_id(&sys_dirent, &evt_dirent))) + (strcmp(evt_dirent.d_name, ".."))) #define MAX_EVENT_LENGTH 30 @@ -239,15 +223,9 @@ char *event_name(int counter) { u64 config = attrs[counter].config; int type = attrs[counter].type; - - return __event_name(type, config); -} - -char *__event_name(int type, u64 config) -{ static char buf[32]; - if (type == PERF_TYPE_RAW) { + if (attrs[counter].type == PERF_TYPE_RAW) { sprintf(buf, "raw 0x%llx", config); return buf; } diff --git a/trunk/tools/perf/util/parse-events.h b/trunk/tools/perf/util/parse-events.h index 192a962e3a0f..1ea5d09b6eb1 100644 --- a/trunk/tools/perf/util/parse-events.h +++ b/trunk/tools/perf/util/parse-events.h @@ -10,7 +10,6 @@ extern int nr_counters; extern struct perf_counter_attr attrs[MAX_COUNTERS]; extern char *event_name(int ctr); -extern char *__event_name(int type, u64 config); extern int parse_events(const struct option *opt, const char *str, int unset); diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index f1dcede14307..16ddca202948 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -24,16 +24,6 @@ const char *sym_hist_filter; #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ #endif -enum dso_origin { - DSO__ORIG_KERNEL = 0, - DSO__ORIG_JAVA_JIT, - DSO__ORIG_FEDORA, - DSO__ORIG_UBUNTU, - DSO__ORIG_BUILDID, - DSO__ORIG_DSO, - DSO__ORIG_NOT_FOUND, -}; - static struct symbol *symbol__new(u64 start, u64 len, const char *name, unsigned int priv_size, u64 obj_start, int verbose) @@ -91,7 +81,6 @@ struct dso *dso__new(const char *name, unsigned int sym_priv_size) self->sym_priv_size = sym_priv_size; self->find_symbol = dso__find_symbol; self->slen_calculated = 0; - self->origin = DSO__ORIG_NOT_FOUND; } return self; @@ -721,7 +710,7 @@ static char *dso__read_build_id(struct dso *self, int verbose) ++raw; bid += 2; } - if (verbose >= 2) + if (verbose) printf("%s(%s): %s\n", __func__, self->name, build_id); out_elf_end: elf_end(elf); @@ -731,26 +720,11 @@ static char *dso__read_build_id(struct dso *self, int verbose) return build_id; } -char dso__symtab_origin(const struct dso *self) -{ - static const char origin[] = { - [DSO__ORIG_KERNEL] = 'k', - [DSO__ORIG_JAVA_JIT] = 'j', - [DSO__ORIG_FEDORA] = 'f', - [DSO__ORIG_UBUNTU] = 'u', - [DSO__ORIG_BUILDID] = 'b', - [DSO__ORIG_DSO] = 'd', - }; - - if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) - return '!'; - return origin[self->origin]; -} - int dso__load(struct dso *self, symbol_filter_t filter, int verbose) { int size = PATH_MAX; char *name = malloc(size), *build_id = NULL; + int variant = 0; int ret = -1; int fd; @@ -759,26 +733,19 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose) self->adjust_symbols = 0; - if (strncmp(self->name, "/tmp/perf-", 10) == 0) { - ret = dso__load_perf_map(self, filter, verbose); - self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : - DSO__ORIG_NOT_FOUND; - return ret; - } - - self->origin = DSO__ORIG_FEDORA - 1; + if (strncmp(self->name, "/tmp/perf-", 10) == 0) + return dso__load_perf_map(self, filter, verbose); more: do { - self->origin++; - switch (self->origin) { - case DSO__ORIG_FEDORA: + switch (variant) { + case 0: /* Fedora */ snprintf(name, size, "/usr/lib/debug%s.debug", self->name); break; - case DSO__ORIG_UBUNTU: + case 1: /* Ubuntu */ snprintf(name, size, "/usr/lib/debug%s", self->name); break; - case DSO__ORIG_BUILDID: + case 2: build_id = dso__read_build_id(self, verbose); if (build_id != NULL) { snprintf(name, size, @@ -787,15 +754,16 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose) free(build_id); break; } - self->origin++; + variant++; /* Fall thru */ - case DSO__ORIG_DSO: + case 3: /* Sane people */ snprintf(name, size, "%s", self->name); break; default: goto out; } + variant++; fd = open(name, O_RDONLY); } while (fd < 0); @@ -931,9 +899,6 @@ int dso__load_kernel(struct dso *self, const char *vmlinux, if (err <= 0) err = dso__load_kallsyms(self, filter, verbose); - if (err > 0) - self->origin = DSO__ORIG_KERNEL; - return err; } diff --git a/trunk/tools/perf/util/symbol.h b/trunk/tools/perf/util/symbol.h index 1e003ec2f4b1..2f92b21c712d 100644 --- a/trunk/tools/perf/util/symbol.h +++ b/trunk/tools/perf/util/symbol.h @@ -26,7 +26,6 @@ struct dso { unsigned int sym_priv_size; unsigned char adjust_symbols; unsigned char slen_calculated; - unsigned char origin; char name[0]; }; @@ -50,7 +49,6 @@ int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose); int dso__load(struct dso *self, symbol_filter_t filter, int verbose); size_t dso__fprintf(struct dso *self, FILE *fp); -char dso__symtab_origin(const struct dso *self); void symbol__init(void); #endif /* _PERF_SYMBOL_ */ diff --git a/trunk/virt/kvm/ioapic.c b/trunk/virt/kvm/ioapic.c index 1150c6d5c7b8..1eddae94bab3 100644 --- a/trunk/virt/kvm/ioapic.c +++ b/trunk/virt/kvm/ioapic.c @@ -95,6 +95,8 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) pent->fields.remote_irr = 1; } + if (!pent->fields.trig_mode) + ioapic->irr &= ~(1 << idx); return injected; } @@ -134,8 +136,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) mask_after = ioapic->redirtbl[index].fields.mask; if (mask_before != mask_after) kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after); - if (ioapic->redirtbl[index].fields.trig_mode == IOAPIC_LEVEL_TRIG - && ioapic->irr & (1 << index)) + if (ioapic->irr & (1 << index)) ioapic_service(ioapic, index); break; } @@ -183,10 +184,9 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) if (!level) ioapic->irr &= ~mask; else { - int edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG); ioapic->irr |= mask; - if ((edge && old_irr != ioapic->irr) || - (!edge && !entry.fields.remote_irr)) + if ((!entry.fields.trig_mode && old_irr != ioapic->irr) + || !entry.fields.remote_irr) ret = ioapic_service(ioapic, irq); } } diff --git a/trunk/virt/kvm/irq_comm.c b/trunk/virt/kvm/irq_comm.c index ddc17f0e2f35..a8bd466d00cc 100644 --- a/trunk/virt/kvm/irq_comm.c +++ b/trunk/virt/kvm/irq_comm.c @@ -160,8 +160,7 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) unsigned gsi = pin; list_for_each_entry(e, &kvm->irq_routing, link) - if (e->type == KVM_IRQ_ROUTING_IRQCHIP && - e->irqchip.irqchip == irqchip && + if (e->irqchip.irqchip == irqchip && e->irqchip.pin == pin) { gsi = e->gsi; break; @@ -260,7 +259,6 @@ static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e, int delta; e->gsi = ue->gsi; - e->type = ue->type; switch (ue->type) { case KVM_IRQ_ROUTING_IRQCHIP: delta = 0;