From e7fd19b35b7eb4f635636e176b8a5a39ffea581b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 21 Jun 2012 14:07:16 +0200 Subject: [PATCH] --- yaml --- r: 312300 b: refs/heads/master c: c9fc3f778a6a215ace14ee556067c73982b6d40f h: refs/heads/master v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-block-rssd | 21 + trunk/Documentation/device-mapper/verity.txt | 131 +- trunk/Documentation/prctl/no_new_privs.txt | 50 - trunk/MAINTAINERS | 4 +- trunk/arch/arm/kernel/vmlinux.lds.S | 2 - trunk/arch/arm/mm/mmu.c | 74 - trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +- trunk/arch/powerpc/xmon/xmon.c | 2 +- trunk/arch/x86/include/asm/msr.h | 46 +- trunk/arch/x86/include/asm/paravirt.h | 41 +- trunk/arch/x86/include/asm/paravirt_types.h | 2 + trunk/arch/x86/include/asm/uprobes.h | 2 +- trunk/arch/x86/kernel/cpu/Makefile | 4 +- trunk/arch/x86/kernel/cpu/amd.c | 39 +- trunk/arch/x86/kernel/cpu/common.c | 2 +- trunk/arch/x86/kernel/cpu/perf_event.c | 32 +- trunk/arch/x86/kernel/cpu/perf_event.h | 17 +- trunk/arch/x86/kernel/cpu/perf_event_intel.c | 8 +- .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 8 +- .../x86/kernel/cpu/perf_event_intel_uncore.c | 1703 ----------------- .../x86/kernel/cpu/perf_event_intel_uncore.h | 406 ---- trunk/arch/x86/kernel/cpu/perf_event_p4.c | 14 +- trunk/arch/x86/kernel/cpu/perf_event_p6.c | 4 +- trunk/arch/x86/kernel/microcode_core.c | 26 +- trunk/arch/x86/kernel/paravirt.c | 2 + trunk/arch/x86/kernel/process_64.c | 4 +- trunk/arch/x86/kernel/uprobes.c | 3 +- trunk/arch/x86/lib/msr-reg-export.c | 4 +- trunk/arch/x86/lib/msr-reg.S | 10 +- trunk/arch/x86/vdso/vdso32-setup.c | 6 +- trunk/arch/x86/xen/enlighten.c | 2 + trunk/block/blk-cgroup.c | 9 +- trunk/block/blk-core.c | 25 +- trunk/block/blk-timeout.c | 41 + trunk/block/cfq-iosched.c | 30 +- trunk/block/scsi_ioctl.c | 5 +- trunk/drivers/block/drbd/drbd_bitmap.c | 11 +- trunk/drivers/block/drbd/drbd_req.c | 66 +- trunk/drivers/block/floppy.c | 1 - trunk/drivers/block/mtip32xx/mtip32xx.c | 166 +- trunk/drivers/block/mtip32xx/mtip32xx.h | 5 +- trunk/drivers/block/umem.c | 40 - trunk/drivers/block/xen-blkback/common.h | 2 - trunk/drivers/block/xen-blkfront.c | 58 +- trunk/drivers/clk/clk.c | 28 +- trunk/drivers/gpu/drm/drm_edid.c | 27 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 37 +- trunk/drivers/gpu/drm/radeon/radeon_gart.c | 13 +- trunk/drivers/gpu/drm/radeon/radeon_gem.c | 10 +- trunk/drivers/gpu/drm/radeon/si.c | 4 +- trunk/drivers/md/dm-thin.c | 7 - trunk/drivers/md/md.c | 8 +- trunk/drivers/md/multipath.c | 3 +- .../md/persistent-data/dm-space-map-checker.c | 54 +- .../md/persistent-data/dm-space-map-disk.c | 11 +- .../persistent-data/dm-transaction-manager.c | 11 +- trunk/drivers/md/raid1.c | 13 +- trunk/drivers/md/raid10.c | 26 +- trunk/drivers/md/raid5.c | 67 +- .../drivers/net/ethernet/freescale/gianfar.c | 10 +- .../net/ethernet/intel/e1000e/defines.h | 1 - .../net/ethernet/intel/e1000e/netdev.c | 75 +- .../net/ethernet/intel/igbvf/ethtool.c | 29 +- trunk/drivers/net/ethernet/ti/davinci_cpdma.c | 1 - trunk/drivers/net/usb/qmi_wwan.c | 4 - trunk/drivers/net/wireless/ath/ath.h | 1 - trunk/drivers/net/wireless/ath/ath9k/hw.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 7 +- trunk/drivers/net/wireless/ath/key.c | 4 - .../net/wireless/iwlwifi/iwl-mac80211.c | 12 - .../net/wireless/mwifiex/11n_rxreorder.c | 5 +- .../net/wireless/mwifiex/11n_rxreorder.h | 7 - trunk/drivers/net/wireless/mwifiex/ie.c | 1 - trunk/drivers/net/wireless/mwifiex/sdio.c | 6 +- .../drivers/net/wireless/mwifiex/sta_event.c | 9 +- trunk/drivers/net/wireless/mwifiex/usb.c | 28 +- trunk/drivers/net/wireless/mwifiex/wmm.c | 3 - .../net/wireless/rtlwifi/rtl8192cu/sw.c | 3 - trunk/drivers/net/wireless/ti/wlcore/Kconfig | 1 + trunk/fs/splice.c | 35 +- trunk/include/linux/blkdev.h | 1 + trunk/include/linux/ftrace_event.h | 3 - trunk/include/linux/pci_ids.h | 11 - trunk/include/linux/perf_event.h | 3 - trunk/include/linux/sched.h | 1 + trunk/include/linux/splice.h | 8 +- trunk/include/net/sctp/structs.h | 4 - trunk/include/net/sctp/tsnmap.h | 3 +- trunk/kernel/events/core.c | 49 +- trunk/kernel/events/uprobes.c | 461 ++--- trunk/kernel/relay.c | 5 +- trunk/kernel/trace/ftrace.c | 8 +- trunk/kernel/trace/trace.c | 6 +- trunk/kernel/trace/trace_output.c | 2 +- trunk/mm/shmem.c | 3 +- trunk/net/core/dev.c | 4 +- trunk/net/core/skbuff.c | 1 - trunk/net/mac80211/mlme.c | 13 +- trunk/net/mac80211/rx.c | 5 +- trunk/net/netfilter/ipset/ip_set_core.c | 12 - .../netfilter/ipset/ip_set_hash_netiface.c | 32 +- trunk/net/netfilter/ipvs/ip_vs_ctl.c | 14 +- trunk/net/netfilter/nfnetlink.c | 4 +- trunk/net/nfc/nci/ntf.c | 10 +- trunk/net/nfc/rawsock.c | 5 +- trunk/net/sctp/associola.c | 1 - trunk/net/sctp/output.c | 5 - trunk/net/sctp/sm_make_chunk.c | 16 - trunk/net/sctp/sm_sideeffect.c | 2 +- trunk/net/sctp/transport.c | 2 - trunk/net/sctp/tsnmap.c | 6 +- trunk/net/sctp/ulpevent.c | 3 +- trunk/net/sctp/ulpqueue.c | 2 +- trunk/security/security.c | 1 - trunk/sound/pci/hda/patch_realtek.c | 28 - trunk/sound/soc/codecs/tlv320aic3x.c | 4 +- trunk/sound/soc/codecs/tlv320aic3x.h | 1 - trunk/sound/soc/codecs/wm2200.c | 1 - trunk/tools/perf/Documentation/perf-bench.txt | 78 +- .../tools/perf/Documentation/perf-report.txt | 2 +- trunk/tools/perf/Documentation/perf-top.txt | 2 +- trunk/tools/perf/Makefile | 8 +- trunk/tools/perf/bench/mem-memcpy.c | 4 +- trunk/tools/perf/bench/mem-memset.c | 8 +- trunk/tools/perf/builtin-bench.c | 4 +- trunk/tools/perf/builtin-evlist.c | 2 +- trunk/tools/perf/builtin-kmem.c | 37 +- trunk/tools/perf/builtin-lock.c | 4 +- trunk/tools/perf/builtin-record.c | 4 +- trunk/tools/perf/builtin-report.c | 16 +- trunk/tools/perf/builtin-sched.c | 38 +- trunk/tools/perf/builtin-script.c | 106 +- trunk/tools/perf/builtin-stat.c | 12 +- trunk/tools/perf/builtin-test.c | 2 +- trunk/tools/perf/builtin-top.c | 12 +- trunk/tools/perf/config/feature-tests.mak | 13 - trunk/tools/perf/ui/browsers/annotate.c | 4 +- trunk/tools/perf/ui/browsers/hists.c | 210 +- trunk/tools/perf/ui/gtk/browser.c | 69 +- trunk/tools/perf/ui/gtk/gtk.h | 31 - trunk/tools/perf/ui/gtk/setup.c | 5 - trunk/tools/perf/ui/gtk/util.c | 129 -- trunk/tools/perf/ui/tui/setup.c | 6 - trunk/tools/perf/ui/tui/util.c | 243 --- trunk/tools/perf/ui/util.c | 277 ++- trunk/tools/perf/ui/util.h | 9 +- trunk/tools/perf/util/debug.c | 2 +- trunk/tools/perf/util/debug.h | 23 +- trunk/tools/perf/util/evlist.c | 4 +- trunk/tools/perf/util/evlist.h | 3 - trunk/tools/perf/util/evsel.c | 197 +- trunk/tools/perf/util/evsel.h | 15 +- trunk/tools/perf/util/header.c | 33 +- trunk/tools/perf/util/hist.h | 1 - trunk/tools/perf/util/map.h | 2 +- trunk/tools/perf/util/parse-events-test.c | 131 +- trunk/tools/perf/util/parse-events.c | 274 ++- trunk/tools/perf/util/parse-events.h | 17 +- trunk/tools/perf/util/parse-events.l | 129 +- trunk/tools/perf/util/parse-events.y | 71 +- trunk/tools/perf/util/pmu.c | 166 -- trunk/tools/perf/util/pmu.h | 11 +- .../util/scripting-engines/trace-event-perl.c | 28 +- .../scripting-engines/trace-event-python.c | 21 +- trunk/tools/perf/util/session.c | 65 +- trunk/tools/perf/util/session.h | 14 +- trunk/tools/perf/util/sort.c | 49 - trunk/tools/perf/util/sort.h | 2 - trunk/tools/perf/util/string.c | 22 - trunk/tools/perf/util/symbol.c | 65 +- trunk/tools/perf/util/symbol.h | 1 - trunk/tools/perf/util/top.c | 2 +- trunk/tools/perf/util/trace-event-parse.c | 58 +- trunk/tools/perf/util/trace-event-read.c | 97 +- trunk/tools/perf/util/trace-event-scripting.c | 7 +- trunk/tools/perf/util/trace-event.h | 38 +- trunk/tools/perf/util/util.h | 2 - 178 files changed, 1757 insertions(+), 5563 deletions(-) delete mode 100644 trunk/Documentation/prctl/no_new_privs.txt delete mode 100644 trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c delete mode 100644 trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h delete mode 100644 trunk/tools/perf/ui/gtk/util.c delete mode 100644 trunk/tools/perf/ui/tui/util.c diff --git a/[refs] b/[refs] index 82a126cdf8ec..7d3c29bf321d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b0338e99b2a775c157e3e795f49fdcfb6c257f7a +refs/heads/master: c9fc3f778a6a215ace14ee556067c73982b6d40f diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd index beef30c046b0..679ce3543122 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ b/trunk/Documentation/ABI/testing/sysfs-block-rssd @@ -1,5 +1,26 @@ +What: /sys/block/rssd*/registers +Date: March 2012 +KernelVersion: 3.3 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps below driver information and + hardware registers. + - S ACTive + - Command Issue + - Completed + - PORT IRQ STAT + - HOST IRQ STAT + - Allocated + - Commands in Q + What: /sys/block/rssd*/status Date: April 2012 KernelVersion: 3.4 Contact: Asai Thambi S P Description: This is a read-only file. Indicates the status of the device. + +What: /sys/block/rssd*/flags +Date: May 2012 +KernelVersion: 3.5 +Contact: Asai Thambi S P +Description: This is a read-only file. Dumps the flags in port and driver + data structure diff --git a/trunk/Documentation/device-mapper/verity.txt b/trunk/Documentation/device-mapper/verity.txt index 9884681535ee..32e48797a14f 100644 --- a/trunk/Documentation/device-mapper/verity.txt +++ b/trunk/Documentation/device-mapper/verity.txt @@ -7,39 +7,39 @@ This target is read-only. Construction Parameters ======================= - + - This is the type of the on-disk hash format. + This is the version number of the on-disk format. 0 is the original format used in the Chromium OS. - The salt is appended when hashing, digests are stored continuously and - the rest of the block is padded with zeros. + The salt is appended when hashing, digests are stored continuously and + the rest of the block is padded with zeros. 1 is the current format that should be used for new devices. - The salt is prepended when hashing and each digest is - padded with zeros to the power of two. + The salt is prepended when hashing and each digest is + padded with zeros to the power of two. - This is the device containing data, the integrity of which needs to be + This is the device containing the data the integrity of which needs to be checked. It may be specified as a path, like /dev/sdaX, or a device number, :. - This is the device that supplies the hash tree data. It may be + This is the device that that supplies the hash tree data. It may be specified similarly to the device path and may be the same device. If the - same device is used, the hash_start should be outside the configured - dm-verity device. + same device is used, the hash_start should be outside of the dm-verity + configured device size. - The block size on a data device in bytes. - Each block corresponds to one digest on the hash device. + The block size on a data device. Each block corresponds to one digest on + the hash device. - The size of a hash block in bytes. + The size of a hash block. The number of data blocks on the data device. Additional blocks are @@ -65,7 +65,7 @@ Construction Parameters Theory of operation =================== -dm-verity is meant to be set up as part of a verified boot path. This +dm-verity is meant to be setup as part of a verified boot path. This may be anything ranging from a boot using tboot or trustedgrub to just booting from a known-good device (like a USB drive or CD). @@ -73,20 +73,20 @@ When a dm-verity device is configured, it is expected that the caller has been authenticated in some way (cryptographic signatures, etc). After instantiation, all hashes will be verified on-demand during disk access. If they cannot be verified up to the root node of the -tree, the root hash, then the I/O will fail. This should detect +tree, the root hash, then the I/O will fail. This should identify tampering with any data on the device and the hash data. Cryptographic hashes are used to assert the integrity of the device on a -per-block basis. This allows for a lightweight hash computation on first read -into the page cache. Block hashes are stored linearly, aligned to the nearest -block size. +per-block basis. This allows for a lightweight hash computation on first read +into the page cache. Block hashes are stored linearly-aligned to the nearest +block the size of a page. Hash Tree --------- Each node in the tree is a cryptographic hash. If it is a leaf node, the hash -of some data block on disk is calculated. If it is an intermediary node, -the hash of a number of child nodes is calculated. +is of some block data on disk. If it is an intermediary node, then the hash is +of a number of child nodes. Each entry in the tree is a collection of neighboring nodes that fit in one block. The number is determined based on block_size and the size of the @@ -110,23 +110,63 @@ alg = sha256, num_blocks = 32768, block_size = 4096 On-disk format ============== -The verity kernel code does not read the verity metadata on-disk header. -It only reads the hash blocks which directly follow the header. -It is expected that a user-space tool will verify the integrity of the -verity header. +Below is the recommended on-disk format. The verity kernel code does not +read the on-disk header. It only reads the hash blocks which directly +follow the header. It is expected that a user-space tool will verify the +integrity of the verity_header and then call dmsetup with the correct +parameters. Alternatively, the header can be omitted and the dmsetup +parameters can be passed via the kernel command-line in a rooted chain +of trust where the command-line is verified. -Alternatively, the header can be omitted and the dmsetup parameters can -be passed via the kernel command-line in a rooted chain of trust where -the command-line is verified. +The on-disk format is especially useful in cases where the hash blocks +are on a separate partition. The magic number allows easy identification +of the partition contents. Alternatively, the hash blocks can be stored +in the same partition as the data to be verified. In such a configuration +the filesystem on the partition would be sized a little smaller than +the full-partition, leaving room for the hash blocks. + +struct superblock { + uint8_t signature[8] + "verity\0\0"; + + uint8_t version; + 1 - current format + + uint8_t data_block_bits; + log2(data block size) + + uint8_t hash_block_bits; + log2(hash block size) + + uint8_t pad1[1]; + zero padding + + uint16_t salt_size; + big-endian salt size + + uint8_t pad2[2]; + zero padding + + uint32_t data_blocks_hi; + big-endian high 32 bits of the 64-bit number of data blocks + + uint32_t data_blocks_lo; + big-endian low 32 bits of the 64-bit number of data blocks + + uint8_t algorithm[16]; + cryptographic algorithm + + uint8_t salt[384]; + salt (the salt size is specified above) + + uint8_t pad3[88]; + zero padding to 512-byte boundary +} Directly following the header (and with sector number padded to the next hash block boundary) are the hash blocks which are stored a depth at a time (starting from the root), sorted in order of increasing index. -The full specification of kernel parameters and on-disk metadata format -is available at the cryptsetup project's wiki page - http://code.google.com/p/cryptsetup/wiki/DMVerity - Status ====== V (for Valid) is returned if every check performed so far was valid. @@ -134,22 +174,21 @@ If any check failed, C (for Corruption) is returned. Example ======= -Set up a device: - # dmsetup create vroot --readonly --table \ - "0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\ + +Setup a device: + dmsetup create vroot --table \ + "0 2097152 "\ + "verity 1 /dev/sda1 /dev/sda2 4096 4096 2097152 1 "\ "4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\ "1234000000000000000000000000000000000000000000000000000000000000" A command line tool veritysetup is available to compute or verify -the hash tree or activate the kernel device. This is available from -the cryptsetup upstream repository http://code.google.com/p/cryptsetup/ -(as a libcryptsetup extension). - -Create hash on the device: - # veritysetup format /dev/sda1 /dev/sda2 - ... - Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 - -Activate the device: - # veritysetup create vroot /dev/sda1 /dev/sda2 \ - 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 +the hash tree or activate the kernel driver. This is available from +the LVM2 upstream repository and may be supplied as a package called +device-mapper-verity-tools: + git://sources.redhat.com/git/lvm2 + http://sourceware.org/git/?p=lvm2.git + http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/verity?cvsroot=lvm2 + +veritysetup -a vroot /dev/sda1 /dev/sda2 \ + 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 diff --git a/trunk/Documentation/prctl/no_new_privs.txt b/trunk/Documentation/prctl/no_new_privs.txt deleted file mode 100644 index cb705ec69abe..000000000000 --- a/trunk/Documentation/prctl/no_new_privs.txt +++ /dev/null @@ -1,50 +0,0 @@ -The execve system call can grant a newly-started program privileges that -its parent did not have. The most obvious examples are setuid/setgid -programs and file capabilities. To prevent the parent program from -gaining these privileges as well, the kernel and user code must be -careful to prevent the parent from doing anything that could subvert the -child. For example: - - - The dynamic loader handles LD_* environment variables differently if - a program is setuid. - - - chroot is disallowed to unprivileged processes, since it would allow - /etc/passwd to be replaced from the point of view of a process that - inherited chroot. - - - The exec code has special handling for ptrace. - -These are all ad-hoc fixes. The no_new_privs bit (since Linux 3.5) is a -new, generic mechanism to make it safe for a process to modify its -execution environment in a manner that persists across execve. Any task -can set no_new_privs. Once the bit is set, it is inherited across fork, -clone, and execve and cannot be unset. With no_new_privs set, execve -promises not to grant the privilege to do anything that could not have -been done without the execve call. For example, the setuid and setgid -bits will no longer change the uid or gid; file capabilities will not -add to the permitted set, and LSMs will not relax constraints after -execve. - -Note that no_new_privs does not prevent privilege changes that do not -involve execve. An appropriately privileged task can still call -setuid(2) and receive SCM_RIGHTS datagrams. - -There are two main use cases for no_new_privs so far: - - - Filters installed for the seccomp mode 2 sandbox persist across - execve and can change the behavior of newly-executed programs. - Unprivileged users are therefore only allowed to install such filters - if no_new_privs is set. - - - By itself, no_new_privs can be used to reduce the attack surface - available to an unprivileged user. If everything running with a - given uid has no_new_privs set, then that uid will be unable to - escalate its privileges by directly attacking setuid, setgid, and - fcap-using binaries; it will need to compromise something without the - no_new_privs bit set first. - -In the future, other potentially dangerous kernel features could become -available to unprivileged tasks if no_new_privs is set. In principle, -several options to unshare(2) and clone(2) would be safe when -no_new_privs is set, and no_new_privs + chroot is considerable less -dangerous than chroot by itself. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 03df1d15ebf3..eb22272b2116 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4654,8 +4654,8 @@ L: netfilter@vger.kernel.org L: coreteam@netfilter.org W: http://www.netfilter.org/ W: http://www.iptables.org/ -T: git git://1984.lsi.us.es/nf -T: git git://1984.lsi.us.es/nf-next +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git S: Supported F: include/linux/netfilter* F: include/linux/netfilter/ diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 36ff15bbfdd4..43a31fb06318 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -183,9 +183,7 @@ SECTIONS } #endif -#ifdef CONFIG_SMP PERCPU_SECTION(L1_CACHE_BYTES) -#endif #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index cf4528d51774..e5dad60b558b 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -791,79 +791,6 @@ void __init iotable_init(struct map_desc *io_desc, int nr) } } -#ifndef CONFIG_ARM_LPAE - -/* - * The Linux PMD is made of two consecutive section entries covering 2MB - * (see definition in include/asm/pgtable-2level.h). However a call to - * create_mapping() may optimize static mappings by using individual - * 1MB section mappings. This leaves the actual PMD potentially half - * initialized if the top or bottom section entry isn't used, leaving it - * open to problems if a subsequent ioremap() or vmalloc() tries to use - * the virtual space left free by that unused section entry. - * - * Let's avoid the issue by inserting dummy vm entries covering the unused - * PMD halves once the static mappings are in place. - */ - -static void __init pmd_empty_section_gap(unsigned long addr) -{ - struct vm_struct *vm; - - vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm)); - vm->addr = (void *)addr; - vm->size = SECTION_SIZE; - vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; - vm->caller = pmd_empty_section_gap; - vm_area_add_early(vm); -} - -static void __init fill_pmd_gaps(void) -{ - struct vm_struct *vm; - unsigned long addr, next = 0; - pmd_t *pmd; - - /* we're still single threaded hence no lock needed here */ - for (vm = vmlist; vm; vm = vm->next) { - if (!(vm->flags & VM_ARM_STATIC_MAPPING)) - continue; - addr = (unsigned long)vm->addr; - if (addr < next) - continue; - - /* - * Check if this vm starts on an odd section boundary. - * If so and the first section entry for this PMD is free - * then we block the corresponding virtual address. - */ - if ((addr & ~PMD_MASK) == SECTION_SIZE) { - pmd = pmd_off_k(addr); - if (pmd_none(*pmd)) - pmd_empty_section_gap(addr & PMD_MASK); - } - - /* - * Then check if this vm ends on an odd section boundary. - * If so and the second section entry for this PMD is empty - * then we block the corresponding virtual address. - */ - addr += vm->size; - if ((addr & ~PMD_MASK) == SECTION_SIZE) { - pmd = pmd_off_k(addr) + 1; - if (pmd_none(*pmd)) - pmd_empty_section_gap(addr); - } - - /* no need to look at any vm entry until we hit the next PMD */ - next = (addr + PMD_SIZE - 1) & PMD_MASK; - } -} - -#else -#define fill_pmd_gaps() do { } while (0) -#endif - static void * __initdata vmalloc_min = (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET); @@ -1145,7 +1072,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc) */ if (mdesc->map_io) mdesc->map_io(); - fill_pmd_gaps(); /* * Finally flush the caches and tlb to ensure that we're in a diff --git a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S index a1044f43becd..a84aafce2a12 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -810,7 +810,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) lwz r3,VCORE_NAPPING_THREADS(r5) lwz r4,VCPU_PTID(r9) li r0,1 - sld r0,r0,r4 + sldi r0,r0,r4 andc. r3,r3,r0 /* no sense IPI'ing ourselves */ beq 43f mulli r4,r4,PACA_SIZE /* get paca for thread 0 */ diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index eab3492a45c5..0f3ab06d2222 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -971,7 +971,7 @@ static int cpu_cmd(void) /* print cpus waiting or in xmon */ printf("cpus stopped:"); count = 0; - for_each_possible_cpu(cpu) { + for (cpu = 0; cpu < NR_CPUS; ++cpu) { if (cpumask_test_cpu(cpu, &cpus_in_xmon)) { if (count == 0) printf(" %x", cpu); diff --git a/trunk/arch/x86/include/asm/msr.h b/trunk/arch/x86/include/asm/msr.h index 813ed103f45e..084ef95274cd 100644 --- a/trunk/arch/x86/include/asm/msr.h +++ b/trunk/arch/x86/include/asm/msr.h @@ -115,8 +115,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr, extern unsigned long long native_read_tsc(void); -extern int rdmsr_safe_regs(u32 regs[8]); -extern int wrmsr_safe_regs(u32 regs[8]); +extern int native_rdmsr_safe_regs(u32 regs[8]); +extern int native_wrmsr_safe_regs(u32 regs[8]); static __always_inline unsigned long long __native_read_tsc(void) { @@ -187,6 +187,43 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = native_rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return native_wrmsr_safe_regs(gprs); +} + +static inline int rdmsr_safe_regs(u32 regs[8]) +{ + return native_rdmsr_safe_regs(regs); +} + +static inline int wrmsr_safe_regs(u32 regs[8]) +{ + return native_wrmsr_safe_regs(regs); +} + #define rdtscl(low) \ ((low) = (u32)__native_read_tsc()) @@ -200,8 +237,6 @@ do { \ (high) = (u32)(_l >> 32); \ } while (0) -#define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) - #define rdtscp(low, high, aux) \ do { \ unsigned long long _val = native_read_tscp(&(aux)); \ @@ -213,7 +248,8 @@ do { \ #endif /* !CONFIG_PARAVIRT */ -#define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \ + +#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ (u32)((val) >> 32)) #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index 0b47ddb6f00b..6cbbabf52707 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -128,11 +128,21 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); } +static inline int paravirt_rdmsr_regs(u32 *regs) +{ + return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs); +} + static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) { return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); } +static inline int paravirt_wrmsr_regs(u32 *regs) +{ + return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs); +} + /* These should all do BUG_ON(_err), but our headers are too tangled. */ #define rdmsr(msr, val1, val2) \ do { \ @@ -166,6 +176,9 @@ do { \ _err; \ }) +#define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs) +#define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs) + static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) { int err; @@ -173,6 +186,32 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) *p = paravirt_read_msr(msr, &err); return err; } +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = paravirt_rdmsr_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return paravirt_wrmsr_regs(gprs); +} static inline u64 paravirt_read_tsc(void) { @@ -213,8 +252,6 @@ do { \ high = _l >> 32; \ } while (0) -#define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter)) - static inline unsigned long long paravirt_rdtscp(unsigned int *aux) { return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); diff --git a/trunk/arch/x86/include/asm/paravirt_types.h b/trunk/arch/x86/include/asm/paravirt_types.h index 8613cbb7ba41..8e8b9a4987ee 100644 --- a/trunk/arch/x86/include/asm/paravirt_types.h +++ b/trunk/arch/x86/include/asm/paravirt_types.h @@ -153,7 +153,9 @@ struct pv_cpu_ops { /* MSR, PMC and TSR operations. err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ u64 (*read_msr)(unsigned int msr, int *err); + int (*rdmsr_regs)(u32 *regs); int (*write_msr)(unsigned int msr, unsigned low, unsigned high); + int (*wrmsr_regs)(u32 *regs); u64 (*read_tsc)(void); u64 (*read_pmc)(int counter); diff --git a/trunk/arch/x86/include/asm/uprobes.h b/trunk/arch/x86/include/asm/uprobes.h index f3971bbcd1de..1e9bed14f7ae 100644 --- a/trunk/arch/x86/include/asm/uprobes.h +++ b/trunk/arch/x86/include/asm/uprobes.h @@ -48,7 +48,7 @@ struct arch_uprobe_task { #endif }; -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); +extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm); extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); diff --git a/trunk/arch/x86/kernel/cpu/Makefile b/trunk/arch/x86/kernel/cpu/Makefile index bac4c3804cc7..6ab6aa2fdfdd 100644 --- a/trunk/arch/x86/kernel/cpu/Makefile +++ b/trunk/arch/x86/kernel/cpu/Makefile @@ -32,9 +32,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o ifdef CONFIG_PERF_EVENTS obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o endif obj-$(CONFIG_X86_MCE) += mcheck/ diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 9d92e19039f0..146bb6218eec 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -19,39 +19,6 @@ #include "cpu.h" -static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) -{ - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - u32 gprs[8] = { 0 }; - int err; - - WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); - - gprs[1] = msr; - gprs[7] = 0x9c5a203a; - - err = rdmsr_safe_regs(gprs); - - *p = gprs[0] | ((u64)gprs[2] << 32); - - return err; -} - -static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) -{ - struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); - u32 gprs[8] = { 0 }; - - WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); - - gprs[0] = (u32)val; - gprs[1] = msr; - gprs[2] = val >> 32; - gprs[7] = 0x9c5a203a; - - return wrmsr_safe_regs(gprs); -} - #ifdef CONFIG_X86_32 /* * B step AMD K6 before B 9730xxxx have hardware bugs that can cause @@ -619,9 +586,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) !cpu_has(c, X86_FEATURE_TOPOEXT)) { u64 val; - if (!rdmsrl_safe(0xc0011005, &val)) { + if (!rdmsrl_amd_safe(0xc0011005, &val)) { val |= 1ULL << 54; - wrmsrl_safe(0xc0011005, val); + wrmsrl_amd_safe(0xc0011005, val); rdmsrl(0xc0011005, val); if (val & (1ULL << 54)) { set_cpu_cap(c, X86_FEATURE_TOPOEXT); @@ -712,7 +679,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); if (err == 0) { mask |= (1 << 10); - wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask); + checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); } } diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index 5bbc082c47ad..6b9333b429ba 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -947,7 +947,7 @@ static void __cpuinit __print_cpu_msr(void) index_max = msr_range_array[i].max; for (index = index_min; index < index_max; index++) { - if (rdmsrl_safe(index, &val)) + if (rdmsrl_amd_safe(index, &val)) continue; printk(KERN_INFO " MSR%08x: %016llx\n", index, val); } diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index e677d9923f4f..c4706cf9c011 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -35,6 +35,17 @@ #include "perf_event.h" +#if 0 +#undef wrmsrl +#define wrmsrl(msr, val) \ +do { \ + trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\ + (unsigned long)(val)); \ + native_write_msr((msr), (u32)((u64)(val)), \ + (u32)((u64)(val) >> 32)); \ +} while (0) +#endif + struct x86_pmu x86_pmu __read_mostly; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { @@ -75,7 +86,7 @@ u64 x86_perf_event_update(struct perf_event *event) */ again: prev_raw_count = local64_read(&hwc->prev_count); - rdpmcl(hwc->event_base_rdpmc, new_raw_count); + rdmsrl(hwc->event_base, new_raw_count); if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, new_raw_count) != prev_raw_count) @@ -211,7 +222,7 @@ static bool check_hw_exists(void) * that don't trap on the MSR access and always return 0s. */ val = 0xabcdUL; - ret = wrmsrl_safe(x86_pmu_event_addr(0), val); + ret = checking_wrmsrl(x86_pmu_event_addr(0), val); ret |= rdmsrl_safe(x86_pmu_event_addr(0), &val_new); if (ret || val != val_new) goto msr_fail; @@ -626,7 +637,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) c = sched->constraints[sched->state.event]; /* Prefer fixed purpose counters */ - if (c->idxmsk64 & (~0ULL << X86_PMC_IDX_FIXED)) { + if (x86_pmu.num_counters_fixed) { idx = X86_PMC_IDX_FIXED; for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { if (!__test_and_set_bit(idx, sched->state.used)) @@ -693,8 +704,8 @@ static bool perf_sched_next_event(struct perf_sched *sched) /* * Assign a counter for each event. */ -int perf_assign_events(struct event_constraint **constraints, int n, - int wmin, int wmax, int *assign) +static int perf_assign_events(struct event_constraint **constraints, int n, + int wmin, int wmax, int *assign) { struct perf_sched sched; @@ -819,11 +830,9 @@ static inline void x86_assign_hw_event(struct perf_event *event, } else if (hwc->idx >= X86_PMC_IDX_FIXED) { hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); - hwc->event_base_rdpmc = (hwc->idx - X86_PMC_IDX_FIXED) | 1<<30; } else { hwc->config_base = x86_pmu_config_addr(hwc->idx); hwc->event_base = x86_pmu_event_addr(hwc->idx); - hwc->event_base_rdpmc = hwc->idx; } } @@ -1640,12 +1649,7 @@ static ssize_t set_attr_rdpmc(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long val; - ssize_t ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; + unsigned long val = simple_strtoul(buf, NULL, 0); if (!!val != !!x86_pmu.attr_rdpmc) { x86_pmu.attr_rdpmc = !!val; @@ -1859,7 +1863,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) else misc |= PERF_RECORD_MISC_GUEST_KERNEL; } else { - if (!kernel_ip(regs->ip)) + if (user_mode(regs)) misc |= PERF_RECORD_MISC_USER; else misc |= PERF_RECORD_MISC_KERNEL; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.h b/trunk/arch/x86/kernel/cpu/perf_event.h index 83238f2a12b2..7241e2fc3c17 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.h +++ b/trunk/arch/x86/kernel/cpu/perf_event.h @@ -14,18 +14,6 @@ #include -#if 0 -#undef wrmsrl -#define wrmsrl(msr, val) \ -do { \ - unsigned int _msr = (msr); \ - u64 _val = (val); \ - trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \ - (unsigned long long)(_val)); \ - native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \ -} while (0) -#endif - /* * | NHM/WSM | SNB | * register ------------------------------- @@ -69,7 +57,7 @@ struct amd_nb { }; /* The maximal number of PEBS events: */ -#define MAX_PEBS_EVENTS 8 +#define MAX_PEBS_EVENTS 4 /* * A debug store configuration. @@ -378,7 +366,6 @@ struct x86_pmu { void (*drain_pebs)(struct pt_regs *regs); struct event_constraint *pebs_constraints; void (*pebs_aliases)(struct perf_event *event); - int max_pebs_events; /* * Intel LBR @@ -481,8 +468,6 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, void x86_pmu_enable_all(int added); -int perf_assign_events(struct event_constraint **constraints, int n, - int wmin, int wmax, int *assign); int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); void x86_pmu_stop(struct perf_event *event, int flags); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index 8408e37f5fa4..187c294bc658 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -1003,11 +1003,11 @@ static void intel_pmu_reset(void) printk("clearing PMU state on CPU#%d\n", smp_processor_id()); for (idx = 0; idx < x86_pmu.num_counters; idx++) { - wrmsrl_safe(x86_pmu_config_addr(idx), 0ull); - wrmsrl_safe(x86_pmu_event_addr(idx), 0ull); + checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); + checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); } for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) - wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); + checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); if (ds) ds->bts_index = ds->bts_buffer_base; @@ -1800,8 +1800,6 @@ __init int intel_pmu_init(void) x86_pmu.events_maskl = ebx.full; x86_pmu.events_mask_len = eax.split.mask_length; - x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); - /* * Quirk: v2 perfmon does not report fixed-purpose events, so * assume at least 3 events: diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index 026373edef7f..35e2192df9f4 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -620,7 +620,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ONCE(n > 1, "bad leftover pebs %d\n", n); + WARN_ON_ONCE(n > 1); at += n - 1; __intel_pmu_pebs_event(event, iregs, at); @@ -651,10 +651,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) * Should not happen, we program the threshold at 1 and do not * set a reset value. */ - WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n); + WARN_ON_ONCE(n > MAX_PEBS_EVENTS); for ( ; at < top; at++) { - for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) { + for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { event = cpuc->events[bit]; if (!test_bit(bit, cpuc->active_mask)) continue; @@ -670,7 +670,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) break; } - if (!event || bit >= x86_pmu.max_pebs_events) + if (!event || bit >= MAX_PEBS_EVENTS) continue; __intel_pmu_pebs_event(event, iregs, at); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c deleted file mode 100644 index 6f43f9584e3d..000000000000 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ /dev/null @@ -1,1703 +0,0 @@ -#include "perf_event_intel_uncore.h" - -static struct intel_uncore_type *empty_uncore[] = { NULL, }; -static struct intel_uncore_type **msr_uncores = empty_uncore; -static struct intel_uncore_type **pci_uncores = empty_uncore; -/* pci bus to socket mapping */ -static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; - -static DEFINE_RAW_SPINLOCK(uncore_box_lock); - -/* mask of cpus that collect uncore events */ -static cpumask_t uncore_cpu_mask; - -/* constraint for the fixed counter */ -static struct event_constraint constraint_fixed = - EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); - -DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); -DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); -DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); -DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); -DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); -DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); - -/* Sandy Bridge-EP uncore support */ -static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config; - - pci_read_config_dword(pdev, box_ctl, &config); - config |= SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); -} - -static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config; - - pci_read_config_dword(pdev, box_ctl, &config); - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); -} - -static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config | - SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config); -} - -static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - u64 count; - - pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); - pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); - return count; -} - -static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, - SNBEP_PMON_BOX_CTL_INT); -} - -static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config |= SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - return; - } -} - -static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - return; - } -} - -static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - wrmsrl(hwc->config_base, hwc->config); -} - -static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - u64 count; - - rdmsrl(hwc->event_base, count); - return count; -} - -static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - if (msr) - wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); -} - -static struct attribute *snbep_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - NULL, -}; - -static struct attribute *snbep_uncore_ubox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - NULL, -}; - -static struct attribute *snbep_uncore_pcu_formats_attr[] = { - &format_attr_event.attr, - &format_attr_occ_sel.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - &format_attr_occ_invert.attr, - &format_attr_occ_edge.attr, - NULL, -}; - -static struct uncore_event_desc snbep_uncore_imc_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0xff"), - INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), - INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), - { /* end: all zeroes */ }, -}; - -static struct uncore_event_desc snbep_uncore_qpi_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), - INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), - INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), - { /* end: all zeroes */ }, -}; - -static struct attribute_group snbep_uncore_format_group = { - .name = "format", - .attrs = snbep_uncore_formats_attr, -}; - -static struct attribute_group snbep_uncore_ubox_format_group = { - .name = "format", - .attrs = snbep_uncore_ubox_formats_attr, -}; - -static struct attribute_group snbep_uncore_pcu_format_group = { - .name = "format", - .attrs = snbep_uncore_pcu_formats_attr, -}; - -static struct intel_uncore_ops snbep_uncore_msr_ops = { - .init_box = snbep_uncore_msr_init_box, - .disable_box = snbep_uncore_msr_disable_box, - .enable_box = snbep_uncore_msr_enable_box, - .disable_event = snbep_uncore_msr_disable_event, - .enable_event = snbep_uncore_msr_enable_event, - .read_counter = snbep_uncore_msr_read_counter, -}; - -static struct intel_uncore_ops snbep_uncore_pci_ops = { - .init_box = snbep_uncore_pci_init_box, - .disable_box = snbep_uncore_pci_disable_box, - .enable_box = snbep_uncore_pci_enable_box, - .disable_event = snbep_uncore_pci_disable_event, - .enable_event = snbep_uncore_pci_enable_event, - .read_counter = snbep_uncore_pci_read_counter, -}; - -static struct event_constraint snbep_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x01, 0x1), - UNCORE_EVENT_CONSTRAINT(0x02, 0x3), - UNCORE_EVENT_CONSTRAINT(0x04, 0x3), - UNCORE_EVENT_CONSTRAINT(0x05, 0x3), - UNCORE_EVENT_CONSTRAINT(0x07, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x1), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x3), - UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1f, 0xe), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x35, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x1), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - UNCORE_EVENT_CONSTRAINT(0x38, 0x3), - UNCORE_EVENT_CONSTRAINT(0x39, 0x3), - UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r2pcie_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x1), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r3qpi_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x1), - UNCORE_EVENT_CONSTRAINT(0x20, 0x3), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x22, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x30, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x3), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snbep_uncore_ubox = { - .name = "ubox", - .num_counters = 2, - .num_boxes = 1, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNBEP_U_MSR_PMON_CTR0, - .event_ctl = SNBEP_U_MSR_PMON_CTL0, - .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, - .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, - .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_ubox_format_group, -}; - -static struct intel_uncore_type snbep_uncore_cbox = { - .name = "cbox", - .num_counters = 4, - .num_boxes = 8, - .perf_ctr_bits = 44, - .event_ctl = SNBEP_C0_MSR_PMON_CTL0, - .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, - .msr_offset = SNBEP_CBO_MSR_OFFSET, - .constraints = snbep_uncore_cbox_constraints, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_format_group, -}; - -static struct intel_uncore_type snbep_uncore_pcu = { - .name = "pcu", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, - .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, - .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_pcu_format_group, -}; - -static struct intel_uncore_type *snbep_msr_uncores[] = { - &snbep_uncore_ubox, - &snbep_uncore_cbox, - &snbep_uncore_pcu, - NULL, -}; - -#define SNBEP_UNCORE_PCI_COMMON_INIT() \ - .perf_ctr = SNBEP_PCI_PMON_CTR0, \ - .event_ctl = SNBEP_PCI_PMON_CTL0, \ - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ - .ops = &snbep_uncore_pci_ops, \ - .format_group = &snbep_uncore_format_group - -static struct intel_uncore_type snbep_uncore_ha = { - .name = "ha", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_imc = { - .name = "imc", - .num_counters = 4, - .num_boxes = 4, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, - .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, - .event_descs = snbep_uncore_imc_events, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_qpi = { - .name = "qpi", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_descs = snbep_uncore_qpi_events, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - - -static struct intel_uncore_type snbep_uncore_r2pcie = { - .name = "r2pcie", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r2pcie_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_r3qpi = { - .name = "r3qpi", - .num_counters = 3, - .num_boxes = 2, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r3qpi_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type *snbep_pci_uncores[] = { - &snbep_uncore_ha, - &snbep_uncore_imc, - &snbep_uncore_qpi, - &snbep_uncore_r2pcie, - &snbep_uncore_r3qpi, - NULL, -}; - -static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { - { /* Home Agent */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), - .driver_data = (unsigned long)&snbep_uncore_ha, - }, - { /* MC Channel 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 2 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* MC Channel 3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), - .driver_data = (unsigned long)&snbep_uncore_imc, - }, - { /* QPI Port 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), - .driver_data = (unsigned long)&snbep_uncore_qpi, - }, - { /* QPI Port 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), - .driver_data = (unsigned long)&snbep_uncore_qpi, - }, - { /* P2PCIe */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), - .driver_data = (unsigned long)&snbep_uncore_r2pcie, - }, - { /* R3QPI Link 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), - .driver_data = (unsigned long)&snbep_uncore_r3qpi, - }, - { /* R3QPI Link 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), - .driver_data = (unsigned long)&snbep_uncore_r3qpi, - }, - { /* end: all zeroes */ } -}; - -static struct pci_driver snbep_uncore_pci_driver = { - .name = "snbep_uncore", - .id_table = snbep_uncore_pci_ids, -}; - -/* - * build pci bus to socket mapping - */ -static void snbep_pci2phy_map_init(void) -{ - struct pci_dev *ubox_dev = NULL; - int i, bus, nodeid; - u32 config; - - while (1) { - /* find the UBOX device */ - ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX, - ubox_dev); - if (!ubox_dev) - break; - bus = ubox_dev->bus->number; - /* get the Node ID of the local register */ - pci_read_config_dword(ubox_dev, 0x40, &config); - nodeid = config; - /* get the Node ID mapping */ - pci_read_config_dword(ubox_dev, 0x54, &config); - /* - * every three bits in the Node ID mapping register maps - * to a particular node. - */ - for (i = 0; i < 8; i++) { - if (nodeid == ((config >> (3 * i)) & 0x7)) { - pcibus_to_physid[bus] = i; - break; - } - } - }; - return; -} -/* end of Sandy Bridge-EP uncore support */ - - -/* Sandy Bridge uncore support */ -static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); -} - -static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - wrmsrl(event->hw.config_base, 0); -} - -static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - u64 count; - rdmsrl(event->hw.event_base, count); - return count; -} - -static void snb_uncore_msr_init_box(struct intel_uncore_box *box) -{ - if (box->pmu->pmu_idx == 0) { - wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, - SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); - } -} - -static struct attribute *snb_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask5.attr, - NULL, -}; - -static struct attribute_group snb_uncore_format_group = { - .name = "format", - .attrs = snb_uncore_formats_attr, -}; - -static struct intel_uncore_ops snb_uncore_msr_ops = { - .init_box = snb_uncore_msr_init_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = snb_uncore_msr_enable_event, - .read_counter = snb_uncore_msr_read_counter, -}; - -static struct event_constraint snb_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x80, 0x1), - UNCORE_EVENT_CONSTRAINT(0x83, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snb_uncore_cbox = { - .name = "cbox", - .num_counters = 2, - .num_boxes = 4, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, - .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, - .fixed_ctr = SNB_UNC_FIXED_CTR, - .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, - .single_fixed = 1, - .event_mask = SNB_UNC_RAW_EVENT_MASK, - .msr_offset = SNB_UNC_CBO_MSR_OFFSET, - .constraints = snb_uncore_cbox_constraints, - .ops = &snb_uncore_msr_ops, - .format_group = &snb_uncore_format_group, -}; - -static struct intel_uncore_type *snb_msr_uncores[] = { - &snb_uncore_cbox, - NULL, -}; -/* end of Sandy Bridge uncore support */ - -/* Nehalem uncore support */ -static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); -} - -static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, - NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); -} - -static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); -} - -static struct attribute *nhm_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask8.attr, - NULL, -}; - -static struct attribute_group nhm_uncore_format_group = { - .name = "format", - .attrs = nhm_uncore_formats_attr, -}; - -static struct uncore_event_desc nhm_uncore_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0xff"), - INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_ops nhm_uncore_msr_ops = { - .disable_box = nhm_uncore_msr_disable_box, - .enable_box = nhm_uncore_msr_enable_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = nhm_uncore_msr_enable_event, - .read_counter = snb_uncore_msr_read_counter, -}; - -static struct intel_uncore_type nhm_uncore = { - .name = "", - .num_counters = 8, - .num_boxes = 1, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .event_ctl = NHM_UNC_PERFEVTSEL0, - .perf_ctr = NHM_UNC_UNCORE_PMC0, - .fixed_ctr = NHM_UNC_FIXED_CTR, - .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, - .event_mask = NHM_UNC_RAW_EVENT_MASK, - .event_descs = nhm_uncore_events, - .ops = &nhm_uncore_msr_ops, - .format_group = &nhm_uncore_format_group, -}; - -static struct intel_uncore_type *nhm_msr_uncores[] = { - &nhm_uncore, - NULL, -}; -/* end of Nehalem uncore support */ - -static void uncore_assign_hw_event(struct intel_uncore_box *box, - struct perf_event *event, int idx) -{ - struct hw_perf_event *hwc = &event->hw; - - hwc->idx = idx; - hwc->last_tag = ++box->tags[idx]; - - if (hwc->idx == UNCORE_PMC_IDX_FIXED) { - hwc->event_base = uncore_fixed_ctr(box); - hwc->config_base = uncore_fixed_ctl(box); - return; - } - - hwc->config_base = uncore_event_ctl(box, hwc->idx); - hwc->event_base = uncore_perf_ctr(box, hwc->idx); -} - -static void uncore_perf_event_update(struct intel_uncore_box *box, - struct perf_event *event) -{ - u64 prev_count, new_count, delta; - int shift; - - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) - shift = 64 - uncore_fixed_ctr_bits(box); - else - shift = 64 - uncore_perf_ctr_bits(box); - - /* the hrtimer might modify the previous event value */ -again: - prev_count = local64_read(&event->hw.prev_count); - new_count = uncore_read_counter(box, event); - if (local64_xchg(&event->hw.prev_count, new_count) != prev_count) - goto again; - - delta = (new_count << shift) - (prev_count << shift); - delta >>= shift; - - local64_add(delta, &event->count); -} - -/* - * The overflow interrupt is unavailable for SandyBridge-EP, is broken - * for SandyBridge. So we use hrtimer to periodically poll the counter - * to avoid overflow. - */ -static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) -{ - struct intel_uncore_box *box; - unsigned long flags; - int bit; - - box = container_of(hrtimer, struct intel_uncore_box, hrtimer); - if (!box->n_active || box->cpu != smp_processor_id()) - return HRTIMER_NORESTART; - /* - * disable local interrupt to prevent uncore_pmu_event_start/stop - * to interrupt the update process - */ - local_irq_save(flags); - - for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX) - uncore_perf_event_update(box, box->events[bit]); - - local_irq_restore(flags); - - hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL)); - return HRTIMER_RESTART; -} - -static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) -{ - __hrtimer_start_range_ns(&box->hrtimer, - ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0, - HRTIMER_MODE_REL_PINNED, 0); -} - -static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) -{ - hrtimer_cancel(&box->hrtimer); -} - -static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) -{ - hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - box->hrtimer.function = uncore_pmu_hrtimer; -} - -struct intel_uncore_box *uncore_alloc_box(int cpu) -{ - struct intel_uncore_box *box; - - box = kmalloc_node(sizeof(*box), GFP_KERNEL | __GFP_ZERO, - cpu_to_node(cpu)); - if (!box) - return NULL; - - uncore_pmu_init_hrtimer(box); - atomic_set(&box->refcnt, 1); - box->cpu = -1; - box->phys_id = -1; - - return box; -} - -static struct intel_uncore_box * -uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) -{ - static struct intel_uncore_box *box; - - box = *per_cpu_ptr(pmu->box, cpu); - if (box) - return box; - - raw_spin_lock(&uncore_box_lock); - list_for_each_entry(box, &pmu->box_list, list) { - if (box->phys_id == topology_physical_package_id(cpu)) { - atomic_inc(&box->refcnt); - *per_cpu_ptr(pmu->box, cpu) = box; - break; - } - } - raw_spin_unlock(&uncore_box_lock); - - return *per_cpu_ptr(pmu->box, cpu); -} - -static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) -{ - return container_of(event->pmu, struct intel_uncore_pmu, pmu); -} - -static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) -{ - /* - * perf core schedules event on the basis of cpu, uncore events are - * collected by one of the cpus inside a physical package. - */ - return uncore_pmu_to_box(uncore_event_to_pmu(event), - smp_processor_id()); -} - -static int uncore_collect_events(struct intel_uncore_box *box, - struct perf_event *leader, bool dogrp) -{ - struct perf_event *event; - int n, max_count; - - max_count = box->pmu->type->num_counters; - if (box->pmu->type->fixed_ctl) - max_count++; - - if (box->n_events >= max_count) - return -EINVAL; - - n = box->n_events; - box->event_list[n] = leader; - n++; - if (!dogrp) - return n; - - list_for_each_entry(event, &leader->sibling_list, group_entry) { - if (event->state <= PERF_EVENT_STATE_OFF) - continue; - - if (n >= max_count) - return -EINVAL; - - box->event_list[n] = event; - n++; - } - return n; -} - -static struct event_constraint * -uncore_event_constraint(struct intel_uncore_type *type, - struct perf_event *event) -{ - struct event_constraint *c; - - if (event->hw.config == ~0ULL) - return &constraint_fixed; - - if (type->constraints) { - for_each_event_constraint(c, type->constraints) { - if ((event->hw.config & c->cmask) == c->code) - return c; - } - } - - return &type->unconstrainted; -} - -static int uncore_assign_events(struct intel_uncore_box *box, - int assign[], int n) -{ - unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; - struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; - int i, ret, wmin, wmax; - struct hw_perf_event *hwc; - - bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); - - for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { - c = uncore_event_constraint(box->pmu->type, - box->event_list[i]); - constraints[i] = c; - wmin = min(wmin, c->weight); - wmax = max(wmax, c->weight); - } - - /* fastpath, try to reuse previous register */ - for (i = 0; i < n; i++) { - hwc = &box->event_list[i]->hw; - c = constraints[i]; - - /* never assigned */ - if (hwc->idx == -1) - break; - - /* constraint still honored */ - if (!test_bit(hwc->idx, c->idxmsk)) - break; - - /* not already used */ - if (test_bit(hwc->idx, used_mask)) - break; - - __set_bit(hwc->idx, used_mask); - assign[i] = hwc->idx; - } - if (i == n) - return 0; - - /* slow path */ - ret = perf_assign_events(constraints, n, wmin, wmax, assign); - return ret ? -EINVAL : 0; -} - -static void uncore_pmu_event_start(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - int idx = event->hw.idx; - - if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) - return; - - if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX)) - return; - - event->hw.state = 0; - box->events[idx] = event; - box->n_active++; - __set_bit(idx, box->active_mask); - - local64_set(&event->hw.prev_count, uncore_read_counter(box, event)); - uncore_enable_event(box, event); - - if (box->n_active == 1) { - uncore_enable_box(box); - uncore_pmu_start_hrtimer(box); - } -} - -static void uncore_pmu_event_stop(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - - if (__test_and_clear_bit(hwc->idx, box->active_mask)) { - uncore_disable_event(box, event); - box->n_active--; - box->events[hwc->idx] = NULL; - WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); - hwc->state |= PERF_HES_STOPPED; - - if (box->n_active == 0) { - uncore_disable_box(box); - uncore_pmu_cancel_hrtimer(box); - } - } - - if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { - /* - * Drain the remaining delta count out of a event - * that we are disabling: - */ - uncore_perf_event_update(box, event); - hwc->state |= PERF_HES_UPTODATE; - } -} - -static int uncore_pmu_event_add(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - int assign[UNCORE_PMC_IDX_MAX]; - int i, n, ret; - - if (!box) - return -ENODEV; - - ret = n = uncore_collect_events(box, event, false); - if (ret < 0) - return ret; - - hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; - if (!(flags & PERF_EF_START)) - hwc->state |= PERF_HES_ARCH; - - ret = uncore_assign_events(box, assign, n); - if (ret) - return ret; - - /* save events moving to new counters */ - for (i = 0; i < box->n_events; i++) { - event = box->event_list[i]; - hwc = &event->hw; - - if (hwc->idx == assign[i] && - hwc->last_tag == box->tags[assign[i]]) - continue; - /* - * Ensure we don't accidentally enable a stopped - * counter simply because we rescheduled. - */ - if (hwc->state & PERF_HES_STOPPED) - hwc->state |= PERF_HES_ARCH; - - uncore_pmu_event_stop(event, PERF_EF_UPDATE); - } - - /* reprogram moved events into new counters */ - for (i = 0; i < n; i++) { - event = box->event_list[i]; - hwc = &event->hw; - - if (hwc->idx != assign[i] || - hwc->last_tag != box->tags[assign[i]]) - uncore_assign_hw_event(box, event, assign[i]); - else if (i < box->n_events) - continue; - - if (hwc->state & PERF_HES_ARCH) - continue; - - uncore_pmu_event_start(event, 0); - } - box->n_events = n; - - return 0; -} - -static void uncore_pmu_event_del(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - int i; - - uncore_pmu_event_stop(event, PERF_EF_UPDATE); - - for (i = 0; i < box->n_events; i++) { - if (event == box->event_list[i]) { - while (++i < box->n_events) - box->event_list[i - 1] = box->event_list[i]; - - --box->n_events; - break; - } - } - - event->hw.idx = -1; - event->hw.last_tag = ~0ULL; -} - -static void uncore_pmu_event_read(struct perf_event *event) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - uncore_perf_event_update(box, event); -} - -/* - * validation ensures the group can be loaded onto the - * PMU if it was the only group available. - */ -static int uncore_validate_group(struct intel_uncore_pmu *pmu, - struct perf_event *event) -{ - struct perf_event *leader = event->group_leader; - struct intel_uncore_box *fake_box; - int assign[UNCORE_PMC_IDX_MAX]; - int ret = -EINVAL, n; - - fake_box = uncore_alloc_box(smp_processor_id()); - if (!fake_box) - return -ENOMEM; - - fake_box->pmu = pmu; - /* - * the event is not yet connected with its - * siblings therefore we must first collect - * existing siblings, then add the new event - * before we can simulate the scheduling - */ - n = uncore_collect_events(fake_box, leader, true); - if (n < 0) - goto out; - - fake_box->n_events = n; - n = uncore_collect_events(fake_box, event, false); - if (n < 0) - goto out; - - fake_box->n_events = n; - - ret = uncore_assign_events(fake_box, assign, n); -out: - kfree(fake_box); - return ret; -} - -int uncore_pmu_event_init(struct perf_event *event) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - struct hw_perf_event *hwc = &event->hw; - int ret; - - if (event->attr.type != event->pmu->type) - return -ENOENT; - - pmu = uncore_event_to_pmu(event); - /* no device found for this pmu */ - if (pmu->func_id < 0) - return -ENOENT; - - /* - * Uncore PMU does measure at all privilege level all the time. - * So it doesn't make sense to specify any exclude bits. - */ - if (event->attr.exclude_user || event->attr.exclude_kernel || - event->attr.exclude_hv || event->attr.exclude_idle) - return -EINVAL; - - /* Sampling not supported yet */ - if (hwc->sample_period) - return -EINVAL; - - /* - * Place all uncore events for a particular physical package - * onto a single cpu - */ - if (event->cpu < 0) - return -EINVAL; - box = uncore_pmu_to_box(pmu, event->cpu); - if (!box || box->cpu < 0) - return -EINVAL; - event->cpu = box->cpu; - - if (event->attr.config == UNCORE_FIXED_EVENT) { - /* no fixed counter */ - if (!pmu->type->fixed_ctl) - return -EINVAL; - /* - * if there is only one fixed counter, only the first pmu - * can access the fixed counter - */ - if (pmu->type->single_fixed && pmu->pmu_idx > 0) - return -EINVAL; - hwc->config = ~0ULL; - } else { - hwc->config = event->attr.config & pmu->type->event_mask; - } - - event->hw.idx = -1; - event->hw.last_tag = ~0ULL; - - if (event->group_leader != event) - ret = uncore_validate_group(pmu, event); - else - ret = 0; - - return ret; -} - -static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) -{ - int ret; - - pmu->pmu = (struct pmu) { - .attr_groups = pmu->type->attr_groups, - .task_ctx_nr = perf_invalid_context, - .event_init = uncore_pmu_event_init, - .add = uncore_pmu_event_add, - .del = uncore_pmu_event_del, - .start = uncore_pmu_event_start, - .stop = uncore_pmu_event_stop, - .read = uncore_pmu_event_read, - }; - - if (pmu->type->num_boxes == 1) { - if (strlen(pmu->type->name) > 0) - sprintf(pmu->name, "uncore_%s", pmu->type->name); - else - sprintf(pmu->name, "uncore"); - } else { - sprintf(pmu->name, "uncore_%s_%d", pmu->type->name, - pmu->pmu_idx); - } - - ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); - return ret; -} - -static void __init uncore_type_exit(struct intel_uncore_type *type) -{ - int i; - - for (i = 0; i < type->num_boxes; i++) - free_percpu(type->pmus[i].box); - kfree(type->pmus); - type->pmus = NULL; - kfree(type->attr_groups[1]); - type->attr_groups[1] = NULL; -} - -static void uncore_types_exit(struct intel_uncore_type **types) -{ - int i; - for (i = 0; types[i]; i++) - uncore_type_exit(types[i]); -} - -static int __init uncore_type_init(struct intel_uncore_type *type) -{ - struct intel_uncore_pmu *pmus; - struct attribute_group *events_group; - struct attribute **attrs; - int i, j; - - pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL); - if (!pmus) - return -ENOMEM; - - type->unconstrainted = (struct event_constraint) - __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, - 0, type->num_counters, 0); - - for (i = 0; i < type->num_boxes; i++) { - pmus[i].func_id = -1; - pmus[i].pmu_idx = i; - pmus[i].type = type; - INIT_LIST_HEAD(&pmus[i].box_list); - pmus[i].box = alloc_percpu(struct intel_uncore_box *); - if (!pmus[i].box) - goto fail; - } - - if (type->event_descs) { - i = 0; - while (type->event_descs[i].attr.attr.name) - i++; - - events_group = kzalloc(sizeof(struct attribute *) * (i + 1) + - sizeof(*events_group), GFP_KERNEL); - if (!events_group) - goto fail; - - attrs = (struct attribute **)(events_group + 1); - events_group->name = "events"; - events_group->attrs = attrs; - - for (j = 0; j < i; j++) - attrs[j] = &type->event_descs[j].attr.attr; - - type->attr_groups[1] = events_group; - } - - type->pmus = pmus; - return 0; -fail: - uncore_type_exit(type); - return -ENOMEM; -} - -static int __init uncore_types_init(struct intel_uncore_type **types) -{ - int i, ret; - - for (i = 0; types[i]; i++) { - ret = uncore_type_init(types[i]); - if (ret) - goto fail; - } - return 0; -fail: - while (--i >= 0) - uncore_type_exit(types[i]); - return ret; -} - -static struct pci_driver *uncore_pci_driver; -static bool pcidrv_registered; - -/* - * add a pci uncore device - */ -static int __devinit uncore_pci_add(struct intel_uncore_type *type, - struct pci_dev *pdev) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, phys_id; - - phys_id = pcibus_to_physid[pdev->bus->number]; - if (phys_id < 0) - return -ENODEV; - - box = uncore_alloc_box(0); - if (!box) - return -ENOMEM; - - /* - * for performance monitoring unit with multiple boxes, - * each box has a different function id. - */ - for (i = 0; i < type->num_boxes; i++) { - pmu = &type->pmus[i]; - if (pmu->func_id == pdev->devfn) - break; - if (pmu->func_id < 0) { - pmu->func_id = pdev->devfn; - break; - } - pmu = NULL; - } - - if (!pmu) { - kfree(box); - return -EINVAL; - } - - box->phys_id = phys_id; - box->pci_dev = pdev; - box->pmu = pmu; - uncore_box_init(box); - pci_set_drvdata(pdev, box); - - raw_spin_lock(&uncore_box_lock); - list_add_tail(&box->list, &pmu->box_list); - raw_spin_unlock(&uncore_box_lock); - - return 0; -} - -static void uncore_pci_remove(struct pci_dev *pdev) -{ - struct intel_uncore_box *box = pci_get_drvdata(pdev); - struct intel_uncore_pmu *pmu = box->pmu; - int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; - - if (WARN_ON_ONCE(phys_id != box->phys_id)) - return; - - raw_spin_lock(&uncore_box_lock); - list_del(&box->list); - raw_spin_unlock(&uncore_box_lock); - - for_each_possible_cpu(cpu) { - if (*per_cpu_ptr(pmu->box, cpu) == box) { - *per_cpu_ptr(pmu->box, cpu) = NULL; - atomic_dec(&box->refcnt); - } - } - - WARN_ON_ONCE(atomic_read(&box->refcnt) != 1); - kfree(box); -} - -static int __devinit uncore_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct intel_uncore_type *type; - - type = (struct intel_uncore_type *)id->driver_data; - return uncore_pci_add(type, pdev); -} - -static int __init uncore_pci_init(void) -{ - int ret; - - switch (boot_cpu_data.x86_model) { - case 45: /* Sandy Bridge-EP */ - pci_uncores = snbep_pci_uncores; - uncore_pci_driver = &snbep_uncore_pci_driver; - snbep_pci2phy_map_init(); - break; - default: - return 0; - } - - ret = uncore_types_init(pci_uncores); - if (ret) - return ret; - - uncore_pci_driver->probe = uncore_pci_probe; - uncore_pci_driver->remove = uncore_pci_remove; - - ret = pci_register_driver(uncore_pci_driver); - if (ret == 0) - pcidrv_registered = true; - else - uncore_types_exit(pci_uncores); - - return ret; -} - -static void __init uncore_pci_exit(void) -{ - if (pcidrv_registered) { - pcidrv_registered = false; - pci_unregister_driver(uncore_pci_driver); - uncore_types_exit(pci_uncores); - } -} - -static void __cpuinit uncore_cpu_dying(int cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - box = *per_cpu_ptr(pmu->box, cpu); - *per_cpu_ptr(pmu->box, cpu) = NULL; - if (box && atomic_dec_and_test(&box->refcnt)) - kfree(box); - } - } -} - -static int __cpuinit uncore_cpu_starting(int cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box, *exist; - int i, j, k, phys_id; - - phys_id = topology_physical_package_id(cpu); - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - box = *per_cpu_ptr(pmu->box, cpu); - /* called by uncore_cpu_init? */ - if (box && box->phys_id >= 0) { - uncore_box_init(box); - continue; - } - - for_each_online_cpu(k) { - exist = *per_cpu_ptr(pmu->box, k); - if (exist && exist->phys_id == phys_id) { - atomic_inc(&exist->refcnt); - *per_cpu_ptr(pmu->box, cpu) = exist; - kfree(box); - box = NULL; - break; - } - } - - if (box) { - box->phys_id = phys_id; - uncore_box_init(box); - } - } - } - return 0; -} - -static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - if (pmu->func_id < 0) - pmu->func_id = j; - - box = uncore_alloc_box(cpu); - if (!box) - return -ENOMEM; - - box->pmu = pmu; - box->phys_id = phys_id; - *per_cpu_ptr(pmu->box, cpu) = box; - } - } - return 0; -} - -static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, - int old_cpu, int new_cpu) -{ - struct intel_uncore_type *type; - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - int i, j; - - for (i = 0; uncores[i]; i++) { - type = uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - if (old_cpu < 0) - box = uncore_pmu_to_box(pmu, new_cpu); - else - box = uncore_pmu_to_box(pmu, old_cpu); - if (!box) - continue; - - if (old_cpu < 0) { - WARN_ON_ONCE(box->cpu != -1); - box->cpu = new_cpu; - continue; - } - - WARN_ON_ONCE(box->cpu != old_cpu); - if (new_cpu >= 0) { - uncore_pmu_cancel_hrtimer(box); - perf_pmu_migrate_context(&pmu->pmu, - old_cpu, new_cpu); - box->cpu = new_cpu; - } else { - box->cpu = -1; - } - } - } -} - -static void __cpuinit uncore_event_exit_cpu(int cpu) -{ - int i, phys_id, target; - - /* if exiting cpu is used for collecting uncore events */ - if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask)) - return; - - /* find a new cpu to collect uncore events */ - phys_id = topology_physical_package_id(cpu); - target = -1; - for_each_online_cpu(i) { - if (i == cpu) - continue; - if (phys_id == topology_physical_package_id(i)) { - target = i; - break; - } - } - - /* migrate uncore events to the new cpu */ - if (target >= 0) - cpumask_set_cpu(target, &uncore_cpu_mask); - - uncore_change_context(msr_uncores, cpu, target); - uncore_change_context(pci_uncores, cpu, target); -} - -static void __cpuinit uncore_event_init_cpu(int cpu) -{ - int i, phys_id; - - phys_id = topology_physical_package_id(cpu); - for_each_cpu(i, &uncore_cpu_mask) { - if (phys_id == topology_physical_package_id(i)) - return; - } - - cpumask_set_cpu(cpu, &uncore_cpu_mask); - - uncore_change_context(msr_uncores, -1, cpu); - uncore_change_context(pci_uncores, -1, cpu); -} - -static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (long)hcpu; - - /* allocate/free data structure for uncore box */ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_UP_PREPARE: - uncore_cpu_prepare(cpu, -1); - break; - case CPU_STARTING: - uncore_cpu_starting(cpu); - break; - case CPU_UP_CANCELED: - case CPU_DYING: - uncore_cpu_dying(cpu); - break; - default: - break; - } - - /* select the cpu that collects uncore events */ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DOWN_FAILED: - case CPU_STARTING: - uncore_event_init_cpu(cpu); - break; - case CPU_DOWN_PREPARE: - uncore_event_exit_cpu(cpu); - break; - default: - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block uncore_cpu_nb __cpuinitdata = { - .notifier_call = uncore_cpu_notifier, - /* - * to migrate uncore events, our notifier should be executed - * before perf core's notifier. - */ - .priority = CPU_PRI_PERF + 1, -}; - -static void __init uncore_cpu_setup(void *dummy) -{ - uncore_cpu_starting(smp_processor_id()); -} - -static int __init uncore_cpu_init(void) -{ - int ret, cpu; - - switch (boot_cpu_data.x86_model) { - case 26: /* Nehalem */ - case 30: - case 37: /* Westmere */ - case 44: - msr_uncores = nhm_msr_uncores; - break; - case 42: /* Sandy Bridge */ - msr_uncores = snb_msr_uncores; - break; - case 45: /* Sandy Birdge-EP */ - msr_uncores = snbep_msr_uncores; - break; - default: - return 0; - } - - ret = uncore_types_init(msr_uncores); - if (ret) - return ret; - - get_online_cpus(); - - for_each_online_cpu(cpu) { - int i, phys_id = topology_physical_package_id(cpu); - - for_each_cpu(i, &uncore_cpu_mask) { - if (phys_id == topology_physical_package_id(i)) { - phys_id = -1; - break; - } - } - if (phys_id < 0) - continue; - - uncore_cpu_prepare(cpu, phys_id); - uncore_event_init_cpu(cpu); - } - on_each_cpu(uncore_cpu_setup, NULL, 1); - - register_cpu_notifier(&uncore_cpu_nb); - - put_online_cpus(); - - return 0; -} - -static int __init uncore_pmus_register(void) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_type *type; - int i, j; - - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - uncore_pmu_register(pmu); - } - } - - for (i = 0; pci_uncores[i]; i++) { - type = pci_uncores[i]; - for (j = 0; j < type->num_boxes; j++) { - pmu = &type->pmus[j]; - uncore_pmu_register(pmu); - } - } - - return 0; -} - -static int __init intel_uncore_init(void) -{ - int ret; - - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - ret = uncore_pci_init(); - if (ret) - goto fail; - ret = uncore_cpu_init(); - if (ret) { - uncore_pci_exit(); - goto fail; - } - - uncore_pmus_register(); - return 0; -fail: - return ret; -} -device_initcall(intel_uncore_init); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h deleted file mode 100644 index 4d52db0d1dfe..000000000000 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ /dev/null @@ -1,406 +0,0 @@ -#include -#include -#include -#include -#include "perf_event.h" - -#define UNCORE_PMU_NAME_LEN 32 -#define UNCORE_BOX_HASH_SIZE 8 - -#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) - -#define UNCORE_FIXED_EVENT 0xffff -#define UNCORE_PMC_IDX_MAX_GENERIC 8 -#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC -#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) - -#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) - -/* SNB event control */ -#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff -#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 -#define SNB_UNC_CTL_EDGE_DET (1 << 18) -#define SNB_UNC_CTL_EN (1 << 22) -#define SNB_UNC_CTL_INVERT (1 << 23) -#define SNB_UNC_CTL_CMASK_MASK 0x1f000000 -#define NHM_UNC_CTL_CMASK_MASK 0xff000000 -#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) - -#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - SNB_UNC_CTL_CMASK_MASK) - -#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - NHM_UNC_CTL_CMASK_MASK) - -/* SNB global control register */ -#define SNB_UNC_PERF_GLOBAL_CTL 0x391 -#define SNB_UNC_FIXED_CTR_CTRL 0x394 -#define SNB_UNC_FIXED_CTR 0x395 - -/* SNB uncore global control */ -#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) -#define SNB_UNC_GLOBAL_CTL_EN (1 << 29) - -/* SNB Cbo register */ -#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 -#define SNB_UNC_CBO_0_PER_CTR0 0x706 -#define SNB_UNC_CBO_MSR_OFFSET 0x10 - -/* NHM global control register */ -#define NHM_UNC_PERF_GLOBAL_CTL 0x391 -#define NHM_UNC_FIXED_CTR 0x394 -#define NHM_UNC_FIXED_CTR_CTRL 0x395 - -/* NHM uncore global control */ -#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) -#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) - -/* NHM uncore register */ -#define NHM_UNC_PERFEVTSEL0 0x3c0 -#define NHM_UNC_UNCORE_PMC0 0x3b0 - -/* SNB-EP Box level control */ -#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) -#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) -#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) -#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) -#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ - SNBEP_PMON_BOX_CTL_RST_CTRS | \ - SNBEP_PMON_BOX_CTL_FRZ_EN) -/* SNB-EP event control */ -#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff -#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 -#define SNBEP_PMON_CTL_RST (1 << 17) -#define SNBEP_PMON_CTL_EDGE_DET (1 << 18) -#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */ -#define SNBEP_PMON_CTL_EN (1 << 22) -#define SNBEP_PMON_CTL_INVERT (1 << 23) -#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 -#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PMON_CTL_TRESH_MASK) - -/* SNB-EP Ubox event control */ -#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_U_MSR_PMON_CTL_TRESH_MASK) - -/* SNB-EP PCU event control */ -#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 -#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) -#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) -#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) - -/* SNB-EP pci control register */ -#define SNBEP_PCI_PMON_BOX_CTL 0xf4 -#define SNBEP_PCI_PMON_CTL0 0xd8 -/* SNB-EP pci counter register */ -#define SNBEP_PCI_PMON_CTR0 0xa0 - -/* SNB-EP home agent register */ -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 -#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 -/* SNB-EP memory controller register */ -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 -/* SNB-EP QPI register */ -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c - -/* SNB-EP Ubox register */ -#define SNBEP_U_MSR_PMON_CTR0 0xc16 -#define SNBEP_U_MSR_PMON_CTL0 0xc10 - -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 - -/* SNB-EP Cbo register */ -#define SNBEP_C0_MSR_PMON_CTR0 0xd16 -#define SNBEP_C0_MSR_PMON_CTL0 0xd10 -#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 -#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 -#define SNBEP_CBO_MSR_OFFSET 0x20 - -/* SNB-EP PCU register */ -#define SNBEP_PCU_MSR_PMON_CTR0 0xc36 -#define SNBEP_PCU_MSR_PMON_CTL0 0xc30 -#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 -#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 -#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc -#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd - -struct intel_uncore_ops; -struct intel_uncore_pmu; -struct intel_uncore_box; -struct uncore_event_desc; - -struct intel_uncore_type { - const char *name; - int num_counters; - int num_boxes; - int perf_ctr_bits; - int fixed_ctr_bits; - int single_fixed; - unsigned perf_ctr; - unsigned event_ctl; - unsigned event_mask; - unsigned fixed_ctr; - unsigned fixed_ctl; - unsigned box_ctl; - unsigned msr_offset; - struct event_constraint unconstrainted; - struct event_constraint *constraints; - struct intel_uncore_pmu *pmus; - struct intel_uncore_ops *ops; - struct uncore_event_desc *event_descs; - const struct attribute_group *attr_groups[3]; -}; - -#define format_group attr_groups[0] - -struct intel_uncore_ops { - void (*init_box)(struct intel_uncore_box *); - void (*disable_box)(struct intel_uncore_box *); - void (*enable_box)(struct intel_uncore_box *); - void (*disable_event)(struct intel_uncore_box *, struct perf_event *); - void (*enable_event)(struct intel_uncore_box *, struct perf_event *); - u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *); -}; - -struct intel_uncore_pmu { - struct pmu pmu; - char name[UNCORE_PMU_NAME_LEN]; - int pmu_idx; - int func_id; - struct intel_uncore_type *type; - struct intel_uncore_box ** __percpu box; - struct list_head box_list; -}; - -struct intel_uncore_box { - int phys_id; - int n_active; /* number of active events */ - int n_events; - int cpu; /* cpu to collect events */ - unsigned long flags; - atomic_t refcnt; - struct perf_event *events[UNCORE_PMC_IDX_MAX]; - struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; - unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; - u64 tags[UNCORE_PMC_IDX_MAX]; - struct pci_dev *pci_dev; - struct intel_uncore_pmu *pmu; - struct hrtimer hrtimer; - struct list_head list; -}; - -#define UNCORE_BOX_FLAG_INITIATED 0 - -struct uncore_event_desc { - struct kobj_attribute attr; - const char *config; -}; - -#define INTEL_UNCORE_EVENT_DESC(_name, _config) \ -{ \ - .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \ - .config = _config, \ -} - -#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ -static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ - char *page) \ -{ \ - BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ - return sprintf(page, _format "\n"); \ -} \ -static struct kobj_attribute format_attr_##_var = \ - __ATTR(_name, 0444, __uncore_##_var##_show, NULL) - - -static ssize_t uncore_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct uncore_event_desc *event = - container_of(attr, struct uncore_event_desc, attr); - return sprintf(buf, "%s", event->config); -} - -static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) -{ - return box->pmu->type->box_ctl; -} - -static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctl; -} - -static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr; -} - -static inline -unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) -{ - return idx * 4 + box->pmu->type->event_ctl; -} - -static inline -unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) -{ - return idx * 8 + box->pmu->type->perf_ctr; -} - -static inline -unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) -{ - if (!box->pmu->type->box_ctl) - return 0; - return box->pmu->type->box_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) -{ - if (!box->pmu->type->fixed_ctl) - return 0; - return box->pmu->type->fixed_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) -{ - return idx + box->pmu->type->event_ctl + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) -{ - return idx + box->pmu->type->perf_ctr + - box->pmu->type->msr_offset * box->pmu->pmu_idx; -} - -static inline -unsigned uncore_fixed_ctl(struct intel_uncore_box *box) -{ - if (box->pci_dev) - return uncore_pci_fixed_ctl(box); - else - return uncore_msr_fixed_ctl(box); -} - -static inline -unsigned uncore_fixed_ctr(struct intel_uncore_box *box) -{ - if (box->pci_dev) - return uncore_pci_fixed_ctr(box); - else - return uncore_msr_fixed_ctr(box); -} - -static inline -unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx) -{ - if (box->pci_dev) - return uncore_pci_event_ctl(box, idx); - else - return uncore_msr_event_ctl(box, idx); -} - -static inline -unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx) -{ - if (box->pci_dev) - return uncore_pci_perf_ctr(box, idx); - else - return uncore_msr_perf_ctr(box, idx); -} - -static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box) -{ - return box->pmu->type->perf_ctr_bits; -} - -static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box) -{ - return box->pmu->type->fixed_ctr_bits; -} - -static inline int uncore_num_counters(struct intel_uncore_box *box) -{ - return box->pmu->type->num_counters; -} - -static inline void uncore_disable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->disable_box) - box->pmu->type->ops->disable_box(box); -} - -static inline void uncore_enable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->enable_box) - box->pmu->type->ops->enable_box(box); -} - -static inline void uncore_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - box->pmu->type->ops->disable_event(box, event); -} - -static inline void uncore_enable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - box->pmu->type->ops->enable_event(box, event); -} - -static inline u64 uncore_read_counter(struct intel_uncore_box *box, - struct perf_event *event) -{ - return box->pmu->type->ops->read_counter(box, event); -} - -static inline void uncore_box_init(struct intel_uncore_box *box) -{ - if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { - if (box->pmu->type->ops->init_box) - box->pmu->type->ops->init_box(box); - } -} diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c index 6c82e4037989..47124a73dd73 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p4.c @@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void) * So at moment let leave metrics turned on forever -- it's * ok for now but need to be revisited! * - * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0); - * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0); + * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); + * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); */ } @@ -909,7 +909,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) * state we need to clear P4_CCCR_OVF, otherwise interrupt get * asserted again and again */ - (void)wrmsrl_safe(hwc->config_base, + (void)checking_wrmsrl(hwc->config_base, (u64)(p4_config_unpack_cccr(hwc->config)) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); } @@ -943,8 +943,8 @@ static void p4_pmu_enable_pebs(u64 config) bind = &p4_pebs_bind_map[idx]; - (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); - (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); + (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); + (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); } static void p4_pmu_enable_event(struct perf_event *event) @@ -978,8 +978,8 @@ static void p4_pmu_enable_event(struct perf_event *event) */ p4_pmu_enable_pebs(hwc->config); - (void)wrmsrl_safe(escr_addr, escr_conf); - (void)wrmsrl_safe(hwc->config_base, + (void)checking_wrmsrl(escr_addr, escr_conf); + (void)checking_wrmsrl(hwc->config_base, (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); } diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p6.c b/trunk/arch/x86/kernel/cpu/perf_event_p6.c index e4dd0f7a0453..32bcfc7dd230 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p6.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p6.c @@ -71,7 +71,7 @@ p6_pmu_disable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)wrmsrl_safe(hwc->config_base, val); + (void)checking_wrmsrl(hwc->config_base, val); } static void p6_pmu_enable_event(struct perf_event *event) @@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event) if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)wrmsrl_safe(hwc->config_base, val); + (void)checking_wrmsrl(hwc->config_base, val); } PMU_FORMAT_ATTR(event, "config:0-7" ); diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c index fbdfc6917180..24b852b61be3 100644 --- a/trunk/arch/x86/kernel/microcode_core.c +++ b/trunk/arch/x86/kernel/microcode_core.c @@ -298,19 +298,31 @@ static ssize_t reload_store(struct device *dev, const char *buf, size_t size) { unsigned long val; - int cpu = dev->id; - ssize_t ret = 0; + int cpu; + ssize_t ret = 0, tmp_ret; + + /* allow reload only from the BSP */ + if (boot_cpu_data.cpu_index != dev->id) + return -EINVAL; ret = kstrtoul(buf, 0, &val); if (ret) return ret; - if (val == 1) { - get_online_cpus(); - if (cpu_online(cpu)) - ret = reload_for_cpu(cpu); - put_online_cpus(); + if (val != 1) + return size; + + get_online_cpus(); + for_each_online_cpu(cpu) { + tmp_ret = reload_for_cpu(cpu); + if (tmp_ret != 0) + pr_warn("Error reloading microcode on CPU %d\n", cpu); + + /* save retval of the first encountered reload error */ + if (!ret) + ret = tmp_ret; } + put_online_cpus(); if (!ret) ret = size; diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index 17fff18a1031..9ce885996fd7 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -352,7 +352,9 @@ struct pv_cpu_ops pv_cpu_ops = { #endif .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = native_write_msr_safe, + .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, .read_tscp = native_read_tscp, diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index 3e215ba68766..61cdf7fdf099 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -466,7 +466,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) task->thread.gs = addr; if (doit) { load_gs_index(0); - ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); + ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); } } put_cpu(); @@ -494,7 +494,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); - ret = wrmsrl_safe(MSR_FS_BASE, addr); + ret = checking_wrmsrl(MSR_FS_BASE, addr); } } put_cpu(); diff --git a/trunk/arch/x86/kernel/uprobes.c b/trunk/arch/x86/kernel/uprobes.c index 36fd42091fa7..dc4e910a7d96 100644 --- a/trunk/arch/x86/kernel/uprobes.c +++ b/trunk/arch/x86/kernel/uprobes.c @@ -409,10 +409,9 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. * @mm: the probed address space. * @arch_uprobe: the probepoint information. - * @addr: virtual address at which to install the probepoint * Return 0 on success or a -ve number on error. */ -int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr) +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm) { int ret; struct insn insn; diff --git a/trunk/arch/x86/lib/msr-reg-export.c b/trunk/arch/x86/lib/msr-reg-export.c index 8d6ef78b5d01..a311cc59b65d 100644 --- a/trunk/arch/x86/lib/msr-reg-export.c +++ b/trunk/arch/x86/lib/msr-reg-export.c @@ -1,5 +1,5 @@ #include #include -EXPORT_SYMBOL(rdmsr_safe_regs); -EXPORT_SYMBOL(wrmsr_safe_regs); +EXPORT_SYMBOL(native_rdmsr_safe_regs); +EXPORT_SYMBOL(native_wrmsr_safe_regs); diff --git a/trunk/arch/x86/lib/msr-reg.S b/trunk/arch/x86/lib/msr-reg.S index f6d13eefad10..69fa10623f21 100644 --- a/trunk/arch/x86/lib/msr-reg.S +++ b/trunk/arch/x86/lib/msr-reg.S @@ -6,13 +6,13 @@ #ifdef CONFIG_X86_64 /* - * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); + * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); * * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] * */ .macro op_safe_regs op -ENTRY(\op\()_safe_regs) +ENTRY(native_\op\()_safe_regs) CFI_STARTPROC pushq_cfi %rbx pushq_cfi %rbp @@ -45,13 +45,13 @@ ENTRY(\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(\op\()_safe_regs) +ENDPROC(native_\op\()_safe_regs) .endm #else /* X86_32 */ .macro op_safe_regs op -ENTRY(\op\()_safe_regs) +ENTRY(native_\op\()_safe_regs) CFI_STARTPROC pushl_cfi %ebx pushl_cfi %ebp @@ -92,7 +92,7 @@ ENTRY(\op\()_safe_regs) _ASM_EXTABLE(1b, 3b) CFI_ENDPROC -ENDPROC(\op\()_safe_regs) +ENDPROC(native_\op\()_safe_regs) .endm #endif diff --git a/trunk/arch/x86/vdso/vdso32-setup.c b/trunk/arch/x86/vdso/vdso32-setup.c index 0faad646f5fd..66e6d9359826 100644 --- a/trunk/arch/x86/vdso/vdso32-setup.c +++ b/trunk/arch/x86/vdso/vdso32-setup.c @@ -205,9 +205,9 @@ void syscall32_cpu_init(void) { /* Load these always in case some future AMD CPU supports SYSENTER from compat mode too. */ - wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); - wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); - wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); + checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); + checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); + checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); wrmsrl(MSR_CSTAR, ia32_cstar_target); } diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index ed7d54985d0c..ff962d4b821e 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -1124,7 +1124,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { .wbinvd = native_wbinvd, .read_msr = native_read_msr_safe, + .rdmsr_regs = native_rdmsr_safe_regs, .write_msr = xen_write_msr_safe, + .wrmsr_regs = native_wrmsr_safe_regs, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index e7dee617358e..02cf6335e9bd 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -125,8 +125,12 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q) blkg->pd[i] = pd; pd->blkg = blkg; + } + + /* invoke per-policy init */ + for (i = 0; i < BLKCG_MAX_POLS; i++) { + struct blkcg_policy *pol = blkcg_policy[i]; - /* invoke per-policy init */ if (blkcg_policy_enabled(blkg->q, pol)) pol->pd_init_fn(blkg); } @@ -241,9 +245,10 @@ EXPORT_SYMBOL_GPL(blkg_lookup_create); static void blkg_destroy(struct blkcg_gq *blkg) { + struct request_queue *q = blkg->q; struct blkcg *blkcg = blkg->blkcg; - lockdep_assert_held(blkg->q->queue_lock); + lockdep_assert_held(q->queue_lock); lockdep_assert_held(&blkcg->lock); /* Something wrong if we are trying to remove same group twice */ diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 93eb3e4f88ce..3c923a7aeb56 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -361,10 +361,9 @@ EXPORT_SYMBOL(blk_put_queue); */ void blk_drain_queue(struct request_queue *q, bool drain_all) { - int i; - while (true) { bool drain = false; + int i; spin_lock_irq(q->queue_lock); @@ -409,18 +408,6 @@ void blk_drain_queue(struct request_queue *q, bool drain_all) break; msleep(10); } - - /* - * With queue marked dead, any woken up waiter will fail the - * allocation path, so the wakeup chaining is lost and we're - * left with hung waiters. We need to wake up those waiters. - */ - if (q->request_fn) { - spin_lock_irq(q->queue_lock); - for (i = 0; i < ARRAY_SIZE(q->rq.wait); i++) - wake_up_all(&q->rq.wait[i]); - spin_unlock_irq(q->queue_lock); - } } /** @@ -480,6 +467,7 @@ void blk_cleanup_queue(struct request_queue *q) /* mark @q DEAD, no new request or merges will be allowed afterwards */ mutex_lock(&q->sysfs_lock); queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q); + spin_lock_irq(lock); /* @@ -497,6 +485,10 @@ void blk_cleanup_queue(struct request_queue *q) queue_flag_set(QUEUE_FLAG_NOMERGES, q); queue_flag_set(QUEUE_FLAG_NOXMERGES, q); queue_flag_set(QUEUE_FLAG_DEAD, q); + + if (q->queue_lock != &q->__queue_lock) + q->queue_lock = &q->__queue_lock; + spin_unlock_irq(lock); mutex_unlock(&q->sysfs_lock); @@ -507,11 +499,6 @@ void blk_cleanup_queue(struct request_queue *q) del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer); blk_sync_queue(q); - spin_lock_irq(lock); - if (q->queue_lock != &q->__queue_lock) - q->queue_lock = &q->__queue_lock; - spin_unlock_irq(lock); - /* @q is and will stay empty, shutdown and put */ blk_put_queue(q); } diff --git a/trunk/block/blk-timeout.c b/trunk/block/blk-timeout.c index 6e4744cbfb56..780354888958 100644 --- a/trunk/block/blk-timeout.c +++ b/trunk/block/blk-timeout.c @@ -197,3 +197,44 @@ void blk_add_timer(struct request *req) mod_timer(&q->timeout, expiry); } +/** + * blk_abort_queue -- Abort all request on given queue + * @queue: pointer to queue + * + */ +void blk_abort_queue(struct request_queue *q) +{ + unsigned long flags; + struct request *rq, *tmp; + LIST_HEAD(list); + + /* + * Not a request based block device, nothing to abort + */ + if (!q->request_fn) + return; + + spin_lock_irqsave(q->queue_lock, flags); + + elv_abort_queue(q); + + /* + * Splice entries to local list, to avoid deadlocking if entries + * get readded to the timeout list by error handling + */ + list_splice_init(&q->timeout_list, &list); + + list_for_each_entry_safe(rq, tmp, &list, timeout_list) + blk_abort_request(rq); + + /* + * Occasionally, blk_abort_request() will return without + * deleting the element from the list. Make sure we add those back + * instead of leaving them on the local stack list. + */ + list_splice(&list, &q->timeout_list); + + spin_unlock_irqrestore(q->queue_lock, flags); + +} +EXPORT_SYMBOL_GPL(blk_abort_queue); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index fb52df9744f5..673c977cc2bf 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -17,6 +17,8 @@ #include "blk.h" #include "blk-cgroup.h" +static struct blkcg_policy blkcg_policy_cfq __maybe_unused; + /* * tunables */ @@ -416,6 +418,11 @@ static inline struct cfq_group *pd_to_cfqg(struct blkg_policy_data *pd) return pd ? container_of(pd, struct cfq_group, pd) : NULL; } +static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) +{ + return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); +} + static inline struct blkcg_gq *cfqg_to_blkg(struct cfq_group *cfqg) { return pd_to_blkg(&cfqg->pd); @@ -565,13 +572,6 @@ static inline void cfqg_stats_update_avg_queue_size(struct cfq_group *cfqg) { } #ifdef CONFIG_CFQ_GROUP_IOSCHED -static struct blkcg_policy blkcg_policy_cfq; - -static inline struct cfq_group *blkg_to_cfqg(struct blkcg_gq *blkg) -{ - return pd_to_cfqg(blkg_to_pd(blkg, &blkcg_policy_cfq)); -} - static inline void cfqg_get(struct cfq_group *cfqg) { return blkg_get(cfqg_to_blkg(cfqg)); @@ -3951,11 +3951,10 @@ static void cfq_exit_queue(struct elevator_queue *e) cfq_shutdown_timer_wq(cfqd); -#ifdef CONFIG_CFQ_GROUP_IOSCHED - blkcg_deactivate_policy(q, &blkcg_policy_cfq); -#else +#ifndef CONFIG_CFQ_GROUP_IOSCHED kfree(cfqd->root_group); #endif + blkcg_deactivate_policy(q, &blkcg_policy_cfq); kfree(cfqd); } @@ -4195,15 +4194,14 @@ static int __init cfq_init(void) #ifdef CONFIG_CFQ_GROUP_IOSCHED if (!cfq_group_idle) cfq_group_idle = 1; +#else + cfq_group_idle = 0; +#endif ret = blkcg_policy_register(&blkcg_policy_cfq); if (ret) return ret; -#else - cfq_group_idle = 0; -#endif - ret = -ENOMEM; cfq_pool = KMEM_CACHE(cfq_queue, 0); if (!cfq_pool) goto err_pol_unreg; @@ -4217,17 +4215,13 @@ static int __init cfq_init(void) err_free_pool: kmem_cache_destroy(cfq_pool); err_pol_unreg: -#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); -#endif return ret; } static void __exit cfq_exit(void) { -#ifdef CONFIG_CFQ_GROUP_IOSCHED blkcg_policy_unregister(&blkcg_policy_cfq); -#endif elv_unregister(&iosched_cfq); kmem_cache_destroy(cfq_pool); } diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 9a87daa6f4fb..260fa80ef575 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -721,14 +721,11 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) break; } - if (capable(CAP_SYS_RAWIO)) - return 0; - /* In particular, rule out all resets and host-specific ioctls. */ printk_ratelimited(KERN_WARNING "%s: sending ioctl %x to a partition!\n", current->comm, cmd); - return -ENOIOCTLCMD; + return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD; } EXPORT_SYMBOL(scsi_verify_blk_ioctl); diff --git a/trunk/drivers/block/drbd/drbd_bitmap.c b/trunk/drivers/block/drbd/drbd_bitmap.c index fcb956bb4b4c..b5c5ff53cb57 100644 --- a/trunk/drivers/block/drbd/drbd_bitmap.c +++ b/trunk/drivers/block/drbd/drbd_bitmap.c @@ -1475,17 +1475,10 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi first_word = 0; spin_lock_irq(&b->bm_lock); } + /* last page (respectively only page, for first page == last page) */ last_word = MLPP(el >> LN2_BPL); - - /* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples). - * ==> e = 32767, el = 32768, last_page = 2, - * and now last_word = 0. - * We do not want to touch last_page in this case, - * as we did not allocate it, it is not present in bitmap->bm_pages. - */ - if (last_word) - bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); + bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); /* possibly trailing bits. * example: (e & 63) == 63, el will be e+1. diff --git a/trunk/drivers/block/drbd/drbd_req.c b/trunk/drivers/block/drbd/drbd_req.c index 8e93a6ac9bb6..9c5c84946b05 100644 --- a/trunk/drivers/block/drbd/drbd_req.c +++ b/trunk/drivers/block/drbd/drbd_req.c @@ -472,17 +472,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - if (req->rq_state & RQ_LOCAL_ABORTED) { - _req_may_be_done(req, m); - break; - } + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); __drbd_chk_io_error(mdev, false); goto_queue_for_net_read: - D_ASSERT(!(req->rq_state & RQ_NET_MASK)); - /* no point in retrying if there is no good remote data, * or we have no connection. */ if (mdev->state.pdsk != D_UP_TO_DATE) { @@ -770,40 +765,6 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); } -static void maybe_pull_ahead(struct drbd_conf *mdev) -{ - int congested = 0; - - /* If I don't even have good local storage, we can not reasonably try - * to pull ahead of the peer. We also need the local reference to make - * sure mdev->act_log is there. - * Note: caller has to make sure that net_conf is there. - */ - if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) - return; - - if (mdev->net_conf->cong_fill && - atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { - dev_info(DEV, "Congestion-fill threshold reached\n"); - congested = 1; - } - - if (mdev->act_log->used >= mdev->net_conf->cong_extents) { - dev_info(DEV, "Congestion-extents threshold reached\n"); - congested = 1; - } - - if (congested) { - queue_barrier(mdev); /* last barrier, after mirrored writes */ - - if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) - _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); - else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); - } - put_ldev(mdev); -} - static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) { const int rw = bio_rw(bio); @@ -1011,8 +972,29 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns _req_mod(req, queue_for_send_oos); if (remote && - mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) - maybe_pull_ahead(mdev); + mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) { + int congested = 0; + + if (mdev->net_conf->cong_fill && + atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { + dev_info(DEV, "Congestion-fill threshold reached\n"); + congested = 1; + } + + if (mdev->act_log->used >= mdev->net_conf->cong_extents) { + dev_info(DEV, "Congestion-extents threshold reached\n"); + congested = 1; + } + + if (congested) { + queue_barrier(mdev); /* last barrier, after mirrored writes */ + + if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) + _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); + else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ + _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); + } + } spin_unlock_irq(&mdev->req_lock); kfree(b); /* if someone else has beaten us to it... */ diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 553f43a90953..cce7df367b79 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -671,7 +671,6 @@ static void __reschedule_timeout(int drive, const char *message) if (drive == current_reqD) drive = current_drive; - __cancel_delayed_work(&fd_timeout); if (drive < 0 || drive >= N_DRIVE) { delay = 20UL * HZ; diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index a8fddeb3d638..264bc77dcb91 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -37,7 +37,6 @@ #include #include <../drivers/ata/ahci.h> #include -#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -86,7 +85,6 @@ static int instance; * allocated in mtip_init(). */ static int mtip_major; -static struct dentry *dfs_parent; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); @@ -2548,7 +2546,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, } /* - * Sysfs status dump. + * Sysfs register/status dump. * * @dev Pointer to the device structure, passed by the kernrel. * @attr Pointer to the device_attribute structure passed by the kernel. @@ -2557,68 +2555,45 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_status(struct device *dev, +static ssize_t mtip_hw_show_registers(struct device *dev, struct device_attribute *attr, char *buf) { + u32 group_allocated; struct driver_data *dd = dev_to_disk(dev)->private_data; int size = 0; - - if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "write_protect\n"); - else - size += sprintf(buf, "%s", "online\n"); - - return size; -} - -static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); - -static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) -{ - struct driver_data *dd = (struct driver_data *)f->private_data; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - u32 group_allocated; - int size = *offset; int n; - if (!len || size) - return 0; - - if (size < 0) - return -EINVAL; - - size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); + size += sprintf(&buf[size], "Hardware\n--------\n"); + size += sprintf(&buf[size], "S ACTive : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->s_active[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ Command Issue : [ 0x"); + size += sprintf(&buf[size], "Command Issue : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->cmd_issue[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ Completed : [ 0x"); + size += sprintf(&buf[size], "Completed : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->completed[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "H/ PORT IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "H/ HOST IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", readl(dd->mmio + HOST_IRQ_STAT)); size += sprintf(&buf[size], "\n"); - size += sprintf(&buf[size], "L/ Allocated : [ 0x"); + size += sprintf(&buf[size], "Local\n-----\n"); + size += sprintf(&buf[size], "Allocated : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2630,7 +2605,7 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, } size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "L/ Commands in Q : [ 0x"); + size += sprintf(&buf[size], "Commands in Q: [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2642,53 +2617,44 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, } size += sprintf(&buf[size], "]\n"); - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; + return size; } -static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) +static ssize_t mtip_hw_show_status(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct driver_data *dd = (struct driver_data *)f->private_data; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - int size = *offset; + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; - if (!len || size) - return 0; + if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "thermal_shutdown\n"); + else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "write_protect\n"); + else + size += sprintf(buf, "%s", "online\n"); - if (size < 0) - return -EINVAL; + return size; +} - size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", +static ssize_t mtip_hw_show_flags(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct driver_data *dd = dev_to_disk(dev)->private_data; + int size = 0; + + size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", dd->port->flags); - size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", + size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", dd->dd_flag); - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; + return size; } -static const struct file_operations mtip_regs_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_registers, - .llseek = no_llseek, -}; - -static const struct file_operations mtip_flags_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_flags, - .llseek = no_llseek, -}; +static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); +static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); +static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); /* * Create the sysfs related attributes. @@ -2705,9 +2671,15 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; + if (sysfs_create_file(kobj, &dev_attr_registers.attr)) + dev_warn(&dd->pdev->dev, + "Error creating 'registers' sysfs entry\n"); if (sysfs_create_file(kobj, &dev_attr_status.attr)) dev_warn(&dd->pdev->dev, "Error creating 'status' sysfs entry\n"); + if (sysfs_create_file(kobj, &dev_attr_flags.attr)) + dev_warn(&dd->pdev->dev, + "Error creating 'flags' sysfs entry\n"); return 0; } @@ -2726,39 +2698,13 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; + sysfs_remove_file(kobj, &dev_attr_registers.attr); sysfs_remove_file(kobj, &dev_attr_status.attr); + sysfs_remove_file(kobj, &dev_attr_flags.attr); return 0; } -static int mtip_hw_debugfs_init(struct driver_data *dd) -{ - if (!dfs_parent) - return -1; - - dd->dfs_node = debugfs_create_dir(dd->disk->disk_name, dfs_parent); - if (IS_ERR_OR_NULL(dd->dfs_node)) { - dev_warn(&dd->pdev->dev, - "Error creating node %s under debugfs\n", - dd->disk->disk_name); - dd->dfs_node = NULL; - return -1; - } - - debugfs_create_file("flags", S_IRUGO, dd->dfs_node, dd, - &mtip_flags_fops); - debugfs_create_file("registers", S_IRUGO, dd->dfs_node, dd, - &mtip_regs_fops); - - return 0; -} - -static void mtip_hw_debugfs_exit(struct driver_data *dd) -{ - debugfs_remove_recursive(dd->dfs_node); -} - - /* * Perform any init/resume time hardware setup * @@ -3784,7 +3730,6 @@ static int mtip_block_initialize(struct driver_data *dd) mtip_hw_sysfs_init(dd, kobj); kobject_put(kobj); } - mtip_hw_debugfs_init(dd); if (dd->mtip_svc_handler) { set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); @@ -3810,8 +3755,6 @@ static int mtip_block_initialize(struct driver_data *dd) return rv; kthread_run_error: - mtip_hw_debugfs_exit(dd); - /* Delete our gendisk. This also removes the device from /dev */ del_gendisk(dd->disk); @@ -3862,7 +3805,6 @@ static int mtip_block_remove(struct driver_data *dd) kobject_put(kobj); } } - mtip_hw_debugfs_exit(dd); /* * Delete our gendisk structure. This also removes the device @@ -4210,20 +4152,10 @@ static int __init mtip_init(void) } mtip_major = error; - if (!dfs_parent) { - dfs_parent = debugfs_create_dir("rssd", NULL); - if (IS_ERR_OR_NULL(dfs_parent)) { - printk(KERN_WARNING "Error creating debugfs parent\n"); - dfs_parent = NULL; - } - } - /* Register our PCI operations. */ error = pci_register_driver(&mtip_pci_driver); - if (error) { - debugfs_remove(dfs_parent); + if (error) unregister_blkdev(mtip_major, MTIP_DRV_NAME); - } return error; } @@ -4240,8 +4172,6 @@ static int __init mtip_init(void) */ static void __exit mtip_exit(void) { - debugfs_remove_recursive(dfs_parent); - /* Release the allocated major block device number. */ unregister_blkdev(mtip_major, MTIP_DRV_NAME); diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index f51fc23d17bb..b2c88da26b2a 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -26,6 +26,7 @@ #include #include #include +#include /* Offset of Subsystem Device ID in pci confoguration space */ #define PCI_SUBSYSTEM_DEVICEID 0x2E @@ -110,8 +111,6 @@ #define dbg_printk(format, arg...) #endif -#define MTIP_DFS_MAX_BUF_SIZE 1024 - #define __force_bit2int (unsigned int __force) enum { @@ -448,8 +447,6 @@ struct driver_data { unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ - - struct dentry *dfs_node; }; #endif diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index 9a72277a31df..aa2712060bfb 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -513,44 +513,6 @@ static void process_page(unsigned long data) } } -struct mm_plug_cb { - struct blk_plug_cb cb; - struct cardinfo *card; -}; - -static void mm_unplug(struct blk_plug_cb *cb) -{ - struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); - - spin_lock_irq(&mmcb->card->lock); - activate(mmcb->card); - spin_unlock_irq(&mmcb->card->lock); - kfree(mmcb); -} - -static int mm_check_plugged(struct cardinfo *card) -{ - struct blk_plug *plug = current->plug; - struct mm_plug_cb *mmcb; - - if (!plug) - return 0; - - list_for_each_entry(mmcb, &plug->cb_list, cb.list) { - if (mmcb->cb.callback == mm_unplug && mmcb->card == card) - return 1; - } - /* Not currently on the callback list */ - mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); - if (!mmcb) - return 0; - - mmcb->card = card; - mmcb->cb.callback = mm_unplug; - list_add(&mmcb->cb.list, &plug->cb_list); - return 1; -} - static void mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -561,8 +523,6 @@ static void mm_make_request(struct request_queue *q, struct bio *bio) *card->biotail = bio; bio->bi_next = NULL; card->biotail = &bio->bi_next; - if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) - activate(card); spin_unlock_irq(&card->lock); return; diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 9ad3b5ec1dc1..773cf27dc23f 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -257,7 +257,6 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; - dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; @@ -288,7 +287,6 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; - dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index e4fb3374dcd2..60eed4bdd2e4 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -141,36 +141,14 @@ static int get_id_from_freelist(struct blkfront_info *info) return free; } -static int add_id_to_freelist(struct blkfront_info *info, +static void add_id_to_freelist(struct blkfront_info *info, unsigned long id) { - if (info->shadow[id].req.u.rw.id != id) - return -EINVAL; - if (info->shadow[id].request == NULL) - return -EINVAL; info->shadow[id].req.u.rw.id = info->shadow_free; info->shadow[id].request = NULL; info->shadow_free = id; - return 0; } -static const char *op_name(int op) -{ - static const char *const names[] = { - [BLKIF_OP_READ] = "read", - [BLKIF_OP_WRITE] = "write", - [BLKIF_OP_WRITE_BARRIER] = "barrier", - [BLKIF_OP_FLUSH_DISKCACHE] = "flush", - [BLKIF_OP_DISCARD] = "discard" }; - - if (op < 0 || op >= ARRAY_SIZE(names)) - return "unknown"; - - if (!names[op]) - return "reserved"; - - return names[op]; -} static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) { unsigned int end = minor + nr; @@ -768,36 +746,20 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; - /* - * The backend has messed up and given us an id that we would - * never have given to it (we stamp it up to BLK_RING_SIZE - - * look in get_id_from_freelist. - */ - if (id >= BLK_RING_SIZE) { - WARN(1, "%s: response to %s has incorrect id (%ld)\n", - info->gd->disk_name, op_name(bret->operation), id); - /* We can't safely get the 'struct request' as - * the id is busted. */ - continue; - } req = info->shadow[id].request; if (bret->operation != BLKIF_OP_DISCARD) blkif_completion(&info->shadow[id]); - if (add_id_to_freelist(info, id)) { - WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n", - info->gd->disk_name, op_name(bret->operation), id); - continue; - } + add_id_to_freelist(info, id); error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; switch (bret->operation) { case BLKIF_OP_DISCARD: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { struct request_queue *rq = info->rq; - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: discard op failed\n", + info->gd->disk_name); error = -EOPNOTSUPP; info->feature_discard = 0; info->feature_secdiscard = 0; @@ -809,14 +771,18 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_WRITE_BARRIER: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: write %s op failed\n", + info->flush_op == BLKIF_OP_WRITE_BARRIER ? + "barrier" : "flush disk cache", + info->gd->disk_name); error = -EOPNOTSUPP; } if (unlikely(bret->status == BLKIF_RSP_ERROR && info->shadow[id].req.u.rw.nr_segments == 0)) { - printk(KERN_WARNING "blkfront: %s: empty %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n", + info->flush_op == BLKIF_OP_WRITE_BARRIER ? + "barrier" : "flush disk cache", + info->gd->disk_name); error = -EOPNOTSUPP; } if (unlikely(error)) { diff --git a/trunk/drivers/clk/clk.c b/trunk/drivers/clk/clk.c index 9a1eb0cfa95f..dcbe05616090 100644 --- a/trunk/drivers/clk/clk.c +++ b/trunk/drivers/clk/clk.c @@ -1067,24 +1067,26 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) old_parent = clk->parent; - if (!clk->parents) + /* find index of new parent clock using cached parent ptrs */ + if (clk->parents) + for (i = 0; i < clk->num_parents; i++) + if (clk->parents[i] == parent) + break; + else clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to __clk_lookup. + * find index of new parent clock using string name comparison + * also try to cache the parent to avoid future calls to __clk_lookup */ - for (i = 0; i < clk->num_parents; i++) { - if (clk->parents && clk->parents[i] == parent) - break; - else if (!strcmp(clk->parent_names[i], parent->name)) { - if (clk->parents) - clk->parents[i] = __clk_lookup(parent->name); - break; - } - } + if (i == clk->num_parents) + for (i = 0; i < clk->num_parents; i++) + if (!strcmp(clk->parent_names[i], parent->name)) { + if (clk->parents) + clk->parents[i] = __clk_lookup(parent->name); + break; + } if (i == clk->num_parents) { pr_debug("%s: clock %s is not a possible parent of clock %s\n", diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index a8743c399e83..5873e481e5d2 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -1039,24 +1039,6 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid, return true; } -static bool valid_inferred_mode(const struct drm_connector *connector, - const struct drm_display_mode *mode) -{ - struct drm_display_mode *m; - bool ok = false; - - list_for_each_entry(m, &connector->probed_modes, head) { - if (mode->hdisplay == m->hdisplay && - mode->vdisplay == m->vdisplay && - drm_mode_vrefresh(mode) == drm_mode_vrefresh(m)) - return false; /* duplicated */ - if (mode->hdisplay <= m->hdisplay && - mode->vdisplay <= m->vdisplay) - ok = true; - } - return ok; -} - static int drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct detailed_timing *timing) @@ -1066,8 +1048,7 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct drm_device *dev = connector->dev; for (i = 0; i < drm_num_dmt_modes; i++) { - if (mode_in_range(drm_dmt_modes + i, edid, timing) && - valid_inferred_mode(connector, drm_dmt_modes + i)) { + if (mode_in_range(drm_dmt_modes + i, edid, timing)) { newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); if (newmode) { drm_mode_probed_add(connector, newmode); @@ -1107,8 +1088,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing) || - !valid_inferred_mode(connector, newmode)) { + if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue; } @@ -1136,8 +1116,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing) || - !valid_inferred_mode(connector, newmode)) { + if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue; } diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 36822b924eb1..f94792626b94 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1401,27 +1401,6 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, } } -static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{ - struct apertures_struct *ap; - struct pci_dev *pdev = dev_priv->dev->pdev; - bool primary; - - ap = alloc_apertures(1); - if (!ap) - return; - - ap->ranges[0].base = dev_priv->dev->agp->base; - ap->ranges[0].size = - dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - primary = - pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - - remove_conflicting_framebuffers(ap, "inteldrmfb", primary); - - kfree(ap); -} - /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1467,15 +1446,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto put_bridge; - } - - i915_kick_out_firmware_fb(dev_priv); - pci_set_master(dev->pdev); /* overlay on gen2 is broken and can't address above 1G */ @@ -1501,6 +1471,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_bridge; } + dev_priv->mm.gtt = intel_gtt_get(); + if (!dev_priv->mm.gtt) { + DRM_ERROR("Failed to initialize GTT\n"); + ret = -ENODEV; + goto out_rmmap; + } + aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; dev_priv->mm.gtt_mapping = diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gart.c b/trunk/drivers/gpu/drm/radeon/radeon_gart.c index 84b648a7ddd8..59d44937dd9f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gart.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gart.c @@ -289,9 +289,8 @@ int radeon_vm_manager_init(struct radeon_device *rdev) rdev->vm_manager.enabled = false; /* mark first vm as always in use, it's the system one */ - /* allocate enough for 2 full VM pts */ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8 * 2, + rdev->vm_manager.max_pfn * 8, RADEON_GEM_DOMAIN_VRAM); if (r) { dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", @@ -634,15 +633,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) mutex_init(&vm->mutex); INIT_LIST_HEAD(&vm->list); INIT_LIST_HEAD(&vm->va); - /* SI requires equal sized PTs for all VMs, so always set - * last_pfn to max_pfn. cayman allows variable sized - * pts so we can grow then as needed. Once we switch - * to two level pts we can unify this again. - */ - if (rdev->family >= CHIP_TAHITI) - vm->last_pfn = rdev->vm_manager.max_pfn; - else - vm->last_pfn = 0; + vm->last_pfn = 0; /* map the ib pool buffer at 0 in virtual address space, set * read only */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gem.c b/trunk/drivers/gpu/drm/radeon/radeon_gem.c index 21ec9f5653ce..f28bd4b7ef98 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gem.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gem.c @@ -292,7 +292,6 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { - struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_busy *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -318,14 +317,13 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, break; } drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(rdev, r); + r = radeon_gem_handle_lockup(robj->rdev, r); return r; } int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { - struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_wait_idle *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -338,10 +336,10 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, robj = gem_to_radeon_bo(gobj); r = radeon_bo_wait(robj, NULL, false); /* callback hw specific functions if any */ - if (rdev->asic->ioctl_wait_idle) - robj->rdev->asic->ioctl_wait_idle(rdev, robj); + if (robj->rdev->asic->ioctl_wait_idle) + robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(rdev, r); + r = radeon_gem_handle_lockup(robj->rdev, r); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 0b0279291a73..c7b61f16ecfd 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2365,12 +2365,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev) WREG32(0x15DC, 0); /* empty context1-15 */ - /* FIXME start with 4G, once using 2 level pt switch to full + /* FIXME start with 1G, once using 2 level pt switch to full * vm size space */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); for (i = 1; i < 16; i++) { if (i < 8) WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), diff --git a/trunk/drivers/md/dm-thin.c b/trunk/drivers/md/dm-thin.c index ce59824fb414..37fdaf81bd1f 100644 --- a/trunk/drivers/md/dm-thin.c +++ b/trunk/drivers/md/dm-thin.c @@ -2292,13 +2292,6 @@ static int process_reserve_metadata_snap_mesg(unsigned argc, char **argv, struct if (r) return r; - r = dm_pool_commit_metadata(pool->pmd); - if (r) { - DMERR("%s: dm_pool_commit_metadata() failed, error = %d", - __func__, r); - return r; - } - r = dm_pool_reserve_metadata_snap(pool->pmd); if (r) DMWARN("reserve_metadata_snap message failed."); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index a4c219e3c859..1c2f9048e1ae 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -5784,7 +5784,8 @@ static int add_new_disk(struct mddev * mddev, mdu_disk_info_t *info) super_types[mddev->major_version]. validate_super(mddev, rdev); if ((info->state & (1<raid_disk != info->raid_disk) { + (!test_bit(In_sync, &rdev->flags) || + rdev->raid_disk != info->raid_disk)) { /* This was a hot-add request, but events doesn't * match, so reject it. */ @@ -6750,7 +6751,7 @@ struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev thread->tsk = kthread_run(md_thread, thread, "%s_%s", mdname(thread->mddev), - name); + name ?: mddev->pers->name); if (IS_ERR(thread->tsk)) { kfree(thread); return NULL; @@ -7297,7 +7298,6 @@ void md_do_sync(struct mddev *mddev) int skipped = 0; struct md_rdev *rdev; char *desc; - struct blk_plug plug; /* just incase thread restarts... */ if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) @@ -7447,7 +7447,6 @@ void md_do_sync(struct mddev *mddev) } mddev->curr_resync_completed = j; - blk_start_plug(&plug); while (j < max_sectors) { sector_t sectors; @@ -7553,7 +7552,6 @@ void md_do_sync(struct mddev *mddev) * this also signals 'finished resyncing' to md_stop */ out: - blk_finish_plug(&plug); wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); /* tell personality that we are finished */ diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 61a1833ebaf3..9339e67fcc79 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -474,8 +474,7 @@ static int multipath_run (struct mddev *mddev) } { - mddev->thread = md_register_thread(multipathd, mddev, - "multipath"); + mddev->thread = md_register_thread(multipathd, mddev, NULL); if (!mddev->thread) { printk(KERN_ERR "multipath: couldn't allocate thread" " for %s\n", mdname(mddev)); diff --git a/trunk/drivers/md/persistent-data/dm-space-map-checker.c b/trunk/drivers/md/persistent-data/dm-space-map-checker.c index fc90c11620ad..50ed53bf4aa2 100644 --- a/trunk/drivers/md/persistent-data/dm-space-map-checker.c +++ b/trunk/drivers/md/persistent-data/dm-space-map-checker.c @@ -8,7 +8,6 @@ #include #include -#include #ifdef CONFIG_DM_DEBUG_SPACE_MAPS @@ -90,23 +89,13 @@ static int ca_create(struct count_array *ca, struct dm_space_map *sm) ca->nr = nr_blocks; ca->nr_free = nr_blocks; - - if (!nr_blocks) - ca->counts = NULL; - else { - ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks); - if (!ca->counts) - return -ENOMEM; - } + ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL); + if (!ca->counts) + return -ENOMEM; return 0; } -static void ca_destroy(struct count_array *ca) -{ - vfree(ca->counts); -} - static int ca_load(struct count_array *ca, struct dm_space_map *sm) { int r; @@ -137,14 +126,12 @@ static int ca_load(struct count_array *ca, struct dm_space_map *sm) static int ca_extend(struct count_array *ca, dm_block_t extra_blocks) { dm_block_t nr_blocks = ca->nr + extra_blocks; - uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks); + uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL); if (!counts) return -ENOMEM; - if (ca->counts) { - memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); - ca_destroy(ca); - } + memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); + kfree(ca->counts); ca->nr = nr_blocks; ca->nr_free += extra_blocks; ca->counts = counts; @@ -164,6 +151,11 @@ static int ca_commit(struct count_array *old, struct count_array *new) return 0; } +static void ca_destroy(struct count_array *ca) +{ + kfree(ca->counts); +} + /*----------------------------------------------------------------*/ struct sm_checker { @@ -351,25 +343,25 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (IS_ERR_OR_NULL(sm)) - return ERR_PTR(-EINVAL); + if (!sm) + return NULL; smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return ERR_PTR(-ENOMEM); + return NULL; memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } smc->real_sm = sm; @@ -379,7 +371,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_commit(&smc->old_counts, &smc->counts); @@ -387,7 +379,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } return &smc->sm; @@ -399,25 +391,25 @@ struct dm_space_map *dm_sm_checker_create_fresh(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (IS_ERR_OR_NULL(sm)) - return ERR_PTR(-EINVAL); + if (!sm) + return NULL; smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return ERR_PTR(-ENOMEM); + return NULL; memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return ERR_PTR(r); + return NULL; } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return ERR_PTR(r); + return NULL; } smc->real_sm = sm; diff --git a/trunk/drivers/md/persistent-data/dm-space-map-disk.c b/trunk/drivers/md/persistent-data/dm-space-map-disk.c index 3d0ed5332883..fc469ba9f627 100644 --- a/trunk/drivers/md/persistent-data/dm-space-map-disk.c +++ b/trunk/drivers/md/persistent-data/dm-space-map-disk.c @@ -290,16 +290,7 @@ struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm, dm_block_t nr_blocks) { struct dm_space_map *sm = dm_sm_disk_create_real(tm, nr_blocks); - struct dm_space_map *smc; - - if (IS_ERR_OR_NULL(sm)) - return sm; - - smc = dm_sm_checker_create_fresh(sm); - if (IS_ERR(smc)) - dm_sm_destroy(sm); - - return smc; + return dm_sm_checker_create_fresh(sm); } EXPORT_SYMBOL_GPL(dm_sm_disk_create); diff --git a/trunk/drivers/md/persistent-data/dm-transaction-manager.c b/trunk/drivers/md/persistent-data/dm-transaction-manager.c index e5604b32d91f..400fe144c0cd 100644 --- a/trunk/drivers/md/persistent-data/dm-transaction-manager.c +++ b/trunk/drivers/md/persistent-data/dm-transaction-manager.c @@ -138,9 +138,6 @@ EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone); void dm_tm_destroy(struct dm_transaction_manager *tm) { - if (!tm->is_clone) - wipe_shadow_table(tm); - kfree(tm); } EXPORT_SYMBOL_GPL(dm_tm_destroy); @@ -347,10 +344,8 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (IS_ERR(*sm)) { - r = PTR_ERR(*sm); + if (!*sm) goto bad2; - } } else { r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location, @@ -369,10 +364,8 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (IS_ERR(*sm)) { - r = PTR_ERR(*sm); + if (!*sm) goto bad2; - } } return 0; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 8c2754f835ef..a9c7981ddd24 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -517,8 +517,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect int bad_sectors; int disk = start_disk + i; - if (disk >= conf->raid_disks * 2) - disk -= conf->raid_disks * 2; + if (disk >= conf->raid_disks) + disk -= conf->raid_disks; rdev = rcu_dereference(conf->mirrors[disk].rdev); if (r1_bio->bios[disk] == IO_BLOCKED @@ -883,6 +883,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); struct md_rdev *blocked_rdev; + int plugged; int first_clone; int sectors_handled; int max_sectors; @@ -1033,6 +1034,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) * the bad blocks. Each set of writes gets it's own r1bio * with a set of bios attached. */ + plugged = mddev_check_plugged(mddev); disks = conf->raid_disks * 2; retry_write: @@ -1189,8 +1191,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } /* Mustn't call r1_bio_write_done before this next test, * as it could result in the bio being freed. @@ -1213,6 +1213,9 @@ static void make_request(struct mddev *mddev, struct bio * bio) /* In case raid1d snuck in to freeze_array */ wake_up(&conf->wait_barrier); + + if (do_sync || !bitmap || !plugged) + md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -2618,7 +2621,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) goto abort; } err = -ENOMEM; - conf->thread = md_register_thread(raid1d, mddev, "raid1"); + conf->thread = md_register_thread(raid1d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR "md/raid1:%s: couldn't allocate thread\n", diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 8da6282254c3..99ae6068e456 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1039,6 +1039,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_fua = (bio->bi_rw & REQ_FUA); unsigned long flags; struct md_rdev *blocked_rdev; + int plugged; int sectors_handled; int max_sectors; int sectors; @@ -1238,6 +1239,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) * of r10_bios is recored in bio->bi_phys_segments just as with * the read case. */ + plugged = mddev_check_plugged(mddev); r10_bio->read_slot = -1; /* make sure repl_bio gets freed */ raid10_find_phys(conf, r10_bio); @@ -1394,8 +1396,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); if (!r10_bio->devs[i].repl_bio) continue; @@ -1423,8 +1423,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); - if (!mddev_check_plugged(mddev)) - md_wakeup_thread(mddev->thread); } /* Don't remove the bias on 'remaining' (one_write_done) until @@ -1450,6 +1448,9 @@ static void make_request(struct mddev *mddev, struct bio * bio) /* In case raid10d snuck in to freeze_array */ wake_up(&conf->wait_barrier); + + if (do_sync || !mddev->bitmap || !plugged) + md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -2309,7 +2310,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 if (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s, conf->tmppage, WRITE) + s<<9, conf->tmppage, WRITE) == 0) { /* Well, this device is dead */ printk(KERN_NOTICE @@ -2348,7 +2349,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 switch (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s, conf->tmppage, + s<<9, conf->tmppage, READ)) { case 0: /* Well, this device is dead */ @@ -2511,7 +2512,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) slot = r10_bio->read_slot; printk_ratelimited( KERN_ERR - "md/raid10:%s: %s: redirecting " + "md/raid10:%s: %s: redirecting" "sector %llu to another mirror\n", mdname(mddev), bdevname(rdev->bdev, b), @@ -2660,8 +2661,7 @@ static void raid10d(struct mddev *mddev) blk_start_plug(&plug); for (;;) { - if (atomic_read(&mddev->plug_cnt) == 0) - flush_pending_writes(conf); + flush_pending_writes(conf); spin_lock_irqsave(&conf->device_lock, flags); if (list_empty(head)) { @@ -2890,12 +2890,6 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, /* want to reconstruct this device */ rb2 = r10_bio; sect = raid10_find_virt(conf, sector_nr, i); - if (sect >= mddev->resync_max_sectors) { - /* last stripe is not complete - don't - * try to recover this sector. - */ - continue; - } /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3427,7 +3421,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) spin_lock_init(&conf->resync_lock); init_waitqueue_head(&conf->wait_barrier); - conf->thread = md_register_thread(raid10d, mddev, "raid10"); + conf->thread = md_register_thread(raid10d, mddev, NULL); if (!conf->thread) goto out; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 04348d76bb30..d26767246d26 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -196,14 +196,12 @@ static void __release_stripe(struct r5conf *conf, struct stripe_head *sh) BUG_ON(!list_empty(&sh->lru)); BUG_ON(atomic_read(&conf->active_stripes)==0); if (test_bit(STRIPE_HANDLE, &sh->state)) { - if (test_bit(STRIPE_DELAYED, &sh->state) && - !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) + if (test_bit(STRIPE_DELAYED, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) list_add_tail(&sh->lru, &conf->bitmap_list); else { - clear_bit(STRIPE_DELAYED, &sh->state); clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); } @@ -608,12 +606,6 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) * a chance*/ md_check_recovery(conf->mddev); } - /* - * Because md_wait_for_blocked_rdev - * will dec nr_pending, we must - * increment it first. - */ - atomic_inc(&rdev->nr_pending); md_wait_for_blocked_rdev(rdev, conf->mddev); } else { /* Acknowledged bad block - skip the write */ @@ -1745,7 +1737,6 @@ static void raid5_end_read_request(struct bio * bi, int error) } else { const char *bdn = bdevname(rdev->bdev, b); int retry = 0; - int set_bad = 0; clear_bit(R5_UPTODATE, &sh->dev[i].flags); atomic_inc(&rdev->read_errors); @@ -1757,8 +1748,7 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - else if (conf->mddev->degraded >= conf->max_degraded) { - set_bad = 1; + else if (conf->mddev->degraded >= conf->max_degraded) printk_ratelimited( KERN_WARNING "md/raid:%s: read error not correctable " @@ -1766,9 +1756,8 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - } else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) { + else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) /* Oh, no!!! */ - set_bad = 1; printk_ratelimited( KERN_WARNING "md/raid:%s: read error NOT corrected!! " @@ -1776,7 +1765,7 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - } else if (atomic_read(&rdev->read_errors) + else if (atomic_read(&rdev->read_errors) > conf->max_nr_stripes) printk(KERN_WARNING "md/raid:%s: Too many read errors, failing device %s.\n", @@ -1788,11 +1777,7 @@ static void raid5_end_read_request(struct bio * bi, int error) else { clear_bit(R5_ReadError, &sh->dev[i].flags); clear_bit(R5_ReWrite, &sh->dev[i].flags); - if (!(set_bad - && test_bit(In_sync, &rdev->flags) - && rdev_set_badblocks( - rdev, sh->sector, STRIPE_SECTORS, 0))) - md_error(conf->mddev, rdev); + md_error(conf->mddev, rdev); } } rdev_dec_pending(rdev, conf->mddev); @@ -3597,18 +3582,8 @@ static void handle_stripe(struct stripe_head *sh) finish: /* wait for this device to become unblocked */ - if (unlikely(s.blocked_rdev)) { - if (conf->mddev->external) - md_wait_for_blocked_rdev(s.blocked_rdev, - conf->mddev); - else - /* Internal metadata will immediately - * be written by raid5d, so we don't - * need to wait here. - */ - rdev_dec_pending(s.blocked_rdev, - conf->mddev); - } + if (conf->mddev->external && unlikely(s.blocked_rdev)) + md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); if (s.handle_bad_blocks) for (i = disks; i--; ) { @@ -3906,6 +3881,8 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) raid_bio->bi_next = (void*)rdev; align_bi->bi_bdev = rdev->bdev; align_bi->bi_flags &= ~(1 << BIO_SEG_VALID); + /* No reshape active, so we can trust rdev->data_offset */ + align_bi->bi_sector += rdev->data_offset; if (!bio_fits_rdev(align_bi) || is_badblock(rdev, align_bi->bi_sector, align_bi->bi_size>>9, @@ -3916,9 +3893,6 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) return 0; } - /* No reshape active, so we can trust rdev->data_offset */ - align_bi->bi_sector += rdev->data_offset; - spin_lock_irq(&conf->device_lock); wait_event_lock_irq(conf->wait_for_stripe, conf->quiesce == 0, @@ -3997,6 +3971,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) struct stripe_head *sh; const int rw = bio_data_dir(bi); int remaining; + int plugged; if (unlikely(bi->bi_rw & REQ_FLUSH)) { md_flush_request(mddev, bi); @@ -4015,6 +3990,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ + plugged = mddev_check_plugged(mddev); for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); int previous; @@ -4116,7 +4092,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ((bi->bi_rw & REQ_SYNC) && !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) atomic_inc(&conf->preread_active_stripes); - mddev_check_plugged(mddev); release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ @@ -4124,7 +4099,10 @@ static void make_request(struct mddev *mddev, struct bio * bi) finish_wait(&conf->wait_for_overlap, &w); break; } + } + if (!plugged) + md_wakeup_thread(mddev->thread); spin_lock_irq(&conf->device_lock); remaining = raid5_dec_bi_phys_segments(bi); @@ -4845,7 +4823,6 @@ static struct r5conf *setup_conf(struct mddev *mddev) int raid_disk, memory, max_disks; struct md_rdev *rdev; struct disk_info *disk; - char pers_name[6]; if (mddev->new_level != 5 && mddev->new_level != 4 @@ -4969,8 +4946,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) printk(KERN_INFO "md/raid:%s: allocated %dkB\n", mdname(mddev), memory); - sprintf(pers_name, "raid%d", mddev->new_level); - conf->thread = md_register_thread(raid5d, mddev, pers_name); + conf->thread = md_register_thread(raid5d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR "md/raid:%s: couldn't allocate thread.\n", @@ -5489,9 +5465,10 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk >= 0 && rdev->saved_raid_disk >= first && conf->disks[rdev->saved_raid_disk].rdev == NULL) - first = rdev->saved_raid_disk; - - for (disk = first; disk <= last; disk++) { + disk = rdev->saved_raid_disk; + else + disk = first; + for ( ; disk <= last ; disk++) { p = conf->disks + disk; if (p->rdev == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5500,11 +5477,8 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk != disk) conf->fullsync = 1; rcu_assign_pointer(p->rdev, rdev); - goto out; + break; } - } - for (disk = first; disk <= last; disk++) { - p = conf->disks + disk; if (test_bit(WantReplacement, &p->rdev->flags) && p->replacement == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5516,7 +5490,6 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) break; } } -out: print_raid5_conf(conf); return err; } diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index f2db8fca46a1..0741aded9eb0 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1804,16 +1804,18 @@ void gfar_configure_coalescing(struct gfar_private *priv, if (priv->mode == MQ_MG_MODE) { baddr = ®s->txic0; for_each_set_bit(i, &tx_mask, priv->num_tx_queues) { - gfar_write(baddr + i, 0); - if (likely(priv->tx_queue[i]->txcoalescing)) + if (likely(priv->tx_queue[i]->txcoalescing)) { + gfar_write(baddr + i, 0); gfar_write(baddr + i, priv->tx_queue[i]->txic); + } } baddr = ®s->rxic0; for_each_set_bit(i, &rx_mask, priv->num_rx_queues) { - gfar_write(baddr + i, 0); - if (likely(priv->rx_queue[i]->rxcoalescing)) + if (likely(priv->rx_queue[i]->rxcoalescing)) { + gfar_write(baddr + i, 0); gfar_write(baddr + i, priv->rx_queue[i]->rxic); + } } } } diff --git a/trunk/drivers/net/ethernet/intel/e1000e/defines.h b/trunk/drivers/net/ethernet/intel/e1000e/defines.h index 76edbc1be33b..351a4097b2ba 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/defines.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/defines.h @@ -103,7 +103,6 @@ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ #define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ #define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 623e30b9964d..31d37a2b5ba8 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -496,7 +496,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - struct sk_buff *skb) + __le16 csum, struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); @@ -511,8 +511,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, if (status & E1000_RXD_STAT_IXSM) return; - /* TCP/UDP checksum error bit or IP checksum error bit is set */ - if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) { + /* TCP/UDP checksum error bit is set */ + if (errors & E1000_RXD_ERR_TCPE) { /* let the stack verify checksum errors */ adapter->hw_csum_err++; return; @@ -523,7 +523,19 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, return; /* It must be a TCP or UDP packet with a valid checksum */ - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (status & E1000_RXD_STAT_TCPCS) { + /* TCP checksum is good */ + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + /* + * IP fragment with UDP payload + * Hardware complements the payload checksum, so we undo it + * and then put the value in host order for further stack use. + */ + __sum16 sum = (__force __sum16)swab16((__force u16)csum); + skb->csum = csum_unfold(~sum); + skb->ip_summed = CHECKSUM_COMPLETE; + } adapter->hw_csum_good++; } @@ -942,7 +954,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1328,7 +1341,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1498,8 +1512,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, } } - /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, skb); + /* Receive Checksum Offload XXX recompute due to CRC strip? */ + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -3083,10 +3098,19 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); - if (adapter->netdev->features & NETIF_F_RXCSUM) + if (adapter->netdev->features & NETIF_F_RXCSUM) { rxcsum |= E1000_RXCSUM_TUOFL; - else + + /* + * IPv4 payload checksum for UDP fragments must be + * used in conjunction with packet-split. + */ + if (adapter->rx_ps_pages) + rxcsum |= E1000_RXCSUM_IPPCSE; + } else { rxcsum &= ~E1000_RXCSUM_TUOFL; + /* no need to clear IPPCSE as it defaults to 0 */ + } ew32(RXCSUM, rxcsum); if (adapter->hw.mac.type == e1000_pch2lan) { @@ -5217,10 +5241,22 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && - !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; + if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { + if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + + /* + * IP payload checksum (enabled with jumbos/packet-split when + * Rx checksum is enabled) and generation of RSS hash is + * mutually exclusive in the hardware. + */ + if ((netdev->features & NETIF_F_RXCSUM) && + (netdev->features & NETIF_F_RXHASH)) { + e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); + return -EINVAL; + } } /* Supported frame sizes */ @@ -5994,6 +6030,17 @@ static int e1000_set_features(struct net_device *netdev, NETIF_F_RXALL))) return 0; + /* + * IP payload checksum (enabled with jumbos/packet-split when Rx + * checksum is enabled) and generation of RSS hash is mutually + * exclusive in the hardware. + */ + if (adapter->rx_ps_pages && + (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { + e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); + return -EINVAL; + } + if (changed & NETIF_F_RXFCS) { if (features & NETIF_F_RXFCS) { adapter->flags2 &= ~FLAG2_CRC_STRIPPING; diff --git a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c index 90eef07943f4..8ce67064b9c5 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -357,28 +357,21 @@ static int igbvf_set_coalesce(struct net_device *netdev, struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && - (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { - adapter->current_itr = ec->rx_coalesce_usecs << 2; - adapter->requested_itr = 1000000000 / - (adapter->current_itr * 256); - } else if ((ec->rx_coalesce_usecs == 3) || - (ec->rx_coalesce_usecs == 2)) { + if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) || + ((ec->rx_coalesce_usecs > 3) && + (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) || + (ec->rx_coalesce_usecs == 2)) + return -EINVAL; + + /* convert to rate of irq's per second */ + if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { adapter->current_itr = IGBVF_START_ITR; adapter->requested_itr = ec->rx_coalesce_usecs; - } else if (ec->rx_coalesce_usecs == 0) { - /* - * The user's desire is to turn off interrupt throttling - * altogether, but due to HW limitations, we can't do that. - * Instead we set a very small value in EITR, which would - * allow ~967k interrupts per second, but allow the adapter's - * internal clocking to still function properly. - */ - adapter->current_itr = 4; + } else { + adapter->current_itr = ec->rx_coalesce_usecs << 2; adapter->requested_itr = 1000000000 / (adapter->current_itr * 256); - } else - return -EINVAL; + } writel(adapter->current_itr, hw->hw_addr + adapter->rx_ring->itr_register); diff --git a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c index 3b5c4571b55e..d614c374ed9d 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/trunk/drivers/net/ethernet/ti/davinci_cpdma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index b01960fcfbc9..3767a1225860 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -197,10 +197,6 @@ static int qmi_wwan_manage_power(struct usbnet *dev, int on) static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) { struct usbnet *dev = usb_get_intfdata(intf); - - /* can be called while disconnecting */ - if (!dev) - return 0; return qmi_wwan_manage_power(dev, on); } diff --git a/trunk/drivers/net/wireless/ath/ath.h b/trunk/drivers/net/wireless/ath/ath.h index 420d69b2674c..c54b7d37bff1 100644 --- a/trunk/drivers/net/wireless/ath/ath.h +++ b/trunk/drivers/net/wireless/ath/ath.h @@ -143,7 +143,6 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); - DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; unsigned int clockrate; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 995ca8e1302e..1c68e564f503 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -622,7 +622,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index 0735aeb3b26c..e1fcc68124dc 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -695,9 +695,9 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, __skb_unlink(skb, &rx_edma->rx_fifo); list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); + } else { + bf = NULL; } - - bf = NULL; } *dest = bf; @@ -822,8 +822,7 @@ static bool ath9k_rx_accept(struct ath_common *common, * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption. */ - if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || - !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) + if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID) rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; if (!rx_stats->rs_datalen) { diff --git a/trunk/drivers/net/wireless/ath/key.c b/trunk/drivers/net/wireless/ath/key.c index 5c54aa43ca2d..0e81904956cf 100644 --- a/trunk/drivers/net/wireless/ath/key.c +++ b/trunk/drivers/net/wireless/ath/key.c @@ -556,9 +556,6 @@ int ath_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); - if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - set_bit(idx, common->ccmp_keymap); - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); @@ -585,7 +582,6 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) return; clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 013680332f07..3ee23134c02b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -796,18 +796,6 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, switch (op) { case ADD: ret = iwlagn_mac_sta_add(hw, vif, sta); - if (ret) - break; - /* - * Clear the in-progress flag, the AP station entry was added - * but we'll initialize LQ only when we've associated (which - * would also clear the in-progress flag). This is necessary - * in case we never initialize LQ because association fails. - */ - spin_lock_bh(&priv->sta_lock); - priv->stations[iwl_sta_id(sta)].used &= - ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_bh(&priv->sta_lock); break; case REMOVE: ret = iwlagn_mac_sta_remove(hw, vif, sta); diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c index 900ee129e825..9c44088054dd 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -256,8 +256,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && - last_seq >= new_node->start_win) + if (last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -597,5 +596,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - mwifiex_reset_11n_rx_seq_num(priv); + memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); } diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h index 6c9815a0f5d8..f1bffebabc60 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,13 +37,6 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 -#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff - -static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) -{ - memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); -} - int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/trunk/drivers/net/wireless/mwifiex/ie.c b/trunk/drivers/net/wireless/mwifiex/ie.c index 383820a52beb..ceb82cd749cc 100644 --- a/trunk/drivers/net/wireless/mwifiex/ie.c +++ b/trunk/drivers/net/wireless/mwifiex/ie.c @@ -213,7 +213,6 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, /* save assoc resp ie index after auto-indexing */ *assoc_idx = *((u16 *)pos); - kfree(ap_custom_ie); return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa1248..e0377473282f 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -978,10 +978,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); adapter->event_cause = *(u32 *) skb->data; + skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); + if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) - memcpy(adapter->event_body, - skb->data + MWIFIEX_EVENT_HEADER_LEN, - skb->len); + memcpy(adapter->event_body, skb->data, skb->len); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 11e731f3581c..4ace5a3dcd23 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -406,9 +406,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_UAP_STA_ASSOC: + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *) - (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER); + event = (struct mwifiex_assoc_event *)adapter->event_skb->data; if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { len = -1; @@ -433,8 +433,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) GFP_KERNEL); break; case EVENT_UAP_STA_DEAUTH: - cfg80211_del_sta(priv->netdev, adapter->event_body + - MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL); + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); + cfg80211_del_sta(priv->netdev, adapter->event_skb->data, + GFP_KERNEL); break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index 22a5916564b8..49ebf20c56eb 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -49,7 +49,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, struct device *dev = adapter->dev; u32 recv_type; __le32 tmp; - int ret; if (adapter->hs_activated) mwifiex_process_hs_config(adapter); @@ -70,19 +69,16 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_CMD: if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) { dev_err(dev, "CMD: skb->len too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } else if (!adapter->curr_cmd) { dev_dbg(dev, "CMD: no curr_cmd\n"); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp( adapter, skb->data, skb->len); - ret = 0; - goto exit_restore_skb; + return 0; } - ret = -1; - goto exit_restore_skb; + return -1; } adapter->curr_cmd->resp_skb = skb; @@ -91,22 +87,20 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_EVENT: if (skb->len < sizeof(u32)) { dev_err(dev, "EVENT: skb->len too small\n"); - ret = -1; - goto exit_restore_skb; + return -1; } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); + skb_pull(skb, sizeof(u32)); dev_dbg(dev, "event_cause %#x\n", adapter->event_cause); if (skb->len > MAX_EVENT_SIZE) { dev_err(dev, "EVENT: event body too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } - memcpy(adapter->event_body, skb->data + - MWIFIEX_EVENT_HEADER_LEN, skb->len); - + skb_copy_from_linear_data(skb, adapter->event_body, + skb->len); adapter->event_received = true; adapter->event_skb = skb; break; @@ -130,12 +124,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } return -EINPROGRESS; - -exit_restore_skb: - /* The buffer will be reused for further cmds/events */ - skb_push(skb, INTF_HEADER_LEN); - - return ret; } static void mwifiex_usb_rx_complete(struct urb *urb) diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 3fa4d4176993..f3fc65515857 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -404,8 +404,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; - mwifiex_reset_11n_rx_seq_num(priv); - atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } @@ -1223,7 +1221,6 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || - priv->wps.session_enable || ((priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)) { diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b199..d228358e6a40 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -301,11 +301,9 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ - {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ - {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ @@ -348,7 +346,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ - {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ diff --git a/trunk/drivers/net/wireless/ti/wlcore/Kconfig b/trunk/drivers/net/wireless/ti/wlcore/Kconfig index d7b907e67170..54156b0b5c2d 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/Kconfig +++ b/trunk/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,6 +1,7 @@ config WLCORE tristate "TI wlcore support" depends on WL_TI && GENERIC_HARDIRQS && MAC80211 + depends on INET select FW_LOADER ---help--- This module contains the main code for TI WLAN chips. It abstracts diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index 7bf08fa22ec9..c9f1318a3b82 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -273,16 +273,13 @@ void spd_release_page(struct splice_pipe_desc *spd, unsigned int i) * Check if we need to grow the arrays holding pages and partial page * descriptions. */ -int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) +int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) { - unsigned int buffers = ACCESS_ONCE(pipe->buffers); - - spd->nr_pages_max = buffers; - if (buffers <= PIPE_DEF_BUFFERS) + if (pipe->buffers <= PIPE_DEF_BUFFERS) return 0; - spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL); - spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL); + spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL); + spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL); if (spd->pages && spd->partial) return 0; @@ -292,9 +289,10 @@ int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc return -ENOMEM; } -void splice_shrink_spd(struct splice_pipe_desc *spd) +void splice_shrink_spd(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd) { - if (spd->nr_pages_max <= PIPE_DEF_BUFFERS) + if (pipe->buffers <= PIPE_DEF_BUFFERS) return; kfree(spd->pages); @@ -317,7 +315,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &page_cache_pipe_buf_ops, .spd_release = spd_release_page, @@ -329,7 +326,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, index = *ppos >> PAGE_CACHE_SHIFT; loff = *ppos & ~PAGE_CACHE_MASK; req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - nr_pages = min(req_pages, spd.nr_pages_max); + nr_pages = min(req_pages, pipe->buffers); /* * Lookup the (hopefully) full range of pages we need. @@ -500,7 +497,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, if (spd.nr_pages) error = splice_to_pipe(pipe, &spd); - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); return error; } @@ -601,7 +598,6 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &default_pipe_buf_ops, .spd_release = spd_release_page, @@ -612,8 +608,8 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, res = -ENOMEM; vec = __vec; - if (spd.nr_pages_max > PIPE_DEF_BUFFERS) { - vec = kmalloc(spd.nr_pages_max * sizeof(struct iovec), GFP_KERNEL); + if (pipe->buffers > PIPE_DEF_BUFFERS) { + vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL); if (!vec) goto shrink_ret; } @@ -621,7 +617,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, offset = *ppos & ~PAGE_CACHE_MASK; nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - for (i = 0; i < nr_pages && i < spd.nr_pages_max && len; i++) { + for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) { struct page *page; page = alloc_page(GFP_USER); @@ -669,7 +665,7 @@ ssize_t default_file_splice_read(struct file *in, loff_t *ppos, shrink_ret: if (vec != __vec) kfree(vec); - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); return res; err: @@ -1618,7 +1614,6 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &user_page_pipe_buf_ops, .spd_release = spd_release_page, @@ -1634,13 +1629,13 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov, spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages, spd.partial, false, - spd.nr_pages_max); + pipe->buffers); if (spd.nr_pages <= 0) ret = spd.nr_pages; else ret = splice_to_pipe(pipe, &spd); - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); return ret; } diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 07954b05b86c..ba43f408baa3 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -827,6 +827,7 @@ extern bool __blk_end_request_err(struct request *rq, int error); extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); +extern void blk_abort_queue(struct request_queue *); extern void blk_unprep_request(struct request *); /* diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index 1aff18346c71..176a939d1547 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -207,9 +207,6 @@ struct ftrace_event_call { * bit 1: enabled * bit 2: filter_active * bit 3: enabled cmd record - * bit 4: allow trace by non root (cap any) - * bit 5: failed to apply filter - * bit 6: ftrace internal event (do not enable) * * Changes to flags must hold the event_mutex. * diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 5f187026b812..ab741b0d0074 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2755,17 +2755,6 @@ #define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 #define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e #define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f -#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46 -#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0 -#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1 -#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4 -#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5 -#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41 -#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42 -#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43 -#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44 -#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45 -#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index 76c5c8b724a7..45db49f64bb4 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -677,7 +677,6 @@ struct hw_perf_event { u64 last_tag; unsigned long config_base; unsigned long event_base; - int event_base_rdpmc; int idx; int last_cpu; @@ -1107,8 +1106,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, struct task_struct *task, perf_overflow_handler_t callback, void *context); -extern void perf_pmu_migrate_context(struct pmu *pmu, - int src_cpu, int dst_cpu); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index c7cfa6996db4..4059c0f33f07 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1581,6 +1581,7 @@ struct task_struct { #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; + int uprobe_srcu_id; #endif }; diff --git a/trunk/include/linux/splice.h b/trunk/include/linux/splice.h index 09a545a7dfa3..26e5b613deda 100644 --- a/trunk/include/linux/splice.h +++ b/trunk/include/linux/splice.h @@ -51,8 +51,7 @@ struct partial_page { struct splice_pipe_desc { struct page **pages; /* page map */ struct partial_page *partial; /* pages[] may not be contig */ - int nr_pages; /* number of populated pages in map */ - unsigned int nr_pages_max; /* pages[] & partial[] arrays size */ + int nr_pages; /* number of pages in map */ unsigned int flags; /* splice flags */ const struct pipe_buf_operations *ops;/* ops associated with output pipe */ void (*spd_release)(struct splice_pipe_desc *, unsigned int); @@ -86,8 +85,9 @@ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, /* * for dynamic pipe sizing */ -extern int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *); -extern void splice_shrink_spd(struct splice_pipe_desc *); +extern int splice_grow_spd(struct pipe_inode_info *, struct splice_pipe_desc *); +extern void splice_shrink_spd(struct pipe_inode_info *, + struct splice_pipe_desc *); extern void spd_release_page(struct splice_pipe_desc *, unsigned int); extern const struct pipe_buf_operations page_cache_pipe_buf_ops; diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index fecdf31816f2..e4652fe58958 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -912,9 +912,6 @@ struct sctp_transport { /* Is this structure kfree()able? */ malloced:1; - /* Has this transport moved the ctsn since we last sacked */ - __u32 sack_generation; - struct flowi fl; /* This is the peer's IP address and port. */ @@ -1587,7 +1584,6 @@ struct sctp_association { */ __u8 sack_needed; /* Do we need to sack the peer? */ __u32 sack_cnt; - __u32 sack_generation; /* These are capabilities which our peer advertised. */ __u8 ecn_capable:1, /* Can peer do ECN? */ diff --git a/trunk/include/net/sctp/tsnmap.h b/trunk/include/net/sctp/tsnmap.h index 2c5d2b4d5d1e..e7728bc14ccf 100644 --- a/trunk/include/net/sctp/tsnmap.h +++ b/trunk/include/net/sctp/tsnmap.h @@ -117,8 +117,7 @@ void sctp_tsnmap_free(struct sctp_tsnmap *map); int sctp_tsnmap_check(const struct sctp_tsnmap *, __u32 tsn); /* Mark this TSN as seen. */ -int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn, - struct sctp_transport *trans); +int sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn); /* Mark this TSN and all lower as seen. */ void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn); diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index f1cf0edeb39a..d7d71d6ec972 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -1645,8 +1645,6 @@ perf_install_in_context(struct perf_event_context *ctx, lockdep_assert_held(&ctx->mutex); event->ctx = ctx; - if (event->cpu != -1) - event->cpu = cpu; if (!task) { /* @@ -6254,8 +6252,6 @@ SYSCALL_DEFINE5(perf_event_open, } } - get_online_cpus(); - event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, NULL, NULL); if (IS_ERR(event)) { @@ -6308,7 +6304,7 @@ SYSCALL_DEFINE5(perf_event_open, /* * Get the target context (task or percpu): */ - ctx = find_get_context(pmu, task, event->cpu); + ctx = find_get_context(pmu, task, cpu); if (IS_ERR(ctx)) { err = PTR_ERR(ctx); goto err_alloc; @@ -6381,23 +6377,20 @@ SYSCALL_DEFINE5(perf_event_open, mutex_lock(&ctx->mutex); if (move_group) { - synchronize_rcu(); - perf_install_in_context(ctx, group_leader, event->cpu); + perf_install_in_context(ctx, group_leader, cpu); get_ctx(ctx); list_for_each_entry(sibling, &group_leader->sibling_list, group_entry) { - perf_install_in_context(ctx, sibling, event->cpu); + perf_install_in_context(ctx, sibling, cpu); get_ctx(ctx); } } - perf_install_in_context(ctx, event, event->cpu); + perf_install_in_context(ctx, event, cpu); ++ctx->generation; perf_unpin_context(ctx); mutex_unlock(&ctx->mutex); - put_online_cpus(); - event->owner = current; mutex_lock(¤t->perf_event_mutex); @@ -6426,7 +6419,6 @@ SYSCALL_DEFINE5(perf_event_open, err_alloc: free_event(event); err_task: - put_online_cpus(); if (task) put_task_struct(task); err_group_fd: @@ -6487,39 +6479,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, } EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); -void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) -{ - struct perf_event_context *src_ctx; - struct perf_event_context *dst_ctx; - struct perf_event *event, *tmp; - LIST_HEAD(events); - - src_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, src_cpu)->ctx; - dst_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, dst_cpu)->ctx; - - mutex_lock(&src_ctx->mutex); - list_for_each_entry_safe(event, tmp, &src_ctx->event_list, - event_entry) { - perf_remove_from_context(event); - put_ctx(src_ctx); - list_add(&event->event_entry, &events); - } - mutex_unlock(&src_ctx->mutex); - - synchronize_rcu(); - - mutex_lock(&dst_ctx->mutex); - list_for_each_entry_safe(event, tmp, &events, event_entry) { - list_del(&event->event_entry); - if (event->state >= PERF_EVENT_STATE_OFF) - event->state = PERF_EVENT_STATE_INACTIVE; - perf_install_in_context(dst_ctx, event, dst_cpu); - get_ctx(dst_ctx); - } - mutex_unlock(&dst_ctx->mutex); -} -EXPORT_SYMBOL_GPL(perf_pmu_migrate_context); - static void sync_child_event(struct perf_event *child_event, struct task_struct *child) { diff --git a/trunk/kernel/events/uprobes.c b/trunk/kernel/events/uprobes.c index f93532748bca..985be4d80fe8 100644 --- a/trunk/kernel/events/uprobes.c +++ b/trunk/kernel/events/uprobes.c @@ -38,29 +38,13 @@ #define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES) #define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE +static struct srcu_struct uprobes_srcu; static struct rb_root uprobes_tree = RB_ROOT; static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ #define UPROBES_HASH_SZ 13 -/* - * We need separate register/unregister and mmap/munmap lock hashes because - * of mmap_sem nesting. - * - * uprobe_register() needs to install probes on (potentially) all processes - * and thus needs to acquire multiple mmap_sems (consequtively, not - * concurrently), whereas uprobe_mmap() is called while holding mmap_sem - * for the particular process doing the mmap. - * - * uprobe_register()->register_for_each_vma() needs to drop/acquire mmap_sem - * because of lock order against i_mmap_mutex. This means there's a hole in - * the register vma iteration where a mmap() can happen. - * - * Thus uprobe_register() can race with uprobe_mmap() and we can try and - * install a probe where one is already installed. - */ - /* serialize (un)register */ static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; @@ -77,6 +61,17 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; */ static atomic_t uprobe_events = ATOMIC_INIT(0); +/* + * Maintain a temporary per vma info that can be used to search if a vma + * has already been handled. This structure is introduced since extending + * vm_area_struct wasnt recommended. + */ +struct vma_info { + struct list_head probe_list; + struct mm_struct *mm; + loff_t vaddr; +}; + struct uprobe { struct rb_node rb_node; /* node in the rb tree */ atomic_t ref; @@ -105,8 +100,7 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register) if (!is_register) return true; - if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) - == (VM_READ|VM_EXEC)) + if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC)) return true; return false; @@ -135,17 +129,33 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset) static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage) { struct mm_struct *mm = vma->vm_mm; - unsigned long addr; - spinlock_t *ptl; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; pte_t *ptep; + spinlock_t *ptl; + unsigned long addr; + int err = -EFAULT; addr = page_address_in_vma(page, vma); if (addr == -EFAULT) - return -EFAULT; + goto out; + + pgd = pgd_offset(mm, addr); + if (!pgd_present(*pgd)) + goto out; + + pud = pud_offset(pgd, addr); + if (!pud_present(*pud)) + goto out; + + pmd = pmd_offset(pud, addr); + if (!pmd_present(*pmd)) + goto out; - ptep = page_check_address(page, mm, addr, &ptl, 0); + ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); if (!ptep) - return -EAGAIN; + goto out; get_page(kpage); page_add_new_anon_rmap(kpage, vma, addr); @@ -164,8 +174,10 @@ static int __replace_page(struct vm_area_struct *vma, struct page *page, struct try_to_free_swap(page); put_page(page); pte_unmap_unlock(ptep, ptl); + err = 0; - return 0; +out: + return err; } /** @@ -210,8 +222,9 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, void *vaddr_old, *vaddr_new; struct vm_area_struct *vma; struct uprobe *uprobe; + loff_t addr; int ret; -retry: + /* Read the page with vaddr into memory */ ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); if (ret <= 0) @@ -233,6 +246,10 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, if (mapping != vma->vm_file->f_mapping) goto put_out; + addr = vma_address(vma, uprobe->offset); + if (vaddr != (unsigned long)addr) + goto put_out; + ret = -ENOMEM; new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); if (!new_page) @@ -250,7 +267,11 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, vaddr_new = kmap_atomic(new_page); memcpy(vaddr_new, vaddr_old, PAGE_SIZE); - memcpy(vaddr_new + (vaddr & ~PAGE_MASK), &opcode, UPROBE_SWBP_INSN_SIZE); + + /* poke the new insn in, ASSUMES we don't cross page boundary */ + vaddr &= ~PAGE_MASK; + BUG_ON(vaddr + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); + memcpy(vaddr_new + vaddr, &opcode, UPROBE_SWBP_INSN_SIZE); kunmap_atomic(vaddr_new); kunmap_atomic(vaddr_old); @@ -270,8 +291,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, put_out: put_page(old_page); - if (unlikely(ret == -EAGAIN)) - goto retry; return ret; } @@ -293,7 +312,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_ void *vaddr_new; int ret; - ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); + ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL); if (ret <= 0) return ret; @@ -314,20 +333,10 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) uprobe_opcode_t opcode; int result; - if (current->mm == mm) { - pagefault_disable(); - result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, - sizeof(opcode)); - pagefault_enable(); - - if (likely(result == 0)) - goto out; - } - result = read_opcode(mm, vaddr, &opcode); if (result) return result; -out: + if (is_swbp_insn(&opcode)) return 1; @@ -346,9 +355,7 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) { int result; - /* - * See the comment near uprobes_hash(). - */ + result = is_swbp_at_addr(mm, vaddr); if (result == 1) return -EEXIST; @@ -513,6 +520,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) uprobe->inode = igrab(inode); uprobe->offset = offset; init_rwsem(&uprobe->consumer_rwsem); + INIT_LIST_HEAD(&uprobe->pending_list); /* add to uprobes_tree, sorted on inode:offset */ cur_uprobe = insert_uprobe(uprobe); @@ -580,22 +588,20 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc) } static int -__copy_insn(struct address_space *mapping, struct file *filp, char *insn, - unsigned long nbytes, loff_t offset) +__copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *insn, + unsigned long nbytes, unsigned long offset) { + struct file *filp = vma->vm_file; struct page *page; void *vaddr; - unsigned long off; - pgoff_t idx; + unsigned long off1; + unsigned long idx; if (!filp) return -EINVAL; - if (!mapping->a_ops->readpage) - return -EIO; - - idx = offset >> PAGE_CACHE_SHIFT; - off = offset & ~PAGE_MASK; + idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT); + off1 = offset &= ~PAGE_MASK; /* * Ensure that the page that has the original instruction is @@ -606,20 +612,22 @@ __copy_insn(struct address_space *mapping, struct file *filp, char *insn, return PTR_ERR(page); vaddr = kmap_atomic(page); - memcpy(insn, vaddr + off, nbytes); + memcpy(insn, vaddr + off1, nbytes); kunmap_atomic(vaddr); page_cache_release(page); return 0; } -static int copy_insn(struct uprobe *uprobe, struct file *filp) +static int +copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) { struct address_space *mapping; unsigned long nbytes; int bytes; - nbytes = PAGE_SIZE - (uprobe->offset & ~PAGE_MASK); + addr &= ~PAGE_MASK; + nbytes = PAGE_SIZE - addr; mapping = uprobe->inode->i_mapping; /* Instruction at end of binary; copy only available bytes */ @@ -630,13 +638,13 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) /* Instruction at the page-boundary; copy bytes in second page */ if (nbytes < bytes) { - int err = __copy_insn(mapping, filp, uprobe->arch.insn + nbytes, - bytes - nbytes, uprobe->offset + nbytes); - if (err) - return err; + if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes, + bytes - nbytes, uprobe->offset + nbytes)) + return -ENOMEM; + bytes = nbytes; } - return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); + return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset); } /* @@ -664,8 +672,9 @@ static int copy_insn(struct uprobe *uprobe, struct file *filp) */ static int install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, - struct vm_area_struct *vma, unsigned long vaddr) + struct vm_area_struct *vma, loff_t vaddr) { + unsigned long addr; int ret; /* @@ -678,22 +687,20 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, if (!uprobe->consumers) return -EEXIST; + addr = (unsigned long)vaddr; + if (!(uprobe->flags & UPROBE_COPY_INSN)) { - ret = copy_insn(uprobe, vma->vm_file); + ret = copy_insn(uprobe, vma, addr); if (ret) return ret; if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) - return -ENOTSUPP; + return -EEXIST; - ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); + ret = arch_uprobe_analyze_insn(&uprobe->arch, mm); if (ret) return ret; - /* write_opcode() assumes we don't cross page boundary */ - BUG_ON((uprobe->offset & ~PAGE_MASK) + - UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - uprobe->flags |= UPROBE_COPY_INSN; } @@ -706,7 +713,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, * Hence increment before and decrement on failure. */ atomic_inc(&mm->uprobes_state.count); - ret = set_swbp(&uprobe->arch, mm, vaddr); + ret = set_swbp(&uprobe->arch, mm, addr); if (ret) atomic_dec(&mm->uprobes_state.count); @@ -714,21 +721,27 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, } static void -remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr) +remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr) { - if (!set_orig_insn(&uprobe->arch, mm, vaddr, true)) + if (!set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true)) atomic_dec(&mm->uprobes_state.count); } /* - * There could be threads that have already hit the breakpoint. They - * will recheck the current insn and restart if find_uprobe() fails. - * See find_active_uprobe(). + * There could be threads that have hit the breakpoint and are entering the + * notifier code and trying to acquire the uprobes_treelock. The thread + * calling delete_uprobe() that is removing the uprobe from the rb_tree can + * race with these threads and might acquire the uprobes_treelock compared + * to some of the breakpoint hit threads. In such a case, the breakpoint + * hit threads will not find the uprobe. The current unregistering thread + * waits till all other threads have hit a breakpoint, to acquire the + * uprobes_treelock before the uprobe is removed from the rbtree. */ static void delete_uprobe(struct uprobe *uprobe) { unsigned long flags; + synchronize_srcu(&uprobes_srcu); spin_lock_irqsave(&uprobes_treelock, flags); rb_erase(&uprobe->rb_node, &uprobes_tree); spin_unlock_irqrestore(&uprobes_treelock, flags); @@ -737,135 +750,139 @@ static void delete_uprobe(struct uprobe *uprobe) atomic_dec(&uprobe_events); } -struct map_info { - struct map_info *next; - struct mm_struct *mm; - unsigned long vaddr; -}; - -static inline struct map_info *free_map_info(struct map_info *info) -{ - struct map_info *next = info->next; - kfree(info); - return next; -} - -static struct map_info * -build_map_info(struct address_space *mapping, loff_t offset, bool is_register) +static struct vma_info * +__find_next_vma_info(struct address_space *mapping, struct list_head *head, + struct vma_info *vi, loff_t offset, bool is_register) { - unsigned long pgoff = offset >> PAGE_SHIFT; struct prio_tree_iter iter; struct vm_area_struct *vma; - struct map_info *curr = NULL; - struct map_info *prev = NULL; - struct map_info *info; - int more = 0; + struct vma_info *tmpvi; + unsigned long pgoff; + int existing_vma; + loff_t vaddr; + + pgoff = offset >> PAGE_SHIFT; - again: - mutex_lock(&mapping->i_mmap_mutex); vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { if (!valid_vma(vma, is_register)) continue; - if (!prev && !more) { - /* - * Needs GFP_NOWAIT to avoid i_mmap_mutex recursion through - * reclaim. This is optimistic, no harm done if it fails. - */ - prev = kmalloc(sizeof(struct map_info), - GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN); - if (prev) - prev->next = NULL; + existing_vma = 0; + vaddr = vma_address(vma, offset); + + list_for_each_entry(tmpvi, head, probe_list) { + if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) { + existing_vma = 1; + break; + } } - if (!prev) { - more++; - continue; + + /* + * Another vma needs a probe to be installed. However skip + * installing the probe if the vma is about to be unlinked. + */ + if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) { + vi->mm = vma->vm_mm; + vi->vaddr = vaddr; + list_add(&vi->probe_list, head); + + return vi; } + } - if (!atomic_inc_not_zero(&vma->vm_mm->mm_users)) - continue; + return NULL; +} - info = prev; - prev = prev->next; - info->next = curr; - curr = info; +/* + * Iterate in the rmap prio tree and find a vma where a probe has not + * yet been inserted. + */ +static struct vma_info * +find_next_vma_info(struct address_space *mapping, struct list_head *head, + loff_t offset, bool is_register) +{ + struct vma_info *vi, *retvi; - info->mm = vma->vm_mm; - info->vaddr = vma_address(vma, offset); - } - mutex_unlock(&mapping->i_mmap_mutex); + vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL); + if (!vi) + return ERR_PTR(-ENOMEM); - if (!more) - goto out; + mutex_lock(&mapping->i_mmap_mutex); + retvi = __find_next_vma_info(mapping, head, vi, offset, is_register); + mutex_unlock(&mapping->i_mmap_mutex); - prev = curr; - while (curr) { - mmput(curr->mm); - curr = curr->next; - } + if (!retvi) + kfree(vi); - do { - info = kmalloc(sizeof(struct map_info), GFP_KERNEL); - if (!info) { - curr = ERR_PTR(-ENOMEM); - goto out; - } - info->next = prev; - prev = info; - } while (--more); - - goto again; - out: - while (prev) - prev = free_map_info(prev); - return curr; + return retvi; } static int register_for_each_vma(struct uprobe *uprobe, bool is_register) { - struct map_info *info; - int err = 0; + struct list_head try_list; + struct vm_area_struct *vma; + struct address_space *mapping; + struct vma_info *vi, *tmpvi; + struct mm_struct *mm; + loff_t vaddr; + int ret; - info = build_map_info(uprobe->inode->i_mapping, - uprobe->offset, is_register); - if (IS_ERR(info)) - return PTR_ERR(info); + mapping = uprobe->inode->i_mapping; + INIT_LIST_HEAD(&try_list); - while (info) { - struct mm_struct *mm = info->mm; - struct vm_area_struct *vma; + ret = 0; - if (err) - goto free; + for (;;) { + vi = find_next_vma_info(mapping, &try_list, uprobe->offset, is_register); + if (!vi) + break; - down_write(&mm->mmap_sem); - vma = find_vma(mm, (unsigned long)info->vaddr); - if (!vma || !valid_vma(vma, is_register)) - goto unlock; + if (IS_ERR(vi)) { + ret = PTR_ERR(vi); + break; + } + mm = vi->mm; + down_read(&mm->mmap_sem); + vma = find_vma(mm, (unsigned long)vi->vaddr); + if (!vma || !valid_vma(vma, is_register)) { + list_del(&vi->probe_list); + kfree(vi); + up_read(&mm->mmap_sem); + mmput(mm); + continue; + } + vaddr = vma_address(vma, uprobe->offset); if (vma->vm_file->f_mapping->host != uprobe->inode || - vma_address(vma, uprobe->offset) != info->vaddr) - goto unlock; + vaddr != vi->vaddr) { + list_del(&vi->probe_list); + kfree(vi); + up_read(&mm->mmap_sem); + mmput(mm); + continue; + } + + if (is_register) + ret = install_breakpoint(uprobe, mm, vma, vi->vaddr); + else + remove_breakpoint(uprobe, mm, vi->vaddr); + up_read(&mm->mmap_sem); + mmput(mm); if (is_register) { - err = install_breakpoint(uprobe, mm, vma, info->vaddr); - /* - * We can race against uprobe_mmap(), see the - * comment near uprobe_hash(). - */ - if (err == -EEXIST) - err = 0; - } else { - remove_breakpoint(uprobe, mm, info->vaddr); + if (ret && ret == -EEXIST) + ret = 0; + if (ret) + break; } - unlock: - up_write(&mm->mmap_sem); - free: - mmput(mm); - info = free_map_info(info); } - return err; + list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) { + list_del(&vi->probe_list); + kfree(vi); + } + + return ret; } static int __uprobe_register(struct uprobe *uprobe) @@ -1031,7 +1048,7 @@ static void build_probe_list(struct inode *inode, struct list_head *head) int uprobe_mmap(struct vm_area_struct *vma) { struct list_head tmp_list; - struct uprobe *uprobe; + struct uprobe *uprobe, *u; struct inode *inode; int ret, count; @@ -1049,9 +1066,12 @@ int uprobe_mmap(struct vm_area_struct *vma) ret = 0; count = 0; - list_for_each_entry(uprobe, &tmp_list, pending_list) { + list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { + loff_t vaddr; + + list_del(&uprobe->pending_list); if (!ret) { - loff_t vaddr = vma_address(vma, uprobe->offset); + vaddr = vma_address(vma, uprobe->offset); if (vaddr < vma->vm_start || vaddr >= vma->vm_end) { put_uprobe(uprobe); @@ -1059,10 +1079,8 @@ int uprobe_mmap(struct vm_area_struct *vma) } ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); - /* - * We can race against uprobe_register(), see the - * comment near uprobe_hash(). - */ + + /* Ignore double add: */ if (ret == -EEXIST) { ret = 0; @@ -1097,7 +1115,7 @@ int uprobe_mmap(struct vm_area_struct *vma) void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) { struct list_head tmp_list; - struct uprobe *uprobe; + struct uprobe *uprobe, *u; struct inode *inode; if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) @@ -1114,8 +1132,11 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon mutex_lock(uprobes_mmap_hash(inode)); build_probe_list(inode, &tmp_list); - list_for_each_entry(uprobe, &tmp_list, pending_list) { - loff_t vaddr = vma_address(vma, uprobe->offset); + list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { + loff_t vaddr; + + list_del(&uprobe->pending_list); + vaddr = vma_address(vma, uprobe->offset); if (vaddr >= start && vaddr < end) { /* @@ -1357,6 +1378,9 @@ void uprobe_free_utask(struct task_struct *t) { struct uprobe_task *utask = t->utask; + if (t->uprobe_srcu_id != -1) + srcu_read_unlock_raw(&uprobes_srcu, t->uprobe_srcu_id); + if (!utask) return; @@ -1374,6 +1398,7 @@ void uprobe_free_utask(struct task_struct *t) void uprobe_copy_process(struct task_struct *t) { t->utask = NULL; + t->uprobe_srcu_id = -1; } /* @@ -1392,6 +1417,7 @@ static struct uprobe_task *add_utask(void) if (unlikely(!utask)) return NULL; + utask->active_uprobe = NULL; current->utask = utask; return utask; } @@ -1453,64 +1479,41 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) return false; } -static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) -{ - struct mm_struct *mm = current->mm; - struct uprobe *uprobe = NULL; - struct vm_area_struct *vma; - - down_read(&mm->mmap_sem); - vma = find_vma(mm, bp_vaddr); - if (vma && vma->vm_start <= bp_vaddr) { - if (valid_vma(vma, false)) { - struct inode *inode; - loff_t offset; - - inode = vma->vm_file->f_mapping->host; - offset = bp_vaddr - vma->vm_start; - offset += (vma->vm_pgoff << PAGE_SHIFT); - uprobe = find_uprobe(inode, offset); - } - - if (!uprobe) - *is_swbp = is_swbp_at_addr(mm, bp_vaddr); - } else { - *is_swbp = -EFAULT; - } - up_read(&mm->mmap_sem); - - return uprobe; -} - /* * Run handler and ask thread to singlestep. * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. */ static void handle_swbp(struct pt_regs *regs) { + struct vm_area_struct *vma; struct uprobe_task *utask; struct uprobe *uprobe; + struct mm_struct *mm; unsigned long bp_vaddr; - int uninitialized_var(is_swbp); + uprobe = NULL; bp_vaddr = uprobe_get_swbp_addr(regs); - uprobe = find_active_uprobe(bp_vaddr, &is_swbp); + mm = current->mm; + down_read(&mm->mmap_sem); + vma = find_vma(mm, bp_vaddr); + + if (vma && vma->vm_start <= bp_vaddr && valid_vma(vma, false)) { + struct inode *inode; + loff_t offset; + + inode = vma->vm_file->f_mapping->host; + offset = bp_vaddr - vma->vm_start; + offset += (vma->vm_pgoff << PAGE_SHIFT); + uprobe = find_uprobe(inode, offset); + } + + srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id); + current->uprobe_srcu_id = -1; + up_read(&mm->mmap_sem); if (!uprobe) { - if (is_swbp > 0) { - /* No matching uprobe; signal SIGTRAP. */ - send_sig(SIGTRAP, current, 0); - } else { - /* - * Either we raced with uprobe_unregister() or we can't - * access this memory. The latter is only possible if - * another thread plays with our ->mm. In both cases - * we can simply restart. If this vma was unmapped we - * can pretend this insn was not executed yet and get - * the (correct) SIGSEGV after restart. - */ - instruction_pointer_set(regs, bp_vaddr); - } + /* No matching uprobe; signal SIGTRAP. */ + send_sig(SIGTRAP, current, 0); return; } @@ -1617,6 +1620,7 @@ int uprobe_pre_sstep_notifier(struct pt_regs *regs) utask->state = UTASK_BP_HIT; set_thread_flag(TIF_UPROBE); + current->uprobe_srcu_id = srcu_read_lock_raw(&uprobes_srcu); return 1; } @@ -1651,6 +1655,7 @@ static int __init init_uprobes(void) mutex_init(&uprobes_mutex[i]); mutex_init(&uprobes_mmap_mutex[i]); } + init_srcu_struct(&uprobes_srcu); return register_die_notifier(&uprobe_exception_nb); } diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index e8cd2027abbd..ab56a1764d4d 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -1235,7 +1235,6 @@ static ssize_t subbuf_splice_actor(struct file *in, struct splice_pipe_desc spd = { .pages = pages, .nr_pages = 0, - .nr_pages_max = PIPE_DEF_BUFFERS, .partial = partial, .flags = flags, .ops = &relay_pipe_buf_ops, @@ -1303,8 +1302,8 @@ static ssize_t subbuf_splice_actor(struct file *in, ret += padding; out: - splice_shrink_spd(&spd); - return ret; + splice_shrink_spd(pipe, &spd); + return ret; } static ssize_t relay_file_splice_read(struct file *in, diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index b4f20fba09fc..a008663d86c8 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -312,7 +312,7 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list, static int __register_ftrace_function(struct ftrace_ops *ops) { - if (unlikely(ftrace_disabled)) + if (ftrace_disabled) return -ENODEV; if (FTRACE_WARN_ON(ops == &global_ops)) @@ -4299,12 +4299,16 @@ int register_ftrace_function(struct ftrace_ops *ops) mutex_lock(&ftrace_lock); + if (unlikely(ftrace_disabled)) + goto out_unlock; + ret = __register_ftrace_function(ops); if (!ret) ret = ftrace_startup(ops, 0); - mutex_unlock(&ftrace_lock); + out_unlock: + mutex_unlock(&ftrace_lock); return ret; } EXPORT_SYMBOL_GPL(register_ftrace_function); diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index a7fa0702be1c..49249c28690d 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -3609,7 +3609,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, .pages = pages_def, .partial = partial_def, .nr_pages = 0, /* This gets updated below. */ - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &tracing_pipe_buf_ops, .spd_release = tracing_spd_release_pipe, @@ -3681,7 +3680,7 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, ret = splice_to_pipe(pipe, &spd); out: - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); return ret; out_err: @@ -4232,7 +4231,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages_def, .partial = partial_def, - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &buffer_pipe_buf_ops, .spd_release = buffer_spd_release, @@ -4320,7 +4318,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, } ret = splice_to_pipe(pipe, &spd); - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); out: return ret; } diff --git a/trunk/kernel/trace/trace_output.c b/trunk/kernel/trace/trace_output.c index 123b189c732c..df611a0e76c5 100644 --- a/trunk/kernel/trace/trace_output.c +++ b/trunk/kernel/trace/trace_output.c @@ -1325,4 +1325,4 @@ __init static int init_events(void) return 0; } -early_initcall(init_events); +device_initcall(init_events); diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 4ce02e0673db..a15a466d0d1d 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -1594,7 +1594,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, - .nr_pages_max = PIPE_DEF_BUFFERS, .flags = flags, .ops = &page_cache_pipe_buf_ops, .spd_release = spd_release_page, @@ -1683,7 +1682,7 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, if (spd.nr_pages) error = splice_to_pipe(pipe, &spd); - splice_shrink_spd(&spd); + splice_shrink_spd(pipe, &spd); if (error > 0) { *ppos += error; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 84f01ba81a34..6df214041a5e 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1136,8 +1136,8 @@ void dev_load(struct net *net, const char *name) no_module = request_module("netdev-%s", name); if (no_module && capable(CAP_SYS_MODULE)) { if (!request_module("%s", name)) - pr_warn("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", - name); + pr_err("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", + name); } } EXPORT_SYMBOL(dev_load); diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 46a3d23d259e..d78671e9d545 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -1755,7 +1755,6 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, - .nr_pages_max = MAX_SKB_FRAGS, .flags = flags, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index a4bb856de08f..66e4fcdd1c6b 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -1342,6 +1342,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct sta_info *sta; u32 changed = 0; + u8 bssid[ETH_ALEN]; ASSERT_MGD_MTX(ifmgd); @@ -1353,7 +1354,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, ieee80211_stop_poll(sdata); + memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); + ifmgd->associated = NULL; + memset(ifmgd->bssid, 0, ETH_ALEN); /* * we need to commit the associated = NULL change because the @@ -1373,7 +1377,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, netif_carrier_off(sdata->dev); mutex_lock(&local->sta_mtx); - sta = sta_info_get(sdata, ifmgd->bssid); + sta = sta_info_get(sdata, bssid); if (sta) { set_sta_flag(sta, WLAN_STA_BLOCK_BA); ieee80211_sta_tear_down_BA_sessions(sta, tx); @@ -1382,16 +1386,13 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, /* deauthenticate/disassociate now */ if (tx || frame_buf) - ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, - reason, tx, frame_buf); + ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, + tx, frame_buf); /* flush out frame */ if (tx) drv_flush(local, false); - /* clear bssid only after building the needed mgmt frames */ - memset(ifmgd->bssid, 0, ETH_ALEN); - /* remove AP and TDLS peers */ sta_info_flush(local, sdata); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 965e6ec0adb6..7bcecf73aafb 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -2455,7 +2455,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * frames that we didn't handle, including returning unknown * ones. For all other modes we will return them to the sender, * setting the 0x80 bit in the action category, as required by - * 802.11-2012 9.24.4. + * 802.11-2007 7.3.1.11. * Newer versions of hostapd shall also use the management frame * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. @@ -2465,9 +2465,6 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; - if (is_multicast_ether_addr(mgmt->da)) - return RX_DROP_MONITOR; - /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) return RX_DROP_UNUSABLE; diff --git a/trunk/net/netfilter/ipset/ip_set_core.c b/trunk/net/netfilter/ipset/ip_set_core.c index 9730882697aa..819c342f5b30 100644 --- a/trunk/net/netfilter/ipset/ip_set_core.c +++ b/trunk/net/netfilter/ipset/ip_set_core.c @@ -639,14 +639,6 @@ find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) return 0; } -static int -ip_set_none(struct sock *ctnl, struct sk_buff *skb, - const struct nlmsghdr *nlh, - const struct nlattr * const attr[]) -{ - return -EOPNOTSUPP; -} - static int ip_set_create(struct sock *ctnl, struct sk_buff *skb, const struct nlmsghdr *nlh, @@ -1547,10 +1539,6 @@ ip_set_protocol(struct sock *ctnl, struct sk_buff *skb, } static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = { - [IPSET_CMD_NONE] = { - .call = ip_set_none, - .attr_count = IPSET_ATTR_CMD_MAX, - }, [IPSET_CMD_CREATE] = { .call = ip_set_create, .attr_count = IPSET_ATTR_CMD_MAX, diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c index d5d3607ae7bc..ee863943c826 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c @@ -38,6 +38,30 @@ struct iface_node { #define iface_data(n) (rb_entry(n, struct iface_node, node)->iface) +static inline long +ifname_compare(const char *_a, const char *_b) +{ + const long *a = (const long *)_a; + const long *b = (const long *)_b; + + BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); + if (a[0] != b[0]) + return a[0] - b[0]; + if (IFNAMSIZ > sizeof(long)) { + if (a[1] != b[1]) + return a[1] - b[1]; + } + if (IFNAMSIZ > 2 * sizeof(long)) { + if (a[2] != b[2]) + return a[2] - b[2]; + } + if (IFNAMSIZ > 3 * sizeof(long)) { + if (a[3] != b[3]) + return a[3] - b[3]; + } + return 0; +} + static void rbtree_destroy(struct rb_root *root) { @@ -75,7 +99,7 @@ iface_test(struct rb_root *root, const char **iface) while (n) { const char *d = iface_data(n); - int res = strcmp(*iface, d); + long res = ifname_compare(*iface, d); if (res < 0) n = n->rb_left; @@ -97,7 +121,7 @@ iface_add(struct rb_root *root, const char **iface) while (*n) { char *ifname = iface_data(*n); - int res = strcmp(*iface, ifname); + long res = ifname_compare(*iface, ifname); p = *n; if (res < 0) @@ -342,7 +366,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], struct hash_netiface4_elem data = { .cidr = HOST_MASK }; u32 ip = 0, ip_to, last; u32 timeout = h->timeout; - char iface[IFNAMSIZ]; + char iface[IFNAMSIZ] = {}; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || @@ -639,7 +663,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_netiface6_elem data = { .cidr = HOST_MASK }; u32 timeout = h->timeout; - char iface[IFNAMSIZ]; + char iface[IFNAMSIZ] = {}; int ret; if (unlikely(!tb[IPSET_ATTR_IP] || diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index d43e3c122f7b..dd811b8dd97c 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -76,19 +76,19 @@ static void __ip_vs_del_service(struct ip_vs_service *svc); #ifdef CONFIG_IP_VS_IPV6 /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ -static bool __ip_vs_addr_is_local_v6(struct net *net, - const struct in6_addr *addr) +static int __ip_vs_addr_is_local_v6(struct net *net, + const struct in6_addr *addr) { + struct rt6_info *rt; struct flowi6 fl6 = { .daddr = *addr, }; - struct dst_entry *dst = ip6_route_output(net, NULL, &fl6); - bool is_local; - is_local = !dst->error && dst->dev && (dst->dev->flags & IFF_LOOPBACK); + rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); + if (rt && rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK)) + return 1; - dst_release(dst); - return is_local; + return 0; } #endif diff --git a/trunk/net/netfilter/nfnetlink.c b/trunk/net/netfilter/nfnetlink.c index 791d56bbd74a..3e797d1fcb94 100644 --- a/trunk/net/netfilter/nfnetlink.c +++ b/trunk/net/netfilter/nfnetlink.c @@ -169,10 +169,8 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) err = nla_parse(cda, ss->cb[cb_id].attr_count, attr, attrlen, ss->cb[cb_id].policy); - if (err < 0) { - rcu_read_unlock(); + if (err < 0) return err; - } if (nc->call_rcu) { err = nc->call_rcu(net->nfnl, skb, nlh, diff --git a/trunk/net/nfc/nci/ntf.c b/trunk/net/nfc/nci/ntf.c index 2ab196a9f228..cb2646179e5f 100644 --- a/trunk/net/nfc/nci/ntf.c +++ b/trunk/net/nfc/nci/ntf.c @@ -106,7 +106,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); data += 2; - nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE); + nfca_poll->nfcid1_len = *data++; pr_debug("sens_res 0x%x, nfcid1_len %d\n", nfca_poll->sens_res, nfca_poll->nfcid1_len); @@ -130,7 +130,7 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcb_poll *nfcb_poll, __u8 *data) { - nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE); + nfcb_poll->sensb_res_len = *data++; pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); @@ -145,7 +145,7 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, __u8 *data) { nfcf_poll->bit_rate = *data++; - nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE); + nfcf_poll->sensf_res_len = *data++; pr_debug("bit_rate %d, sensf_res_len %d\n", nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); @@ -331,7 +331,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, switch (ntf->activation_rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; - nfca_poll->rats_res_len = min_t(__u8, *data++, 20); + nfca_poll->rats_res_len = *data++; pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); if (nfca_poll->rats_res_len > 0) { memcpy(nfca_poll->rats_res, @@ -341,7 +341,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, case NCI_NFC_B_PASSIVE_POLL_MODE: nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; - nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50); + nfcb_poll->attrib_res_len = *data++; pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); if (nfcb_poll->attrib_res_len > 0) { memcpy(nfcb_poll->attrib_res, diff --git a/trunk/net/nfc/rawsock.c b/trunk/net/nfc/rawsock.c index 8b8a6a2b2bad..ec1134c9e07f 100644 --- a/trunk/net/nfc/rawsock.c +++ b/trunk/net/nfc/rawsock.c @@ -54,10 +54,7 @@ static int rawsock_release(struct socket *sock) { struct sock *sk = sock->sk; - pr_debug("sock=%p sk=%p\n", sock, sk); - - if (!sk) - return 0; + pr_debug("sock=%p\n", sock); sock_orphan(sk); sock_put(sk); diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index b16517ee1aaf..5bc9ab161b37 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -271,7 +271,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a */ asoc->peer.sack_needed = 1; asoc->peer.sack_cnt = 0; - asoc->peer.sack_generation = 1; /* Assume that the peer will tell us if he recognizes ASCONF * as part of INIT exchange. diff --git a/trunk/net/sctp/output.c b/trunk/net/sctp/output.c index 6ae47acaaec6..f1b7d4bb591e 100644 --- a/trunk/net/sctp/output.c +++ b/trunk/net/sctp/output.c @@ -248,11 +248,6 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, /* If the SACK timer is running, we have a pending SACK */ if (timer_pending(timer)) { struct sctp_chunk *sack; - - if (pkt->transport->sack_generation != - pkt->transport->asoc->peer.sack_generation) - return retval; - asoc->a_rwnd = asoc->rwnd; sack = sctp_make_sack(asoc); if (sack) { diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index b6de71efb140..a85eeeb55dd0 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -734,10 +734,8 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) int len; __u32 ctsn; __u16 num_gabs, num_dup_tsns; - struct sctp_association *aptr = (struct sctp_association *)asoc; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; - struct sctp_transport *trans; memset(gabs, 0, sizeof(gabs)); ctsn = sctp_tsnmap_get_ctsn(map); @@ -807,20 +805,6 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, sctp_tsnmap_get_dups(map)); - /* Once we have a sack generated, check to see what our sack - * generation is, if its 0, reset the transports to 0, and reset - * the association generation to 1 - * - * The idea is that zero is never used as a valid generation for the - * association so no transport will match after a wrap event like this, - * Until the next sack - */ - if (++aptr->peer.sack_generation == 0) { - list_for_each_entry(trans, &asoc->peer.transport_addr_list, - transports) - trans->sack_generation = 0; - aptr->peer.sack_generation = 1; - } nodata: return retval; } diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index 8716da1a8592..c96d1a81cf42 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -1268,7 +1268,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, case SCTP_CMD_REPORT_TSN: /* Record the arrival of a TSN. */ error = sctp_tsnmap_mark(&asoc->peer.tsn_map, - cmd->obj.u32, NULL); + cmd->obj.u32); break; case SCTP_CMD_REPORT_FWDTSN: diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index 1dcceb6e0ce6..b026ba0c6992 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -68,8 +68,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->af_specific = sctp_get_af_specific(addr->sa.sa_family); memset(&peer->saddr, 0, sizeof(union sctp_addr)); - peer->sack_generation = 0; - /* From 6.3.1 RTO Calculation: * * C1) Until an RTT measurement has been made for a packet sent to the diff --git a/trunk/net/sctp/tsnmap.c b/trunk/net/sctp/tsnmap.c index b5fb7c409023..f1e40cebc981 100644 --- a/trunk/net/sctp/tsnmap.c +++ b/trunk/net/sctp/tsnmap.c @@ -114,8 +114,7 @@ int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn) /* Mark this TSN as seen. */ -int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn, - struct sctp_transport *trans) +int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) { u16 gap; @@ -134,9 +133,6 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn, */ map->max_tsn_seen++; map->cumulative_tsn_ack_point++; - if (trans) - trans->sack_generation = - trans->asoc->peer.sack_generation; map->base_tsn++; } else { /* Either we already have a gap, or about to record a gap, so diff --git a/trunk/net/sctp/ulpevent.c b/trunk/net/sctp/ulpevent.c index 33d894776192..8a84017834c2 100644 --- a/trunk/net/sctp/ulpevent.c +++ b/trunk/net/sctp/ulpevent.c @@ -715,8 +715,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, * can mark it as received so the tsn_map is updated correctly. */ if (sctp_tsnmap_mark(&asoc->peer.tsn_map, - ntohl(chunk->subh.data_hdr->tsn), - chunk->transport)) + ntohl(chunk->subh.data_hdr->tsn))) goto fail_mark; /* First calculate the padding, so we don't inadvertently diff --git a/trunk/net/sctp/ulpqueue.c b/trunk/net/sctp/ulpqueue.c index f5a6a4f4faf7..f2d1de7f2ffb 100644 --- a/trunk/net/sctp/ulpqueue.c +++ b/trunk/net/sctp/ulpqueue.c @@ -1051,7 +1051,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, if (chunk && (freed >= needed)) { __u32 tsn; tsn = ntohl(chunk->subh.data_hdr->tsn); - sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport); + sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn); sctp_ulpq_tail_data(ulpq, chunk, gfp); sctp_ulpq_partial_delivery(ulpq, chunk, gfp); diff --git a/trunk/security/security.c b/trunk/security/security.c index 860aeb349cb3..3efc9b12aef4 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #define MAX_LSM_EVM_XATTR 2 diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index aa4c25e0f327..5ccf10a4d593 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -6688,31 +6688,6 @@ static const struct alc_model_fixup alc662_fixup_models[] = { {} }; -static void alc662_fill_coef(struct hda_codec *codec) -{ - int val, coef; - - coef = alc_get_coef0(codec); - - switch (codec->vendor_id) { - case 0x10ec0662: - if ((coef & 0x00f0) == 0x0030) { - val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ - alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); - } - break; - case 0x10ec0272: - case 0x10ec0273: - case 0x10ec0663: - case 0x10ec0665: - case 0x10ec0670: - case 0x10ec0671: - case 0x10ec0672: - val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ - alc_write_coef_idx(codec, 0xd, val | (1<<14)); - break; - } -} /* */ @@ -6732,9 +6707,6 @@ static int patch_alc662(struct hda_codec *codec) alc_fix_pll_init(codec, 0x20, 0x04, 15); - spec->init_hook = alc662_fill_coef; - alc662_fill_coef(codec); - alc_pick_fixup(codec, alc662_fixup_models, alc662_fixup_tbl, alc662_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); diff --git a/trunk/sound/soc/codecs/tlv320aic3x.c b/trunk/sound/soc/codecs/tlv320aic3x.c index e9b62b5ea637..64d2a4fa34b2 100644 --- a/trunk/sound/soc/codecs/tlv320aic3x.c +++ b/trunk/sound/soc/codecs/tlv320aic3x.c @@ -935,7 +935,9 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, } found: - snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p); + data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); + snd_soc_write(codec, AIC3X_PLL_PROGA_REG, + data | (pll_p << PLLP_SHIFT)); snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT); diff --git a/trunk/sound/soc/codecs/tlv320aic3x.h b/trunk/sound/soc/codecs/tlv320aic3x.h index 08c7f6685ff0..6f097fb60683 100644 --- a/trunk/sound/soc/codecs/tlv320aic3x.h +++ b/trunk/sound/soc/codecs/tlv320aic3x.h @@ -166,7 +166,6 @@ /* PLL registers bitfields */ #define PLLP_SHIFT 0 -#define PLLP_MASK 7 #define PLLQ_SHIFT 3 #define PLLR_SHIFT 0 #define PLLJ_SHIFT 2 diff --git a/trunk/sound/soc/codecs/wm2200.c b/trunk/sound/soc/codecs/wm2200.c index 32682c1b7cde..acbdc5fde923 100644 --- a/trunk/sound/soc/codecs/wm2200.c +++ b/trunk/sound/soc/codecs/wm2200.c @@ -1491,7 +1491,6 @@ static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { 5644800, - 3763200, 2882400, 1881600, 1411200, diff --git a/trunk/tools/perf/Documentation/perf-bench.txt b/trunk/tools/perf/Documentation/perf-bench.txt index f3c716a4cad3..a3dbadb26ef5 100644 --- a/trunk/tools/perf/Documentation/perf-bench.txt +++ b/trunk/tools/perf/Documentation/perf-bench.txt @@ -12,7 +12,7 @@ SYNOPSIS DESCRIPTION ----------- -This 'perf bench' command is a general framework for benchmark suites. +This 'perf bench' command is general framework for benchmark suites. COMMON OPTIONS -------------- @@ -45,20 +45,14 @@ SUBSYSTEM 'sched':: Scheduler and IPC mechanisms. -'mem':: - Memory access performance. - -'all':: - All benchmark subsystems. - SUITES FOR 'sched' ~~~~~~~~~~~~~~~~~~ *messaging*:: Suite for evaluating performance of scheduler and IPC mechanisms. Based on hackbench by Rusty Russell. -Options of *messaging* -^^^^^^^^^^^^^^^^^^^^^^ +Options of *pipe* +^^^^^^^^^^^^^^^^^ -p:: --pipe:: Use pipe() instead of socketpair() @@ -121,72 +115,6 @@ Example of *pipe* 59004 ops/sec --------------------- -SUITES FOR 'mem' -~~~~~~~~~~~~~~~~ -*memcpy*:: -Suite for evaluating performance of simple memory copy in various ways. - -Options of *memcpy* -^^^^^^^^^^^^^^^^^^^ --l:: ---length:: -Specify length of memory to copy (default: 1MB). -Available units are B, KB, MB, GB and TB (case insensitive). - --r:: ---routine:: -Specify routine to copy (default: default). -Available routines are depend on the architecture. -On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. - --i:: ---iterations:: -Repeat memcpy invocation this number of times. - --c:: ---clock:: -Use perf's cpu-cycles event instead of gettimeofday syscall. - --o:: ---only-prefault:: -Show only the result with page faults before memcpy. - --n:: ---no-prefault:: -Show only the result without page faults before memcpy. - -*memset*:: -Suite for evaluating performance of simple memory set in various ways. - -Options of *memset* -^^^^^^^^^^^^^^^^^^^ --l:: ---length:: -Specify length of memory to set (default: 1MB). -Available units are B, KB, MB, GB and TB (case insensitive). - --r:: ---routine:: -Specify routine to set (default: default). -Available routines are depend on the architecture. -On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. - --i:: ---iterations:: -Repeat memset invocation this number of times. - --c:: ---clock:: -Use perf's cpu-cycles event instead of gettimeofday syscall. - --o:: ---only-prefault:: -Show only the result with page faults before memset. - --n:: ---no-prefault:: -Show only the result without page faults before memset. - SEE ALSO -------- linkperf:perf[1] diff --git a/trunk/tools/perf/Documentation/perf-report.txt b/trunk/tools/perf/Documentation/perf-report.txt index 495210a612c4..2d89f02719b5 100644 --- a/trunk/tools/perf/Documentation/perf-report.txt +++ b/trunk/tools/perf/Documentation/perf-report.txt @@ -57,7 +57,7 @@ OPTIONS -s:: --sort=:: - Sort by key(s): pid, comm, dso, symbol, parent, srcline. + Sort by key(s): pid, comm, dso, symbol, parent. -p:: --parent=:: diff --git a/trunk/tools/perf/Documentation/perf-top.txt b/trunk/tools/perf/Documentation/perf-top.txt index 5b80d84d6b4a..4a5680cb242e 100644 --- a/trunk/tools/perf/Documentation/perf-top.txt +++ b/trunk/tools/perf/Documentation/perf-top.txt @@ -112,7 +112,7 @@ Default is to monitor all CPUS. -s:: --sort:: - Sort by key(s): pid, comm, dso, symbol, parent, srcline. + Sort by key(s): pid, comm, dso, symbol, parent -n:: --show-nr-samples:: diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 75d74e5db8d5..0eee64cfe9a0 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -155,7 +155,7 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables @@ -503,7 +503,6 @@ else LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/tui/setup.o - LIB_OBJS += $(OUTPUT)ui/tui/util.o LIB_H += ui/browser.h LIB_H += ui/browsers/map.h LIB_H += ui/helpline.h @@ -523,18 +522,13 @@ else msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); BASIC_CFLAGS += -DNO_GTK2_SUPPORT else - ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) - BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR - endif BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) EXTLIBS += $(shell pkg-config --libs gtk+-2.0) LIB_OBJS += $(OUTPUT)ui/gtk/browser.o LIB_OBJS += $(OUTPUT)ui/gtk/setup.o - LIB_OBJS += $(OUTPUT)ui/gtk/util.o # Make sure that it'd be included only once. ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) LIB_OBJS += $(OUTPUT)ui/setup.o - LIB_OBJS += $(OUTPUT)ui/util.o endif endif endif diff --git a/trunk/tools/perf/bench/mem-memcpy.c b/trunk/tools/perf/bench/mem-memcpy.c index d990365cafa0..71557225bf92 100644 --- a/trunk/tools/perf/bench/mem-memcpy.c +++ b/trunk/tools/perf/bench/mem-memcpy.c @@ -32,13 +32,13 @@ static bool no_prefault; static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB", "Specify length of memory to copy. " - "Available units: B, KB, MB, GB and TB (upper and lower)"), + "available unit: B, MB, GB (upper and lower)"), OPT_STRING('r', "routine", &routine, "default", "Specify routine to copy"), OPT_INTEGER('i', "iterations", &iterations, "repeat memcpy() invocation this number of times"), OPT_BOOLEAN('c', "clock", &use_clock, - "Use cycles event instead of gettimeofday() for measuring"), + "Use CPU clock for measuring"), OPT_BOOLEAN('o', "only-prefault", &only_prefault, "Show only the result with page faults before memcpy()"), OPT_BOOLEAN('n', "no-prefault", &no_prefault, diff --git a/trunk/tools/perf/bench/mem-memset.c b/trunk/tools/perf/bench/mem-memset.c index bf0d5f552017..e9079185bd72 100644 --- a/trunk/tools/perf/bench/mem-memset.c +++ b/trunk/tools/perf/bench/mem-memset.c @@ -31,14 +31,14 @@ static bool no_prefault; static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB", - "Specify length of memory to set. " - "Available units: B, KB, MB, GB and TB (upper and lower)"), + "Specify length of memory to copy. " + "available unit: B, MB, GB (upper and lower)"), OPT_STRING('r', "routine", &routine, "default", - "Specify routine to set"), + "Specify routine to copy"), OPT_INTEGER('i', "iterations", &iterations, "repeat memset() invocation this number of times"), OPT_BOOLEAN('c', "clock", &use_clock, - "Use cycles event instead of gettimeofday() for measuring"), + "Use CPU clock for measuring"), OPT_BOOLEAN('o', "only-prefault", &only_prefault, "Show only the result with page faults before memset()"), OPT_BOOLEAN('n', "no-prefault", &no_prefault, diff --git a/trunk/tools/perf/builtin-bench.c b/trunk/tools/perf/builtin-bench.c index 1f3100216448..b0e74ab2d7a2 100644 --- a/trunk/tools/perf/builtin-bench.c +++ b/trunk/tools/perf/builtin-bench.c @@ -33,7 +33,7 @@ struct bench_suite { }; \ /* sentinel: easy for help */ -#define suite_all { "all", "Test all benchmark suites", NULL } +#define suite_all { "all", "test all suite (pseudo suite)", NULL } static struct bench_suite sched_suites[] = { { "messaging", @@ -75,7 +75,7 @@ static struct bench_subsys subsystems[] = { "memory access performance", mem_suites }, { "all", /* sentinel: easy for help */ - "all benchmark subsystem", + "test all subsystem (pseudo subsystem)", NULL }, { NULL, NULL, diff --git a/trunk/tools/perf/builtin-evlist.c b/trunk/tools/perf/builtin-evlist.c index 0dd5a058f766..acd78dc28341 100644 --- a/trunk/tools/perf/builtin-evlist.c +++ b/trunk/tools/perf/builtin-evlist.c @@ -60,7 +60,7 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail list_for_each_entry(pos, &session->evlist->entries, node) { bool first = true; - printf("%s", perf_evsel__name(pos)); + printf("%s", event_name(pos)); if (details->verbose || details->freq) { comma_printf(&first, " sample_freq=%" PRIu64, diff --git a/trunk/tools/perf/builtin-kmem.c b/trunk/tools/perf/builtin-kmem.c index ce35015f2dc6..547af48deb4f 100644 --- a/trunk/tools/perf/builtin-kmem.c +++ b/trunk/tools/perf/builtin-kmem.c @@ -57,11 +57,6 @@ static unsigned long nr_allocs, nr_cross_allocs; #define PATH_SYS_NODE "/sys/devices/system/node" -struct perf_kmem { - struct perf_tool tool; - struct perf_session *session; -}; - static void init_cpunode_map(void) { FILE *fp; @@ -283,16 +278,14 @@ static void process_free_event(void *data, s_alloc->alloc_cpu = -1; } -static void process_raw_event(struct perf_tool *tool, - union perf_event *raw_event __used, void *data, +static void process_raw_event(union perf_event *raw_event __used, void *data, int cpu, u64 timestamp, struct thread *thread) { - struct perf_kmem *kmem = container_of(tool, struct perf_kmem, tool); struct event_format *event; int type; - type = trace_parse_common_type(kmem->session->pevent, data); - event = pevent_find_event(kmem->session->pevent, type); + type = trace_parse_common_type(data); + event = trace_find_event(type); if (!strcmp(event->name, "kmalloc") || !strcmp(event->name, "kmem_cache_alloc")) { @@ -313,7 +306,7 @@ static void process_raw_event(struct perf_tool *tool, } } -static int process_sample_event(struct perf_tool *tool, +static int process_sample_event(struct perf_tool *tool __used, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel __used, @@ -329,18 +322,16 @@ static int process_sample_event(struct perf_tool *tool, dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - process_raw_event(tool, event, sample->raw_data, sample->cpu, + process_raw_event(event, sample->raw_data, sample->cpu, sample->time, thread); return 0; } -static struct perf_kmem perf_kmem = { - .tool = { - .sample = process_sample_event, - .comm = perf_event__process_comm, - .ordered_samples = true, - }, +static struct perf_tool perf_kmem = { + .sample = process_sample_event, + .comm = perf_event__process_comm, + .ordered_samples = true, }; static double fragmentation(unsigned long n_req, unsigned long n_alloc) @@ -495,15 +486,11 @@ static void sort_result(void) static int __cmd_kmem(void) { int err = -EINVAL; - struct perf_session *session; - - session = perf_session__new(input_name, O_RDONLY, 0, false, - &perf_kmem.tool); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, false, &perf_kmem); if (session == NULL) return -ENOMEM; - perf_kmem.session = session; - if (perf_session__create_kernel_maps(session) < 0) goto out_delete; @@ -511,7 +498,7 @@ static int __cmd_kmem(void) goto out_delete; setup_pager(); - err = perf_session__process_events(session, &perf_kmem.tool); + err = perf_session__process_events(session, &perf_kmem); if (err != 0) goto out_delete; sort_result(); diff --git a/trunk/tools/perf/builtin-lock.c b/trunk/tools/perf/builtin-lock.c index b3c428548868..fd53319de20d 100644 --- a/trunk/tools/perf/builtin-lock.c +++ b/trunk/tools/perf/builtin-lock.c @@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) struct event_format *event; int type; - type = trace_parse_common_type(session->pevent, data); - event = pevent_find_event(session->pevent, type); + type = trace_parse_common_type(data); + event = trace_find_event(type); if (!strcmp(event->name, "lock_acquire")) process_lock_acquire_event(data, event, cpu, timestamp, thread); diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index f5a6452931e6..f95840d04e4c 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -265,7 +265,7 @@ static void perf_record__open(struct perf_record *rec) if (err == ENOENT) { ui__error("The %s event is not supported.\n", - perf_evsel__name(pos)); + event_name(pos)); exit(EXIT_FAILURE); } @@ -916,7 +916,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) usage_with_options(record_usage, record_options); list_for_each_entry(pos, &evsel_list->entries, node) { - if (perf_header__push_event(pos->attr.config, perf_evsel__name(pos))) + if (perf_header__push_event(pos->attr.config, event_name(pos))) goto out_free_fd; } diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index 69b1c1185159..25249f76329d 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -69,7 +69,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, al->thread, + err = machine__resolve_callchain(machine, evsel, al->thread, sample->callchain, &parent); if (err) return err; @@ -140,7 +140,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, struct hist_entry *he; if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, al->thread, + err = machine__resolve_callchain(machine, evsel, al->thread, sample->callchain, &parent); if (err) return err; @@ -230,7 +230,7 @@ static int process_read_event(struct perf_tool *tool, struct perf_report *rep = container_of(tool, struct perf_report, tool); if (rep->show_threads) { - const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; + const char *name = evsel ? event_name(evsel) : "unknown"; perf_read_values_add_value(&rep->show_threads_values, event->read.pid, event->read.tid, event->read.id, @@ -239,18 +239,17 @@ static int process_read_event(struct perf_tool *tool, } dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, - evsel ? perf_evsel__name(evsel) : "FAIL", + evsel ? event_name(evsel) : "FAIL", event->read.value); return 0; } -/* For pipe mode, sample_type is not currently set */ static int perf_report__setup_sample_type(struct perf_report *rep) { struct perf_session *self = rep->session; - if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { + if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { ui__error("Selected --sort parent, but no " "callchain data. Did you call " @@ -273,8 +272,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) } if (sort__branch_mode == 1) { - if (!self->fd_pipe && - !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { + if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { ui__error("Selected -b but no branch data. " "Did you call perf record without -b?\n"); return -1; @@ -316,7 +314,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, list_for_each_entry(pos, &evlist->entries, node) { struct hists *hists = &pos->hists; - const char *evname = perf_evsel__name(pos); + const char *evname = event_name(pos); hists__fprintf_nr_sample_events(hists, evname, stdout); hists__fprintf(hists, NULL, false, true, 0, 0, stdout); diff --git a/trunk/tools/perf/builtin-sched.c b/trunk/tools/perf/builtin-sched.c index 7a9ad2b1ee76..b125e07eb399 100644 --- a/trunk/tools/perf/builtin-sched.c +++ b/trunk/tools/perf/builtin-sched.c @@ -43,11 +43,6 @@ static u64 sleep_measurement_overhead; static unsigned long nr_tasks; -struct perf_sched { - struct perf_tool tool; - struct perf_session *session; -}; - struct sched_atom; struct task_desc { @@ -1602,13 +1597,11 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, struct perf_evsel *evsel, struct machine *machine) { - struct perf_sched *sched = container_of(tool, struct perf_sched, tool); - struct pevent *pevent = sched->session->pevent; struct thread *thread = machine__findnew_thread(machine, sample->pid); if (thread == NULL) { pr_debug("problem processing %s event, skipping it.\n", - perf_evsel__name(evsel)); + evsel->name); return -1; } @@ -1619,8 +1612,7 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, tracepoint_handler f = evsel->handler.func; if (evsel->handler.data == NULL) - evsel->handler.data = pevent_find_event(pevent, - evsel->attr.config); + evsel->handler.data = trace_find_event(evsel->attr.config); f(tool, evsel->handler.data, sample, machine, thread); } @@ -1628,14 +1620,12 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, return 0; } -static struct perf_sched perf_sched = { - .tool = { - .sample = perf_sched__process_tracepoint_sample, - .comm = perf_event__process_comm, - .lost = perf_event__process_lost, - .fork = perf_event__process_task, - .ordered_samples = true, - }, +static struct perf_tool perf_sched = { + .sample = perf_sched__process_tracepoint_sample, + .comm = perf_event__process_comm, + .lost = perf_event__process_lost, + .fork = perf_event__process_task, + .ordered_samples = true, }; static void read_events(bool destroy, struct perf_session **psession) @@ -1650,20 +1640,16 @@ static void read_events(bool destroy, struct perf_session **psession) { "sched:sched_process_exit", process_sched_exit_event, }, { "sched:sched_migrate_task", process_sched_migrate_task_event, }, }; - struct perf_session *session; - - session = perf_session__new(input_name, O_RDONLY, 0, false, - &perf_sched.tool); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, + 0, false, &perf_sched); if (session == NULL) die("No Memory"); - perf_sched.session = session; - - err = perf_session__set_tracepoints_handlers(session, handlers); + err = perf_evlist__set_tracepoints_handlers_array(session->evlist, handlers); assert(err == 0); if (perf_session__has_traces(session, "record -R")) { - err = perf_session__process_events(session, &perf_sched.tool); + err = perf_session__process_events(session, &perf_sched); if (err) die("Failed to process events, error %d", err); diff --git a/trunk/tools/perf/builtin-script.c b/trunk/tools/perf/builtin-script.c index 1e60ab70b2b1..8e395a538eb9 100644 --- a/trunk/tools/perf/builtin-script.c +++ b/trunk/tools/perf/builtin-script.c @@ -28,11 +28,6 @@ static bool system_wide; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); -struct perf_script { - struct perf_tool tool; - struct perf_session *session; -}; - enum perf_output_field { PERF_OUTPUT_COMM = 1U << 0, PERF_OUTPUT_TID = 1U << 1, @@ -142,11 +137,10 @@ static const char *output_field2str(enum perf_output_field field) #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) -static int perf_evsel__check_stype(struct perf_evsel *evsel, - u64 sample_type, const char *sample_msg, - enum perf_output_field field) +static int perf_event_attr__check_stype(struct perf_event_attr *attr, + u64 sample_type, const char *sample_msg, + enum perf_output_field field) { - struct perf_event_attr *attr = &evsel->attr; int type = attr->type; const char *evname; @@ -154,7 +148,7 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel, return 0; if (output[type].user_set) { - evname = perf_evsel__name(evsel); + evname = __event_name(attr->type, attr->config); pr_err("Samples for '%s' event do not have %s attribute set. " "Cannot print '%s' field.\n", evname, sample_msg, output_field2str(field)); @@ -163,7 +157,7 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel, /* user did not ask for it explicitly so remove from the default list */ output[type].fields &= ~field; - evname = perf_evsel__name(evsel); + evname = __event_name(attr->type, attr->config); pr_debug("Samples for '%s' event do not have %s attribute set. " "Skipping '%s' field.\n", evname, sample_msg, output_field2str(field)); @@ -181,8 +175,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, return -EINVAL; if (PRINT_FIELD(IP)) { - if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", - PERF_OUTPUT_IP)) + if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", + PERF_OUTPUT_IP)) return -EINVAL; if (!no_callchain && @@ -191,8 +185,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, } if (PRINT_FIELD(ADDR) && - perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", - PERF_OUTPUT_ADDR)) + perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR", + PERF_OUTPUT_ADDR)) return -EINVAL; if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { @@ -214,18 +208,18 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, } if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && - perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", - PERF_OUTPUT_TID|PERF_OUTPUT_PID)) + perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", + PERF_OUTPUT_TID|PERF_OUTPUT_PID)) return -EINVAL; if (PRINT_FIELD(TIME) && - perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", - PERF_OUTPUT_TIME)) + perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME", + PERF_OUTPUT_TIME)) return -EINVAL; if (PRINT_FIELD(CPU) && - perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU", - PERF_OUTPUT_CPU)) + perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU", + PERF_OUTPUT_CPU)) return -EINVAL; return 0; @@ -262,13 +256,11 @@ static int perf_session__check_output_opt(struct perf_session *session) return 0; } -static void print_sample_start(struct pevent *pevent, - struct perf_sample *sample, +static void print_sample_start(struct perf_sample *sample, struct thread *thread, - struct perf_evsel *evsel) + struct perf_event_attr *attr) { int type; - struct perf_event_attr *attr = &evsel->attr; struct event_format *event; const char *evname = NULL; unsigned long secs; @@ -308,18 +300,12 @@ static void print_sample_start(struct pevent *pevent, if (PRINT_FIELD(EVNAME)) { if (attr->type == PERF_TYPE_TRACEPOINT) { - /* - * XXX Do we really need this here? - * perf_evlist__set_tracepoint_names should have done - * this already - */ - type = trace_parse_common_type(pevent, - sample->raw_data); - event = pevent_find_event(pevent, type); + type = trace_parse_common_type(sample->raw_data); + event = trace_find_event(type); if (event) evname = event->name; } else - evname = perf_evsel__name(evsel); + evname = __event_name(attr->type, attr->config); printf("%s: ", evname ? evname : "[unknown]"); } @@ -401,7 +387,7 @@ static void print_sample_bts(union perf_event *event, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, + perf_event__print_ip(event, sample, machine, evsel, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } @@ -416,7 +402,6 @@ static void print_sample_bts(union perf_event *event, } static void process_event(union perf_event *event __unused, - struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, @@ -427,7 +412,7 @@ static void process_event(union perf_event *event __unused, if (output[attr->type].fields == 0) return; - print_sample_start(pevent, sample, thread, evsel); + print_sample_start(sample, thread, attr); if (is_bts_event(attr)) { print_sample_bts(event, sample, evsel, machine, thread); @@ -435,7 +420,7 @@ static void process_event(union perf_event *event __unused, } if (PRINT_FIELD(TRACE)) - print_trace_event(pevent, sample->cpu, sample->raw_data, + print_trace_event(sample->cpu, sample->raw_data, sample->raw_size); if (PRINT_FIELD(ADDR)) @@ -446,7 +431,7 @@ static void process_event(union perf_event *event __unused, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, + perf_event__print_ip(event, sample, machine, evsel, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } @@ -466,8 +451,7 @@ static int default_stop_script(void) return 0; } -static int default_generate_script(struct pevent *pevent __unused, - const char *outfile __unused) +static int default_generate_script(const char *outfile __unused) { return 0; } @@ -505,7 +489,6 @@ static int process_sample_event(struct perf_tool *tool __used, struct machine *machine) { struct addr_location al; - struct perf_script *scr = container_of(tool, struct perf_script, tool); struct thread *thread = machine__findnew_thread(machine, event->ip.tid); if (thread == NULL) { @@ -537,27 +520,24 @@ static int process_sample_event(struct perf_tool *tool __used, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) return 0; - scripting_ops->process_event(event, scr->session->pevent, - sample, evsel, machine, thread); + scripting_ops->process_event(event, sample, evsel, machine, thread); evsel->hists.stats.total_period += sample->period; return 0; } -static struct perf_script perf_script = { - .tool = { - .sample = process_sample_event, - .mmap = perf_event__process_mmap, - .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, - .attr = perf_event__process_attr, - .event_type = perf_event__process_event_type, - .tracing_data = perf_event__process_tracing_data, - .build_id = perf_event__process_build_id, - .ordered_samples = true, - .ordering_requires_timestamps = true, - }, +static struct perf_tool perf_script = { + .sample = process_sample_event, + .mmap = perf_event__process_mmap, + .comm = perf_event__process_comm, + .exit = perf_event__process_task, + .fork = perf_event__process_task, + .attr = perf_event__process_attr, + .event_type = perf_event__process_event_type, + .tracing_data = perf_event__process_tracing_data, + .build_id = perf_event__process_build_id, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; extern volatile int session_done; @@ -573,7 +553,7 @@ static int __cmd_script(struct perf_session *session) signal(SIGINT, sig_handler); - ret = perf_session__process_events(session, &perf_script.tool); + ret = perf_session__process_events(session, &perf_script); if (debug_mode) pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); @@ -1355,13 +1335,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (!script_name) setup_pager(); - session = perf_session__new(input_name, O_RDONLY, 0, false, - &perf_script.tool); + session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script); if (session == NULL) return -ENOMEM; - perf_script.session = session; - if (cpu_list) { if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) return -1; @@ -1407,8 +1384,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) return -1; } - err = scripting_ops->generate_script(session->pevent, - "perf-script"); + err = scripting_ops->generate_script("perf-script"); goto out; } diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index 861f0aec77ae..07b5c7703dd1 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -391,7 +391,7 @@ static int read_counter_aggr(struct perf_evsel *counter) if (verbose) { fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", - perf_evsel__name(counter), count[0], count[1], count[2]); + event_name(counter), count[0], count[1], count[2]); } /* @@ -496,7 +496,7 @@ static int run_perf_stat(int argc __used, const char **argv) errno == ENXIO) { if (verbose) ui__warning("%s event is not supported by the kernel.\n", - perf_evsel__name(counter)); + event_name(counter)); counter->supported = false; continue; } @@ -594,7 +594,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) csv_output ? 0 : -4, evsel_list->cpus->map[cpu], csv_sep); - fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); + fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel)); if (evsel->cgrp) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); @@ -792,7 +792,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) else cpu = 0; - fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel)); + fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel)); if (evsel->cgrp) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); @@ -908,7 +908,7 @@ static void print_counter_aggr(struct perf_evsel *counter) counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep, csv_output ? 0 : -24, - perf_evsel__name(counter)); + event_name(counter)); if (counter->cgrp) fprintf(output, "%s%s", csv_sep, counter->cgrp->name); @@ -961,7 +961,7 @@ static void print_counter(struct perf_evsel *counter) counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep, csv_output ? 0 : -24, - perf_evsel__name(counter)); + event_name(counter)); if (counter->cgrp) fprintf(output, "%s%s", diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 5ce30305462b..5a8727c08757 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -583,7 +583,7 @@ static int test__basic_mmap(void) if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { pr_debug("expected %d %s events, got %d\n", expected_nr_events[evsel->idx], - perf_evsel__name(evsel), nr_events[evsel->idx]); + event_name(evsel), nr_events[evsel->idx]); goto out_munmap; } } diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index e3cab5f088f8..6bb0277b7dfe 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -245,7 +245,7 @@ static void perf_top__show_details(struct perf_top *top) if (notes->src == NULL) goto out_unlock; - printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name); + printf("Showing %s for %s\n", event_name(top->sym_evsel), symbol->name); printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter); more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx, @@ -408,7 +408,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top) fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); if (top->evlist->nr_entries > 1) - fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel)); + fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top->sym_evsel)); fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); @@ -503,13 +503,13 @@ static void perf_top__handle_keypress(struct perf_top *top, int c) fprintf(stderr, "\nAvailable events:"); list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) - fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); + fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, event_name(top->sym_evsel)); prompt_integer(&counter, "Enter details event counter"); if (counter >= top->evlist->nr_entries) { top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node); - fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); + fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top->sym_evsel)); sleep(1); break; } @@ -774,7 +774,7 @@ static void perf_event__process_sample(struct perf_tool *tool, if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { - err = machine__resolve_callchain(machine, al.thread, + err = machine__resolve_callchain(machine, evsel, al.thread, sample->callchain, &parent); if (err) return; @@ -960,7 +960,7 @@ static void perf_top__start_counters(struct perf_top *top) if (err == ENOENT) { ui__error("The %s event is not supported.\n", - perf_evsel__name(counter)); + event_name(counter)); goto out_err; } else if (err == EMFILE) { ui__error("Too many events are opened.\n" diff --git a/trunk/tools/perf/config/feature-tests.mak b/trunk/tools/perf/config/feature-tests.mak index 6c18785a6417..d9084e03ce56 100644 --- a/trunk/tools/perf/config/feature-tests.mak +++ b/trunk/tools/perf/config/feature-tests.mak @@ -78,19 +78,6 @@ int main(int argc, char *argv[]) return 0; } endef - -define SOURCE_GTK2_INFOBAR -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#include -#pragma GCC diagnostic error \"-Wstrict-prototypes\" - -int main(void) -{ - gtk_info_bar_new(); - - return 0; -} -endef endif ifndef NO_LIBPERL diff --git a/trunk/tools/perf/ui/browsers/annotate.c b/trunk/tools/perf/ui/browsers/annotate.c index 67a2703e666a..34b1c46eaf42 100644 --- a/trunk/tools/perf/ui/browsers/annotate.c +++ b/trunk/tools/perf/ui/browsers/annotate.c @@ -814,7 +814,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, { struct disasm_line *pos, *n; struct annotation *notes; - size_t size; + const size_t size = symbol__size(sym); struct map_symbol ms = { .map = map, .sym = sym, @@ -834,8 +834,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, if (sym == NULL) return -1; - size = symbol__size(sym); - if (map->dso->annotate_warned) return -1; diff --git a/trunk/tools/perf/ui/browsers/hists.c b/trunk/tools/perf/ui/browsers/hists.c index 482f0517b61e..53f6697d014e 100644 --- a/trunk/tools/perf/ui/browsers/hists.c +++ b/trunk/tools/perf/ui/browsers/hists.c @@ -23,7 +23,6 @@ struct hist_browser { struct hists *hists; struct hist_entry *he_selection; struct map_symbol *selection; - int print_seq; bool has_symbols; }; @@ -801,196 +800,6 @@ static void ui_browser__hists_seek(struct ui_browser *browser, } } -static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *browser, - struct callchain_node *chain_node, - u64 total, int level, - FILE *fp) -{ - struct rb_node *node; - int offset = level * LEVEL_OFFSET_STEP; - u64 new_total, remaining; - int printed = 0; - - if (callchain_param.mode == CHAIN_GRAPH_REL) - new_total = chain_node->children_hit; - else - new_total = total; - - remaining = new_total; - node = rb_first(&chain_node->rb_root); - while (node) { - struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); - struct rb_node *next = rb_next(node); - u64 cumul = callchain_cumul_hits(child); - struct callchain_list *chain; - char folded_sign = ' '; - int first = true; - int extra_offset = 0; - - remaining -= cumul; - - list_for_each_entry(chain, &child->val, list) { - char ipstr[BITS_PER_LONG / 4 + 1], *alloc_str; - const char *str; - bool was_first = first; - - if (first) - first = false; - else - extra_offset = LEVEL_OFFSET_STEP; - - folded_sign = callchain_list__folded(chain); - - alloc_str = NULL; - str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); - if (was_first) { - double percent = cumul * 100.0 / new_total; - - if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) - str = "Not enough memory!"; - else - str = alloc_str; - } - - printed += fprintf(fp, "%*s%c %s\n", offset + extra_offset, " ", folded_sign, str); - free(alloc_str); - if (folded_sign == '+') - break; - } - - if (folded_sign == '-') { - const int new_level = level + (extra_offset ? 2 : 1); - printed += hist_browser__fprintf_callchain_node_rb_tree(browser, child, new_total, - new_level, fp); - } - - node = next; - } - - return printed; -} - -static int hist_browser__fprintf_callchain_node(struct hist_browser *browser, - struct callchain_node *node, - int level, FILE *fp) -{ - struct callchain_list *chain; - int offset = level * LEVEL_OFFSET_STEP; - char folded_sign = ' '; - int printed = 0; - - list_for_each_entry(chain, &node->val, list) { - char ipstr[BITS_PER_LONG / 4 + 1], *s; - - folded_sign = callchain_list__folded(chain); - s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); - printed += fprintf(fp, "%*s%c %s\n", offset, " ", folded_sign, s); - } - - if (folded_sign == '-') - printed += hist_browser__fprintf_callchain_node_rb_tree(browser, node, - browser->hists->stats.total_period, - level + 1, fp); - return printed; -} - -static int hist_browser__fprintf_callchain(struct hist_browser *browser, - struct rb_root *chain, int level, FILE *fp) -{ - struct rb_node *nd; - int printed = 0; - - for (nd = rb_first(chain); nd; nd = rb_next(nd)) { - struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); - - printed += hist_browser__fprintf_callchain_node(browser, node, level, fp); - } - - return printed; -} - -static int hist_browser__fprintf_entry(struct hist_browser *browser, - struct hist_entry *he, FILE *fp) -{ - char s[8192]; - double percent; - int printed = 0; - char folded_sign = ' '; - - if (symbol_conf.use_callchain) - folded_sign = hist_entry__folded(he); - - hist_entry__snprintf(he, s, sizeof(s), browser->hists); - percent = (he->period * 100.0) / browser->hists->stats.total_period; - - if (symbol_conf.use_callchain) - printed += fprintf(fp, "%c ", folded_sign); - - printed += fprintf(fp, " %5.2f%%", percent); - - if (symbol_conf.show_nr_samples) - printed += fprintf(fp, " %11u", he->nr_events); - - if (symbol_conf.show_total_period) - printed += fprintf(fp, " %12" PRIu64, he->period); - - printed += fprintf(fp, "%s\n", rtrim(s)); - - if (folded_sign == '-') - printed += hist_browser__fprintf_callchain(browser, &he->sorted_chain, 1, fp); - - return printed; -} - -static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) -{ - struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); - int printed = 0; - - while (nd) { - struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - - printed += hist_browser__fprintf_entry(browser, h, fp); - nd = hists__filter_entries(rb_next(nd)); - } - - return printed; -} - -static int hist_browser__dump(struct hist_browser *browser) -{ - char filename[64]; - FILE *fp; - - while (1) { - scnprintf(filename, sizeof(filename), "perf.hist.%d", browser->print_seq); - if (access(filename, F_OK)) - break; - /* - * XXX: Just an arbitrary lazy upper limit - */ - if (++browser->print_seq == 8192) { - ui_helpline__fpush("Too many perf.hist.N files, nothing written!"); - return -1; - } - } - - fp = fopen(filename, "w"); - if (fp == NULL) { - char bf[64]; - strerror_r(errno, bf, sizeof(bf)); - ui_helpline__fpush("Couldn't write to %s: %s", filename, bf); - return -1; - } - - ++browser->print_seq; - hist_browser__fprintf(browser, fp); - fclose(fp); - ui_helpline__fpush("%s written!", filename); - - return 0; -} - static struct hist_browser *hist_browser__new(struct hists *hists) { struct hist_browser *browser = zalloc(sizeof(*browser)); @@ -1128,9 +937,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, browser->selection->map->dso->annotate_warned) continue; goto do_annotate; - case 'P': - hist_browser__dump(browser); - continue; case 'd': goto zoom_dso; case 't': @@ -1163,7 +969,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "E Expand all callchains\n" "d Zoom into current DSO\n" "t Zoom into current Thread\n" - "P Print histograms to perf.hist.N\n" "/ Filter symbol by name"); continue; case K_ENTER: @@ -1367,7 +1172,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); bool current_entry = ui_browser__is_current_entry(browser, row); unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; - const char *ev_name = perf_evsel__name(evsel); + const char *ev_name = event_name(evsel); char bf[256], unit; const char *warn = " "; size_t printed; @@ -1435,7 +1240,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, */ if (timer) timer(arg); - ev_name = perf_evsel__name(pos); + ev_name = event_name(pos); key = perf_evsel__hists_browse(pos, nr_events, help, ev_name, true, timer, arg, delay_secs); @@ -1504,11 +1309,17 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ui_helpline__push("Press ESC to exit"); list_for_each_entry(pos, &evlist->entries, node) { - const char *ev_name = perf_evsel__name(pos); + const char *ev_name = event_name(pos); size_t line_len = strlen(ev_name) + 7; if (menu.b.width < line_len) menu.b.width = line_len; + /* + * Cache the evsel name, tracepoints have a _high_ cost per + * event_name() call. + */ + if (pos->name == NULL) + pos->name = strdup(ev_name); } return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, @@ -1519,10 +1330,11 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, void(*timer)(void *arg), void *arg, int delay_secs) { + if (evlist->nr_entries == 1) { struct perf_evsel *first = list_entry(evlist->entries.next, struct perf_evsel, node); - const char *ev_name = perf_evsel__name(first); + const char *ev_name = event_name(first); return perf_evsel__hists_browse(first, evlist->nr_entries, help, ev_name, false, timer, arg, delay_secs); diff --git a/trunk/tools/perf/ui/gtk/browser.c b/trunk/tools/perf/ui/gtk/browser.c index ec12e0b4ded6..0656c381a89c 100644 --- a/trunk/tools/perf/ui/gtk/browser.c +++ b/trunk/tools/perf/ui/gtk/browser.c @@ -11,8 +11,8 @@ static void perf_gtk__signal(int sig) { - perf_gtk__exit(false); psignal(sig, "perf"); + gtk_main_quit(); } static void perf_gtk__resize_window(GtkWidget *window) @@ -122,59 +122,13 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) gtk_container_add(GTK_CONTAINER(window), view); } -#ifdef HAVE_GTK_INFO_BAR -static GtkWidget *perf_gtk__setup_info_bar(void) -{ - GtkWidget *info_bar; - GtkWidget *label; - GtkWidget *content_area; - - info_bar = gtk_info_bar_new(); - gtk_widget_set_no_show_all(info_bar, TRUE); - - label = gtk_label_new(""); - gtk_widget_show(label); - - content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); - gtk_container_add(GTK_CONTAINER(content_area), label); - - gtk_info_bar_add_button(GTK_INFO_BAR(info_bar), GTK_STOCK_OK, - GTK_RESPONSE_OK); - g_signal_connect(info_bar, "response", - G_CALLBACK(gtk_widget_hide), NULL); - - pgctx->info_bar = info_bar; - pgctx->message_label = label; - - return info_bar; -} -#endif - -static GtkWidget *perf_gtk__setup_statusbar(void) -{ - GtkWidget *stbar; - unsigned ctxid; - - stbar = gtk_statusbar_new(); - - ctxid = gtk_statusbar_get_context_id(GTK_STATUSBAR(stbar), - "perf report"); - pgctx->statbar = stbar; - pgctx->statbar_ctx_id = ctxid; - - return stbar; -} - int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help __used, void (*timer) (void *arg)__used, void *arg __used, int delay_secs __used) { struct perf_evsel *pos; - GtkWidget *vbox; GtkWidget *notebook; - GtkWidget *info_bar; - GtkWidget *statbar; GtkWidget *window; signal(SIGSEGV, perf_gtk__signal); @@ -189,17 +143,11 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, g_signal_connect(window, "delete_event", gtk_main_quit, NULL); - pgctx = perf_gtk__activate_context(window); - if (!pgctx) - return -1; - - vbox = gtk_vbox_new(FALSE, 0); - notebook = gtk_notebook_new(); list_for_each_entry(pos, &evlist->entries, node) { struct hists *hists = &pos->hists; - const char *evname = perf_evsel__name(pos); + const char *evname = event_name(pos); GtkWidget *scrolled_window; GtkWidget *tab_label; @@ -216,16 +164,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); } - gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); - - info_bar = perf_gtk__setup_info_bar(); - if (info_bar) - gtk_box_pack_start(GTK_BOX(vbox), info_bar, FALSE, FALSE, 0); - - statbar = perf_gtk__setup_statusbar(); - gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); - - gtk_container_add(GTK_CONTAINER(window), vbox); + gtk_container_add(GTK_CONTAINER(window), notebook); gtk_widget_show_all(window); @@ -235,7 +174,5 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_main(); - perf_gtk__deactivate_context(&pgctx); - return 0; } diff --git a/trunk/tools/perf/ui/gtk/gtk.h b/trunk/tools/perf/ui/gtk/gtk.h index a4d0f2b4a2dc..75177ee04032 100644 --- a/trunk/tools/perf/ui/gtk/gtk.h +++ b/trunk/tools/perf/ui/gtk/gtk.h @@ -1,39 +1,8 @@ #ifndef _PERF_GTK_H_ #define _PERF_GTK_H_ 1 -#include - #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #pragma GCC diagnostic error "-Wstrict-prototypes" - -struct perf_gtk_context { - GtkWidget *main_window; - -#ifdef HAVE_GTK_INFO_BAR - GtkWidget *info_bar; - GtkWidget *message_label; -#endif - GtkWidget *statbar; - guint statbar_ctx_id; -}; - -extern struct perf_gtk_context *pgctx; - -static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) -{ - return ctx && ctx->main_window; -} - -struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window); -int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); - -#ifndef HAVE_GTK_INFO_BAR -static inline GtkWidget *perf_gtk__setup_info_bar(void) -{ - return NULL; -} -#endif - #endif /* _PERF_GTK_H_ */ diff --git a/trunk/tools/perf/ui/gtk/setup.c b/trunk/tools/perf/ui/gtk/setup.c index 92879ce61e2f..829529957766 100644 --- a/trunk/tools/perf/ui/gtk/setup.c +++ b/trunk/tools/perf/ui/gtk/setup.c @@ -1,17 +1,12 @@ #include "gtk.h" #include "../../util/cache.h" -#include "../../util/debug.h" - -extern struct perf_error_ops perf_gtk_eops; int perf_gtk__init(void) { - perf_error__register(&perf_gtk_eops); return gtk_init_check(NULL, NULL) ? 0 : -1; } void perf_gtk__exit(bool wait_for_ok __used) { - perf_error__unregister(&perf_gtk_eops); gtk_main_quit(); } diff --git a/trunk/tools/perf/ui/gtk/util.c b/trunk/tools/perf/ui/gtk/util.c deleted file mode 100644 index 0ead373c0dfb..000000000000 --- a/trunk/tools/perf/ui/gtk/util.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "../util.h" -#include "../../util/debug.h" -#include "gtk.h" - -#include - - -struct perf_gtk_context *pgctx; - -struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window) -{ - struct perf_gtk_context *ctx; - - ctx = malloc(sizeof(*pgctx)); - if (ctx) - ctx->main_window = window; - - return ctx; -} - -int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) -{ - if (!perf_gtk__is_active_context(*ctx)) - return -1; - - free(*ctx); - *ctx = NULL; - return 0; -} - -static int perf_gtk__error(const char *format, va_list args) -{ - char *msg; - GtkWidget *dialog; - - if (!perf_gtk__is_active_context(pgctx) || - vasprintf(&msg, format, args) < 0) { - fprintf(stderr, "Error:\n"); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - return -1; - } - - dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(pgctx->main_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "Error\n\n%s", msg); - gtk_dialog_run(GTK_DIALOG(dialog)); - - gtk_widget_destroy(dialog); - free(msg); - return 0; -} - -#ifdef HAVE_GTK_INFO_BAR -static int perf_gtk__warning_info_bar(const char *format, va_list args) -{ - char *msg; - - if (!perf_gtk__is_active_context(pgctx) || - vasprintf(&msg, format, args) < 0) { - fprintf(stderr, "Warning:\n"); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - return -1; - } - - gtk_label_set_text(GTK_LABEL(pgctx->message_label), msg); - gtk_info_bar_set_message_type(GTK_INFO_BAR(pgctx->info_bar), - GTK_MESSAGE_WARNING); - gtk_widget_show(pgctx->info_bar); - - free(msg); - return 0; -} -#else -static int perf_gtk__warning_statusbar(const char *format, va_list args) -{ - char *msg, *p; - - if (!perf_gtk__is_active_context(pgctx) || - vasprintf(&msg, format, args) < 0) { - fprintf(stderr, "Warning:\n"); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - return -1; - } - - gtk_statusbar_pop(GTK_STATUSBAR(pgctx->statbar), - pgctx->statbar_ctx_id); - - /* Only first line can be displayed */ - p = strchr(msg, '\n'); - if (p) - *p = '\0'; - - gtk_statusbar_push(GTK_STATUSBAR(pgctx->statbar), - pgctx->statbar_ctx_id, msg); - - free(msg); - return 0; -} -#endif - -struct perf_error_ops perf_gtk_eops = { - .error = perf_gtk__error, -#ifdef HAVE_GTK_INFO_BAR - .warning = perf_gtk__warning_info_bar, -#else - .warning = perf_gtk__warning_statusbar, -#endif -}; - -/* - * FIXME: Functions below should be implemented properly. - * For now, just add stubs for NO_NEWT=1 build. - */ -#ifdef NO_NEWT_SUPPORT -int ui_helpline__show_help(const char *format __used, va_list ap __used) -{ - return 0; -} - -void ui_progress__update(u64 curr __used, u64 total __used, - const char *title __used) -{ -} -#endif diff --git a/trunk/tools/perf/ui/tui/setup.c b/trunk/tools/perf/ui/tui/setup.c index e813c1d17346..d33e943ac434 100644 --- a/trunk/tools/perf/ui/tui/setup.c +++ b/trunk/tools/perf/ui/tui/setup.c @@ -15,8 +15,6 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; static volatile int ui__need_resize; -extern struct perf_error_ops perf_tui_eops; - void ui__refresh_dimensions(bool force) { if (force || ui__need_resize) { @@ -124,8 +122,6 @@ int ui__init(void) signal(SIGINT, ui__signal); signal(SIGQUIT, ui__signal); signal(SIGTERM, ui__signal); - - perf_error__register(&perf_tui_eops); out: return err; } @@ -141,6 +137,4 @@ void ui__exit(bool wait_for_ok) SLsmg_refresh(); SLsmg_reset_smg(); SLang_reset_tty(); - - perf_error__unregister(&perf_tui_eops); } diff --git a/trunk/tools/perf/ui/tui/util.c b/trunk/tools/perf/ui/tui/util.c deleted file mode 100644 index 092902e30cee..000000000000 --- a/trunk/tools/perf/ui/tui/util.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "../../util/util.h" -#include -#include -#include -#include - -#include "../../util/cache.h" -#include "../../util/debug.h" -#include "../browser.h" -#include "../keysyms.h" -#include "../helpline.h" -#include "../ui.h" -#include "../util.h" -#include "../libslang.h" - -static void ui_browser__argv_write(struct ui_browser *browser, - void *entry, int row) -{ - char **arg = entry; - bool current_entry = ui_browser__is_current_entry(browser, row); - - ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : - HE_COLORSET_NORMAL); - slsmg_write_nstring(*arg, browser->width); -} - -static int popup_menu__run(struct ui_browser *menu) -{ - int key; - - if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) - return -1; - - while (1) { - key = ui_browser__run(menu, 0); - - switch (key) { - case K_RIGHT: - case K_ENTER: - key = menu->index; - break; - case K_LEFT: - case K_ESC: - case 'q': - case CTRL('c'): - key = -1; - break; - default: - continue; - } - - break; - } - - ui_browser__hide(menu); - return key; -} - -int ui__popup_menu(int argc, char * const argv[]) -{ - struct ui_browser menu = { - .entries = (void *)argv, - .refresh = ui_browser__argv_refresh, - .seek = ui_browser__argv_seek, - .write = ui_browser__argv_write, - .nr_entries = argc, - }; - - return popup_menu__run(&menu); -} - -int ui_browser__input_window(const char *title, const char *text, char *input, - const char *exit_msg, int delay_secs) -{ - int x, y, len, key; - int max_len = 60, nr_lines = 0; - static char buf[50]; - const char *t; - - t = text; - while (1) { - const char *sep = strchr(t, '\n'); - - if (sep == NULL) - sep = strchr(t, '\0'); - len = sep - t; - if (max_len < len) - max_len = len; - ++nr_lines; - if (*sep == '\0') - break; - t = sep + 1; - } - - max_len += 2; - nr_lines += 8; - y = SLtt_Screen_Rows / 2 - nr_lines / 2; - x = SLtt_Screen_Cols / 2 - max_len / 2; - - SLsmg_set_color(0); - SLsmg_draw_box(y, x++, nr_lines, max_len); - if (title) { - SLsmg_gotorc(y, x + 1); - SLsmg_write_string((char *)title); - } - SLsmg_gotorc(++y, x); - nr_lines -= 7; - max_len -= 2; - SLsmg_write_wrapped_string((unsigned char *)text, y, x, - nr_lines, max_len, 1); - y += nr_lines; - len = 5; - while (len--) { - SLsmg_gotorc(y + len - 1, x); - SLsmg_write_nstring((char *)" ", max_len); - } - SLsmg_draw_box(y++, x + 1, 3, max_len - 2); - - SLsmg_gotorc(y + 3, x); - SLsmg_write_nstring((char *)exit_msg, max_len); - SLsmg_refresh(); - - x += 2; - len = 0; - key = ui__getch(delay_secs); - while (key != K_TIMER && key != K_ENTER && key != K_ESC) { - if (key == K_BKSPC) { - if (len == 0) - goto next_key; - SLsmg_gotorc(y, x + --len); - SLsmg_write_char(' '); - } else { - buf[len] = key; - SLsmg_gotorc(y, x + len++); - SLsmg_write_char(key); - } - SLsmg_refresh(); - - /* XXX more graceful overflow handling needed */ - if (len == sizeof(buf) - 1) { - ui_helpline__push("maximum size of symbol name reached!"); - key = K_ENTER; - break; - } -next_key: - key = ui__getch(delay_secs); - } - - buf[len] = '\0'; - strncpy(input, buf, len+1); - return key; -} - -int ui__question_window(const char *title, const char *text, - const char *exit_msg, int delay_secs) -{ - int x, y; - int max_len = 0, nr_lines = 0; - const char *t; - - t = text; - while (1) { - const char *sep = strchr(t, '\n'); - int len; - - if (sep == NULL) - sep = strchr(t, '\0'); - len = sep - t; - if (max_len < len) - max_len = len; - ++nr_lines; - if (*sep == '\0') - break; - t = sep + 1; - } - - max_len += 2; - nr_lines += 4; - y = SLtt_Screen_Rows / 2 - nr_lines / 2, - x = SLtt_Screen_Cols / 2 - max_len / 2; - - SLsmg_set_color(0); - SLsmg_draw_box(y, x++, nr_lines, max_len); - if (title) { - SLsmg_gotorc(y, x + 1); - SLsmg_write_string((char *)title); - } - SLsmg_gotorc(++y, x); - nr_lines -= 2; - max_len -= 2; - SLsmg_write_wrapped_string((unsigned char *)text, y, x, - nr_lines, max_len, 1); - SLsmg_gotorc(y + nr_lines - 2, x); - SLsmg_write_nstring((char *)" ", max_len); - SLsmg_gotorc(y + nr_lines - 1, x); - SLsmg_write_nstring((char *)exit_msg, max_len); - SLsmg_refresh(); - return ui__getch(delay_secs); -} - -int ui__help_window(const char *text) -{ - return ui__question_window("Help", text, "Press any key...", 0); -} - -int ui__dialog_yesno(const char *msg) -{ - return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); -} - -static int __ui__warning(const char *title, const char *format, va_list args) -{ - char *s; - - if (vasprintf(&s, format, args) > 0) { - int key; - - pthread_mutex_lock(&ui__lock); - key = ui__question_window(title, s, "Press any key...", 0); - pthread_mutex_unlock(&ui__lock); - free(s); - return key; - } - - fprintf(stderr, "%s\n", title); - vfprintf(stderr, format, args); - return K_ESC; -} - -static int perf_tui__error(const char *format, va_list args) -{ - return __ui__warning("Error:", format, args); -} - -static int perf_tui__warning(const char *format, va_list args) -{ - return __ui__warning("Warning:", format, args); -} - -struct perf_error_ops perf_tui_eops = { - .error = perf_tui__error, - .warning = perf_tui__warning, -}; diff --git a/trunk/tools/perf/ui/util.c b/trunk/tools/perf/ui/util.c index 4f989774c8c6..ad4374a16bb0 100644 --- a/trunk/tools/perf/ui/util.c +++ b/trunk/tools/perf/ui/util.c @@ -1,85 +1,250 @@ -#include "util.h" +#include "../util.h" +#include +#include +#include +#include + +#include "../cache.h" #include "../debug.h" +#include "browser.h" +#include "keysyms.h" +#include "helpline.h" +#include "ui.h" +#include "util.h" +#include "libslang.h" + +static void ui_browser__argv_write(struct ui_browser *browser, + void *entry, int row) +{ + char **arg = entry; + bool current_entry = ui_browser__is_current_entry(browser, row); + ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : + HE_COLORSET_NORMAL); + slsmg_write_nstring(*arg, browser->width); +} -/* - * Default error logging functions - */ -static int perf_stdio__error(const char *format, va_list args) +static int popup_menu__run(struct ui_browser *menu) { - fprintf(stderr, "Error:\n"); - vfprintf(stderr, format, args); - return 0; + int key; + + if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) + return -1; + + while (1) { + key = ui_browser__run(menu, 0); + + switch (key) { + case K_RIGHT: + case K_ENTER: + key = menu->index; + break; + case K_LEFT: + case K_ESC: + case 'q': + case CTRL('c'): + key = -1; + break; + default: + continue; + } + + break; + } + + ui_browser__hide(menu); + return key; } -static int perf_stdio__warning(const char *format, va_list args) +int ui__popup_menu(int argc, char * const argv[]) { - fprintf(stderr, "Warning:\n"); - vfprintf(stderr, format, args); - return 0; + struct ui_browser menu = { + .entries = (void *)argv, + .refresh = ui_browser__argv_refresh, + .seek = ui_browser__argv_seek, + .write = ui_browser__argv_write, + .nr_entries = argc, + }; + + return popup_menu__run(&menu); } -static struct perf_error_ops default_eops = +int ui_browser__input_window(const char *title, const char *text, char *input, + const char *exit_msg, int delay_secs) { - .error = perf_stdio__error, - .warning = perf_stdio__warning, -}; + int x, y, len, key; + int max_len = 60, nr_lines = 0; + static char buf[50]; + const char *t; + + t = text; + while (1) { + const char *sep = strchr(t, '\n'); + + if (sep == NULL) + sep = strchr(t, '\0'); + len = sep - t; + if (max_len < len) + max_len = len; + ++nr_lines; + if (*sep == '\0') + break; + t = sep + 1; + } + + max_len += 2; + nr_lines += 8; + y = SLtt_Screen_Rows / 2 - nr_lines / 2; + x = SLtt_Screen_Cols / 2 - max_len / 2; + + SLsmg_set_color(0); + SLsmg_draw_box(y, x++, nr_lines, max_len); + if (title) { + SLsmg_gotorc(y, x + 1); + SLsmg_write_string((char *)title); + } + SLsmg_gotorc(++y, x); + nr_lines -= 7; + max_len -= 2; + SLsmg_write_wrapped_string((unsigned char *)text, y, x, + nr_lines, max_len, 1); + y += nr_lines; + len = 5; + while (len--) { + SLsmg_gotorc(y + len - 1, x); + SLsmg_write_nstring((char *)" ", max_len); + } + SLsmg_draw_box(y++, x + 1, 3, max_len - 2); + + SLsmg_gotorc(y + 3, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + SLsmg_refresh(); + + x += 2; + len = 0; + key = ui__getch(delay_secs); + while (key != K_TIMER && key != K_ENTER && key != K_ESC) { + if (key == K_BKSPC) { + if (len == 0) + goto next_key; + SLsmg_gotorc(y, x + --len); + SLsmg_write_char(' '); + } else { + buf[len] = key; + SLsmg_gotorc(y, x + len++); + SLsmg_write_char(key); + } + SLsmg_refresh(); + + /* XXX more graceful overflow handling needed */ + if (len == sizeof(buf) - 1) { + ui_helpline__push("maximum size of symbol name reached!"); + key = K_ENTER; + break; + } +next_key: + key = ui__getch(delay_secs); + } + + buf[len] = '\0'; + strncpy(input, buf, len+1); + return key; +} -static struct perf_error_ops *perf_eops = &default_eops; +int ui__question_window(const char *title, const char *text, + const char *exit_msg, int delay_secs) +{ + int x, y; + int max_len = 0, nr_lines = 0; + const char *t; + + t = text; + while (1) { + const char *sep = strchr(t, '\n'); + int len; + + if (sep == NULL) + sep = strchr(t, '\0'); + len = sep - t; + if (max_len < len) + max_len = len; + ++nr_lines; + if (*sep == '\0') + break; + t = sep + 1; + } + + max_len += 2; + nr_lines += 4; + y = SLtt_Screen_Rows / 2 - nr_lines / 2, + x = SLtt_Screen_Cols / 2 - max_len / 2; + + SLsmg_set_color(0); + SLsmg_draw_box(y, x++, nr_lines, max_len); + if (title) { + SLsmg_gotorc(y, x + 1); + SLsmg_write_string((char *)title); + } + SLsmg_gotorc(++y, x); + nr_lines -= 2; + max_len -= 2; + SLsmg_write_wrapped_string((unsigned char *)text, y, x, + nr_lines, max_len, 1); + SLsmg_gotorc(y + nr_lines - 2, x); + SLsmg_write_nstring((char *)" ", max_len); + SLsmg_gotorc(y + nr_lines - 1, x); + SLsmg_write_nstring((char *)exit_msg, max_len); + SLsmg_refresh(); + return ui__getch(delay_secs); +} +int ui__help_window(const char *text) +{ + return ui__question_window("Help", text, "Press any key...", 0); +} -int ui__error(const char *format, ...) +int ui__dialog_yesno(const char *msg) { - int ret; - va_list args; + return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); +} - va_start(args, format); - ret = perf_eops->error(format, args); - va_end(args); +int __ui__warning(const char *title, const char *format, va_list args) +{ + char *s; + + if (use_browser > 0 && vasprintf(&s, format, args) > 0) { + int key; + + pthread_mutex_lock(&ui__lock); + key = ui__question_window(title, s, "Press any key...", 0); + pthread_mutex_unlock(&ui__lock); + free(s); + return key; + } - return ret; + fprintf(stderr, "%s:\n", title); + vfprintf(stderr, format, args); + return K_ESC; } int ui__warning(const char *format, ...) { - int ret; + int key; va_list args; va_start(args, format); - ret = perf_eops->warning(format, args); + key = __ui__warning("Warning", format, args); va_end(args); - - return ret; -} - - -/** - * perf_error__register - Register error logging functions - * @eops: The pointer to error logging function struct - * - * Register UI-specific error logging functions. Before calling this, - * other logging functions should be unregistered, if any. - */ -int perf_error__register(struct perf_error_ops *eops) -{ - if (perf_eops != &default_eops) - return -1; - - perf_eops = eops; - return 0; + return key; } -/** - * perf_error__unregister - Unregister error logging functions - * @eops: The pointer to error logging function struct - * - * Unregister already registered error logging functions. - */ -int perf_error__unregister(struct perf_error_ops *eops) +int ui__error(const char *format, ...) { - if (perf_eops != eops) - return -1; + int key; + va_list args; - perf_eops = &default_eops; - return 0; + va_start(args, format); + key = __ui__warning("Error", format, args); + va_end(args); + return key; } diff --git a/trunk/tools/perf/ui/util.h b/trunk/tools/perf/ui/util.h index 361f08c52d37..2d1738bd71c8 100644 --- a/trunk/tools/perf/ui/util.h +++ b/trunk/tools/perf/ui/util.h @@ -9,13 +9,6 @@ int ui__help_window(const char *text); int ui__dialog_yesno(const char *msg); int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs); - -struct perf_error_ops { - int (*error)(const char *format, va_list args); - int (*warning)(const char *format, va_list args); -}; - -int perf_error__register(struct perf_error_ops *eops); -int perf_error__unregister(struct perf_error_ops *eops); +int __ui__warning(const char *title, const char *format, va_list args); #endif /* _PERF_UI_UTIL_H_ */ diff --git a/trunk/tools/perf/util/debug.c b/trunk/tools/perf/util/debug.c index 4dfe0bb3c322..efb1fce259a4 100644 --- a/trunk/tools/perf/util/debug.c +++ b/trunk/tools/perf/util/debug.c @@ -47,7 +47,7 @@ int dump_printf(const char *fmt, ...) return ret; } -#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) +#ifdef NO_NEWT_SUPPORT int ui__warning(const char *format, ...) { va_list args; diff --git a/trunk/tools/perf/util/debug.h b/trunk/tools/perf/util/debug.h index 015c91dbc096..6bebe7f0a20c 100644 --- a/trunk/tools/perf/util/debug.h +++ b/trunk/tools/perf/util/debug.h @@ -12,9 +12,8 @@ int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void trace_event(union perf_event *event); struct ui_progress; -struct perf_error_ops; -#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) +#ifdef NO_NEWT_SUPPORT static inline int ui_helpline__show_help(const char *format __used, va_list ap __used) { return 0; @@ -24,28 +23,12 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used, const char *title __used) {} #define ui__error(format, arg...) ui__warning(format, ##arg) - -static inline int -perf_error__register(struct perf_error_ops *eops __used) -{ - return 0; -} - -static inline int -perf_error__unregister(struct perf_error_ops *eops __used) -{ - return 0; -} - -#else /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ - +#else extern char ui_helpline__last_msg[]; int ui_helpline__show_help(const char *format, va_list ap); #include "../ui/progress.h" int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); -#include "../ui/util.h" - -#endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ +#endif int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); int ui__error_paranoid(void); diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index f74e9560350e..7400fb3fc50c 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -224,8 +224,8 @@ int perf_evlist__add_tracepoints(struct perf_evlist *evlist, return err; } -struct perf_evsel * -perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) +static struct perf_evsel * + perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) { struct perf_evsel *evsel; diff --git a/trunk/tools/perf/util/evlist.h b/trunk/tools/perf/util/evlist.h index 40d4d3cdced0..989bee9624c2 100644 --- a/trunk/tools/perf/util/evlist.h +++ b/trunk/tools/perf/util/evlist.h @@ -73,9 +73,6 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, #define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) -struct perf_evsel * -perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id); - void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, int cpu, int thread, u64 id); diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index 3d1f6968f175..9f6cebd798ee 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -15,6 +15,7 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" +#include "../../include/linux/perf_event.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) @@ -77,7 +78,7 @@ static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { "ref-cycles", }; -static const char *__perf_evsel__hw_name(u64 config) +const char *__perf_evsel__hw_name(u64 config) { if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) return perf_evsel__hw_names[config]; @@ -85,15 +86,16 @@ static const char *__perf_evsel__hw_name(u64 config) return "unknown-hardware"; } -static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t size) +static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) { - int colon = 0, r = 0; + int colon = 0; struct perf_event_attr *attr = &evsel->attr; + int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config)); bool exclude_guest_default = false; #define MOD_PRINT(context, mod) do { \ if (!attr->exclude_##context) { \ - if (!colon) colon = ++r; \ + if (!colon) colon = r++; \ r += scnprintf(bf + r, size - r, "%c", mod); \ } } while(0) @@ -106,7 +108,7 @@ static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t if (attr->precise_ip) { if (!colon) - colon = ++r; + colon = r++; r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); exclude_guest_default = true; } @@ -117,182 +119,39 @@ static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t } #undef MOD_PRINT if (colon) - bf[colon - 1] = ':'; + bf[colon] = ':'; return r; } -static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) -{ - int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config)); - return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); -} - -static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { - "cpu-clock", - "task-clock", - "page-faults", - "context-switches", - "CPU-migrations", - "minor-faults", - "major-faults", - "alignment-faults", - "emulation-faults", -}; - -static const char *__perf_evsel__sw_name(u64 config) -{ - if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config]) - return perf_evsel__sw_names[config]; - return "unknown-software"; -} - -static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size) -{ - int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config)); - return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); -} - -const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] - [PERF_EVSEL__MAX_ALIASES] = { - { "L1-dcache", "l1-d", "l1d", "L1-data", }, - { "L1-icache", "l1-i", "l1i", "L1-instruction", }, - { "LLC", "L2", }, - { "dTLB", "d-tlb", "Data-TLB", }, - { "iTLB", "i-tlb", "Instruction-TLB", }, - { "branch", "branches", "bpu", "btb", "bpc", }, - { "node", }, -}; - -const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_EVSEL__MAX_ALIASES] = { - { "load", "loads", "read", }, - { "store", "stores", "write", }, - { "prefetch", "prefetches", "speculative-read", "speculative-load", }, -}; - -const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] - [PERF_EVSEL__MAX_ALIASES] = { - { "refs", "Reference", "ops", "access", }, - { "misses", "miss", }, -}; - -#define C(x) PERF_COUNT_HW_CACHE_##x -#define CACHE_READ (1 << C(OP_READ)) -#define CACHE_WRITE (1 << C(OP_WRITE)) -#define CACHE_PREFETCH (1 << C(OP_PREFETCH)) -#define COP(x) (1 << x) - -/* - * cache operartion stat - * L1I : Read and prefetch only - * ITLB and BPU : Read-only - */ -static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = { - [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), - [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), - [C(ITLB)] = (CACHE_READ), - [C(BPU)] = (CACHE_READ), - [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), -}; - -bool perf_evsel__is_cache_op_valid(u8 type, u8 op) -{ - if (perf_evsel__hw_cache_stat[type] & COP(op)) - return true; /* valid */ - else - return false; /* invalid */ -} - -int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, - char *bf, size_t size) -{ - if (result) { - return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0], - perf_evsel__hw_cache_op[op][0], - perf_evsel__hw_cache_result[result][0]); - } - - return scnprintf(bf, size, "%s-%s", perf_evsel__hw_cache[type][0], - perf_evsel__hw_cache_op[op][1]); -} - -static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) +int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) { - u8 op, result, type = (config >> 0) & 0xff; - const char *err = "unknown-ext-hardware-cache-type"; - - if (type > PERF_COUNT_HW_CACHE_MAX) - goto out_err; - - op = (config >> 8) & 0xff; - err = "unknown-ext-hardware-cache-op"; - if (op > PERF_COUNT_HW_CACHE_OP_MAX) - goto out_err; - - result = (config >> 16) & 0xff; - err = "unknown-ext-hardware-cache-result"; - if (result > PERF_COUNT_HW_CACHE_RESULT_MAX) - goto out_err; - - err = "invalid-cache"; - if (!perf_evsel__is_cache_op_valid(type, op)) - goto out_err; - - return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size); -out_err: - return scnprintf(bf, size, "%s", err); -} - -static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size) -{ - int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); - return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); -} - -static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size) -{ - int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); - return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); -} - -const char *perf_evsel__name(struct perf_evsel *evsel) -{ - char bf[128]; - - if (evsel->name) - return evsel->name; + int ret; switch (evsel->attr.type) { case PERF_TYPE_RAW: - perf_evsel__raw_name(evsel, bf, sizeof(bf)); + ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); break; case PERF_TYPE_HARDWARE: - perf_evsel__hw_name(evsel, bf, sizeof(bf)); - break; - - case PERF_TYPE_HW_CACHE: - perf_evsel__hw_cache_name(evsel, bf, sizeof(bf)); - break; - - case PERF_TYPE_SOFTWARE: - perf_evsel__sw_name(evsel, bf, sizeof(bf)); + ret = perf_evsel__hw_name(evsel, bf, size); break; - - case PERF_TYPE_TRACEPOINT: - scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint"); - break; - default: - scnprintf(bf, sizeof(bf), "%s", "unknown attr type"); - break; - } - - evsel->name = strdup(bf); - - return evsel->name ?: "unknown"; + /* + * FIXME + * + * This is the minimal perf_evsel__name so that we can + * reconstruct event names taking into account event modifiers. + * + * The old event_name uses it now for raw anr hw events, so that + * we don't drag all the parsing stuff into the python binding. + * + * On the next devel cycle the rest of the event naming will be + * brought here. + */ + return 0; + } + + return ret; } void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, diff --git a/trunk/tools/perf/util/evsel.h b/trunk/tools/perf/util/evsel.h index 67cc5033d192..4ba8b564e6f4 100644 --- a/trunk/tools/perf/util/evsel.h +++ b/trunk/tools/perf/util/evsel.h @@ -83,19 +83,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, struct perf_evsel *first); -bool perf_evsel__is_cache_op_valid(u8 type, u8 op); - -#define PERF_EVSEL__MAX_ALIASES 8 - -extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] - [PERF_EVSEL__MAX_ALIASES]; -extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_EVSEL__MAX_ALIASES]; -const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] - [PERF_EVSEL__MAX_ALIASES]; -int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, - char *bf, size_t size); -const char *perf_evsel__name(struct perf_evsel *evsel); +const char* __perf_evsel__hw_name(u64 config); +int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 5a47aba46759..e909d43cf542 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -641,7 +641,7 @@ static int write_event_desc(int fd, struct perf_header *h __used, /* * write event string as passed on cmdline */ - ret = do_write_string(fd, perf_evsel__name(attr)); + ret = do_write_string(fd, event_name(attr)); if (ret < 0) return ret; /* @@ -1474,15 +1474,15 @@ static int perf_header__read_build_ids(struct perf_header *header, static int process_tracing_data(struct perf_file_section *section __unused, struct perf_header *ph __unused, - int feat __unused, int fd, void *data) + int feat __unused, int fd) { - trace_report(fd, data, false); + trace_report(fd, false); return 0; } static int process_build_id(struct perf_file_section *section, struct perf_header *ph, - int feat __unused, int fd, void *data __used) + int feat __unused, int fd) { if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) pr_debug("Failed to read buildids, continuing...\n"); @@ -1493,7 +1493,7 @@ struct feature_ops { int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); void (*print)(struct perf_header *h, int fd, FILE *fp); int (*process)(struct perf_file_section *section, - struct perf_header *h, int feat, int fd, void *data); + struct perf_header *h, int feat, int fd); const char *name; bool full_only; }; @@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header, static int perf_file_section__process(struct perf_file_section *section, struct perf_header *ph, - int feat, int fd, void *data) + int feat, int fd, void *data __used) { if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " @@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section, if (!feat_ops[feat].process) return 0; - return feat_ops[feat].process(section, ph, feat, fd, data); + return feat_ops[feat].process(section, ph, feat, fd); } static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, @@ -2093,11 +2093,9 @@ static int read_attr(int fd, struct perf_header *ph, return ret <= 0 ? -1 : 0; } -static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, - struct pevent *pevent) +static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) { - struct event_format *event = pevent_find_event(pevent, - evsel->attr.config); + struct event_format *event = trace_find_event(evsel->attr.config); char bf[128]; if (event == NULL) @@ -2111,14 +2109,13 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, return 0; } -static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, - struct pevent *pevent) +static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) { struct perf_evsel *pos; list_for_each_entry(pos, &evlist->entries, node) { if (pos->attr.type == PERF_TYPE_TRACEPOINT && - perf_evsel__set_tracepoint_name(pos, pevent)) + perf_evsel__set_tracepoint_name(pos)) return -1; } @@ -2201,12 +2198,12 @@ int perf_session__read_header(struct perf_session *session, int fd) event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); } - perf_header__process_sections(header, fd, &session->pevent, + perf_header__process_sections(header, fd, NULL, perf_file_section__process); lseek(fd, header->data_offset, SEEK_SET); - if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) + if (perf_evlist__set_tracepoint_names(session->evlist)) goto out_delete_evlist; header->frozen = 1; @@ -2422,8 +2419,8 @@ int perf_event__process_tracing_data(union perf_event *event, lseek(session->fd, offset + sizeof(struct tracing_data_event), SEEK_SET); - size_read = trace_report(session->fd, &session->pevent, - session->repipe); + size_read = trace_report(session->fd, session->repipe); + padding = ALIGN(size_read, sizeof(u64)) - size_read; if (read(session->fd, buf, padding) < 0) diff --git a/trunk/tools/perf/util/hist.h b/trunk/tools/perf/util/hist.h index 0b096c27a419..34bb556d6219 100644 --- a/trunk/tools/perf/util/hist.h +++ b/trunk/tools/perf/util/hist.h @@ -47,7 +47,6 @@ enum hist_column { HISTC_SYMBOL_TO, HISTC_DSO_FROM, HISTC_DSO_TO, - HISTC_SRCLINE, HISTC_NR_COLS, /* Last entry */ }; diff --git a/trunk/tools/perf/util/map.h b/trunk/tools/perf/util/map.h index c14c665d9a25..81371bad4ef0 100644 --- a/trunk/tools/perf/util/map.h +++ b/trunk/tools/perf/util/map.h @@ -157,7 +157,7 @@ void machine__exit(struct machine *self); void machine__delete(struct machine *self); int machine__resolve_callchain(struct machine *machine, - struct thread *thread, + struct perf_evsel *evsel, struct thread *thread, struct ip_callchain *chain, struct symbol **parent); int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, diff --git a/trunk/tools/perf/util/parse-events-test.c b/trunk/tools/perf/util/parse-events-test.c index a0f61a2a6835..76b98e2a587d 100644 --- a/trunk/tools/perf/util/parse-events-test.c +++ b/trunk/tools/perf/util/parse-events-test.c @@ -413,63 +413,19 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) { struct perf_evsel *evsel; - /* cpu/config=1,name=krava/u */ + /* cpu/config=1,name=krava1/u */ evsel = list_entry(evlist->entries.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); + TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "krava")); - /* cpu/config=2/u" */ + /* cpu/config=2/" */ evsel = list_entry(evsel->node.next, struct perf_evsel, node); TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "raw 0x2:u")); - - return 0; -} - -static int test__checkterms_simple(struct list_head *terms) -{ - struct parse_events__term *term; - - /* config=10 */ - term = list_entry(terms->next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 10); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* config1 */ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 1); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* config2=3 */ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 3); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* umask=1*/ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_USER); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 1); - TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); + TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "raw 0x2")); return 0; } @@ -603,23 +559,7 @@ static struct test__event_st test__events_pmu[] = { #define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ sizeof(struct test__event_st)) -struct test__term { - const char *str; - __u32 type; - int (*check)(struct list_head *terms); -}; - -static struct test__term test__terms[] = { - [0] = { - .str = "config=10,config1,config2=3,umask=1", - .check = test__checkterms_simple, - }, -}; - -#define TEST__TERMS_CNT (sizeof(test__terms) / \ - sizeof(struct test__term)) - -static int test_event(struct test__event_st *e) +static int test(struct test__event_st *e) { struct perf_evlist *evlist; int ret; @@ -650,48 +590,7 @@ static int test_events(struct test__event_st *events, unsigned cnt) struct test__event_st *e = &events[i]; pr_debug("running test %d '%s'\n", i, e->name); - ret = test_event(e); - if (ret) - break; - } - - return ret; -} - -static int test_term(struct test__term *t) -{ - struct list_head *terms; - int ret; - - terms = malloc(sizeof(*terms)); - if (!terms) - return -ENOMEM; - - INIT_LIST_HEAD(terms); - - ret = parse_events_terms(terms, t->str); - if (ret) { - pr_debug("failed to parse terms '%s', err %d\n", - t->str , ret); - return ret; - } - - ret = t->check(terms); - parse_events__free_terms(terms); - - return ret; -} - -static int test_terms(struct test__term *terms, unsigned cnt) -{ - int ret = 0; - unsigned i; - - for (i = 0; i < cnt; i++) { - struct test__term *t = &terms[i]; - - pr_debug("running test %d '%s'\n", i, t->str); - ret = test_term(t); + ret = test(e); if (ret) break; } @@ -718,21 +617,9 @@ int parse_events__test(void) { int ret; - do { - ret = test_events(test__events, TEST__EVENTS_CNT); - if (ret) - break; - - if (test_pmu()) { - ret = test_events(test__events_pmu, - TEST__EVENTS_PMU_CNT); - if (ret) - break; - } - - ret = test_terms(test__terms, TEST__TERMS_CNT); - - } while (0); + ret = test_events(test__events, TEST__EVENTS_CNT); + if (!ret && test_pmu()) + ret = test_events(test__events_pmu, TEST__EVENTS_PMU_CNT); return ret; } diff --git a/trunk/tools/perf/util/parse-events.c b/trunk/tools/perf/util/parse-events.c index 0cc27da30ddb..05dbc8b3c767 100644 --- a/trunk/tools/perf/util/parse-events.c +++ b/trunk/tools/perf/util/parse-events.c @@ -11,8 +11,6 @@ #include "cache.h" #include "header.h" #include "debugfs.h" -#include "parse-events-bison.h" -#define YY_EXTRA_TYPE int #include "parse-events-flex.h" #include "pmu.h" @@ -28,7 +26,7 @@ struct event_symbol { #ifdef PARSER_DEBUG extern int parse_events_debug; #endif -int parse_events_parse(void *data, void *scanner); +int parse_events_parse(struct list_head *list, int *idx); #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x @@ -64,6 +62,63 @@ static struct event_symbol event_symbols[] = { #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) +static const char *sw_event_names[PERF_COUNT_SW_MAX] = { + "cpu-clock", + "task-clock", + "page-faults", + "context-switches", + "CPU-migrations", + "minor-faults", + "major-faults", + "alignment-faults", + "emulation-faults", +}; + +#define MAX_ALIASES 8 + +static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = { + { "L1-dcache", "l1-d", "l1d", "L1-data", }, + { "L1-icache", "l1-i", "l1i", "L1-instruction", }, + { "LLC", "L2", }, + { "dTLB", "d-tlb", "Data-TLB", }, + { "iTLB", "i-tlb", "Instruction-TLB", }, + { "branch", "branches", "bpu", "btb", "bpc", }, + { "node", }, +}; + +static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = { + { "load", "loads", "read", }, + { "store", "stores", "write", }, + { "prefetch", "prefetches", "speculative-read", "speculative-load", }, +}; + +static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] + [MAX_ALIASES] = { + { "refs", "Reference", "ops", "access", }, + { "misses", "miss", }, +}; + +#define C(x) PERF_COUNT_HW_CACHE_##x +#define CACHE_READ (1 << C(OP_READ)) +#define CACHE_WRITE (1 << C(OP_WRITE)) +#define CACHE_PREFETCH (1 << C(OP_PREFETCH)) +#define COP(x) (1 << x) + +/* + * cache operartion stat + * L1I : Read and prefetch only + * ITLB and BPU : Read-only + */ +static unsigned long hw_cache_stat[C(MAX)] = { + [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), + [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), + [C(ITLB)] = (CACHE_READ), + [C(BPU)] = (CACHE_READ), + [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), +}; + #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ if (sys_dirent.d_type == DT_DIR && \ @@ -163,6 +218,48 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) return NULL; } +#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) +static const char *tracepoint_id_to_name(u64 config) +{ + static char buf[TP_PATH_LEN]; + struct tracepoint_path *path; + + path = tracepoint_id_to_path(config); + if (path) { + snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); + free(path->name); + free(path->system); + free(path); + } else + snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); + + return buf; +} + +static int is_cache_op_valid(u8 cache_type, u8 cache_op) +{ + if (hw_cache_stat[cache_type] & COP(cache_op)) + return 1; /* valid */ + else + return 0; /* invalid */ +} + +static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) +{ + static char name[50]; + + if (cache_result) { + sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], + hw_cache_op[cache_op][0], + hw_cache_result[cache_result][0]); + } else { + sprintf(name, "%s-%s", hw_cache[cache_type][0], + hw_cache_op[cache_op][1]); + } + + return name; +} + const char *event_type(int type) { switch (type) { @@ -185,6 +282,76 @@ const char *event_type(int type) return "unknown"; } +const char *event_name(struct perf_evsel *evsel) +{ + u64 config = evsel->attr.config; + int type = evsel->attr.type; + + if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { + /* + * XXX minimal fix, see comment on perf_evsen__name, this static buffer + * will go away together with event_name in the next devel cycle. + */ + static char bf[128]; + perf_evsel__name(evsel, bf, sizeof(bf)); + return bf; + } + + if (evsel->name) + return evsel->name; + + return __event_name(type, config); +} + +const char *__event_name(int type, u64 config) +{ + static char buf[32]; + + if (type == PERF_TYPE_RAW) { + sprintf(buf, "raw 0x%" PRIx64, config); + return buf; + } + + switch (type) { + case PERF_TYPE_HARDWARE: + return __perf_evsel__hw_name(config); + + case PERF_TYPE_HW_CACHE: { + u8 cache_type, cache_op, cache_result; + + cache_type = (config >> 0) & 0xff; + if (cache_type > PERF_COUNT_HW_CACHE_MAX) + return "unknown-ext-hardware-cache-type"; + + cache_op = (config >> 8) & 0xff; + if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) + return "unknown-ext-hardware-cache-op"; + + cache_result = (config >> 16) & 0xff; + if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) + return "unknown-ext-hardware-cache-result"; + + if (!is_cache_op_valid(cache_type, cache_op)) + return "invalid-cache"; + + return event_cache_name(cache_type, cache_op, cache_result); + } + + case PERF_TYPE_SOFTWARE: + if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) + return sw_event_names[config]; + return "unknown-software"; + + case PERF_TYPE_TRACEPOINT: + return tracepoint_id_to_name(config); + + default: + break; + } + + return "unknown"; +} + static int add_event(struct list_head **_list, int *idx, struct perf_event_attr *attr, char *name) { @@ -206,20 +373,19 @@ static int add_event(struct list_head **_list, int *idx, return -ENOMEM; } - if (name) - evsel->name = strdup(name); + evsel->name = strdup(name); list_add_tail(&evsel->node, list); *_list = list; return 0; } -static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) +static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) { int i, j; int n, longest = -1; for (i = 0; i < size; i++) { - for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { + for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { n = strlen(names[i][j]); if (n > longest && !strncasecmp(str, names[i][j], n)) longest = n; @@ -244,7 +410,7 @@ int parse_events_add_cache(struct list_head **list, int *idx, * No fallback - if we cannot get a clear cache type * then bail out: */ - cache_type = parse_aliases(type, perf_evsel__hw_cache, + cache_type = parse_aliases(type, hw_cache, PERF_COUNT_HW_CACHE_MAX); if (cache_type == -1) return -EINVAL; @@ -257,18 +423,18 @@ int parse_events_add_cache(struct list_head **list, int *idx, snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); if (cache_op == -1) { - cache_op = parse_aliases(str, perf_evsel__hw_cache_op, + cache_op = parse_aliases(str, hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX); if (cache_op >= 0) { - if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) + if (!is_cache_op_valid(cache_type, cache_op)) return -EINVAL; continue; } } if (cache_result == -1) { - cache_result = parse_aliases(str, perf_evsel__hw_cache_result, - PERF_COUNT_HW_CACHE_RESULT_MAX); + cache_result = parse_aliases(str, hw_cache_result, + PERF_COUNT_HW_CACHE_RESULT_MAX); if (cache_result >= 0) continue; } @@ -500,7 +666,8 @@ int parse_events_add_numeric(struct list_head **list, int *idx, config_attr(&attr, head_config, 1)) return -EINVAL; - return add_event(list, idx, &attr, NULL); + return add_event(list, idx, &attr, + (char *) __event_name(type, config)); } static int parse_events__is_name_term(struct parse_events__term *term) @@ -508,7 +675,8 @@ static int parse_events__is_name_term(struct parse_events__term *term) return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; } -static char *pmu_event_name(struct list_head *head_terms) +static char *pmu_event_name(struct perf_event_attr *attr, + struct list_head *head_terms) { struct parse_events__term *term; @@ -516,7 +684,7 @@ static char *pmu_event_name(struct list_head *head_terms) if (parse_events__is_name_term(term)) return term->val.str; - return NULL; + return (char *) __event_name(PERF_TYPE_RAW, attr->config); } int parse_events_add_pmu(struct list_head **list, int *idx, @@ -531,9 +699,6 @@ int parse_events_add_pmu(struct list_head **list, int *idx, memset(&attr, 0, sizeof(attr)); - if (perf_pmu__check_alias(pmu, head_config)) - return -EINVAL; - /* * Configure hardcoded terms first, no need to check * return value when called with fail == 0 ;) @@ -544,7 +709,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, return -EINVAL; return add_event(list, idx, &attr, - pmu_event_name(head_config)); + pmu_event_name(&attr, head_config)); } void parse_events_update_lists(struct list_head *list_event, @@ -622,62 +787,27 @@ int parse_events_modifier(struct list_head *list, char *str) return 0; } -static int parse_events__scanner(const char *str, void *data, int start_token) +int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) { + LIST_HEAD(list); + LIST_HEAD(list_tmp); YY_BUFFER_STATE buffer; - void *scanner; - int ret; + int ret, idx = evlist->nr_entries; - ret = parse_events_lex_init_extra(start_token, &scanner); - if (ret) - return ret; - - buffer = parse_events__scan_string(str, scanner); + buffer = parse_events__scan_string(str); #ifdef PARSER_DEBUG parse_events_debug = 1; #endif - ret = parse_events_parse(data, scanner); + ret = parse_events_parse(&list, &idx); - parse_events__flush_buffer(buffer, scanner); - parse_events__delete_buffer(buffer, scanner); - parse_events_lex_destroy(scanner); - return ret; -} - -/* - * parse event config string, return a list of event terms. - */ -int parse_events_terms(struct list_head *terms, const char *str) -{ - struct parse_events_data__terms data = { - .terms = NULL, - }; - int ret; - - ret = parse_events__scanner(str, &data, PE_START_TERMS); - if (!ret) { - list_splice(data.terms, terms); - free(data.terms); - return 0; - } - - parse_events__free_terms(data.terms); - return ret; -} - -int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) -{ - struct parse_events_data__events data = { - .list = LIST_HEAD_INIT(data.list), - .idx = evlist->nr_entries, - }; - int ret; + parse_events__flush_buffer(buffer); + parse_events__delete_buffer(buffer); + parse_events_lex_destroy(); - ret = parse_events__scanner(str, &data, PE_START_EVENTS); if (!ret) { - int entries = data.idx - evlist->nr_entries; - perf_evlist__splice_list_tail(evlist, &data.list, entries); + int entries = idx - evlist->nr_entries; + perf_evlist__splice_list_tail(evlist, &list, entries); return 0; } @@ -840,17 +970,16 @@ void print_events_type(u8 type) int print_hwcache_events(const char *event_glob) { unsigned int type, op, i, printed = 0; - char name[64]; for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { /* skip invalid cache type */ - if (!perf_evsel__is_cache_op_valid(type, op)) + if (!is_cache_op_valid(type, op)) continue; for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __perf_evsel__hw_cache_type_op_res_name(type, op, i, - name, sizeof(name)); + char *name = event_cache_name(type, op, i); + if (event_glob != NULL && !strglobmatch(name, event_glob)) continue; @@ -977,13 +1106,6 @@ int parse_events__term_str(struct parse_events__term **term, config, str, 0); } -int parse_events__term_clone(struct parse_events__term **new, - struct parse_events__term *term) -{ - return new_term(new, term->type_val, term->type_term, term->config, - term->val.str, term->val.num); -} - void parse_events__free_terms(struct list_head *terms) { struct parse_events__term *term, *h; diff --git a/trunk/tools/perf/util/parse-events.h b/trunk/tools/perf/util/parse-events.h index ee9c218a193c..8cac57ab4ee6 100644 --- a/trunk/tools/perf/util/parse-events.h +++ b/trunk/tools/perf/util/parse-events.h @@ -26,12 +26,13 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config); extern bool have_tracepoints(struct list_head *evlist); const char *event_type(int type); +const char *event_name(struct perf_evsel *event); +extern const char *__event_name(int type, u64 config); extern int parse_events_option(const struct option *opt, const char *str, int unset); extern int parse_events(struct perf_evlist *evlist, const char *str, int unset); -extern int parse_events_terms(struct list_head *terms, const char *str); extern int parse_filter(const struct option *opt, const char *str, int unset); #define EVENTS_HELP_MAX (128*1024) @@ -62,22 +63,11 @@ struct parse_events__term { struct list_head list; }; -struct parse_events_data__events { - struct list_head list; - int idx; -}; - -struct parse_events_data__terms { - struct list_head *terms; -}; - int parse_events__is_hardcoded_term(struct parse_events__term *term); int parse_events__term_num(struct parse_events__term **_term, int type_term, char *config, long num); int parse_events__term_str(struct parse_events__term **_term, int type_term, char *config, char *str); -int parse_events__term_clone(struct parse_events__term **new, - struct parse_events__term *term); void parse_events__free_terms(struct list_head *terms); int parse_events_modifier(struct list_head *list, char *str); int parse_events_add_tracepoint(struct list_head **list, int *idx, @@ -93,7 +83,8 @@ int parse_events_add_pmu(struct list_head **list, int *idx, char *pmu , struct list_head *head_config); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); -void parse_events_error(void *data, void *scanner, char const *msg); +void parse_events_error(struct list_head *list_all, + int *idx, char const *msg); int parse_events__test(void); void print_events(const char *event_glob); diff --git a/trunk/tools/perf/util/parse-events.l b/trunk/tools/perf/util/parse-events.l index 488362e14133..618a8e788399 100644 --- a/trunk/tools/perf/util/parse-events.l +++ b/trunk/tools/perf/util/parse-events.l @@ -1,6 +1,4 @@ -%option reentrant -%option bison-bridge %option prefix="parse_events_" %option stack @@ -10,10 +8,7 @@ #include "parse-events-bison.h" #include "parse-events.h" -char *parse_events_get_text(yyscan_t yyscanner); -YYSTYPE *parse_events_get_lval(yyscan_t yyscanner); - -static int __value(YYSTYPE *yylval, char *str, int base, int token) +static int __value(char *str, int base, int token) { long num; @@ -22,48 +17,35 @@ static int __value(YYSTYPE *yylval, char *str, int base, int token) if (errno) return PE_ERROR; - yylval->num = num; + parse_events_lval.num = num; return token; } -static int value(yyscan_t scanner, int base) +static int value(int base) { - YYSTYPE *yylval = parse_events_get_lval(scanner); - char *text = parse_events_get_text(scanner); - - return __value(yylval, text, base, PE_VALUE); + return __value(parse_events_text, base, PE_VALUE); } -static int raw(yyscan_t scanner) +static int raw(void) { - YYSTYPE *yylval = parse_events_get_lval(scanner); - char *text = parse_events_get_text(scanner); - - return __value(yylval, text + 1, 16, PE_RAW); + return __value(parse_events_text + 1, 16, PE_RAW); } -static int str(yyscan_t scanner, int token) +static int str(int token) { - YYSTYPE *yylval = parse_events_get_lval(scanner); - char *text = parse_events_get_text(scanner); - - yylval->str = strdup(text); + parse_events_lval.str = strdup(parse_events_text); return token; } -static int sym(yyscan_t scanner, int type, int config) +static int sym(int type, int config) { - YYSTYPE *yylval = parse_events_get_lval(scanner); - - yylval->num = (type << 16) + config; + parse_events_lval.num = (type << 16) + config; return PE_VALUE_SYM; } -static int term(yyscan_t scanner, int type) +static int term(int type) { - YYSTYPE *yylval = parse_events_get_lval(scanner); - - yylval->num = type; + parse_events_lval.num = type; return PE_TERM; } @@ -79,38 +61,25 @@ modifier_event [ukhpGH]{1,8} modifier_bp [rwx] %% - -%{ - { - int start_token; - - start_token = (int) parse_events_get_extra(yyscanner); - if (start_token) { - parse_events_set_extra(NULL, yyscanner); - return start_token; - } - } -%} - -cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } -stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } -stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } -instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } -cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } -cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } -branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } -branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } -bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } -ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } -cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } -task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } -page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } -minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } -major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } -context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } -cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } -alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } -emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } +cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } +stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } +stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } +instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } +cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } +cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } +branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } +branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } +bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } +ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } +cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } +task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } +page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } +minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } +major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } +context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } +cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } +alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } +emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } L1-dcache|l1-d|l1d|L1-data | L1-icache|l1-i|l1i|L1-instruction | @@ -118,14 +87,14 @@ LLC|L2 | dTLB|d-tlb|Data-TLB | iTLB|i-tlb|Instruction-TLB | branch|branches|bpu|btb|bpc | -node { return str(yyscanner, PE_NAME_CACHE_TYPE); } +node { return str(PE_NAME_CACHE_TYPE); } load|loads|read | store|stores|write | prefetch|prefetches | speculative-read|speculative-load | refs|Reference|ops|access | -misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); } +misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } /* * These are event config hardcoded term names to be specified @@ -133,20 +102,20 @@ misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); } * so we can put them here directly. In case the we have a conflict * in future, this needs to go into '//' condition block. */ -config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); } -config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); } -config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); } -name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); } -period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } -branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } +config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } +config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } +config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } +name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } +period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } +branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } mem: { BEGIN(mem); return PE_PREFIX_MEM; } -r{num_raw_hex} { return raw(yyscanner); } -{num_dec} { return value(yyscanner, 10); } -{num_hex} { return value(yyscanner, 16); } +r{num_raw_hex} { return raw(); } +{num_dec} { return value(10); } +{num_hex} { return value(16); } -{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{name} { return str(yyscanner, PE_NAME); } +{modifier_event} { return str(PE_MODIFIER_EVENT); } +{name} { return str(PE_NAME); } "/" { return '/'; } - { return '-'; } , { return ','; } @@ -154,17 +123,17 @@ r{num_raw_hex} { return raw(yyscanner); } = { return '='; } { -{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } +{modifier_bp} { return str(PE_MODIFIER_BP); } : { return ':'; } -{num_dec} { return value(yyscanner, 10); } -{num_hex} { return value(yyscanner, 16); } +{num_dec} { return value(10); } +{num_hex} { return value(16); } /* * We need to separate 'mem:' scanner part, in order to get specific * modifier bits parsed out. Otherwise we would need to handle PE_NAME * and we'd need to parse it manually. During the escape from * state we need to put the escaping char back, so we dont miss it. */ -. { unput(*yytext); BEGIN(INITIAL); } +. { unput(*parse_events_text); BEGIN(INITIAL); } /* * We destroy the scanner after reaching EOF, * but anyway just to be sure get back to INIT state. @@ -174,7 +143,7 @@ r{num_raw_hex} { return raw(yyscanner); } %% -int parse_events_wrap(void *scanner __used) +int parse_events_wrap(void) { return 1; } diff --git a/trunk/tools/perf/util/parse-events.y b/trunk/tools/perf/util/parse-events.y index 9525c455d27f..362cc59332ae 100644 --- a/trunk/tools/perf/util/parse-events.y +++ b/trunk/tools/perf/util/parse-events.y @@ -1,8 +1,7 @@ -%pure-parser + %name-prefix "parse_events_" -%parse-param {void *_data} -%parse-param {void *scanner} -%lex-param {void* scanner} +%parse-param {struct list_head *list_all} +%parse-param {int *idx} %{ @@ -13,9 +12,8 @@ #include "types.h" #include "util.h" #include "parse-events.h" -#include "parse-events-bison.h" -extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); +extern int parse_events_lex (void); #define ABORT_ON(val) \ do { \ @@ -25,7 +23,6 @@ do { \ %} -%token PE_START_EVENTS PE_START_TERMS %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM %token PE_NAME %token PE_MODIFIER_EVENT PE_MODIFIER_BP @@ -61,33 +58,24 @@ do { \ } %% -start: -PE_START_EVENTS events -| -PE_START_TERMS terms - events: events ',' event | event event: event_def PE_MODIFIER_EVENT { - struct parse_events_data__events *data = _data; - /* * Apply modifier on all events added by single event definition * (there could be more events added for multiple tracepoint * definitions via '*?'. */ ABORT_ON(parse_events_modifier($1, $2)); - parse_events_update_lists($1, &data->list); + parse_events_update_lists($1, list_all); } | event_def { - struct parse_events_data__events *data = _data; - - parse_events_update_lists($1, &data->list); + parse_events_update_lists($1, list_all); } event_def: event_pmu | @@ -101,10 +89,9 @@ event_def: event_pmu | event_pmu: PE_NAME '/' event_config '/' { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3)); + ABORT_ON(parse_events_add_pmu(&list, idx, $1, $3)); parse_events__free_terms($3); $$ = list; } @@ -112,115 +99,94 @@ PE_NAME '/' event_config '/' event_legacy_symbol: PE_VALUE_SYM '/' event_config '/' { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, &data->idx, - type, config, $3)); + ABORT_ON(parse_events_add_numeric(&list, idx, type, config, $3)); parse_events__free_terms($3); $$ = list; } | PE_VALUE_SYM sep_slash_dc { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; int type = $1 >> 16; int config = $1 & 255; - ABORT_ON(parse_events_add_numeric(&list, &data->idx, - type, config, NULL)); + ABORT_ON(parse_events_add_numeric(&list, idx, type, config, NULL)); $$ = list; } event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5)); + ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, $5)); $$ = list; } | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL)); + ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, NULL)); $$ = list; } | PE_NAME_CACHE_TYPE { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL)); + ABORT_ON(parse_events_add_cache(&list, idx, $1, NULL, NULL)); $$ = list; } event_legacy_mem: PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, - (void *) $2, $4)); + ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE sep_dc { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, - (void *) $2, NULL)); + ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, NULL)); $$ = list; } event_legacy_tracepoint: PE_NAME ':' PE_NAME { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3)); + ABORT_ON(parse_events_add_tracepoint(&list, idx, $1, $3)); $$ = list; } event_legacy_numeric: PE_VALUE ':' PE_VALUE { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL)); + ABORT_ON(parse_events_add_numeric(&list, idx, $1, $3, NULL)); $$ = list; } event_legacy_raw: PE_RAW { - struct parse_events_data__events *data = _data; struct list_head *list = NULL; - ABORT_ON(parse_events_add_numeric(&list, &data->idx, - PERF_TYPE_RAW, $1, NULL)); + ABORT_ON(parse_events_add_numeric(&list, idx, PERF_TYPE_RAW, $1, NULL)); $$ = list; } -terms: event_config -{ - struct parse_events_data__terms *data = _data; - data->terms = $1; -} - event_config: event_config ',' event_term { @@ -301,7 +267,8 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(void *data __used, void *scanner __used, +void parse_events_error(struct list_head *list_all __used, + int *idx __used, char const *msg __used) { } diff --git a/trunk/tools/perf/util/pmu.c b/trunk/tools/perf/util/pmu.c index 74d0948ec368..a119a5371699 100644 --- a/trunk/tools/perf/util/pmu.c +++ b/trunk/tools/perf/util/pmu.c @@ -80,114 +80,6 @@ static int pmu_format(char *name, struct list_head *format) return 0; } -static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file) -{ - struct perf_pmu__alias *alias; - char buf[256]; - int ret; - - ret = fread(buf, 1, sizeof(buf), file); - if (ret == 0) - return -EINVAL; - buf[ret] = 0; - - alias = malloc(sizeof(*alias)); - if (!alias) - return -ENOMEM; - - INIT_LIST_HEAD(&alias->terms); - ret = parse_events_terms(&alias->terms, buf); - if (ret) { - free(alias); - return ret; - } - - alias->name = strdup(name); - list_add_tail(&alias->list, list); - return 0; -} - -/* - * Process all the sysfs attributes located under the directory - * specified in 'dir' parameter. - */ -static int pmu_aliases_parse(char *dir, struct list_head *head) -{ - struct dirent *evt_ent; - DIR *event_dir; - int ret = 0; - - event_dir = opendir(dir); - if (!event_dir) - return -EINVAL; - - while (!ret && (evt_ent = readdir(event_dir))) { - char path[PATH_MAX]; - char *name = evt_ent->d_name; - FILE *file; - - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; - - snprintf(path, PATH_MAX, "%s/%s", dir, name); - - ret = -EINVAL; - file = fopen(path, "r"); - if (!file) - break; - ret = perf_pmu__new_alias(head, name, file); - fclose(file); - } - - closedir(event_dir); - return ret; -} - -/* - * Reading the pmu event aliases definition, which should be located at: - * /sys/bus/event_source/devices//events as sysfs group attributes. - */ -static int pmu_aliases(char *name, struct list_head *head) -{ - struct stat st; - char path[PATH_MAX]; - const char *sysfs; - - sysfs = sysfs_find_mountpoint(); - if (!sysfs) - return -1; - - snprintf(path, PATH_MAX, - "%s/bus/event_source/devices/%s/events", sysfs, name); - - if (stat(path, &st) < 0) - return -1; - - if (pmu_aliases_parse(path, head)) - return -1; - - return 0; -} - -static int pmu_alias_terms(struct perf_pmu__alias *alias, - struct list_head *terms) -{ - struct parse_events__term *term, *clone; - LIST_HEAD(list); - int ret; - - list_for_each_entry(term, &alias->terms, list) { - ret = parse_events__term_clone(&clone, term); - if (ret) { - parse_events__free_terms(&list); - return ret; - } - list_add_tail(&clone->list, &list); - } - list_splice(&list, terms); - return 0; -} - /* * Reading/parsing the default pmu type value, which should be * located at: @@ -226,7 +118,6 @@ static struct perf_pmu *pmu_lookup(char *name) { struct perf_pmu *pmu; LIST_HEAD(format); - LIST_HEAD(aliases); __u32 type; /* @@ -244,12 +135,8 @@ static struct perf_pmu *pmu_lookup(char *name) if (!pmu) return NULL; - pmu_aliases(name, &aliases); - INIT_LIST_HEAD(&pmu->format); - INIT_LIST_HEAD(&pmu->aliases); list_splice(&format, &pmu->format); - list_splice(&aliases, &pmu->aliases); pmu->name = strdup(name); pmu->type = type; return pmu; @@ -392,59 +279,6 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, return pmu_config(&pmu->format, attr, head_terms); } -static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu, - struct parse_events__term *term) -{ - struct perf_pmu__alias *alias; - char *name; - - if (parse_events__is_hardcoded_term(term)) - return NULL; - - if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { - if (term->val.num != 1) - return NULL; - if (pmu_find_format(&pmu->format, term->config)) - return NULL; - name = term->config; - } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { - if (strcasecmp(term->config, "event")) - return NULL; - name = term->val.str; - } else { - return NULL; - } - - list_for_each_entry(alias, &pmu->aliases, list) { - if (!strcasecmp(alias->name, name)) - return alias; - } - return NULL; -} - -/* - * Find alias in the terms list and replace it with the terms - * defined for the alias - */ -int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms) -{ - struct parse_events__term *term, *h; - struct perf_pmu__alias *alias; - int ret; - - list_for_each_entry_safe(term, h, head_terms, list) { - alias = pmu_find_alias(pmu, term); - if (!alias) - continue; - ret = pmu_alias_terms(alias, &term->list); - if (ret) - return ret; - list_del(&term->list); - free(term); - } - return 0; -} - int perf_pmu__new_format(struct list_head *list, char *name, int config, unsigned long *bits) { diff --git a/trunk/tools/perf/util/pmu.h b/trunk/tools/perf/util/pmu.h index 535f2c5258ab..68c0db965e1f 100644 --- a/trunk/tools/perf/util/pmu.h +++ b/trunk/tools/perf/util/pmu.h @@ -19,26 +19,17 @@ struct perf_pmu__format { struct list_head list; }; -struct perf_pmu__alias { - char *name; - struct list_head terms; - struct list_head list; -}; - struct perf_pmu { char *name; __u32 type; struct list_head format; - struct list_head aliases; struct list_head list; }; struct perf_pmu *perf_pmu__find(char *name); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms); -int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms); -struct list_head *perf_pmu__alias(struct perf_pmu *pmu, - struct list_head *head_terms); + int perf_pmu_wrap(void); void perf_pmu_error(struct list_head *list, char *name, char const *msg); diff --git a/trunk/tools/perf/util/scripting-engines/trace-event-perl.c b/trunk/tools/perf/util/scripting-engines/trace-event-perl.c index b3620fe12763..4c1b3d72a1d2 100644 --- a/trunk/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/trunk/tools/perf/util/scripting-engines/trace-event-perl.c @@ -233,8 +233,7 @@ static void define_event_symbols(struct event_format *event, define_event_symbols(event, ev_name, args->next); } -static inline -struct event_format *find_cache_event(struct pevent *pevent, int type) +static inline struct event_format *find_cache_event(int type) { static char ev_name[256]; struct event_format *event; @@ -242,7 +241,7 @@ struct event_format *find_cache_event(struct pevent *pevent, int type) if (events[type]) return events[type]; - events[type] = event = pevent_find_event(pevent, type); + events[type] = event = trace_find_event(type); if (!event) return NULL; @@ -253,8 +252,7 @@ struct event_format *find_cache_event(struct pevent *pevent, int type) return event; } -static void perl_process_tracepoint(union perf_event *perf_event __unused, - struct pevent *pevent, +static void perl_process_tracepoint(union perf_event *pevent __unused, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __unused, @@ -277,13 +275,13 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused, if (evsel->attr.type != PERF_TYPE_TRACEPOINT) return; - type = trace_parse_common_type(pevent, data); + type = trace_parse_common_type(data); - event = find_cache_event(pevent, type); + event = find_cache_event(type); if (!event) die("ug! no event found for type %d", type); - pid = trace_parse_common_pid(pevent, data); + pid = trace_parse_common_pid(data); sprintf(handler, "%s::%s", event->system, event->name); @@ -316,8 +314,7 @@ static void perl_process_tracepoint(union perf_event *perf_event __unused, offset = field->offset; XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); } else { /* FIELD_IS_NUMERIC */ - val = read_size(pevent, data + field->offset, - field->size); + val = read_size(data + field->offset, field->size); if (field->flags & FIELD_IS_SIGNED) { XPUSHs(sv_2mortal(newSViv(val))); } else { @@ -371,15 +368,14 @@ static void perl_process_event_generic(union perf_event *pevent __unused, LEAVE; } -static void perl_process_event(union perf_event *event, - struct pevent *pevent, +static void perl_process_event(union perf_event *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, struct thread *thread) { - perl_process_tracepoint(event, pevent, sample, evsel, machine, thread); - perl_process_event_generic(event, sample, evsel, machine, thread); + perl_process_tracepoint(pevent, sample, evsel, machine, thread); + perl_process_event_generic(pevent, sample, evsel, machine, thread); } static void run_start_sub(void) @@ -452,7 +448,7 @@ static int perl_stop_script(void) return 0; } -static int perl_generate_script(struct pevent *pevent, const char *outfile) +static int perl_generate_script(const char *outfile) { struct event_format *event = NULL; struct format_field *f; @@ -499,7 +495,7 @@ static int perl_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); - while ((event = trace_find_next_event(pevent, event))) { + while ((event = trace_find_next_event(event))) { fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); fprintf(ofp, "\tmy ("); diff --git a/trunk/tools/perf/util/scripting-engines/trace-event-python.c b/trunk/tools/perf/util/scripting-engines/trace-event-python.c index a8ca2f8179a9..acb9795286c4 100644 --- a/trunk/tools/perf/util/scripting-engines/trace-event-python.c +++ b/trunk/tools/perf/util/scripting-engines/trace-event-python.c @@ -190,8 +190,7 @@ static void define_event_symbols(struct event_format *event, define_event_symbols(event, ev_name, args->next); } -static inline -struct event_format *find_cache_event(struct pevent *pevent, int type) +static inline struct event_format *find_cache_event(int type) { static char ev_name[256]; struct event_format *event; @@ -199,7 +198,7 @@ struct event_format *find_cache_event(struct pevent *pevent, int type) if (events[type]) return events[type]; - events[type] = event = pevent_find_event(pevent, type); + events[type] = event = trace_find_event(type); if (!event) return NULL; @@ -210,8 +209,7 @@ struct event_format *find_cache_event(struct pevent *pevent, int type) return event; } -static void python_process_event(union perf_event *perf_event __unused, - struct pevent *pevent, +static void python_process_event(union perf_event *pevent __unused, struct perf_sample *sample, struct perf_evsel *evsel __unused, struct machine *machine __unused, @@ -235,13 +233,13 @@ static void python_process_event(union perf_event *perf_event __unused, if (!t) Py_FatalError("couldn't create Python tuple"); - type = trace_parse_common_type(pevent, data); + type = trace_parse_common_type(data); - event = find_cache_event(pevent, type); + event = find_cache_event(type); if (!event) die("ug! no event found for type %d", type); - pid = trace_parse_common_pid(pevent, data); + pid = trace_parse_common_pid(data); sprintf(handler_name, "%s__%s", event->system, event->name); @@ -286,8 +284,7 @@ static void python_process_event(union perf_event *perf_event __unused, offset = field->offset; obj = PyString_FromString((char *)data + offset); } else { /* FIELD_IS_NUMERIC */ - val = read_size(pevent, data + field->offset, - field->size); + val = read_size(data + field->offset, field->size); if (field->flags & FIELD_IS_SIGNED) { if ((long long)val >= LONG_MIN && (long long)val <= LONG_MAX) @@ -441,7 +438,7 @@ static int python_stop_script(void) return err; } -static int python_generate_script(struct pevent *pevent, const char *outfile) +static int python_generate_script(const char *outfile) { struct event_format *event = NULL; struct format_field *f; @@ -490,7 +487,7 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, "def trace_end():\n"); fprintf(ofp, "\tprint \"in trace_end\"\n\n"); - while ((event = trace_find_next_event(pevent, event))) { + while ((event = trace_find_next_event(event))) { fprintf(ofp, "def %s__%s(", event->system, event->name); fprintf(ofp, "event_name, "); fprintf(ofp, "context, "); diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index f5baff1495e6..c3e399bcf18d 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -14,7 +14,6 @@ #include "sort.h" #include "util.h" #include "cpumap.h" -#include "event-parse.h" static int perf_session__open(struct perf_session *self, bool force) { @@ -290,6 +289,7 @@ struct branch_info *machine__resolve_bstack(struct machine *self, } int machine__resolve_callchain(struct machine *self, + struct perf_evsel *evsel __used, struct thread *thread, struct ip_callchain *chain, struct symbol **parent) @@ -1449,7 +1449,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) ret += hists__fprintf_nr_events(&session->hists, fp); list_for_each_entry(pos, &session->evlist->entries, node) { - ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); + ret += fprintf(fp, "%s stats:\n", event_name(pos)); ret += hists__fprintf_nr_events(&pos->hists, fp); } @@ -1490,8 +1490,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, } void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, - struct machine *machine, int print_sym, - int print_dso, int print_symoffset) + struct machine *machine, struct perf_evsel *evsel, + int print_sym, int print_dso, int print_symoffset) { struct addr_location al; struct callchain_cursor_node *node; @@ -1505,7 +1505,7 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, if (symbol_conf.use_callchain && sample->callchain) { - if (machine__resolve_callchain(machine, al.thread, + if (machine__resolve_callchain(machine, evsel, al.thread, sample->callchain, NULL) != 0) { if (verbose) error("Failed to resolve callchain. Skipping\n"); @@ -1611,58 +1611,3 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, perf_header__fprintf_info(session, fp, full); fprintf(fp, "# ========\n#\n"); } - - -int __perf_session__set_tracepoints_handlers(struct perf_session *session, - const struct perf_evsel_str_handler *assocs, - size_t nr_assocs) -{ - struct perf_evlist *evlist = session->evlist; - struct event_format *format; - struct perf_evsel *evsel; - char *tracepoint, *name; - size_t i; - int err; - - for (i = 0; i < nr_assocs; i++) { - err = -ENOMEM; - tracepoint = strdup(assocs[i].name); - if (tracepoint == NULL) - goto out; - - err = -ENOENT; - name = strchr(tracepoint, ':'); - if (name == NULL) - goto out_free; - - *name++ = '\0'; - format = pevent_find_event_by_name(session->pevent, - tracepoint, name); - if (format == NULL) { - /* - * Adding a handler for an event not in the session, - * just ignore it. - */ - goto next; - } - - evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id); - if (evsel == NULL) - goto next; - - err = -EEXIST; - if (evsel->handler.func != NULL) - goto out_free; - evsel->handler.func = assocs[i].handler; -next: - free(tracepoint); - } - - err = 0; -out: - return err; - -out_free: - free(tracepoint); - goto out; -} diff --git a/trunk/tools/perf/util/session.h b/trunk/tools/perf/util/session.h index 7c435bde6eb0..0c702e3f0a36 100644 --- a/trunk/tools/perf/util/session.h +++ b/trunk/tools/perf/util/session.h @@ -33,7 +33,6 @@ struct perf_session { struct machine host_machine; struct rb_root machines; struct perf_evlist *evlist; - struct pevent *pevent; /* * FIXME: Need to split this up further, we need global * stats + per event stats. 'perf diff' also needs @@ -152,20 +151,11 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, unsigned int type); void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, - struct machine *machine, int print_sym, - int print_dso, int print_symoffset); + struct machine *machine, struct perf_evsel *evsel, + int print_sym, int print_dso, int print_symoffset); int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap); void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); - -struct perf_evsel_str_handler; - -int __perf_session__set_tracepoints_handlers(struct perf_session *session, - const struct perf_evsel_str_handler *assocs, - size_t nr_assocs); - -#define perf_session__set_tracepoints_handlers(session, array) \ - __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array)) #endif /* __PERF_SESSION_H */ diff --git a/trunk/tools/perf/util/sort.c b/trunk/tools/perf/util/sort.c index 0f5a0a496bc4..a27237430c5f 100644 --- a/trunk/tools/perf/util/sort.c +++ b/trunk/tools/perf/util/sort.c @@ -241,54 +241,6 @@ struct sort_entry sort_sym = { .se_width_idx = HISTC_SYMBOL, }; -/* --sort srcline */ - -static int64_t -sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) -{ - return (int64_t)(right->ip - left->ip); -} - -static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, - size_t size, unsigned int width __used) -{ - FILE *fp; - char cmd[PATH_MAX + 2], *path = self->srcline, *nl; - size_t line_len; - - if (path != NULL) - goto out_path; - - snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, - self->ms.map->dso->long_name, self->ip); - fp = popen(cmd, "r"); - if (!fp) - goto out_ip; - - if (getline(&path, &line_len, fp) < 0 || !line_len) - goto out_ip; - fclose(fp); - self->srcline = strdup(path); - if (self->srcline == NULL) - goto out_ip; - - nl = strchr(self->srcline, '\n'); - if (nl != NULL) - *nl = '\0'; - path = self->srcline; -out_path: - return repsep_snprintf(bf, size, "%s", path); -out_ip: - return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip); -} - -struct sort_entry sort_srcline = { - .se_header = "Source:Line", - .se_cmp = sort__srcline_cmp, - .se_snprintf = hist_entry__srcline_snprintf, - .se_width_idx = HISTC_SRCLINE, -}; - /* --sort parent */ static int64_t @@ -487,7 +439,6 @@ static struct sort_dimension sort_dimensions[] = { DIM(SORT_PARENT, "parent", sort_parent), DIM(SORT_CPU, "cpu", sort_cpu), DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), - DIM(SORT_SRCLINE, "srcline", sort_srcline), }; int sort_dimension__add(const char *tok) diff --git a/trunk/tools/perf/util/sort.h b/trunk/tools/perf/util/sort.h index e724b26acd51..472aa5a63a58 100644 --- a/trunk/tools/perf/util/sort.h +++ b/trunk/tools/perf/util/sort.h @@ -71,7 +71,6 @@ struct hist_entry { char level; bool used; u8 filtered; - char *srcline; struct symbol *parent; union { unsigned long position; @@ -94,7 +93,6 @@ enum sort_type { SORT_SYM_FROM, SORT_SYM_TO, SORT_MISPREDICT, - SORT_SRCLINE, }; /* diff --git a/trunk/tools/perf/util/string.c b/trunk/tools/perf/util/string.c index 199bc4d8905d..d5836382ff2c 100644 --- a/trunk/tools/perf/util/string.c +++ b/trunk/tools/perf/util/string.c @@ -313,25 +313,3 @@ int strtailcmp(const char *s1, const char *s2) return 0; } -/** - * rtrim - Removes trailing whitespace from @s. - * @s: The string to be stripped. - * - * Note that the first trailing whitespace is replaced with a %NUL-terminator - * in the given string @s. Returns @s. - */ -char *rtrim(char *s) -{ - size_t size = strlen(s); - char *end; - - if (!size) - return s; - - end = s + size - 1; - while (end >= s && isspace(*end)) - end--; - *(end + 1) = '\0'; - - return s; -} diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 994f4ffdcd05..3e2e5ea0f03f 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1590,62 +1590,11 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size) return err; } -static int filename__read_debuglink(const char *filename, - char *debuglink, size_t size) -{ - int fd, err = -1; - Elf *elf; - GElf_Ehdr ehdr; - GElf_Shdr shdr; - Elf_Data *data; - Elf_Scn *sec; - Elf_Kind ek; - - fd = open(filename, O_RDONLY); - if (fd < 0) - goto out; - - elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); - if (elf == NULL) { - pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename); - goto out_close; - } - - ek = elf_kind(elf); - if (ek != ELF_K_ELF) - goto out_close; - - if (gelf_getehdr(elf, &ehdr) == NULL) { - pr_err("%s: cannot get elf header.\n", __func__); - goto out_close; - } - - sec = elf_section_by_name(elf, &ehdr, &shdr, - ".gnu_debuglink", NULL); - if (sec == NULL) - goto out_close; - - data = elf_getdata(sec, NULL); - if (data == NULL) - goto out_close; - - /* the start of this section is a zero-terminated string */ - strncpy(debuglink, data->d_buf, size); - - elf_end(elf); - -out_close: - close(fd); -out: - return err; -} - char dso__symtab_origin(const struct dso *dso) { static const char origin[] = { [SYMTAB__KALLSYMS] = 'k', [SYMTAB__JAVA_JIT] = 'j', - [SYMTAB__DEBUGLINK] = 'l', [SYMTAB__BUILD_ID_CACHE] = 'B', [SYMTAB__FEDORA_DEBUGINFO] = 'f', [SYMTAB__UBUNTU_DEBUGINFO] = 'u', @@ -1713,22 +1662,10 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) */ want_symtab = 1; restart: - for (dso->symtab_type = SYMTAB__DEBUGLINK; + for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE; dso->symtab_type != SYMTAB__NOT_FOUND; dso->symtab_type++) { switch (dso->symtab_type) { - case SYMTAB__DEBUGLINK: { - char *debuglink; - strncpy(name, dso->long_name, size); - debuglink = name + dso->long_name_len; - while (debuglink != name && *debuglink != '/') - debuglink--; - if (*debuglink == '/') - debuglink++; - filename__read_debuglink(dso->long_name, debuglink, - size - (debuglink - name)); - } - break; case SYMTAB__BUILD_ID_CACHE: /* skip the locally configured cache if a symfs is given */ if (symbol_conf.symfs[0] || diff --git a/trunk/tools/perf/util/symbol.h b/trunk/tools/perf/util/symbol.h index a884b99017f0..af0752b1aca1 100644 --- a/trunk/tools/perf/util/symbol.h +++ b/trunk/tools/perf/util/symbol.h @@ -257,7 +257,6 @@ enum symtab_type { SYMTAB__KALLSYMS = 0, SYMTAB__GUEST_KALLSYMS, SYMTAB__JAVA_JIT, - SYMTAB__DEBUGLINK, SYMTAB__BUILD_ID_CACHE, SYMTAB__FEDORA_DEBUGINFO, SYMTAB__UBUNTU_DEBUGINFO, diff --git a/trunk/tools/perf/util/top.c b/trunk/tools/perf/util/top.c index 7eeebcee291c..abe0e8e95068 100644 --- a/trunk/tools/perf/util/top.c +++ b/trunk/tools/perf/util/top.c @@ -65,7 +65,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) top->freq ? "Hz" : ""); } - ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel)); + ret += SNPRINTF(bf + ret, size - ret, "%s", event_name(top->sym_evsel)); ret += SNPRINTF(bf + ret, size - ret, "], "); diff --git a/trunk/tools/perf/util/trace-event-parse.c b/trunk/tools/perf/util/trace-event-parse.c index a51bd86f4d09..df2fddbf0cd2 100644 --- a/trunk/tools/perf/util/trace-event-parse.c +++ b/trunk/tools/perf/util/trace-event-parse.c @@ -32,25 +32,29 @@ int header_page_size_size; int header_page_ts_size; int header_page_data_offset; +struct pevent *perf_pevent; +static struct pevent *pevent; + bool latency_format; -struct pevent *read_trace_init(int file_bigendian, int host_bigendian) +int read_trace_init(int file_bigendian, int host_bigendian) { - struct pevent *pevent = pevent_alloc(); + if (pevent) + return 0; - if (pevent != NULL) { - pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); - pevent_set_file_bigendian(pevent, file_bigendian); - pevent_set_host_bigendian(pevent, host_bigendian); - } + perf_pevent = pevent_alloc(); + pevent = perf_pevent; - return pevent; + pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); + pevent_set_file_bigendian(pevent, file_bigendian); + pevent_set_host_bigendian(pevent, host_bigendian); + + return 0; } static int get_common_field(struct scripting_context *context, int *offset, int *size, const char *type) { - struct pevent *pevent = context->pevent; struct event_format *event; struct format_field *field; @@ -146,7 +150,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data) return data + field->offset; } -int trace_parse_common_type(struct pevent *pevent, void *data) +int trace_parse_common_type(void *data) { struct pevent_record record; @@ -154,7 +158,7 @@ int trace_parse_common_type(struct pevent *pevent, void *data) return pevent_data_type(pevent, &record); } -int trace_parse_common_pid(struct pevent *pevent, void *data) +int trace_parse_common_pid(void *data) { struct pevent_record record; @@ -162,21 +166,27 @@ int trace_parse_common_pid(struct pevent *pevent, void *data) return pevent_data_pid(pevent, &record); } -unsigned long long read_size(struct pevent *pevent, void *ptr, int size) +unsigned long long read_size(void *ptr, int size) { return pevent_read_number(pevent, ptr, size); } -void print_trace_event(struct pevent *pevent, int cpu, void *data, int size) +struct event_format *trace_find_event(int type) +{ + return pevent_find_event(pevent, type); +} + + +void print_trace_event(int cpu, void *data, int size) { struct event_format *event; struct pevent_record record; struct trace_seq s; int type; - type = trace_parse_common_type(pevent, data); + type = trace_parse_common_type(data); - event = pevent_find_event(pevent, type); + event = trace_find_event(type); if (!event) { warning("ug! no event found for type %d", type); return; @@ -193,8 +203,8 @@ void print_trace_event(struct pevent *pevent, int cpu, void *data, int size) printf("\n"); } -void print_event(struct pevent *pevent, int cpu, void *data, int size, - unsigned long long nsecs, char *comm) +void print_event(int cpu, void *data, int size, unsigned long long nsecs, + char *comm) { struct pevent_record record; struct trace_seq s; @@ -217,8 +227,7 @@ void print_event(struct pevent *pevent, int cpu, void *data, int size, printf("\n"); } -void parse_proc_kallsyms(struct pevent *pevent, - char *file, unsigned int size __unused) +void parse_proc_kallsyms(char *file, unsigned int size __unused) { unsigned long long addr; char *func; @@ -249,8 +258,7 @@ void parse_proc_kallsyms(struct pevent *pevent, } } -void parse_ftrace_printk(struct pevent *pevent, - char *file, unsigned int size __unused) +void parse_ftrace_printk(char *file, unsigned int size __unused) { unsigned long long addr; char *printk; @@ -274,19 +282,17 @@ void parse_ftrace_printk(struct pevent *pevent, } } -int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size) +int parse_ftrace_file(char *buf, unsigned long size) { return pevent_parse_event(pevent, buf, size, "ftrace"); } -int parse_event_file(struct pevent *pevent, - char *buf, unsigned long size, char *sys) +int parse_event_file(char *buf, unsigned long size, char *sys) { return pevent_parse_event(pevent, buf, size, sys); } -struct event_format *trace_find_next_event(struct pevent *pevent, - struct event_format *event) +struct event_format *trace_find_next_event(struct event_format *event) { static int idx; diff --git a/trunk/tools/perf/util/trace-event-read.c b/trunk/tools/perf/util/trace-event-read.c index 719ed74a8565..f097e0dd6c5c 100644 --- a/trunk/tools/perf/util/trace-event-read.c +++ b/trunk/tools/perf/util/trace-event-read.c @@ -114,20 +114,20 @@ static void skip(int size) }; } -static unsigned int read4(struct pevent *pevent) +static unsigned int read4(void) { unsigned int data; read_or_die(&data, 4); - return __data2host4(pevent, data); + return __data2host4(perf_pevent, data); } -static unsigned long long read8(struct pevent *pevent) +static unsigned long long read8(void) { unsigned long long data; read_or_die(&data, 8); - return __data2host8(pevent, data); + return __data2host8(perf_pevent, data); } static char *read_string(void) @@ -168,12 +168,12 @@ static char *read_string(void) return str; } -static void read_proc_kallsyms(struct pevent *pevent) +static void read_proc_kallsyms(void) { unsigned int size; char *buf; - size = read4(pevent); + size = read4(); if (!size) return; @@ -181,29 +181,29 @@ static void read_proc_kallsyms(struct pevent *pevent) read_or_die(buf, size); buf[size] = '\0'; - parse_proc_kallsyms(pevent, buf, size); + parse_proc_kallsyms(buf, size); free(buf); } -static void read_ftrace_printk(struct pevent *pevent) +static void read_ftrace_printk(void) { unsigned int size; char *buf; - size = read4(pevent); + size = read4(); if (!size) return; buf = malloc_or_die(size); read_or_die(buf, size); - parse_ftrace_printk(pevent, buf, size); + parse_ftrace_printk(buf, size); free(buf); } -static void read_header_files(struct pevent *pevent) +static void read_header_files(void) { unsigned long long size; char *header_event; @@ -214,7 +214,7 @@ static void read_header_files(struct pevent *pevent) if (memcmp(buf, "header_page", 12) != 0) die("did not read header page"); - size = read8(pevent); + size = read8(); skip(size); /* @@ -227,48 +227,47 @@ static void read_header_files(struct pevent *pevent) if (memcmp(buf, "header_event", 13) != 0) die("did not read header event"); - size = read8(pevent); + size = read8(); header_event = malloc_or_die(size); read_or_die(header_event, size); free(header_event); } -static void read_ftrace_file(struct pevent *pevent, unsigned long long size) +static void read_ftrace_file(unsigned long long size) { char *buf; buf = malloc_or_die(size); read_or_die(buf, size); - parse_ftrace_file(pevent, buf, size); + parse_ftrace_file(buf, size); free(buf); } -static void read_event_file(struct pevent *pevent, char *sys, - unsigned long long size) +static void read_event_file(char *sys, unsigned long long size) { char *buf; buf = malloc_or_die(size); read_or_die(buf, size); - parse_event_file(pevent, buf, size, sys); + parse_event_file(buf, size, sys); free(buf); } -static void read_ftrace_files(struct pevent *pevent) +static void read_ftrace_files(void) { unsigned long long size; int count; int i; - count = read4(pevent); + count = read4(); for (i = 0; i < count; i++) { - size = read8(pevent); - read_ftrace_file(pevent, size); + size = read8(); + read_ftrace_file(size); } } -static void read_event_files(struct pevent *pevent) +static void read_event_files(void) { unsigned long long size; char *sys; @@ -276,15 +275,15 @@ static void read_event_files(struct pevent *pevent) int count; int i,x; - systems = read4(pevent); + systems = read4(); for (i = 0; i < systems; i++) { sys = read_string(); - count = read4(pevent); + count = read4(); for (x=0; x < count; x++) { - size = read8(pevent); - read_event_file(pevent, sys, size); + size = read8(); + read_event_file(sys, size); } } } @@ -378,7 +377,7 @@ static int calc_index(void *ptr, int cpu) return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; } -struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) +struct pevent_record *trace_peek_data(int cpu) { struct pevent_record *data; void *page = cpu_data[cpu].page; @@ -400,15 +399,15 @@ struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) /* FIXME: handle header page */ if (header_page_ts_size != 8) die("expected a long long type for timestamp"); - cpu_data[cpu].timestamp = data2host8(pevent, ptr); + cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr); ptr += 8; switch (header_page_size_size) { case 4: - cpu_data[cpu].page_size = data2host4(pevent, ptr); + cpu_data[cpu].page_size = data2host4(perf_pevent, ptr); ptr += 4; break; case 8: - cpu_data[cpu].page_size = data2host8(pevent, ptr); + cpu_data[cpu].page_size = data2host8(perf_pevent, ptr); ptr += 8; break; default: @@ -422,10 +421,10 @@ struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) if (idx >= cpu_data[cpu].page_size) { get_next_page(cpu); - return trace_peek_data(pevent, cpu); + return trace_peek_data(cpu); } - type_len_ts = data2host4(pevent, ptr); + type_len_ts = data2host4(perf_pevent, ptr); ptr += 4; type_len = type_len4host(type_len_ts); @@ -435,14 +434,14 @@ struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) case RINGBUF_TYPE_PADDING: if (!delta) die("error, hit unexpected end of page"); - length = data2host4(pevent, ptr); + length = data2host4(perf_pevent, ptr); ptr += 4; length *= 4; ptr += length; goto read_again; case RINGBUF_TYPE_TIME_EXTEND: - extend = data2host4(pevent, ptr); + extend = data2host4(perf_pevent, ptr); ptr += 4; extend <<= TS_SHIFT; extend += delta; @@ -453,7 +452,7 @@ struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) ptr += 12; break; case 0: - length = data2host4(pevent, ptr); + length = data2host4(perf_pevent, ptr); ptr += 4; die("here! length=%d", length); break; @@ -478,17 +477,17 @@ struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) return data; } -struct pevent_record *trace_read_data(struct pevent *pevent, int cpu) +struct pevent_record *trace_read_data(int cpu) { struct pevent_record *data; - data = trace_peek_data(pevent, cpu); + data = trace_peek_data(cpu); cpu_data[cpu].next = NULL; return data; } -ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) +ssize_t trace_report(int fd, bool __repipe) { char buf[BUFSIZ]; char test[] = { 23, 8, 68 }; @@ -520,32 +519,30 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) file_bigendian = buf[0]; host_bigendian = bigendian(); - *ppevent = read_trace_init(file_bigendian, host_bigendian); - if (*ppevent == NULL) - die("read_trace_init failed"); + read_trace_init(file_bigendian, host_bigendian); read_or_die(buf, 1); long_size = buf[0]; - page_size = read4(*ppevent); + page_size = read4(); - read_header_files(*ppevent); + read_header_files(); - read_ftrace_files(*ppevent); - read_event_files(*ppevent); - read_proc_kallsyms(*ppevent); - read_ftrace_printk(*ppevent); + read_ftrace_files(); + read_event_files(); + read_proc_kallsyms(); + read_ftrace_printk(); size = calc_data_size - 1; calc_data_size = 0; repipe = false; if (show_funcs) { - pevent_print_funcs(*ppevent); + pevent_print_funcs(perf_pevent); return size; } if (show_printk) { - pevent_print_printk(*ppevent); + pevent_print_printk(perf_pevent); return size; } diff --git a/trunk/tools/perf/util/trace-event-scripting.c b/trunk/tools/perf/util/trace-event-scripting.c index 474aa7a7df43..18ae6c1831d3 100644 --- a/trunk/tools/perf/util/trace-event-scripting.c +++ b/trunk/tools/perf/util/trace-event-scripting.c @@ -36,7 +36,6 @@ static int stop_script_unsupported(void) } static void process_event_unsupported(union perf_event *event __unused, - struct pevent *pevent __unused, struct perf_sample *sample __unused, struct perf_evsel *evsel __unused, struct machine *machine __unused, @@ -62,8 +61,7 @@ static int python_start_script_unsupported(const char *script __unused, return -1; } -static int python_generate_script_unsupported(struct pevent *pevent __unused, - const char *outfile __unused) +static int python_generate_script_unsupported(const char *outfile __unused) { print_python_unsupported_msg(); @@ -124,8 +122,7 @@ static int perl_start_script_unsupported(const char *script __unused, return -1; } -static int perl_generate_script_unsupported(struct pevent *pevent __unused, - const char *outfile __unused) +static int perl_generate_script_unsupported(const char *outfile __unused) { print_perl_unsupported_msg(); diff --git a/trunk/tools/perf/util/trace-event.h b/trunk/tools/perf/util/trace-event.h index 8fef1d6687b7..639852ac1117 100644 --- a/trunk/tools/perf/util/trace-event.h +++ b/trunk/tools/perf/util/trace-event.h @@ -8,7 +8,6 @@ struct machine; struct perf_sample; union perf_event; -struct perf_tool; struct thread; extern int header_page_size_size; @@ -30,36 +29,35 @@ enum { int bigendian(void); -struct pevent *read_trace_init(int file_bigendian, int host_bigendian); -void print_trace_event(struct pevent *pevent, int cpu, void *data, int size); +int read_trace_init(int file_bigendian, int host_bigendian); +void print_trace_event(int cpu, void *data, int size); -void print_event(struct pevent *pevent, int cpu, void *data, int size, - unsigned long long nsecs, char *comm); +void print_event(int cpu, void *data, int size, unsigned long long nsecs, + char *comm); -int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size); -int parse_event_file(struct pevent *pevent, - char *buf, unsigned long size, char *sys); +int parse_ftrace_file(char *buf, unsigned long size); +int parse_event_file(char *buf, unsigned long size, char *sys); -struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu); +struct pevent_record *trace_peek_data(int cpu); +struct event_format *trace_find_event(int type); unsigned long long raw_field_value(struct event_format *event, const char *name, void *data); void *raw_field_ptr(struct event_format *event, const char *name, void *data); -void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); -void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size); +void parse_proc_kallsyms(char *file, unsigned int size __unused); +void parse_ftrace_printk(char *file, unsigned int size __unused); -ssize_t trace_report(int fd, struct pevent **pevent, bool repipe); +ssize_t trace_report(int fd, bool repipe); -int trace_parse_common_type(struct pevent *pevent, void *data); -int trace_parse_common_pid(struct pevent *pevent, void *data); +int trace_parse_common_type(void *data); +int trace_parse_common_pid(void *data); -struct event_format *trace_find_next_event(struct pevent *pevent, - struct event_format *event); -unsigned long long read_size(struct pevent *pevent, void *ptr, int size); +struct event_format *trace_find_next_event(struct event_format *event); +unsigned long long read_size(void *ptr, int size); unsigned long long eval_flag(const char *flag); -struct pevent_record *trace_read_data(struct pevent *pevent, int cpu); +struct pevent_record *trace_read_data(int cpu); int read_tracing_data(int fd, struct list_head *pattrs); struct tracing_data { @@ -79,12 +77,11 @@ struct scripting_ops { int (*start_script) (const char *script, int argc, const char **argv); int (*stop_script) (void); void (*process_event) (union perf_event *event, - struct pevent *pevent, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, struct thread *thread); - int (*generate_script) (struct pevent *pevent, const char *outfile); + int (*generate_script) (const char *outfile); }; int script_spec_register(const char *spec, struct scripting_ops *ops); @@ -93,7 +90,6 @@ void setup_perl_scripting(void); void setup_python_scripting(void); struct scripting_context { - struct pevent *pevent; void *event_data; }; diff --git a/trunk/tools/perf/util/util.h b/trunk/tools/perf/util/util.h index b13c7331eaf8..2daaedb83d84 100644 --- a/trunk/tools/perf/util/util.h +++ b/trunk/tools/perf/util/util.h @@ -264,6 +264,4 @@ bool is_power_of_2(unsigned long n) size_t hex_width(u64 v); -char *rtrim(char *s); - #endif