* refs/heads/tmp-d6bbe8b Linux 4.4.127 Revert "ip6_vti: adjust vti mtu according to mtu of lower device" net: cavium: liquidio: fix up "Avoid dma_unmap_single on uninitialized ndata" spi: davinci: fix up dma_mapping_error() incorrect patch Revert "mtip32xx: use runtime tag to initialize command header" Revert "cpufreq: Fix governor module removal race" Revert "ARM: dts: omap3-n900: Fix the audio CODEC's reset pin" Revert "ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin" Revert "PCI/MSI: Stop disabling MSI/MSI-X in pci_device_shutdown()" nospec: Kill array_index_nospec_mask_check() nospec: Move array_index_nospec() parameter checking into separate macro net: hns: Fix ethtool private flags md/raid10: reset the 'first' at the end of loop ARM: dts: am57xx-beagle-x15-common: Add overide powerhold property ARM: dts: dra7: Add power hold and power controller properties to palmas Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition vt: change SGR 21 to follow the standards Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list staging: comedi: ni_mio_common: ack ai fifo error interrupts. fs/proc: Stop trying to report thread stacks crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one crypto: ahash - Fix early termination in hash walk parport_pc: Add support for WCH CH382L PCI-E single parallel port card. media: usbtv: prevent double free in error case mei: remove dev_err message on an unsupported ioctl USB: serial: cp210x: add ELDAT Easywave RX09 id USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator USB: serial: ftdi_sio: add RT Systems VX-8 cable usb: dwc2: Improve gadget state disconnection handling scsi: virtio_scsi: always read VPD pages for multiqueue too llist: clang: introduce member_address_is_nonnull() Bluetooth: Fix missing encryption refresh on Security Request netfilter: x_tables: add and use xt_check_proc_name netfilter: bridge: ebt_among: add more missing match size checks xfrm: Refuse to insert 32 bit userspace socket policies on 64 bit systems net: xfrm: use preempt-safe this_cpu_read() in ipcomp_alloc_tfms() RDMA/ucma: Introduce safer rdma_addr_size() variants RDMA/ucma: Don't allow join attempts for unsupported AF family RDMA/ucma: Check that device exists prior to accessing it RDMA/ucma: Check that device is connected prior to access it RDMA/ucma: Ensure that CM_ID exists prior to access it RDMA/ucma: Fix use-after-free access in ucma_close RDMA/ucma: Check AF family prior resolving address xfrm_user: uncoditionally validate esn replay attribute struct arm64: avoid overflow in VA_START and PAGE_OFFSET selinux: Remove redundant check for unknown labeling behavior netfilter: ctnetlink: Make some parameters integer to avoid enum mismatch tty: provide tty_name() even without CONFIG_TTY audit: add tty field to LOGIN event frv: declare jiffies to be located in the .data section jiffies.h: declare jiffies and jiffies_64 with ____cacheline_aligned_in_smp fs: compat: Remove warning from COMPATIBLE_IOCTL selinux: Remove unnecessary check of array base in selinux_set_mapping() cpumask: Add helper cpumask_available() genirq: Use cpumask_available() for check of cpumask variable netfilter: nf_nat_h323: fix logical-not-parentheses warning Input: mousedev - fix implicit conversion warning dm ioctl: remove double parentheses PCI: Make PCI_ROM_ADDRESS_MASK a 32-bit constant writeback: fix the wrong congested state variable definition ACPI, PCI, irq: remove redundant check for null string pointer kprobes/x86: Fix to set RWX bits correctly before releasing trampoline usb: gadget: f_hid: fix: Prevent accessing released memory usb: gadget: align buffer size when allocating for OUT endpoint usb: gadget: fix usb_ep_align_maybe endianness and new usb_ep_align usb: gadget: change len to size_t on alloc_ep_req() usb: gadget: define free_ep_req as universal function partitions/msdos: Unable to mount UFS 44bsd partitions perf/hwbp: Simplify the perf-hwbp code, fix documentation ALSA: pcm: potential uninitialized return values ALSA: pcm: Use dma_bytes as size parameter in dma_mmap_coherent() mtd: jedec_probe: Fix crash in jedec_read_mfr() Replace #define with enum for better compilation errors. Add missing include to drivers/tty/goldfish.c Fix whitespace in drivers/tty/goldfish.c ANDROID: fuse: Add null terminator to path in canonical path to avoid issue ANDROID: sdcardfs: Fix sdcardfs to stop creating cases-sensitive duplicate entries. ANDROID: add missing include to pdev_bus ANDROID: pdev_bus: replace writel with gf_write_ptr ANDROID: Cleanup type casting in goldfish.h ANDROID: Include missing headers in goldfish.h ANDROID: cpufreq: times: skip printing invalid frequencies ANDROID: xt_qtaguid: Remove unnecessary null checks to device's name ANDROID: xt_qtaguid: Remove unnecessary null checks to ifa_label ANDROID: cpufreq: times: allocate enough space for a uid_entry Linux 4.4.126 net: systemport: Rewrite __bcm_sysport_tx_reclaim() net: fec: Fix unbalanced PM runtime calls ieee802154: 6lowpan: fix possible NULL deref in lowpan_device_event() s390/qeth: on channel error, reject further cmd requests s390/qeth: lock read device while queueing next buffer s390/qeth: when thread completes, wake up all waiters s390/qeth: free netdevice when removing a card team: Fix double free in error path skbuff: Fix not waking applications when errors are enqueued net: Only honor ifindex in IP_PKTINFO if non-0 netlink: avoid a double skb free in genlmsg_mcast() net/iucv: Free memory obtained by kzalloc net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface net: ethernet: arc: Fix a potential memory leak if an optional regulator is deferred l2tp: do not accept arbitrary sockets ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option() dccp: check sk for closed state in dccp_sendmsg() net: Fix hlist corruptions in inet_evict_bucket() Revert "genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs" scsi: sg: don't return bogus Sg_requests Revert "genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs" UPSTREAM: drm: virtio-gpu: set atomic flag UPSTREAM: drm: virtio-gpu: transfer dumb buffers to host on plane update UPSTREAM: drm: virtio-gpu: ensure plane is flushed to host on atomic update UPSTREAM: drm: virtio-gpu: get the fb from the plane state for atomic updates Linux 4.4.125 bpf, x64: increase number of passes bpf: skip unnecessary capability check kbuild: disable clang's default use of -fmerge-all-constants staging: lustre: ptlrpc: kfree used instead of kvfree perf/x86/intel: Don't accidentally clear high bits in bdw_limit_period() x86/entry/64: Don't use IST entry for #BP stack x86/boot/64: Verify alignment of the LOAD segment x86/build/64: Force the linker to use 2MB page size kvm/x86: fix icebp instruction handling tty: vt: fix up tabstops properly can: cc770: Fix use after free in cc770_tx_interrupt() can: cc770: Fix queue stall & dropped RTR reply can: cc770: Fix stalls on rt-linux, remove redundant IRQ ack staging: ncpfs: memory corruption in ncp_read_kernel() mtd: nand: fsl_ifc: Fix nand waitfunc return value tracing: probeevent: Fix to support minus offset from symbol rtlwifi: rtl8723be: Fix loss of signal brcmfmac: fix P2P_DEVICE ethernet address generation acpi, numa: fix pxm to online numa node associations drm: udl: Properly check framebuffer mmap offsets drm/radeon: Don't turn off DP sink when disconnected drm/vmwgfx: Fix a destoy-while-held mutex problem. x86/mm: implement free pmd/pte page interfaces mm/vmalloc: add interfaces to free unmapped page table libata: Modify quirks for MX100 to limit NCQ_TRIM quirk to MU01 version libata: Make Crucial BX100 500GB LPM quirk apply to all firmware versions libata: Apply NOLPM quirk to Crucial M500 480 and 960GB SSDs libata: Enable queued TRIM for Samsung SSD 860 libata: disable LPM for Crucial BX100 SSD 500GB drive libata: Apply NOLPM quirk to Crucial MX100 512GB SSDs libata: remove WARN() for DMA or PIO command without data libata: fix length validation of ATAPI-relayed SCSI commands Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174 clk: bcm2835: Protect sections updating shared registers ahci: Add PCI-id for the Highpoint Rocketraid 644L card PCI: Add function 1 DMA alias quirk for Highpoint RocketRAID 644L mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs ALSA: hda/realtek - Always immediately update mute LED with pin VREF ALSA: aloop: Fix access to not-yet-ready substream via cable ALSA: aloop: Sync stale timer before release ALSA: usb-audio: Fix parsing descriptor of UAC2 processing unit iio: st_pressure: st_accel: pass correct platform data to init MIPS: ralink: Remove ralink_halt() ANDROID: cpufreq: times: fix proc_time_in_state_show dtc: turn off dtc unit address warnings by default Linux 4.4.124 RDMA/ucma: Fix access to non-initialized CM_ID object dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63 clk: si5351: Rename internal plls to avoid name collisions nfsd4: permit layoutget of executable-only files RDMA/ocrdma: Fix permissions for OCRDMA_RESET_STATS ip6_vti: adjust vti mtu according to mtu of lower device iommu/vt-d: clean up pr_irq if request_threaded_irq fails pinctrl: Really force states during suspend/resume coresight: Fix disabling of CoreSight TPIU pty: cancel pty slave port buf's work in tty_release drm/omap: DMM: Check for DMM readiness after successful transaction commit vgacon: Set VGA struct resource types IB/umem: Fix use of npages/nmap fields RDMA/cma: Use correct size when writing netlink stats IB/ipoib: Avoid memory leak if the SA returns a different DGID mmc: avoid removing non-removable hosts during suspend platform/chrome: Use proper protocol transfer function cros_ec: fix nul-termination for firmware build info media: [RESEND] media: dvb-frontends: Add delay to Si2168 restart media: bt8xx: Fix err 'bt878_probe()' rtlwifi: rtl_pci: Fix the bug when inactiveps is enabled. RDMA/iwpm: Fix uninitialized error code in iwpm_send_mapinfo() drm/msm: fix leak in failed get_pages media: c8sectpfe: fix potential NULL pointer dereference in c8sectpfe_timer_interrupt Bluetooth: hci_qca: Avoid setup failure on missing rampatch perf tests kmod-path: Don't fail if compressed modules aren't supported rtc: ds1374: wdt: Fix stop/start ioctl always returning -EINVAL rtc: ds1374: wdt: Fix issue with timeout scaling from secs to wdt ticks cifs: small underflow in cnvrtDosUnixTm() net: hns: fix ethtool_get_strings overflow in hns driver sm501fb: don't return zero on failure path in sm501fb_start() video: fbdev: udlfb: Fix buffer on stack tcm_fileio: Prevent information leak for short reads ia64: fix module loading for gcc-5.4 md/raid10: skip spare disk as 'first' disk Input: twl4030-pwrbutton - use correct device for irq request power: supply: pda_power: move from timer to delayed_work bnx2x: Align RX buffers drm/nouveau/kms: Increase max retries in scanout position queries. ACPI / PMIC: xpower: Fix power_table addresses ipmi/watchdog: fix wdog hang on panic waiting for ipmi response ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP mmc: sdhci-of-esdhc: limit SD clock for ls1012a/ls1046a staging: wilc1000: fix unchecked return value staging: unisys: visorhba: fix s-Par to boot with option CONFIG_VMAP_STACK set to y mtip32xx: use runtime tag to initialize command header mfd: palmas: Reset the POWERHOLD mux during power off mac80211: don't parse encrypted management frames in ieee80211_frame_acked Btrfs: send, fix file hole not being preserved due to inline extent rndis_wlan: add return value validation mt7601u: check return value of alloc_skb iio: st_pressure: st_accel: Initialise sensor platform data properly NFS: don't try to cross a mountpount when there isn't one there. infiniband/uverbs: Fix integer overflows scsi: mac_esp: Replace bogus memory barrier with spinlock qlcnic: fix unchecked return value wan: pc300too: abort path on failure mmc: host: omap_hsmmc: checking for NULL instead of IS_ERR() openvswitch: Delete conntrack entry clashing with an expectation. netfilter: xt_CT: fix refcnt leak on error path Fix driver usage of 128B WQEs when WQ_CREATE is V1. ASoC: Intel: Skylake: Uninitialized variable in probe_codec() IB/mlx4: Change vma from shared to private IB/mlx4: Take write semaphore when changing the vma struct HSI: ssi_protocol: double free in ssip_pn_xmit() IB/ipoib: Update broadcast object if PKey value was changed in index 0 IB/ipoib: Fix deadlock between ipoib_stop and mcast join flow ALSA: hda - Fix headset microphone detection for ASUS N551 and N751 e1000e: fix timing for 82579 Gigabit Ethernet controller tcp: remove poll() flakes with FastOpen NFS: Fix missing pg_cleanup after nfs_pageio_cond_complete() md/raid10: wait up frozen array in handle_write_completed iommu/omap: Register driver before setting IOMMU ops ARM: 8668/1: ftrace: Fix dynamic ftrace with DEBUG_RODATA and !FRAME_POINTER KVM: PPC: Book3S PR: Exit KVM on failed mapping scsi: virtio_scsi: Always try to read VPD pages clk: ns2: Correct SDIO bits ath: Fix updating radar flags for coutry code India spi: dw: Disable clock after unregistering the host media/dvb-core: Race condition when writing to CAM net: ipv6: send unsolicited NA on admin up i2c: i2c-scmi: add a MS HID genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs cpufreq/sh: Replace racy task affinity logic ACPI/processor: Replace racy task affinity logic ACPI/processor: Fix error handling in __acpi_processor_start() time: Change posix clocks ops interfaces to use timespec64 Input: ar1021_i2c - fix too long name in driver's device table rtc: cmos: Do not assume irq 8 for rtc when there are no legacy irqs x86: i8259: export legacy_pic symbol regulator: anatop: set default voltage selector for pcie platform/x86: asus-nb-wmi: Add wapf4 quirk for the X302UA staging: android: ashmem: Fix possible deadlock in ashmem_ioctl CIFS: Enable encryption during session setup phase SMB3: Validate negotiate request must always be signed tpm_tis: fix potential buffer overruns caused by bit glitches on the bus tpm: fix potential buffer overruns caused by bit glitches on the bus BACKPORT, FROMLIST: crypto: arm64/speck - add NEON-accelerated implementation of Speck-XTS Linux 4.4.123 bpf: fix incorrect sign extension in check_alu_op() usb: gadget: bdc: 64-bit pointer capability check USB: gadget: udc: Add missing platform_device_put() on error in bdc_pci_probe() btrfs: Fix use-after-free when cleaning up fs_devs with a single stale device btrfs: alloc_chunk: fix DUP stripe size handling ARM: dts: LogicPD Torpedo: Fix I2C1 pinmux scsi: sg: only check for dxfer_len greater than 256M scsi: sg: fix static checker warning in sg_is_valid_dxfer scsi: sg: fix SG_DXFER_FROM_DEV transfers irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis fs/aio: Use RCU accessors for kioctx_table->table[] fs/aio: Add explicit RCU grace period when freeing kioctx lock_parent() needs to recheck if dentry got __dentry_kill'ed under it fs: Teach path_connected to handle nfs filesystems with multiple roots. drm/amdgpu/dce: Don't turn off DP sink when disconnected ALSA: seq: Clear client entry before deleting else at closing ALSA: seq: Fix possible UAF in snd_seq_check_queue() ALSA: hda - Revert power_save option default value ALSA: pcm: Fix UAF in snd_pcm_oss_get_formats() x86/mm: Fix vmalloc_fault to use pXd_large x86/vm86/32: Fix POPF emulation selftests/x86/entry_from_vm86: Add test cases for POPF selftests/x86: Add tests for the STR and SLDT instructions selftests/x86: Add tests for User-Mode Instruction Prevention selftests/x86/entry_from_vm86: Exit with 1 if we fail ima: relax requiring a file signature for new files with zero length rcutorture/configinit: Fix build directory error message ipvlan: add L2 check for packets arriving via virtual devices ASoC: nuc900: Fix a loop timeout test mac80211: remove BUG() when interface type is invalid mac80211_hwsim: enforce PS_MANUAL_POLL to be set after PS_ENABLED agp/intel: Flush all chipset writes after updating the GGTT drm/amdkfd: Fix memory leaks in kfd topology veth: set peer GSO values media: cpia2: Fix a couple off by one bugs scsi: dh: add new rdac devices scsi: devinfo: apply to HP XP the same flags as Hitachi VSP scsi: core: scsi_get_device_flags_keyed(): Always return device flags spi: sun6i: disable/unprepare clocks on remove tools/usbip: fixes build with musl libc toolchain ath10k: fix invalid STS_CAP_OFFSET_MASK clk: qcom: msm8916: fix mnd_width for codec_digcodec cpufreq: Fix governor module removal race ath10k: update tdls teardown state to target ARM: dts: omap3-n900: Fix the audio CODEC's reset pin ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]() net: xfrm: allow clearing socket xfrm policies. test_firmware: fix setting old custom fw path back on exit sched: Stop resched_cpu() from sending IPIs to offline CPUs sched: Stop switched_to_rt() from sending IPIs to offline CPUs ARM: dts: exynos: Correct Trats2 panel reset line HID: elo: clear BTN_LEFT mapping video/hdmi: Allow "empty" HDMI infoframes drm/edid: set ELD connector type in drm_edid_to_eld() wil6210: fix memory access violation in wil_memcpy_from/toio_32 pwm: tegra: Increase precision in PWM rate calculation kprobes/x86: Set kprobes pages read-only kprobes/x86: Fix kprobe-booster not to boost far call instructions scsi: sg: close race condition in sg_remove_sfp_usercontext() scsi: sg: check for valid direction before starting the request perf session: Don't rely on evlist in pipe mode perf inject: Copy events when reordering events in pipe mode drivers/perf: arm_pmu: handle no platform_device usb: gadget: dummy_hcd: Fix wrong power status bit clear/reset in dummy_hub_control() usb: dwc2: Make sure we disconnect the gadget state md/raid6: Fix anomily when recovering a single device in RAID6. regulator: isl9305: fix array size MIPS: r2-on-r6-emu: Clear BLTZALL and BGEZALL debugfs counters MIPS: r2-on-r6-emu: Fix BLEZL and BGTZL identification MIPS: BPF: Fix multiple problems in JIT skb access helpers. MIPS: BPF: Quit clobbering callee saved registers in JIT code. coresight: Fixes coresight DT parse to get correct output port ID. drm/amdgpu: Fail fb creation from imported dma-bufs. (v2) drm/radeon: Fail fb creation from imported dma-bufs. video: ARM CLCD: fix dma allocation size iommu/iova: Fix underflow bug in __alloc_and_insert_iova_range apparmor: Make path_max parameter readonly scsi: ses: don't get power status of SES device slot on probe fm10k: correctly check if interface is removed ALSA: firewire-digi00x: handle all MIDI messages on streaming packets reiserfs: Make cancel_old_flush() reliable ARM: dts: koelsch: Correct clock frequency of X2 DU clock input net/faraday: Add missing include of of.h powerpc: Avoid taking a data miss on every userspace instruction miss ARM: dts: r8a7791: Correct parent of SSI[0-9] clocks ARM: dts: r8a7790: Correct parent of SSI[0-9] clocks NFC: nfcmrvl: double free on error path NFC: nfcmrvl: Include unaligned.h instead of access_ok.h vxlan: vxlan dev should inherit lowerdev's gso_max_size drm/vmwgfx: Fixes to vmwgfx_fb braille-console: Fix value returned by _braille_console_setup bonding: refine bond_fold_stats() wrap detection f2fs: relax node version check for victim data in gc blk-throttle: make sure expire time isn't too big mm: Fix false-positive VM_BUG_ON() in page_cache_{get,add}_speculative() driver: (adm1275) set the m,b and R coefficients correctly for power dmaengine: imx-sdma: add 1ms delay to ensure SDMA channel is stopped tcp: sysctl: Fix a race to avoid unexpected 0 window from space spi: omap2-mcspi: poll OMAP2_MCSPI_CHSTAT_RXS for PIO transfer ASoC: rcar: ssi: don't set SSICR.CKDV = 000 with SSIWSR.CONT sched: act_csum: don't mangle TCP and UDP GSO packets Input: qt1070 - add OF device ID table sysrq: Reset the watchdog timers while displaying high-resolution timers timers, sched_clock: Update timeout for clock wrap media: i2c/soc_camera: fix ov6650 sensor getting wrong clock scsi: ipr: Fix missed EH wakeup solo6x10: release vb2 buffers in solo_stop_streaming() of: fix of_device_get_modalias returned length when truncating buffers batman-adv: handle race condition for claims between gateways ARM: dts: Adjust moxart IRQ controller and flags net/8021q: create device with all possible features in wanted_features HID: clamp input to logical range if no null state perf probe: Return errno when not hitting any event ath10k: disallow DFS simulation if DFS channel is not enabled drm: Defer disabling the vblank IRQ until the next interrupt (for instant-off) drivers: net: xgene: Fix hardware checksum setting perf tools: Make perf_event__synthesize_mmap_events() scale i40e: fix ethtool to get EEPROM data from X722 interface i40e: Acquire NVM lock before reads on all devices perf sort: Fix segfault with basic block 'cycles' sort dimension selinux: check for address length in selinux_socket_bind() PCI/MSI: Stop disabling MSI/MSI-X in pci_device_shutdown() ath10k: fix a warning during channel switch with multiple vaps drm: qxl: Don't alloc fbdev if emulation is not supported HID: reject input outside logical range only if null state is set staging: wilc1000: add check for kmalloc allocation failure. staging: speakup: Replace BUG_ON() with WARN_ON(). Input: tsc2007 - check for presence and power down tsc2007 during probe blkcg: fix double free of new_blkg in blkcg_init_queue ANDROID: cpufreq: times: avoid prematurely freeing uid_entry ANDROID: Use standard logging functions in goldfish_pipe ANDROID: Fix whitespace in goldfish staging: android: ashmem: Fix possible deadlock in ashmem_ioctl llist: clang: introduce member_address_is_nonnull() Linux 4.4.122 fixup: sctp: verify size of a new chunk in _sctp_make_chunk() serial: 8250_pci: Add Brainboxes UC-260 4 port serial device usb: gadget: f_fs: Fix use-after-free in ffs_fs_kill_sb() usb: usbmon: Read text within supplied buffer size USB: usbmon: remove assignment from IS_ERR argument usb: quirks: add control message delay for 1b1c:1b20 USB: storage: Add JMicron bridge 152d:2567 to unusual_devs.h staging: android: ashmem: Fix lockdep issue during llseek staging: comedi: fix comedi_nsamples_left. uas: fix comparison for error code tty/serial: atmel: add new version check for usart serial: sh-sci: prevent lockup on full TTY buffers x86: Treat R_X86_64_PLT32 as R_X86_64_PC32 x86/module: Detect and skip invalid relocations Revert "ARM: dts: LogicPD Torpedo: Fix I2C1 pinmux" NFS: Fix an incorrect type in struct nfs_direct_req scsi: qla2xxx: Replace fcport alloc with qla2x00_alloc_fcport ubi: Fix race condition between ubi volume creation and udev ext4: inplace xattr block update fails to deduplicate blocks netfilter: x_tables: pack percpu counter allocations netfilter: x_tables: pass xt_counters struct to counter allocator netfilter: x_tables: pass xt_counters struct instead of packet counter netfilter: use skb_to_full_sk in ip_route_me_harder netfilter: ipv6: fix use-after-free Write in nf_nat_ipv6_manip_pkt netfilter: bridge: ebt_among: add missing match size checks netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets netfilter: IDLETIMER: be syzkaller friendly netfilter: nat: cope with negative port range netfilter: x_tables: fix missing timer initialization in xt_LED netfilter: add back stackpointer size checks tc358743: fix register i2c_rd/wr function fix Input: tca8418_keypad - remove double read of key event register ARM: omap2: hide omap3_save_secure_ram on non-OMAP3 builds netfilter: nfnetlink_queue: fix timestamp attribute watchdog: hpwdt: fix unused variable warning watchdog: hpwdt: Check source of NMI watchdog: hpwdt: SMBIOS check nospec: Include <asm/barrier.h> dependency ALSA: hda: add dock and led support for HP ProBook 640 G2 ALSA: hda: add dock and led support for HP EliteBook 820 G3 ALSA: seq: More protection for concurrent write and ioctl races ALSA: seq: Don't allow resizing pool in use ALSA: hda/realtek - Fix dock line-out volume on Dell Precision 7520 x86/MCE: Serialize sysfs changes bcache: don't attach backing with duplicate UUID kbuild: Handle builtin dtb file names containing hyphens loop: Fix lost writes caused by missing flag Input: matrix_keypad - fix race when disabling interrupts MIPS: OCTEON: irq: Check for null return on kzalloc allocation MIPS: ath25: Check for kzalloc allocation failure MIPS: BMIPS: Do not mask IPIs during suspend drm/amdgpu: fix KV harvesting drm/radeon: fix KV harvesting drm/amdgpu: Notify sbios device ready before send request drm/amdgpu: Fix deadlock on runtime suspend drm/radeon: Fix deadlock on runtime suspend drm/nouveau: Fix deadlock on runtime suspend drm: Allow determining if current task is output poll worker workqueue: Allow retrieval of current task's work struct scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS RDMA/mlx5: Fix integer overflow while resizing CQ RDMA/ucma: Check that user doesn't overflow QP state RDMA/ucma: Limit possible option size ANDROID: ranchu: 32 bit framebuffer support ANDROID: Address checkpatch warnings in goldfishfb ANDROID: Address checkpatch.pl warnings in goldfish_pipe ANDROID: sdcardfs: fix lock issue on 32 bit/SMP architectures ANDROID: goldfish: Fix typo in goldfish_cmd_locked() call ANDROID: Address checkpatch.pl warnings in goldfish_pipe_v2 FROMLIST: f2fs: don't put dentry page in pagecache into highmem Linux 4.4.121 btrfs: preserve i_mode if __btrfs_set_acl() fails bpf, x64: implement retpoline for tail call dm io: fix duplicate bio completion due to missing ref count mpls, nospec: Sanitize array index in mpls_label_ok() net: mpls: Pull common label check into helper sctp: verify size of a new chunk in _sctp_make_chunk() s390/qeth: fix IPA command submission race s390/qeth: fix SETIP command handling sctp: fix dst refcnt leak in sctp_v6_get_dst() sctp: fix dst refcnt leak in sctp_v4_get_dst udplite: fix partial checksum initialization ppp: prevent unregistered channels from connecting to PPP units netlink: ensure to loop over all netns in genlmsg_multicast_allns() net: ipv4: don't allow setting net.ipv4.route.min_pmtu below 68 net: fix race on decreasing number of TX queues ipv6 sit: work around bogus gcc-8 -Wrestrict warning hdlc_ppp: carrier detect ok, don't turn off negotiation fib_semantics: Don't match route with mismatching tclassid bridge: check brport attr show in brport_show Revert "led: core: Fix brightness setting when setting delay_off=0" x86/spectre: Fix an error message leds: do not overflow sysfs buffer in led_trigger_show x86/apic/vector: Handle legacy irq data correctly ARM: dts: LogicPD Torpedo: Fix I2C1 pinmux btrfs: Don't clear SGID when inheriting ACLs x86/syscall: Sanitize syscall table de-references under speculation fix KVM: mmu: Fix overlap between public and private memslots ARM: mvebu: Fix broken PL310_ERRATA_753970 selects nospec: Allow index argument to have const-qualified type media: m88ds3103: don't call a non-initalized function cpufreq: s3c24xx: Fix broken s3c_cpufreq_init() ALSA: hda: Add a power_save blacklist ALSA: usb-audio: Add a quirck for B&W PX headphones tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus ANDROID: Delete the goldfish_nand driver. ANDROID: Add input support for Android Wear. ANDROID: proc: fix config & includes for /proc/uid FROMLIST: ARM: amba: Don't read past the end of sysfs "driver_override" buffer UPSTREAM: ANDROID: binder: remove WARN() for redundant txn error ANDROID: cpufreq: times: Add missing includes ANDROID: cpufreq: Add time_in_state to /proc/uid directories ANDROID: proc: Add /proc/uid directory ANDROID: cpufreq: times: track per-uid time in state ANDROID: cpufreq: track per-task time in state Conflicts: drivers/gpu/drm/msm/msm_gem.c drivers/net/wireless/ath/regd.c kernel/sched/core.c Change-Id: I9bb7b5a062415da6925a5a56a34e6eb066a53320 Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
705 lines
18 KiB
C
705 lines
18 KiB
C
/* drivers/misc/uid_sys_stats.c
|
|
*
|
|
* Copyright (C) 2014 - 2015 Google, Inc.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <linux/atomic.h>
|
|
#include <linux/cpufreq_times.h>
|
|
#include <linux/err.h>
|
|
#include <linux/hashtable.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/list.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/profile.h>
|
|
#include <linux/rtmutex.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#define UID_HASH_BITS 10
|
|
DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
|
|
|
|
static DEFINE_RT_MUTEX(uid_lock);
|
|
static struct proc_dir_entry *cpu_parent;
|
|
static struct proc_dir_entry *io_parent;
|
|
static struct proc_dir_entry *proc_parent;
|
|
|
|
struct io_stats {
|
|
u64 read_bytes;
|
|
u64 write_bytes;
|
|
u64 rchar;
|
|
u64 wchar;
|
|
u64 fsync;
|
|
};
|
|
|
|
#define UID_STATE_FOREGROUND 0
|
|
#define UID_STATE_BACKGROUND 1
|
|
#define UID_STATE_BUCKET_SIZE 2
|
|
|
|
#define UID_STATE_TOTAL_CURR 2
|
|
#define UID_STATE_TOTAL_LAST 3
|
|
#define UID_STATE_DEAD_TASKS 4
|
|
#define UID_STATE_SIZE 5
|
|
|
|
#define MAX_TASK_COMM_LEN 256
|
|
|
|
struct task_entry {
|
|
char comm[MAX_TASK_COMM_LEN];
|
|
pid_t pid;
|
|
struct io_stats io[UID_STATE_SIZE];
|
|
struct hlist_node hash;
|
|
};
|
|
|
|
struct uid_entry {
|
|
uid_t uid;
|
|
cputime_t utime;
|
|
cputime_t stime;
|
|
cputime_t active_utime;
|
|
cputime_t active_stime;
|
|
int state;
|
|
struct io_stats io[UID_STATE_SIZE];
|
|
struct hlist_node hash;
|
|
#ifdef CONFIG_UID_SYS_STATS_DEBUG
|
|
DECLARE_HASHTABLE(task_entries, UID_HASH_BITS);
|
|
#endif
|
|
};
|
|
|
|
static u64 compute_write_bytes(struct task_struct *task)
|
|
{
|
|
if (task->ioac.write_bytes <= task->ioac.cancelled_write_bytes)
|
|
return 0;
|
|
|
|
return task->ioac.write_bytes - task->ioac.cancelled_write_bytes;
|
|
}
|
|
|
|
static void compute_io_bucket_stats(struct io_stats *io_bucket,
|
|
struct io_stats *io_curr,
|
|
struct io_stats *io_last,
|
|
struct io_stats *io_dead)
|
|
{
|
|
/* tasks could switch to another uid group, but its io_last in the
|
|
* previous uid group could still be positive.
|
|
* therefore before each update, do an overflow check first
|
|
*/
|
|
int64_t delta;
|
|
|
|
delta = io_curr->read_bytes + io_dead->read_bytes -
|
|
io_last->read_bytes;
|
|
io_bucket->read_bytes += delta > 0 ? delta : 0;
|
|
delta = io_curr->write_bytes + io_dead->write_bytes -
|
|
io_last->write_bytes;
|
|
io_bucket->write_bytes += delta > 0 ? delta : 0;
|
|
delta = io_curr->rchar + io_dead->rchar - io_last->rchar;
|
|
io_bucket->rchar += delta > 0 ? delta : 0;
|
|
delta = io_curr->wchar + io_dead->wchar - io_last->wchar;
|
|
io_bucket->wchar += delta > 0 ? delta : 0;
|
|
delta = io_curr->fsync + io_dead->fsync - io_last->fsync;
|
|
io_bucket->fsync += delta > 0 ? delta : 0;
|
|
|
|
io_last->read_bytes = io_curr->read_bytes;
|
|
io_last->write_bytes = io_curr->write_bytes;
|
|
io_last->rchar = io_curr->rchar;
|
|
io_last->wchar = io_curr->wchar;
|
|
io_last->fsync = io_curr->fsync;
|
|
|
|
memset(io_dead, 0, sizeof(struct io_stats));
|
|
}
|
|
|
|
#ifdef CONFIG_UID_SYS_STATS_DEBUG
|
|
static void get_full_task_comm(struct task_entry *task_entry,
|
|
struct task_struct *task)
|
|
{
|
|
int i = 0, offset = 0, len = 0;
|
|
/* save one byte for terminating null character */
|
|
int unused_len = MAX_TASK_COMM_LEN - TASK_COMM_LEN - 1;
|
|
char buf[unused_len];
|
|
struct mm_struct *mm = task->mm;
|
|
|
|
/* fill the first TASK_COMM_LEN bytes with thread name */
|
|
get_task_comm(task_entry->comm, task);
|
|
i = strlen(task_entry->comm);
|
|
while (i < TASK_COMM_LEN)
|
|
task_entry->comm[i++] = ' ';
|
|
|
|
/* next the executable file name */
|
|
if (mm) {
|
|
down_read(&mm->mmap_sem);
|
|
if (mm->exe_file) {
|
|
char *pathname = d_path(&mm->exe_file->f_path, buf,
|
|
unused_len);
|
|
|
|
if (!IS_ERR(pathname)) {
|
|
len = strlcpy(task_entry->comm + i, pathname,
|
|
unused_len);
|
|
i += len;
|
|
task_entry->comm[i++] = ' ';
|
|
unused_len--;
|
|
}
|
|
}
|
|
up_read(&mm->mmap_sem);
|
|
}
|
|
unused_len -= len;
|
|
|
|
/* fill the rest with command line argument
|
|
* replace each null or new line character
|
|
* between args in argv with whitespace */
|
|
len = get_cmdline(task, buf, unused_len);
|
|
while (offset < len) {
|
|
if (buf[offset] != '\0' && buf[offset] != '\n')
|
|
task_entry->comm[i++] = buf[offset];
|
|
else
|
|
task_entry->comm[i++] = ' ';
|
|
offset++;
|
|
}
|
|
|
|
/* get rid of trailing whitespaces in case when arg is memset to
|
|
* zero before being reset in userspace
|
|
*/
|
|
while (task_entry->comm[i-1] == ' ')
|
|
i--;
|
|
task_entry->comm[i] = '\0';
|
|
}
|
|
|
|
static struct task_entry *find_task_entry(struct uid_entry *uid_entry,
|
|
struct task_struct *task)
|
|
{
|
|
struct task_entry *task_entry;
|
|
|
|
hash_for_each_possible(uid_entry->task_entries, task_entry, hash,
|
|
task->pid) {
|
|
if (task->pid == task_entry->pid) {
|
|
/* if thread name changed, update the entire command */
|
|
int len = strnchr(task_entry->comm, ' ', TASK_COMM_LEN)
|
|
- task_entry->comm;
|
|
|
|
if (strncmp(task_entry->comm, task->comm, len))
|
|
get_full_task_comm(task_entry, task);
|
|
return task_entry;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static struct task_entry *find_or_register_task(struct uid_entry *uid_entry,
|
|
struct task_struct *task)
|
|
{
|
|
struct task_entry *task_entry;
|
|
pid_t pid = task->pid;
|
|
|
|
task_entry = find_task_entry(uid_entry, task);
|
|
if (task_entry)
|
|
return task_entry;
|
|
|
|
task_entry = kzalloc(sizeof(struct task_entry), GFP_ATOMIC);
|
|
if (!task_entry)
|
|
return NULL;
|
|
|
|
get_full_task_comm(task_entry, task);
|
|
|
|
task_entry->pid = pid;
|
|
hash_add(uid_entry->task_entries, &task_entry->hash, (unsigned int)pid);
|
|
|
|
return task_entry;
|
|
}
|
|
|
|
static void remove_uid_tasks(struct uid_entry *uid_entry)
|
|
{
|
|
struct task_entry *task_entry;
|
|
unsigned long bkt_task;
|
|
struct hlist_node *tmp_task;
|
|
|
|
hash_for_each_safe(uid_entry->task_entries, bkt_task,
|
|
tmp_task, task_entry, hash) {
|
|
hash_del(&task_entry->hash);
|
|
kfree(task_entry);
|
|
}
|
|
}
|
|
|
|
static void set_io_uid_tasks_zero(struct uid_entry *uid_entry)
|
|
{
|
|
struct task_entry *task_entry;
|
|
unsigned long bkt_task;
|
|
|
|
hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) {
|
|
memset(&task_entry->io[UID_STATE_TOTAL_CURR], 0,
|
|
sizeof(struct io_stats));
|
|
}
|
|
}
|
|
|
|
static void add_uid_tasks_io_stats(struct uid_entry *uid_entry,
|
|
struct task_struct *task, int slot)
|
|
{
|
|
struct task_entry *task_entry = find_or_register_task(uid_entry, task);
|
|
struct io_stats *task_io_slot = &task_entry->io[slot];
|
|
|
|
task_io_slot->read_bytes += task->ioac.read_bytes;
|
|
task_io_slot->write_bytes += compute_write_bytes(task);
|
|
task_io_slot->rchar += task->ioac.rchar;
|
|
task_io_slot->wchar += task->ioac.wchar;
|
|
task_io_slot->fsync += task->ioac.syscfs;
|
|
}
|
|
|
|
static void compute_io_uid_tasks(struct uid_entry *uid_entry)
|
|
{
|
|
struct task_entry *task_entry;
|
|
unsigned long bkt_task;
|
|
|
|
hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) {
|
|
compute_io_bucket_stats(&task_entry->io[uid_entry->state],
|
|
&task_entry->io[UID_STATE_TOTAL_CURR],
|
|
&task_entry->io[UID_STATE_TOTAL_LAST],
|
|
&task_entry->io[UID_STATE_DEAD_TASKS]);
|
|
}
|
|
}
|
|
|
|
static void show_io_uid_tasks(struct seq_file *m, struct uid_entry *uid_entry)
|
|
{
|
|
struct task_entry *task_entry;
|
|
unsigned long bkt_task;
|
|
|
|
hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) {
|
|
/* Separated by comma because space exists in task comm */
|
|
seq_printf(m, "task,%s,%lu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n",
|
|
task_entry->comm,
|
|
(unsigned long)task_entry->pid,
|
|
task_entry->io[UID_STATE_FOREGROUND].rchar,
|
|
task_entry->io[UID_STATE_FOREGROUND].wchar,
|
|
task_entry->io[UID_STATE_FOREGROUND].read_bytes,
|
|
task_entry->io[UID_STATE_FOREGROUND].write_bytes,
|
|
task_entry->io[UID_STATE_BACKGROUND].rchar,
|
|
task_entry->io[UID_STATE_BACKGROUND].wchar,
|
|
task_entry->io[UID_STATE_BACKGROUND].read_bytes,
|
|
task_entry->io[UID_STATE_BACKGROUND].write_bytes,
|
|
task_entry->io[UID_STATE_FOREGROUND].fsync,
|
|
task_entry->io[UID_STATE_BACKGROUND].fsync);
|
|
}
|
|
}
|
|
#else
|
|
static void remove_uid_tasks(struct uid_entry *uid_entry) {};
|
|
static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) {};
|
|
static void add_uid_tasks_io_stats(struct uid_entry *uid_entry,
|
|
struct task_struct *task, int slot) {};
|
|
static void compute_io_uid_tasks(struct uid_entry *uid_entry) {};
|
|
static void show_io_uid_tasks(struct seq_file *m,
|
|
struct uid_entry *uid_entry) {}
|
|
#endif
|
|
|
|
static struct uid_entry *find_uid_entry(uid_t uid)
|
|
{
|
|
struct uid_entry *uid_entry;
|
|
hash_for_each_possible(hash_table, uid_entry, hash, uid) {
|
|
if (uid_entry->uid == uid)
|
|
return uid_entry;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static struct uid_entry *find_or_register_uid(uid_t uid)
|
|
{
|
|
struct uid_entry *uid_entry;
|
|
|
|
uid_entry = find_uid_entry(uid);
|
|
if (uid_entry)
|
|
return uid_entry;
|
|
|
|
uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC);
|
|
if (!uid_entry)
|
|
return NULL;
|
|
|
|
uid_entry->uid = uid;
|
|
#ifdef CONFIG_UID_SYS_STATS_DEBUG
|
|
hash_init(uid_entry->task_entries);
|
|
#endif
|
|
hash_add(hash_table, &uid_entry->hash, uid);
|
|
|
|
return uid_entry;
|
|
}
|
|
|
|
static int uid_cputime_show(struct seq_file *m, void *v)
|
|
{
|
|
struct uid_entry *uid_entry = NULL;
|
|
struct task_struct *task, *temp;
|
|
struct user_namespace *user_ns = current_user_ns();
|
|
cputime_t utime;
|
|
cputime_t stime;
|
|
unsigned long bkt;
|
|
uid_t uid;
|
|
|
|
rt_mutex_lock(&uid_lock);
|
|
|
|
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
|
uid_entry->active_stime = 0;
|
|
uid_entry->active_utime = 0;
|
|
}
|
|
|
|
rcu_read_lock();
|
|
do_each_thread(temp, task) {
|
|
uid = from_kuid_munged(user_ns, task_uid(task));
|
|
if (!uid_entry || uid_entry->uid != uid)
|
|
uid_entry = find_or_register_uid(uid);
|
|
if (!uid_entry) {
|
|
rcu_read_unlock();
|
|
rt_mutex_unlock(&uid_lock);
|
|
pr_err("%s: failed to find the uid_entry for uid %d\n",
|
|
__func__, uid);
|
|
return -ENOMEM;
|
|
}
|
|
task_cputime_adjusted(task, &utime, &stime);
|
|
uid_entry->active_utime += utime;
|
|
uid_entry->active_stime += stime;
|
|
} while_each_thread(temp, task);
|
|
rcu_read_unlock();
|
|
|
|
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
|
cputime_t total_utime = uid_entry->utime +
|
|
uid_entry->active_utime;
|
|
cputime_t total_stime = uid_entry->stime +
|
|
uid_entry->active_stime;
|
|
seq_printf(m, "%d: %llu %llu\n", uid_entry->uid,
|
|
(unsigned long long)jiffies_to_msecs(
|
|
cputime_to_jiffies(total_utime)) * USEC_PER_MSEC,
|
|
(unsigned long long)jiffies_to_msecs(
|
|
cputime_to_jiffies(total_stime)) * USEC_PER_MSEC);
|
|
}
|
|
|
|
rt_mutex_unlock(&uid_lock);
|
|
return 0;
|
|
}
|
|
|
|
static int uid_cputime_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, uid_cputime_show, PDE_DATA(inode));
|
|
}
|
|
|
|
static const struct file_operations uid_cputime_fops = {
|
|
.open = uid_cputime_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
static int uid_remove_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, NULL, NULL);
|
|
}
|
|
|
|
static ssize_t uid_remove_write(struct file *file,
|
|
const char __user *buffer, size_t count, loff_t *ppos)
|
|
{
|
|
struct uid_entry *uid_entry;
|
|
struct hlist_node *tmp;
|
|
char uids[128];
|
|
char *start_uid, *end_uid = NULL;
|
|
long int uid_start = 0, uid_end = 0;
|
|
|
|
if (count >= sizeof(uids))
|
|
count = sizeof(uids) - 1;
|
|
|
|
if (copy_from_user(uids, buffer, count))
|
|
return -EFAULT;
|
|
|
|
uids[count] = '\0';
|
|
end_uid = uids;
|
|
start_uid = strsep(&end_uid, "-");
|
|
|
|
if (!start_uid || !end_uid)
|
|
return -EINVAL;
|
|
|
|
if (kstrtol(start_uid, 10, &uid_start) != 0 ||
|
|
kstrtol(end_uid, 10, &uid_end) != 0) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Also remove uids from /proc/uid_time_in_state */
|
|
cpufreq_task_times_remove_uids(uid_start, uid_end);
|
|
|
|
rt_mutex_lock(&uid_lock);
|
|
|
|
for (; uid_start <= uid_end; uid_start++) {
|
|
hash_for_each_possible_safe(hash_table, uid_entry, tmp,
|
|
hash, (uid_t)uid_start) {
|
|
if (uid_start == uid_entry->uid) {
|
|
remove_uid_tasks(uid_entry);
|
|
hash_del(&uid_entry->hash);
|
|
kfree(uid_entry);
|
|
}
|
|
}
|
|
}
|
|
|
|
rt_mutex_unlock(&uid_lock);
|
|
return count;
|
|
}
|
|
|
|
static const struct file_operations uid_remove_fops = {
|
|
.open = uid_remove_open,
|
|
.release = single_release,
|
|
.write = uid_remove_write,
|
|
};
|
|
|
|
|
|
static void add_uid_io_stats(struct uid_entry *uid_entry,
|
|
struct task_struct *task, int slot)
|
|
{
|
|
struct io_stats *io_slot = &uid_entry->io[slot];
|
|
|
|
io_slot->read_bytes += task->ioac.read_bytes;
|
|
io_slot->write_bytes += compute_write_bytes(task);
|
|
io_slot->rchar += task->ioac.rchar;
|
|
io_slot->wchar += task->ioac.wchar;
|
|
io_slot->fsync += task->ioac.syscfs;
|
|
|
|
add_uid_tasks_io_stats(uid_entry, task, slot);
|
|
}
|
|
|
|
static void update_io_stats_all_locked(void)
|
|
{
|
|
struct uid_entry *uid_entry = NULL;
|
|
struct task_struct *task, *temp;
|
|
struct user_namespace *user_ns = current_user_ns();
|
|
unsigned long bkt;
|
|
uid_t uid;
|
|
|
|
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
|
memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
|
|
sizeof(struct io_stats));
|
|
set_io_uid_tasks_zero(uid_entry);
|
|
}
|
|
|
|
rcu_read_lock();
|
|
do_each_thread(temp, task) {
|
|
uid = from_kuid_munged(user_ns, task_uid(task));
|
|
if (!uid_entry || uid_entry->uid != uid)
|
|
uid_entry = find_or_register_uid(uid);
|
|
if (!uid_entry)
|
|
continue;
|
|
add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR);
|
|
} while_each_thread(temp, task);
|
|
rcu_read_unlock();
|
|
|
|
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
|
compute_io_bucket_stats(&uid_entry->io[uid_entry->state],
|
|
&uid_entry->io[UID_STATE_TOTAL_CURR],
|
|
&uid_entry->io[UID_STATE_TOTAL_LAST],
|
|
&uid_entry->io[UID_STATE_DEAD_TASKS]);
|
|
compute_io_uid_tasks(uid_entry);
|
|
}
|
|
}
|
|
|
|
static void update_io_stats_uid_locked(struct uid_entry *uid_entry)
|
|
{
|
|
struct task_struct *task, *temp;
|
|
struct user_namespace *user_ns = current_user_ns();
|
|
|
|
memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0,
|
|
sizeof(struct io_stats));
|
|
set_io_uid_tasks_zero(uid_entry);
|
|
|
|
rcu_read_lock();
|
|
do_each_thread(temp, task) {
|
|
if (from_kuid_munged(user_ns, task_uid(task)) != uid_entry->uid)
|
|
continue;
|
|
add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR);
|
|
} while_each_thread(temp, task);
|
|
rcu_read_unlock();
|
|
|
|
compute_io_bucket_stats(&uid_entry->io[uid_entry->state],
|
|
&uid_entry->io[UID_STATE_TOTAL_CURR],
|
|
&uid_entry->io[UID_STATE_TOTAL_LAST],
|
|
&uid_entry->io[UID_STATE_DEAD_TASKS]);
|
|
compute_io_uid_tasks(uid_entry);
|
|
}
|
|
|
|
|
|
static int uid_io_show(struct seq_file *m, void *v)
|
|
{
|
|
struct uid_entry *uid_entry;
|
|
unsigned long bkt;
|
|
|
|
rt_mutex_lock(&uid_lock);
|
|
|
|
update_io_stats_all_locked();
|
|
|
|
hash_for_each(hash_table, bkt, uid_entry, hash) {
|
|
seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
|
|
uid_entry->uid,
|
|
uid_entry->io[UID_STATE_FOREGROUND].rchar,
|
|
uid_entry->io[UID_STATE_FOREGROUND].wchar,
|
|
uid_entry->io[UID_STATE_FOREGROUND].read_bytes,
|
|
uid_entry->io[UID_STATE_FOREGROUND].write_bytes,
|
|
uid_entry->io[UID_STATE_BACKGROUND].rchar,
|
|
uid_entry->io[UID_STATE_BACKGROUND].wchar,
|
|
uid_entry->io[UID_STATE_BACKGROUND].read_bytes,
|
|
uid_entry->io[UID_STATE_BACKGROUND].write_bytes,
|
|
uid_entry->io[UID_STATE_FOREGROUND].fsync,
|
|
uid_entry->io[UID_STATE_BACKGROUND].fsync);
|
|
|
|
show_io_uid_tasks(m, uid_entry);
|
|
}
|
|
|
|
rt_mutex_unlock(&uid_lock);
|
|
return 0;
|
|
}
|
|
|
|
static int uid_io_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, uid_io_show, PDE_DATA(inode));
|
|
}
|
|
|
|
static const struct file_operations uid_io_fops = {
|
|
.open = uid_io_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = single_release,
|
|
};
|
|
|
|
static int uid_procstat_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, NULL, NULL);
|
|
}
|
|
|
|
static ssize_t uid_procstat_write(struct file *file,
|
|
const char __user *buffer, size_t count, loff_t *ppos)
|
|
{
|
|
struct uid_entry *uid_entry;
|
|
uid_t uid;
|
|
int argc, state;
|
|
char input[128];
|
|
|
|
if (count >= sizeof(input))
|
|
return -EINVAL;
|
|
|
|
if (copy_from_user(input, buffer, count))
|
|
return -EFAULT;
|
|
|
|
input[count] = '\0';
|
|
|
|
argc = sscanf(input, "%u %d", &uid, &state);
|
|
if (argc != 2)
|
|
return -EINVAL;
|
|
|
|
if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND)
|
|
return -EINVAL;
|
|
|
|
rt_mutex_lock(&uid_lock);
|
|
|
|
uid_entry = find_or_register_uid(uid);
|
|
if (!uid_entry) {
|
|
rt_mutex_unlock(&uid_lock);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (uid_entry->state == state) {
|
|
rt_mutex_unlock(&uid_lock);
|
|
return count;
|
|
}
|
|
|
|
update_io_stats_uid_locked(uid_entry);
|
|
|
|
uid_entry->state = state;
|
|
|
|
rt_mutex_unlock(&uid_lock);
|
|
|
|
return count;
|
|
}
|
|
|
|
static const struct file_operations uid_procstat_fops = {
|
|
.open = uid_procstat_open,
|
|
.release = single_release,
|
|
.write = uid_procstat_write,
|
|
};
|
|
|
|
static int process_notifier(struct notifier_block *self,
|
|
unsigned long cmd, void *v)
|
|
{
|
|
struct task_struct *task = v;
|
|
struct uid_entry *uid_entry;
|
|
cputime_t utime, stime;
|
|
uid_t uid;
|
|
|
|
if (!task)
|
|
return NOTIFY_OK;
|
|
|
|
rt_mutex_lock(&uid_lock);
|
|
uid = from_kuid_munged(current_user_ns(), task_uid(task));
|
|
uid_entry = find_or_register_uid(uid);
|
|
if (!uid_entry) {
|
|
pr_err("%s: failed to find uid %d\n", __func__, uid);
|
|
goto exit;
|
|
}
|
|
|
|
task_cputime_adjusted(task, &utime, &stime);
|
|
uid_entry->utime += utime;
|
|
uid_entry->stime += stime;
|
|
|
|
add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS);
|
|
|
|
exit:
|
|
rt_mutex_unlock(&uid_lock);
|
|
return NOTIFY_OK;
|
|
}
|
|
|
|
static struct notifier_block process_notifier_block = {
|
|
.notifier_call = process_notifier,
|
|
};
|
|
|
|
static int __init proc_uid_sys_stats_init(void)
|
|
{
|
|
hash_init(hash_table);
|
|
|
|
cpu_parent = proc_mkdir("uid_cputime", NULL);
|
|
if (!cpu_parent) {
|
|
pr_err("%s: failed to create uid_cputime proc entry\n",
|
|
__func__);
|
|
goto err;
|
|
}
|
|
|
|
proc_create_data("remove_uid_range", 0222, cpu_parent,
|
|
&uid_remove_fops, NULL);
|
|
proc_create_data("show_uid_stat", 0444, cpu_parent,
|
|
&uid_cputime_fops, NULL);
|
|
|
|
io_parent = proc_mkdir("uid_io", NULL);
|
|
if (!io_parent) {
|
|
pr_err("%s: failed to create uid_io proc entry\n",
|
|
__func__);
|
|
goto err;
|
|
}
|
|
|
|
proc_create_data("stats", 0444, io_parent,
|
|
&uid_io_fops, NULL);
|
|
|
|
proc_parent = proc_mkdir("uid_procstat", NULL);
|
|
if (!proc_parent) {
|
|
pr_err("%s: failed to create uid_procstat proc entry\n",
|
|
__func__);
|
|
goto err;
|
|
}
|
|
|
|
proc_create_data("set", 0222, proc_parent,
|
|
&uid_procstat_fops, NULL);
|
|
|
|
profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
|
|
|
|
return 0;
|
|
|
|
err:
|
|
remove_proc_subtree("uid_cputime", NULL);
|
|
remove_proc_subtree("uid_io", NULL);
|
|
remove_proc_subtree("uid_procstat", NULL);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
early_initcall(proc_uid_sys_stats_init);
|