The following commit has been merged in the master branch: commit 43d6583c3da67343934eefa1476d752512a8c7e5 Merge: 669b9cac9cd06cddaff8ffa40b5a4da0935d6afe 7c4a6309e27f411743817fe74a832ec2d2798a4b Author: Stephen Rothwell sfr@canb.auug.org.au Date: Wed Dec 14 10:07:13 2022 +1100
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
# Conflicts: # tools/perf/util/stat.c
diff --combined MAINTAINERS index a8b2be4aef72,77aa03cebd02..0e4288d0767f --- a/MAINTAINERS +++ b/MAINTAINERS @@@ -775,24 -775,6 +775,24 @@@ T: git git://linuxtv.org/media_tree.gi F: Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml F: drivers/media/platform/sunxi/sun4i-csi/
+ALLWINNER A31 CSI DRIVER +M: Yong Deng yong.deng@magewell.com +M: Paul Kocialkowski paul.kocialkowski@bootlin.com +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml +F: drivers/media/platform/sunxi/sun6i-csi/ + +ALLWINNER A31 ISP DRIVER +M: Paul Kocialkowski paul.kocialkowski@bootlin.com +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-isp.yaml +F: drivers/staging/media/sunxi/sun6i-isp/ +F: drivers/staging/media/sunxi/sun6i-isp/uapi/sun6i-isp-config.h + ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER M: Paul Kocialkowski paul.kocialkowski@bootlin.com L: linux-media@vger.kernel.org @@@ -1111,16 -1093,6 +1111,16 @@@ S: Maintaine F: Documentation/hid/amd-sfh* F: drivers/hid/amd-sfh-hid/
+AMLOGIC DDR PMU DRIVER +M: Jiucheng Xu jiucheng.xu@amlogic.com +L: linux-amlogic@lists.infradead.org +S: Supported +W: http://www.amlogic.com +F: Documentation/admin-guide/perf/meson-ddr-pmu.rst +F: Documentation/devicetree/bindings/perf/amlogic,g12-ddr-pmu.yaml +F: drivers/perf/amlogic/ +F: include/soc/amlogic/ + AMPHION VPU CODEC V4L2 DRIVER M: Ming Qian ming.qian@nxp.com M: Shijie Qin shijie.qin@nxp.com @@@ -1713,7 -1685,7 +1713,7 @@@ M: Miquel Raynal <miquel.raynal@bootlin M: Naga Sureshkumar Relli nagasure@xilinx.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml +F: Documentation/devicetree/bindings/memory-controllers/arm,pl35x-smc.yaml F: drivers/memory/pl353-smc.c
ARM PRIMECELL CLCD PL110 DRIVER @@@ -1925,13 -1897,13 +1925,14 @@@ T: git https://github.com/AsahiLinux/li F: Documentation/devicetree/bindings/arm/apple.yaml F: Documentation/devicetree/bindings/arm/apple/* F: Documentation/devicetree/bindings/clock/apple,nco.yaml +F: Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml F: Documentation/devicetree/bindings/dma/apple,admac.yaml F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,* F: Documentation/devicetree/bindings/iommu/apple,dart.yaml F: Documentation/devicetree/bindings/iommu/apple,sart.yaml F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml + F: Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.yaml F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml F: Documentation/devicetree/bindings/pci/apple,pcie.yaml @@@ -1939,8 -1911,8 +1940,9 @@@ F: Documentation/devicetree/bindings/pi F: Documentation/devicetree/bindings/power/apple* F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml F: arch/arm64/boot/dts/apple/ + F: drivers/bluetooth/hci_bcm4377.c F: drivers/clk/clk-apple-nco.c +F: drivers/cpufreq/apple-soc-cpufreq.c F: drivers/dma/apple-admac.c F: drivers/i2c/busses/i2c-pasemi-core.c F: drivers/i2c/busses/i2c-pasemi-platform.c @@@ -2302,6 -2274,8 +2304,6 @@@ F: drivers/clocksource/timer-ixp4xx. F: drivers/crypto/ixp4xx_crypto.c F: drivers/gpio/gpio-ixp4xx.c F: drivers/irqchip/irq-ixp4xx.c -F: include/linux/irqchip/irq-ixp4xx.h -F: include/linux/platform_data/timer-ixp4xx.h
ARM/INTEL KEEMBAY ARCHITECTURE M: Paul J. Murphy paul.j.murphy@intel.com @@@ -2369,8 -2343,6 +2371,8 @@@ M: Gregory Clement <gregory.clement@boo L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git +F: Documentation/devicetree/bindings/arm/marvell/marvell,dove.txt +F: Documentation/devicetree/bindings/arm/marvell/marvell,orion5x.txt F: Documentation/devicetree/bindings/soc/dove/ F: arch/arm/boot/dts/dove* F: arch/arm/boot/dts/orion5x* @@@ -2387,7 -2359,6 +2389,7 @@@ M: Sebastian Hesselbarth <sebastian.hes L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git +F: Documentation/devicetree/bindings/arm/marvell/ F: arch/arm/boot/dts/armada* F: arch/arm/boot/dts/kirkwood* F: arch/arm/configs/mvebu_*_defconfig @@@ -2470,6 -2441,7 +2472,7 @@@ L: linux-arm-kernel@lists.infradead.or S: Supported T: git git://github.com/microchip-ung/linux-upstream.git F: arch/arm64/boot/dts/microchip/ + F: drivers/net/ethernet/microchip/vcap/ F: drivers/pinctrl/pinctrl-microchip-sgpio.c N: sparx5
@@@ -2574,7 -2546,6 +2577,7 @@@ S: Maintaine W: https://github.com/neuschaefer/wpcm450/wiki F: Documentation/devicetree/bindings/*/*wpcm* F: arch/arm/boot/dts/nuvoton-wpcm450* +F: arch/arm/configs/wpcm450_defconfig F: arch/arm/mach-npcm/wpcm450.c F: drivers/*/*/*wpcm* F: drivers/*/*wpcm* @@@ -2652,7 -2623,7 +2655,7 @@@ W: http://www.armlinux.org.uk ARM/QUALCOMM SUPPORT M: Andy Gross agross@kernel.org M: Bjorn Andersson andersson@kernel.org -R: Konrad Dybcio konrad.dybcio@somainline.org +R: Konrad Dybcio konrad.dybcio@linaro.org L: linux-arm-msm@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git @@@ -2723,7 -2694,7 +2726,7 @@@ F: arch/arm/boot/dts/rtd F: arch/arm/mach-realtek/ F: arch/arm64/boot/dts/realtek/
-ARM/RENESAS ARCHITECTURE +ARM/RISC-V/RENESAS ARCHITECTURE M: Geert Uytterhoeven geert+renesas@glider.be M: Magnus Damm magnus.damm@gmail.com L: linux-renesas-soc@vger.kernel.org @@@ -2731,6 -2702,7 +2734,6 @@@ S: Supporte Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/ C: irc://irc.libera.chat/renesas-soc T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next -F: Documentation/devicetree/bindings/arm/renesas.yaml F: Documentation/devicetree/bindings/hwinfo/renesas,prr.yaml F: Documentation/devicetree/bindings/soc/renesas/ F: arch/arm/boot/dts/emev2* @@@ -2744,7 -2716,6 +2747,7 @@@ F: arch/arm/configs/shmobile_defconfi F: arch/arm/include/debug/renesas-scif.S F: arch/arm/mach-shmobile/ F: arch/arm64/boot/dts/renesas/ +F: arch/riscv/boot/dts/renesas/ F: drivers/soc/renesas/ F: include/linux/soc/renesas/
@@@ -4973,12 -4944,6 +4976,12 @@@ S: Maintaine F: drivers/platform/chrome/cros_usbpd_notify.c F: include/linux/platform_data/cros_usbpd_notify.h
+CHROMEOS HPS DRIVER +M: Dan Callaghan dcallagh@chromium.org +R: Sami Ky��stil�� skyostil@chromium.org +S: Maintained +F: drivers/platform/chrome/cros_hps_i2c.c + CHRONTEL CH7322 CEC DRIVER M: Joe Tessler jrt@google.com L: linux-media@vger.kernel.org @@@ -5337,7 -5302,7 +5340,7 @@@ M: Johannes Weiner <hannes@cmpxchg.org M: Michal Hocko mhocko@kernel.org M: Roman Gushchin roman.gushchin@linux.dev M: Shakeel Butt shakeelb@google.com -R: Muchun Song songmuchun@bytedance.com +R: Muchun Song muchun.song@linux.dev L: cgroups@vger.kernel.org L: linux-mm@kvack.org S: Maintained @@@ -5540,6 -5505,14 +5543,6 @@@ M: Jaya Kumar <jayakumar.alsa@gmail.com S: Maintained F: sound/pci/cs5535audio/
-CSI DRIVERS FOR ALLWINNER V3s -M: Yong Deng yong.deng@magewell.com -L: linux-media@vger.kernel.org -S: Maintained -T: git git://linuxtv.org/media_tree.git -F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml -F: drivers/media/platform/sunxi/sun6i-csi/ - CTU CAN FD DRIVER M: Pavel Pisa pisa@cmp.felk.cvut.cz M: Ondrej Ille ondrej.ille@gmail.com @@@ -5884,13 -5857,6 +5887,13 @@@ L: Dell.Client.Kernel@dell.co S: Maintained F: drivers/platform/x86/dell/dell-wmi-descriptor.c
+DELL WMI DDV DRIVER +M: Armin Wolf W_Armin@gmx.de +S: Maintained +F: Documentation/ABI/testing/debugfs-dell-wmi-ddv +F: Documentation/ABI/testing/sysfs-platform-dell-wmi-ddv +F: drivers/platform/x86/dell/dell-wmi-ddv.c + DELL WMI SYSMAN DRIVER M: Divya Bharathi divya.bharathi@dell.com M: Prasanth Ksr prasanth.ksr@dell.com @@@ -6066,12 -6032,11 +6069,12 @@@ F: include/net/devlink. F: include/uapi/linux/devlink.h F: net/core/devlink.c
-DH ELECTRONICS IMX6 DHCOM BOARD SUPPORT +DH ELECTRONICS IMX6 DHCOM/DHCOR BOARD SUPPORT M: Christoph Niedermaier cniedermaier@dh-electronics.com L: kernel@dh-electronics.com S: Maintained F: arch/arm/boot/dts/imx6*-dhcom-* +F: arch/arm/boot/dts/imx6*-dhcor-*
DH ELECTRONICS STM32MP1 DHCOM/DHCOR BOARD SUPPORT M: Marek Vasut marex@denx.de @@@ -6363,6 -6328,7 +6366,7 @@@ F: drivers/net/ethernet/freescale/dpaa2 F: drivers/net/ethernet/freescale/dpaa2/Makefile F: drivers/net/ethernet/freescale/dpaa2/dpaa2-eth* F: drivers/net/ethernet/freescale/dpaa2/dpaa2-mac* + F: drivers/net/ethernet/freescale/dpaa2/dpaa2-xsk* F: drivers/net/ethernet/freescale/dpaa2/dpkg.h F: drivers/net/ethernet/freescale/dpaa2/dpmac* F: drivers/net/ethernet/freescale/dpaa2/dpni* @@@ -6540,12 -6506,6 +6544,12 @@@ S: Orphan / Obsolet F: drivers/gpu/drm/i810/ F: include/uapi/drm/i810_drm.h
+DRM DRIVER FOR JADARD JD9365DA-H3 MIPI-DSI LCD PANELS +M: Jagan Teki jagan@edgeble.ai +S: Maintained +F: Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml +F: drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c + DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER M: Paul Kocialkowski paul.kocialkowski@bootlin.com S: Supported @@@ -6735,13 -6695,10 +6739,13 @@@ L: dri-devel@lists.freedesktop.or S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc F: drivers/gpu/drm/drm_aperture.c +F: drivers/gpu/drm/tiny/ofdrm.c F: drivers/gpu/drm/tiny/simpledrm.c F: drivers/video/aperture.c +F: drivers/video/nomodeset.c F: include/drm/drm_aperture.h F: include/linux/aperture.h +F: include/video/nomodeset.h
DRM DRIVER FOR SIS VIDEO CARDS S: Orphan / Obsolete @@@ -6870,15 -6827,6 +6874,15 @@@ F: include/drm/drm F: include/linux/vga* F: include/uapi/drm/drm*
+DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK +M: Oded Gabbay ogabbay@kernel.org +L: dri-devel@lists.freedesktop.org +S: Maintained +C: irc://irc.oftc.net/dri-devel +T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git +F: Documentation/accel/ +F: drivers/accel/ + DRM DRIVERS FOR ALLWINNER A10 M: Maxime Ripard mripard@kernel.org M: Chen-Yu Tsai wens@csie.org @@@ -7167,7 -7115,7 +7171,7 @@@ F: drivers/gpu/drm/ttm F: include/drm/ttm/
DRM GPU SCHEDULER -M: Andrey Grodzovsky andrey.grodzovsky@amd.com +M: Luben Tuikov luben.tuikov@amd.com L: dri-devel@lists.freedesktop.org S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc @@@ -7415,9 -7363,9 +7419,9 @@@ F: drivers/edac/thunderx_edac
EDAC-CORE M: Borislav Petkov bp@alien8.de -M: Mauro Carvalho Chehab mchehab@kernel.org M: Tony Luck tony.luck@intel.com R: James Morse james.morse@arm.com +R: Mauro Carvalho Chehab mchehab@kernel.org R: Robert Richter rric@kernel.org L: linux-edac@vger.kernel.org S: Supported @@@ -7534,7 -7482,8 +7538,7 @@@ S: Maintaine F: drivers/edac/pnd2_edac.[ch]
EDAC-QCOM -M: Channagoud Kadabi ckadabi@codeaurora.org -M: Venkata Narendra Kumar Gutta vnkgutta@codeaurora.org +M: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org L: linux-arm-msm@vger.kernel.org L: linux-edac@vger.kernel.org S: Maintained @@@ -7735,6 -7684,7 +7739,7 @@@ ETAS ES58X CAN/USB DRIVE M: Vincent Mailhol mailhol.vincent@wanadoo.fr L: linux-can@vger.kernel.org S: Maintained + F: Documentation/networking/devlink/etas_es58x.rst F: drivers/net/can/usb/etas_es58x/
ETHERNET BRIDGE @@@ -7886,7 -7836,6 +7891,7 @@@ M: Chao Yu <chao@kernel.org L: linux-f2fs-devel@lists.sourceforge.net S: Maintained W: https://f2fs.wiki.kernel.org/ +B: https://bugzilla.kernel.org/enter_bug.cgi?product=File%20System&componen... T: git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git F: Documentation/ABI/testing/sysfs-fs-f2fs F: Documentation/filesystems/f2fs.rst @@@ -9152,12 -9101,9 +9157,12 @@@ M: Benjamin Tissoires <benjamin.tissoir L: linux-input@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git +F: Documentation/hid/ F: drivers/hid/ F: include/linux/hid* F: include/uapi/linux/hid* +F: samples/hid/ +F: tools/testing/selftests/hid/
HID LOGITECH DRIVERS R: Filipe La��ns lains@riseup.net @@@ -9227,13 -9173,6 +9232,13 @@@ W: http://www.highpoint-tech.co F: Documentation/scsi/hptiop.rst F: drivers/scsi/hptiop.c
+HIMAX HX83112B TOUCHSCREEN SUPPORT +M: Job Noorman job@noorman.info +L: linux-input@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml +F: drivers/input/touchscreen/himax_hx83112b.c + HIPPI M: Jes Sorensen jes@trained-monkey.org L: linux-hippi@sunsite.dk @@@ -9279,7 -9218,6 +9284,7 @@@ M: Yicong Yang <yangyicong@hisilicon.co L: linux-i2c@vger.kernel.org S: Maintained W: https://www.hisilicon.com +F: Documentation/devicetree/bindings/i2c/hisilicon,ascend910-i2c.yaml F: drivers/i2c/busses/i2c-hisi.c
HISILICON LPC BUS DRIVER @@@ -9314,7 -9252,7 +9319,7 @@@ F: drivers/misc/hisi_hikey_usb.
HISILICON PMU DRIVER M: Shaokun Zhang zhangshaokun@hisilicon.com -M: Qi Liu liuqi115@huawei.com +M: Jonathan Cameron jonathan.cameron@huawei.com S: Supported W: http://www.hisilicon.com F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst @@@ -9432,7 -9370,7 +9437,7 @@@ F: drivers/net/wireless/intersil/hostap HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER L: platform-driver-x86@vger.kernel.org S: Orphan -F: drivers/platform/x86/tc1100-wmi.c +F: drivers/platform/x86/hp/tc1100-wmi.c
HPET: High Precision Event Timers driver M: Clemens Ladisch clemens@ladisch.de @@@ -9502,14 -9440,15 +9507,15 @@@ F: Documentation/devicetree/bindings/ii F: drivers/iio/humidity/hts221*
HUAWEI ETHERNET DRIVER + M: Cai Huoqing cai.huoqing@linux.dev L: netdev@vger.kernel.org - S: Orphan + S: Maintained F: Documentation/networking/device_drivers/ethernet/huawei/hinic.rst F: drivers/net/ethernet/huawei/hinic/
HUGETLB SUBSYSTEM M: Mike Kravetz mike.kravetz@oracle.com -M: Muchun Song songmuchun@bytedance.com +M: Muchun Song muchun.song@linux.dev L: linux-mm@kvack.org S: Maintained F: Documentation/ABI/testing/sysfs-kernel-mm-hugepages @@@ -9770,7 -9709,8 +9776,7 @@@ F: Documentation/devicetree/bindings/i3 F: drivers/i3c/master/i3c-master-cdns.c
I3C DRIVER FOR SYNOPSYS DESIGNWARE -M: Vitor Soares vitor.soares@synopsys.com -S: Maintained +S: Orphan F: Documentation/devicetree/bindings/i3c/snps,dw-i3c-master.yaml F: drivers/i3c/master/dw*
@@@ -10092,11 -10032,6 +10098,11 @@@ F: Documentation/hwmon/ina2xx.rs F: drivers/hwmon/ina2xx.c F: include/linux/platform_data/ina2xx.h
+INDEX OF FURTHER KERNEL DOCUMENTATION +M: Carlos Bilbao carlos.bilbao@amd.com +S: Maintained +F: Documentation/process/kernel-docs.rst + INDUSTRY PACK SUBSYSTEM (IPACK) M: Samuel Iglesias Gonsalvez siglesias@igalia.com M: Jens Taprogge jens.taprogge@taprogge.org @@@ -10126,7 -10061,6 +10132,7 @@@ F: drivers/infiniband F: include/rdma/ F: include/trace/events/ib_mad.h F: include/trace/events/ib_umad.h +F: include/trace/misc/rdma.h F: include/uapi/linux/if_infiniband.h F: include/uapi/rdma/ F: samples/bpf/ibumad_kern.c @@@ -10300,7 -10234,6 +10306,7 @@@ Q: http://patchwork.freedesktop.org/pro B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs C: irc://irc.oftc.net/intel-gfx T: git git://anongit.freedesktop.org/drm-intel +F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon F: Documentation/gpu/i915.rst F: drivers/gpu/drm/i915/ F: include/drm/i915* @@@ -10971,13 -10904,6 +10977,13 @@@ F: drivers/isdn/Makefil F: drivers/isdn/hardware/ F: drivers/isdn/mISDN/
+ISOFS FILESYSTEM +M: Jan Kara jack@suse.cz +L: linux-fsdevel@vger.kernel.org +S: Maintained +F: Documentation/filesystems/isofs.rst +F: fs/isofs/ + IT87 HARDWARE MONITORING DRIVER M: Jean Delvare jdelvare@suse.com L: linux-hwmon@vger.kernel.org @@@ -11039,9 -10965,9 +11045,9 @@@ F: drivers/hwmon/jc42. JFS FILESYSTEM M: Dave Kleikamp shaggy@kernel.org L: jfs-discussion@lists.sourceforge.net -S: Maintained +S: Odd Fixes W: http://jfs.sourceforge.net/ -T: git git://github.com/kleikamp/linux-shaggy.git +T: git https://github.com/kleikamp/linux-shaggy.git F: Documentation/admin-guide/jfs.rst F: fs/jfs/
@@@ -11214,18 -11140,11 +11220,18 @@@ L: linux-nfs@vger.kernel.or S: Supported W: http://nfs.sourceforge.net/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git +F: fs/exportfs/ F: fs/lockd/ F: fs/nfs_common/ F: fs/nfsd/ F: include/linux/lockd/ F: include/linux/sunrpc/ +F: include/trace/events/rpcgss.h +F: include/trace/events/rpcrdma.h +F: include/trace/events/sunrpc.h +F: include/trace/misc/fs.h +F: include/trace/misc/nfs.h +F: include/trace/misc/sunrpc.h F: include/uapi/linux/nfsd/ F: include/uapi/linux/sunrpc/ F: net/sunrpc/ @@@ -11947,7 -11866,7 +11953,7 @@@ M: Eric Piel <eric.piel@tremplin-utc.ne S: Maintained F: Documentation/misc-devices/lis3lv02d.rst F: drivers/misc/lis3lv02d/ -F: drivers/platform/x86/hp_accel.c +F: drivers/platform/x86/hp/hp_accel.c
LIST KUNIT TEST M: David Gow davidgow@google.com @@@ -12102,13 -12021,6 +12108,13 @@@ F: drivers/*/*loongarch F: Documentation/loongarch/ F: Documentation/translations/zh_CN/loongarch/
+LOONGSON-2 SOC SERIES GUTS DRIVER +M: Yinbo Zhu zhuyinbo@loongson.cn +L: loongarch@lists.linux.dev +S: Maintained +F: Documentation/devicetree/bindings/hwinfo/loongson,ls2k-chipid.yaml +F: drivers/soc/loongson/loongson2_guts.c + LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) M: Sathya Prakash sathya.prakash@broadcom.com M: Sreekanth Reddy sreekanth.reddy@broadcom.com @@@ -12186,7 -12098,7 +12192,7 @@@ M: Alexey Kodanev <alexey.kodanev@oracl L: ltp@lists.linux.it (subscribers-only) S: Maintained W: http://linux-test-project.github.io/ -T: git git://github.com/linux-test-project/ltp.git +T: git https://github.com/linux-test-project/ltp.git
LYNX 28G SERDES PHY DRIVER M: Ioana Ciornei ioana.ciornei@nxp.com @@@ -12411,7 -12323,7 +12417,7 @@@ M: Marcin Wojtas <mw@semihalf.com M: Russell King linux@armlinux.org.uk L: netdev@vger.kernel.org S: Maintained - F: Documentation/devicetree/bindings/net/marvell-pp2.txt + F: Documentation/devicetree/bindings/net/marvell,pp2.yaml F: drivers/net/ethernet/marvell/mvpp2/
MARVELL MWIFIEX WIRELESS DRIVER @@@ -12459,7 -12371,7 +12465,7 @@@ F: Documentation/networking/device_driv F: drivers/net/ethernet/marvell/octeontx2/af/
MARVELL PRESTERA ETHERNET SWITCH DRIVER - M: Taras Chornyi tchornyi@marvell.com + M: Taras Chornyi taras.chornyi@plvision.eu S: Supported W: https://github.com/Marvell-switching/switchdev-prestera F: drivers/net/ethernet/marvell/prestera/ @@@ -12821,7 -12733,7 +12827,7 @@@ F: Documentation/admin-guide/media/imx7 F: Documentation/devicetree/bindings/media/nxp,imx-mipi-csi2.yaml F: Documentation/devicetree/bindings/media/nxp,imx7-csi.yaml F: drivers/media/platform/nxp/imx-mipi-csis.c -F: drivers/staging/media/imx/imx7-media-csi.c +F: drivers/media/platform/nxp/imx7-media-csi.c
MEDIA DRIVERS FOR HELENE M: Abylay Ospan aospan@netup.ru @@@ -13018,6 -12930,7 +13024,7 @@@ M: Felix Fietkau <nbd@nbd.name M: John Crispin john@phrozen.org M: Sean Wang sean.wang@mediatek.com M: Mark Lee Mark-MC.Lee@mediatek.com + M: Lorenzo Bianconi lorenzo@kernel.org L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/mediatek/ @@@ -13561,7 -13474,7 +13568,7 @@@ M: Eugen Hristev <eugen.hristev@microch L: linux-media@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml -F: drivers/media/platform/atmel/microchip-csi2dc.c +F: drivers/media/platform/microchip/microchip-csi2dc.c
MICROCHIP ECC DRIVER M: Tudor Ambarus tudor.ambarus@microchip.com @@@ -13588,10 -13501,8 +13595,10 @@@ L: linux-media@vger.kernel.or S: Supported F: Documentation/devicetree/bindings/media/atmel,isc.yaml F: Documentation/devicetree/bindings/media/microchip,xisc.yaml -F: drivers/media/platform/atmel/atmel-isc* -F: drivers/media/platform/atmel/atmel-sama*-isc* +F: drivers/staging/media/deprecated/atmel/atmel-isc* +F: drivers/staging/media/deprecated/atmel/atmel-sama*-isc* +F: drivers/media/platform/microchip/microchip-isc* +F: drivers/media/platform/microchip/microchip-sama*-isc* F: include/linux/atmel-isc-media.h
MICROCHIP ISI DRIVER @@@ -13774,15 -13685,6 +13781,15 @@@ F: drivers/scsi/smartpqi/smartpqi*.[ch F: include/linux/cciss*.h F: include/uapi/linux/cciss*.h
+MICROSOFT MANA RDMA DRIVER +M: Long Li longli@microsoft.com +M: Ajay Sharma sharmaajay@microsoft.com +L: linux-rdma@vger.kernel.org +S: Supported +F: drivers/infiniband/hw/mana/ +F: include/net/mana +F: include/uapi/rdma/mana-abi.h + MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH M: Maximilian Luz luzmaximilian@gmail.com L: platform-driver-x86@vger.kernel.org @@@ -14058,6 -13960,7 +14065,7 @@@ F: include/uapi/linux/meye.
MOTORCOMM PHY DRIVER M: Peter Geis pgwipeout@gmail.com + M: Frank Frank.Sae@motor-comm.com L: netdev@vger.kernel.org S: Maintained F: drivers/net/phy/motorcomm.c @@@ -15292,13 -15195,6 +15300,13 @@@ S: Maintaine T: git git://linuxtv.org/media_tree.git F: drivers/media/i2c/ov08d10.c
+OMNIVISION OV08X40 SENSOR DRIVER +M: Jason Chen jason.z.chen@intel.com +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: drivers/media/i2c/ov08x40.c + OMNIVISION OV13858 SENSOR DRIVER M: Sakari Ailus sakari.ailus@linux.intel.com L: linux-media@vger.kernel.org @@@ -15337,14 -15233,6 +15345,14 @@@ S: Maintaine T: git git://linuxtv.org/media_tree.git F: drivers/media/i2c/ov2740.c
+OMNIVISION OV4689 SENSOR DRIVER +M: Mikhail Rudenko mike.rudenko@gmail.com +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/ovti,ov4689.yaml +F: drivers/media/i2c/ov5647.c + OMNIVISION OV5640 SENSOR DRIVER M: Steve Longerbeam slongerbeam@gmail.com L: linux-media@vger.kernel.org @@@ -15469,12 -15357,6 +15477,12 @@@ S: Maintaine F: drivers/mtd/nand/onenand/ F: include/linux/mtd/onenand*.h
+ONEXPLAYER FAN DRIVER +M: Joaqu��n Ignacio Aramend��a samsagax@gmail.com +L: linux-hwmon@vger.kernel.org +S: Maintained +F: drivers/hwmon/oxp-sensors.c + ONION OMEGA2+ BOARD M: Harvey Hunt harveyhuntnexus@gmail.com L: linux-mips@vger.kernel.org @@@ -16328,7 -16210,7 +16336,7 @@@ F: tools/lib/perf F: tools/perf/
PERFORMANCE EVENTS TOOLING ARM64 -R: John Garry john.garry@huawei.com +R: John Garry john.g.garry@oracle.com R: Will Deacon will@kernel.org R: James Clark james.clark@arm.com R: Mike Leach mike.leach@linaro.org @@@ -16507,6 -16389,13 +16515,6 @@@ S: Supporte F: Documentation/devicetree/bindings/input/pine64,pinephone-keyboard.yaml F: drivers/input/keyboard/pinephone-keyboard.c
-PKTCDVD DRIVER -M: linux-block@vger.kernel.org -S: Orphan -F: drivers/block/pktcdvd.c -F: include/linux/pktcdvd.h -F: include/uapi/linux/pktcdvd.h - PLANTOWER PMS7003 AIR POLLUTION SENSOR DRIVER M: Tomasz Duszynski tduszyns@gmail.com S: Maintained @@@ -16784,10 -16673,10 +16792,10 @@@ F: net/psampl
PSTORE FILESYSTEM M: Kees Cook keescook@chromium.org -M: Anton Vorontsov anton@enomsg.org -M: Colin Cross ccross@android.com -M: Tony Luck tony.luck@intel.com -S: Maintained +R: Tony Luck tony.luck@intel.com +R: Guilherme G. Piccoli gpiccoli@igalia.com +L: linux-hardening@vger.kernel.org +S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore F: Documentation/admin-guide/ramoops.rst F: Documentation/admin-guide/pstore-blk.rst @@@ -16834,6 -16723,7 +16842,6 @@@ M: Hans Verkuil <hverkuil@xs4all.nl L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git -F: Documentation/admin-guide/media/pulse8-cec.rst F: drivers/media/cec/usb/pulse8/
PURELIFI PLFXLC DRIVER @@@ -16928,7 -16818,7 +16936,7 @@@ M: Srinivas Kandagatla <srinivas.kandag M: Banajit Goswami bgoswami@quicinc.com L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported -F: Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml +F: Documentation/devicetree/bindings/soc/qcom/qcom,apr* F: Documentation/devicetree/bindings/sound/qcom,* F: drivers/soc/qcom/apr.c F: include/dt-bindings/sound/qcom,wcd9335.h @@@ -17286,8 -17176,7 +17294,8 @@@ F: Documentation/devicetree/bindings/th F: drivers/thermal/qcom/
QUALCOMM VENUS VIDEO ACCELERATOR DRIVER -M: Stanimir Varbanov stanimir.varbanov@linaro.org +M: Stanimir Varbanov stanimir.k.varbanov@gmail.com +M: Vikash Garodia quic_vgarodia@quicinc.com L: linux-media@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Maintained @@@ -19039,7 -18928,7 +19047,7 @@@ F: drivers/video/fbdev/sis F: include/video/sisfb.h
SIS I2C TOUCHSCREEN DRIVER -M: Mika Penttil�� mika.penttila@nextfour.com +M: Mika Penttil�� mpenttil@redhat.com L: linux-input@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/input/touchscreen/sis_i2c.txt @@@ -19182,7 -19071,7 +19190,7 @@@ M: Jassi Brar <jaswinder.singh@linaro.o M: Ilias Apalodimas ilias.apalodimas@linaro.org L: netdev@vger.kernel.org S: Maintained - F: Documentation/devicetree/bindings/net/socionext-netsec.txt + F: Documentation/devicetree/bindings/net/socionext,synquacer-netsec.yaml F: drivers/net/ethernet/socionext/netsec.c
SOCIONEXT (SNI) Synquacer SPI DRIVER @@@ -19337,7 -19226,7 +19345,7 @@@ M: Manivannan Sadhasivam <manivannan.sa L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git -F: Documentation/devicetree/bindings/media/i2c/imx290.txt +F: Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml F: drivers/media/i2c/imx290.c
SONY IMX319 SENSOR DRIVER @@@ -19486,11 -19375,6 +19494,11 @@@ W: https://linuxtv.or Q: http://patchwork.linuxtv.org/project/linux-media/list/ F: drivers/media/dvb-frontends/sp2*
+SPANISH DOCUMENTATION +M: Carlos Bilbao carlos.bilbao@amd.com +S: Maintained +F: Documentation/translations/sp_SP/ + SPARC + UltraSPARC (sparc/sparc64) M: "David S. Miller" davem@davemloft.net L: sparclinux@vger.kernel.org @@@ -19657,16 -19541,6 +19665,16 @@@ S: Maintaine F: Documentation/hwmon/stpddc60.rst F: drivers/hwmon/pmbus/stpddc60.c
+ST VGXY61 DRIVER +M: Benjamin Mugnier benjamin.mugnier@foss.st.com +M: Sylvain Petinot sylvain.petinot@foss.st.com +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/st,st-vgxy61.yaml +F: Documentation/userspace-api/media/drivers/st-vgxy61.rst +F: drivers/media/i2c/st-vgxy61.c + ST VL53L0X ToF RANGER(I2C) IIO DRIVER M: Song Qiang songqiang1304521@gmail.com L: linux-iio@vger.kernel.org @@@ -19682,7 -19556,6 +19690,7 @@@ S: Supporte F: Documentation/process/stable-kernel-rules.rst
STAGING - ATOMISP DRIVER +M: Hans de Goede hdegoede@redhat.com M: Mauro Carvalho Chehab mchehab@kernel.org R: Sakari Ailus sakari.ailus@linux.intel.com L: linux-media@vger.kernel.org @@@ -20143,7 -20016,6 +20151,7 @@@ F: drivers/clk/clk-sc[mp]i. F: drivers/cpufreq/sc[mp]i-cpufreq.c F: drivers/firmware/arm_scmi/ F: drivers/firmware/arm_scpi.c +F: drivers/powercap/arm_scmi_powercap.c F: drivers/regulator/scmi-regulator.c F: drivers/reset/reset-scmi.c F: include/linux/sc[mp]i_protocol.h @@@ -20478,7 -20350,7 +20486,7 @@@ M: Chris Zankel <chris@zankel.net M: Max Filippov jcmvbkbc@gmail.com L: linux-xtensa@linux-xtensa.org S: Maintained -T: git git://github.com/czankel/xtensa-linux.git +T: git https://github.com/jcmvbkbc/linux-xtensa.git F: arch/xtensa/ F: drivers/irqchip/irq-xtensa-*
@@@ -20690,10 -20562,11 +20698,10 @@@ F: drivers/clk/ti F: include/linux/clk/ti.h
TI DAVINCI MACHINE SUPPORT -M: Sekhar Nori nsekhar@ti.com -R: Bartosz Golaszewski brgl@bgdev.pl +M: Bartosz Golaszewski brgl@bgdev.pl L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Supported -T: git git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git F: Documentation/devicetree/bindings/i2c/i2c-davinci.txt F: arch/arm/boot/dts/da850* F: arch/arm/mach-davinci/ @@@ -20827,7 -20700,6 +20835,6 @@@ W: https://wireless.wiki.kernel.org/en/ W: https://wireless.wiki.kernel.org/en/users/Drivers/wl1251 T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git F: drivers/net/wireless/ti/ - F: include/linux/wl12xx.h
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER M: John Stultz jstultz@google.com @@@ -21891,12 -21763,6 +21898,12 @@@ F: include/linux/virtio*. F: include/uapi/linux/virtio_*.h F: tools/virtio/
+VISL VIRTUAL STATELESS DECODER DRIVER +M: Daniel Almeida daniel.almeida@collabora.com +L: linux-media@vger.kernel.org +S: Supported +F: drivers/media/test-drivers/visl + IFCVF VIRTIO DATA PATH ACCELERATOR R: Zhu Lingshan lingshan.zhu@intel.com F: drivers/vdpa/ifcvf/ diff --combined arch/arm/boot/dts/armada-375.dtsi index c310ef26d1cc,9fbe0cfec48f..ddc49547d786 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@@ -178,6 -178,8 +178,8 @@@
/* Network controller */ ethernet: ethernet@f0000 { + #address-cells = <1>; + #size-cells = <0>; compatible = "marvell,armada-375-pp2"; reg = <0xf0000 0xa000>, /* Packet Processor regs */ <0xc0000 0x3060>, /* LMS regs */ @@@ -187,15 -189,17 +189,17 @@@ clock-names = "pp_clk", "gop_clk"; status = "disabled";
- eth0: eth0 { + eth0: ethernet-port@0 { interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - port-id = <0>; + reg = <0>; + port-id = <0>; /* For backward compatibility. */ status = "disabled"; };
- eth1: eth1 { + eth1: ethernet-port@1 { interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; - port-id = <1>; + reg = <1>; + port-id = <1>; /* For backward compatibility. */ status = "disabled"; }; }; @@@ -592,7 -596,7 +596,7 @@@
pcie1: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; diff --combined arch/arm/mach-omap2/pdata-quirks.c index 9deba798cc91,9409b9f5711c..baba73fd6f11 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@@ -10,7 -10,6 +10,6 @@@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/of_platform.h> - #include <linux/wl12xx.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> #include <linux/power/smartreflex.h> @@@ -440,6 -439,7 +439,6 @@@ static struct of_dev_auxdata omap_auxda #ifdef CONFIG_MACH_NOKIA_N8X0 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data), - OF_DEV_AUXDATA("tlv320aic3x", 0x18, "2-0018", &n810_aic33_data), #endif #ifdef CONFIG_ARCH_OMAP3 OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", diff --combined arch/arm64/boot/dts/apple/t8103-j456.dts index 83bb4dc32af9,7ea27456f33c..2db425ceb30f --- a/arch/arm64/boot/dts/apple/t8103-j456.dts +++ b/arch/arm64/boot/dts/apple/t8103-j456.dts @@@ -14,13 -14,17 +14,17 @@@
/ { compatible = "apple,j456", "apple,t8103", "apple,arm-platform"; - model = "Apple iMac (24-inch, 4x USB-C, M1, 2020)"; + model = "Apple iMac (24-inch, 4x USB-C, M1, 2021)";
aliases { ethernet0 = ðernet0; }; };
+ &bluetooth0 { + brcm,board-type = "apple,capri"; + }; + &wifi0 { brcm,board-type = "apple,capri"; }; diff --combined arch/arm64/boot/dts/apple/t8103-j457.dts index 67e433d5f8ba,8ee0ac871426..3821ff146c56 --- a/arch/arm64/boot/dts/apple/t8103-j457.dts +++ b/arch/arm64/boot/dts/apple/t8103-j457.dts @@@ -14,13 -14,17 +14,17 @@@
/ { compatible = "apple,j457", "apple,t8103", "apple,arm-platform"; - model = "Apple iMac (24-inch, 2x USB-C, M1, 2020)"; + model = "Apple iMac (24-inch, 2x USB-C, M1, 2021)";
aliases { ethernet0 = ðernet0; }; };
+ &bluetooth0 { + brcm,board-type = "apple,santorini"; + }; + &wifi0 { brcm,board-type = "apple,santorini"; }; diff --combined arch/arm64/boot/dts/apple/t8103-jxxx.dtsi index 9706d26f9c64,cc2e04035763..5988a4eb6efa --- a/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8103-jxxx.dtsi @@@ -11,6 -11,7 +11,7 @@@
/ { aliases { + bluetooth0 = &bluetooth0; serial0 = &serial0; serial2 = &serial2; wifi0 = &wifi0; @@@ -77,8 -78,11 +78,15 @@@ local-mac-address = [00 00 00 00 00 00]; apple,antenna-sku = "XX"; }; + + bluetooth0: bluetooth@0,1 { + compatible = "pci14e4,5f69"; + reg = <0x10100 0x0 0x0 0x0 0x0>; + /* To be filled by the loader */ + local-bd-address = [00 00 00 00 00 00]; + }; }; + +&nco_clkref { + clock-frequency = <900000000>; +}; diff --combined arch/arm64/boot/dts/mediatek/mt7986a.dtsi index ed703025a7cc,07dee1c0d281..0e9406fc63e2 --- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi @@@ -10,12 -10,11 +10,12 @@@ #include <dt-bindings/reset/mt7986-resets.h>
/ { + compatible = "mediatek,mt7986a"; interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>;
- clk40m: oscillator@0 { + clk40m: oscillator-40m { compatible = "fixed-clock"; clock-frequency = <40000000>; #clock-cells = <0>; @@@ -77,6 -76,47 +77,47 @@@ no-map; reg = <0 0x4fc00000 0 0x00100000>; }; + + wo_emi0: wo-emi@4fd00000 { + reg = <0 0x4fd00000 0 0x40000>; + no-map; + }; + + wo_emi1: wo-emi@4fd40000 { + reg = <0 0x4fd40000 0 0x40000>; + no-map; + }; + + wo_ilm0: wo-ilm@151e0000 { + reg = <0 0x151e0000 0 0x8000>; + no-map; + }; + + wo_ilm1: wo-ilm@151f0000 { + reg = <0 0x151f0000 0 0x8000>; + no-map; + }; + + wo_data: wo-data@4fd80000 { + reg = <0 0x4fd80000 0 0x240000>; + no-map; + }; + + wo_dlm0: wo-dlm@151e8000 { + reg = <0 0x151e8000 0 0x2000>; + no-map; + }; + + wo_dlm1: wo-dlm@151f8000 { + reg = <0 0x151f8000 0 0x2000>; + no-map; + }; + + wo_boot: wo-boot@15194000 { + reg = <0 0x15194000 0 0x1000>; + no-map; + }; + };
timer { @@@ -113,12 -153,6 +154,12 @@@ #clock-cells = <1>; };
+ wed_pcie: wed-pcie@10003000 { + compatible = "mediatek,mt7986-wed-pcie", + "syscon"; + reg = <0 0x10003000 0 0x10>; + }; + topckgen: topckgen@1001b000 { compatible = "mediatek,mt7986-topckgen", "syscon"; reg = <0 0x1001B000 0 0x1000>; @@@ -175,7 -209,7 +216,7 @@@ #clock-cells = <1>; };
- trng: trng@1020f000 { + trng: rng@1020f000 { compatible = "mediatek,mt7986-rng", "mediatek,mt7623-rng"; reg = <0 0x1020f000 0 0x100>; @@@ -184,21 -218,6 +225,21 @@@ status = "disabled"; };
+ crypto: crypto@10320000 { + compatible = "inside-secure,safexcel-eip97"; + reg = <0 0x10320000 0 0x40000>; + interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ring0", "ring1", "ring2", "ring3"; + clocks = <&infracfg CLK_INFRA_EIP97_CK>; + clock-names = "infra_eip97_ck"; + assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>; + assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>; + status = "disabled"; + }; + uart0: serial@11002000 { compatible = "mediatek,mt7986-uart", "mediatek,mt6577-uart"; @@@ -240,48 -259,6 +281,48 @@@ status = "disabled"; };
+ i2c0: i2c@11008000 { + compatible = "mediatek,mt7986-i2c"; + reg = <0 0x11008000 0 0x90>, + <0 0x10217080 0 0x80>; + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + clock-div = <5>; + clocks = <&infracfg CLK_INFRA_I2C0_CK>, + <&infracfg CLK_INFRA_AP_DMA_CK>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1100a000 0 0x100>; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&topckgen CLK_TOP_MPLL_D2>, + <&topckgen CLK_TOP_SPI_SEL>, + <&infracfg CLK_INFRA_SPI0_CK>, + <&infracfg CLK_INFRA_SPI0_HCK_CK>; + clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk"; + status = "disabled"; + }; + + spi1: spi@1100b000 { + compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0 0x1100b000 0 0x100>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&topckgen CLK_TOP_MPLL_D2>, + <&topckgen CLK_TOP_SPIM_MST_SEL>, + <&infracfg CLK_INFRA_SPI1_CK>, + <&infracfg CLK_INFRA_SPI1_HCK_CK>; + clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk"; + status = "disabled"; + }; + ethsys: syscon@15000000 { #address-cells = <1>; #size-cells = <1>; @@@ -292,12 -269,23 +333,17 @@@ #reset-cells = <1>; };
- wed_pcie: wed-pcie@10003000 { - compatible = "mediatek,mt7986-wed-pcie", - "syscon"; - reg = <0 0x10003000 0 0x10>; - }; - wed0: wed@15010000 { compatible = "mediatek,mt7986-wed", "syscon"; reg = <0 0x15010000 0 0x1000>; interrupt-parent = <&gic>; interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>; + memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>, + <&wo_data>, <&wo_boot>; + memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", + "wo-data", "wo-boot"; + mediatek,wo-ccif = <&wo_ccif0>; };
wed1: wed@15011000 { @@@ -306,6 -294,25 +352,25 @@@ reg = <0 0x15011000 0 0x1000>; interrupt-parent = <&gic>; interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>; + memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>, + <&wo_data>, <&wo_boot>; + memory-region-names = "wo-emi", "wo-ilm", "wo-dlm", + "wo-data", "wo-boot"; + mediatek,wo-ccif = <&wo_ccif1>; + }; + + wo_ccif0: syscon@151a5000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151a5000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>; + }; + + wo_ccif1: syscon@151ad000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151ad000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>; };
eth: ethernet@15100000 { diff --combined drivers/bluetooth/hci_qca.c index ba8be8e1bebd,3df9e692756a..6eddc23e49d9 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@@ -696,15 -696,9 +696,15 @@@ static int qca_close(struct hci_uart *h skb_queue_purge(&qca->tx_wait_q); skb_queue_purge(&qca->txq); skb_queue_purge(&qca->rx_memdump_q); + /* + * Shut the timers down so they can't be rearmed when + * destroy_workqueue() drains pending work which in turn might try + * to arm a timer. After shutdown rearm attempts are silently + * ignored by the timer core code. + */ + timer_shutdown_sync(&qca->tx_idle_timer); + timer_shutdown_sync(&qca->wake_retrans_timer); destroy_workqueue(qca->workqueue); - del_timer_sync(&qca->tx_idle_timer); - del_timer_sync(&qca->wake_retrans_timer); qca->hu = NULL;
kfree_skb(qca->rx_skb); @@@ -918,7 -912,7 +918,7 @@@ static int qca_enqueue(struct hci_uart default: BT_ERR("Illegal tx state: %d (losing packet)", qca->tx_ibs_state); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; }
@@@ -1771,7 -1765,8 +1771,8 @@@ retry qca_debugfs_init(hdev); hu->hdev->hw_error = qca_hw_error; hu->hdev->cmd_timeout = qca_cmd_timeout; - hu->hdev->wakeup = qca_wakeup; + if (device_can_wakeup(hu->serdev->ctrl->dev.parent)) + hu->hdev->wakeup = qca_wakeup; } else if (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */ set_bit(QCA_ROM_FW, &qca->flags); diff --combined drivers/net/ethernet/microsoft/mana/gdma_main.c index 69224ff8efb6,690b69cae4e3..e708c2d04983 --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c @@@ -671,7 -671,8 +671,7 @@@ free_q return err; }
-int mana_gd_destroy_dma_region(struct gdma_context *gc, - gdma_obj_handle_t dma_region_handle) +int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle) { struct gdma_destroy_dma_region_req req = {}; struct gdma_general_resp resp = {}; @@@ -1218,8 -1219,10 +1218,10 @@@ static int mana_gd_setup_irqs(struct pc struct gdma_context *gc = pci_get_drvdata(pdev); struct gdma_irq_context *gic; unsigned int max_irqs; + u16 *cpus; + cpumask_var_t req_mask; int nvec, irq; - int err, i, j; + int err, i = 0, j;
if (max_queues_per_port > MANA_MAX_NUM_QUEUES) max_queues_per_port = MANA_MAX_NUM_QUEUES; @@@ -1238,7 -1241,21 +1240,21 @@@ goto free_irq_vector; }
+ if (!zalloc_cpumask_var(&req_mask, GFP_KERNEL)) { + err = -ENOMEM; + goto free_irq; + } + + cpus = kcalloc(nvec, sizeof(*cpus), GFP_KERNEL); + if (!cpus) { + err = -ENOMEM; + goto free_mask; + } + for (i = 0; i < nvec; i++) + cpus[i] = cpumask_local_spread(i, gc->numa_node); + for (i = 0; i < nvec; i++) { + cpumask_set_cpu(cpus[i], req_mask); gic = &gc->irq_contexts[i]; gic->handler = NULL; gic->arg = NULL; @@@ -1246,13 -1263,17 +1262,17 @@@ irq = pci_irq_vector(pdev, i); if (irq < 0) { err = irq; - goto free_irq; + goto free_mask; }
err = request_irq(irq, mana_gd_intr, 0, "mana_intr", gic); if (err) - goto free_irq; + goto free_mask; + irq_set_affinity_and_hint(irq, req_mask); + cpumask_clear(req_mask); } + free_cpumask_var(req_mask); + kfree(cpus);
err = mana_gd_alloc_res_map(nvec, &gc->msix_resource); if (err) @@@ -1263,6 -1284,9 +1283,9 @@@
return 0;
+ free_mask: + free_cpumask_var(req_mask); + kfree(cpus); free_irq: for (j = i - 1; j >= 0; j--) { irq = pci_irq_vector(pdev, j); @@@ -1399,6 -1423,7 +1422,7 @@@ static int mana_gd_probe(struct pci_de if (!bar0_va) goto free_gc;
+ gc->numa_node = dev_to_node(&pdev->dev); gc->is_pf = mana_is_pf(pdev->device); gc->bar0_va = bar0_va; gc->dev = &pdev->dev; diff --combined drivers/net/ppp/ppp_generic.c index be2fab0469cf,d4c821c8cf57..1d71f5276241 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@@ -480,7 -480,7 +480,7 @@@ static ssize_t ppp_read(struct file *fi ret = -EFAULT; iov.iov_base = buf; iov.iov_len = count; - iov_iter_init(&to, READ, &iov, 1, count); + iov_iter_init(&to, ITER_DEST, &iov, 1, count); if (skb_copy_datagram_iter(skb, 0, &to, skb->len)) goto outf; ret = skb->len; @@@ -1743,6 -1743,8 +1743,8 @@@ ppp_send_frame(struct ppp *ppp, struct int len; unsigned char *cp;
+ skb->dev = ppp->dev; + if (proto < 0x8000) { #ifdef CONFIG_PPP_FILTER /* check if we should pass this packet */ diff --combined drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index c704ca752138,af8843507f3d..e975d10e6009 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@@ -1128,7 -1128,7 +1128,7 @@@ static void brcmf_p2p_afx_handler(struc if (afx_hdl->is_listen && afx_hdl->my_listen_chan) /* 100ms ~ 300ms */ err = brcmf_p2p_discover_listen(p2p, afx_hdl->my_listen_chan, - 100 * (1 + prandom_u32_max(3))); + 100 * get_random_u32_inclusive(1, 3)); else err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan);
@@@ -2424,8 -2424,12 +2424,12 @@@ int brcmf_p2p_del_vif(struct wiphy *wip brcmf_remove_interface(vif->ifp, true);
brcmf_cfg80211_arm_vif_event(cfg, NULL); - if (iftype != NL80211_IFTYPE_P2P_DEVICE) - p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; + if (iftype != NL80211_IFTYPE_P2P_DEVICE) { + if (vif == p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif) + p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; + if (vif == p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION2].vif) + p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION2].vif = NULL; + }
return err; } diff --combined drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 3a7a44bb3c60,83abfe996138..aa791dbc3066 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@@ -788,14 -788,40 +788,40 @@@ static u32 iwl_mvm_find_ie_offset(u8 *b return ie - beacon; }
- u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, - struct ieee80211_vif *vif) + static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct ieee80211_vif *vif) { + struct ieee80211_supported_band *sband; + unsigned long basic = vif->bss_conf.basic_rates; + u16 lowest_cck = IWL_RATE_COUNT, lowest_ofdm = IWL_RATE_COUNT; u8 rate; - if (info->band == NL80211_BAND_2GHZ && !vif->p2p) - rate = IWL_FIRST_CCK_RATE; - else - rate = IWL_FIRST_OFDM_RATE; + u32 i; + + sband = mvm->hw->wiphy->bands[info->band]; + for_each_set_bit(i, &basic, BITS_PER_LONG) { + u16 hw = sband->bitrates[i].hw_value; + + if (hw >= IWL_FIRST_OFDM_RATE) { + if (lowest_ofdm > hw) + lowest_ofdm = hw; + } else if (lowest_cck > hw) { + lowest_cck = hw; + } + } + + if (info->band == NL80211_BAND_2GHZ && !vif->p2p) { + if (lowest_cck != IWL_RATE_COUNT) + rate = lowest_cck; + else if (lowest_ofdm != IWL_RATE_COUNT) + rate = lowest_ofdm; + else + rate = IWL_RATE_1M_INDEX; + } else if (lowest_ofdm != IWL_RATE_COUNT) { + rate = lowest_ofdm; + } else { + rate = IWL_RATE_6M_INDEX; + }
return rate; } @@@ -812,6 -838,24 +838,24 @@@ u16 iwl_mvm_mac_ctxt_get_beacon_flags(c return flags; }
+ u8 iwl_mvm_mac_ctxt_get_beacon_rate(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct ieee80211_vif *vif) + { + struct ieee80211_supported_band *sband = + mvm->hw->wiphy->bands[info->band]; + u32 legacy = vif->bss_conf.beacon_tx_rate.control[info->band].legacy; + + /* if beacon rate was configured try using it */ + if (hweight32(legacy) == 1) { + u32 rate = ffs(legacy) - 1; + + return sband->bitrates[rate].hw_value; + } + + return iwl_mvm_mac_ctxt_get_lowest_rate(mvm, info, vif); + } + static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct sk_buff *beacon, @@@ -842,7 -886,7 +886,7 @@@ cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS);
- rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); + rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif);
tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate)); @@@ -926,7 -970,7 +970,7 @@@ static int iwl_mvm_mac_ctxt_send_beacon struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(beacon); struct iwl_mac_beacon_cmd beacon_cmd = {}; - u8 rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); + u8 rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif); u16 flags; struct ieee80211_chanctx_conf *ctx; int channel; @@@ -1099,7 -1143,7 +1143,7 @@@ static void iwl_mvm_mac_ctxt_cmd_fill_a iwl_mvm_mac_ap_iterator, &data);
if (data.beacon_device_ts) { - u32 rand = prandom_u32_max(64 - 36) + 36; + u32 rand = get_random_u32_inclusive(36, 63); mvmvif->ap_beacon_time = data.beacon_device_ts + ieee80211_tu_to_usec(data.beacon_int * rand / 100); diff --combined drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 1a69237dc57e,ce6b701f3f4c..90bc95d96a78 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@@ -501,7 -501,7 +501,7 @@@ struct iwl_mvm_tt_mgmt * @tzone: thermal zone device data */ struct iwl_mvm_thermal_device { - s16 temp_trips[IWL_MAX_DTS_TRIPS]; + struct thermal_trip trips[IWL_MAX_DTS_TRIPS]; u8 fw_trips_index[IWL_MAX_DTS_TRIPS]; struct thermal_zone_device *tzone; }; @@@ -1105,6 -1105,8 +1105,8 @@@ struct iwl_mvm unsigned long last_reset_or_resume_time_jiffies;
bool sta_remove_requires_queue_remove; + + bool pldr_sync; };
/* Extract MVM priv from op_mode and _hw */ @@@ -1644,7 -1646,8 +1646,8 @@@ int iwl_mvm_mac_ctxt_send_beacon(struc int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, struct sk_buff *beacon, void *data, int len); - u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, + u8 iwl_mvm_mac_ctxt_get_beacon_rate(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, struct ieee80211_vif *vif); u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx); @@@ -2079,6 -2082,18 +2082,18 @@@ void iwl_mvm_sta_add_debugfs(struct iee struct dentry *dir); #endif
+ /* new MLD related APIs */ + int iwl_mvm_sec_key_add(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *keyconf); + int iwl_mvm_sec_key_del(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *keyconf); + void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm, + struct ieee80211_vif *vif); + int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, struct iwl_rfi_lut_entry *rfi_table); struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm); @@@ -2201,10 -2216,10 +2216,10 @@@ static inline void iwl_mvm_mei_host_dis iwl_mei_host_disassociated(); }
- static inline void iwl_mvm_mei_device_down(struct iwl_mvm *mvm) + static inline void iwl_mvm_mei_device_state(struct iwl_mvm *mvm, bool up) { if (mvm->mei_registered) - iwl_mei_device_down(); + iwl_mei_device_state(up); }
static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm) diff --combined drivers/ptp/ptp_vmw.c index 0dcbabd1533d,d64eec5b1788..27c5547aa8a9 --- a/drivers/ptp/ptp_vmw.c +++ b/drivers/ptp/ptp_vmw.c @@@ -47,7 -47,7 +47,7 @@@ static int ptp_vmw_adjtime(struct ptp_c return -EOPNOTSUPP; }
- static int ptp_vmw_adjfreq(struct ptp_clock_info *info, s32 delta) + static int ptp_vmw_adjfine(struct ptp_clock_info *info, long delta) { return -EOPNOTSUPP; } @@@ -79,7 -79,7 +79,7 @@@ static struct ptp_clock_info ptp_vmw_cl .name = "ptp_vmw", .max_adj = 0, .adjtime = ptp_vmw_adjtime, - .adjfreq = ptp_vmw_adjfreq, + .adjfine = ptp_vmw_adjfine, .gettime64 = ptp_vmw_gettime, .settime64 = ptp_vmw_settime, .enable = ptp_vmw_enable, @@@ -101,9 -101,10 +101,9 @@@ static int ptp_vmw_acpi_add(struct acpi return 0; }
-static int ptp_vmw_acpi_remove(struct acpi_device *device) +static void ptp_vmw_acpi_remove(struct acpi_device *device) { ptp_clock_unregister(ptp_vmw_clock); - return 0; }
static const struct acpi_device_id ptp_vmw_acpi_device_ids[] = { diff --combined include/linux/module.h index 676614d56c25,35876e89eb93..8c5909c0076c --- a/include/linux/module.h +++ b/include/linux/module.h @@@ -827,6 -827,7 +827,6 @@@ void *dereference_module_function_descr #ifdef CONFIG_SYSFS extern struct kset *module_kset; extern struct kobj_type module_ktype; -extern int module_sysfs_initialized; #endif /* CONFIG_SYSFS */
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) @@@ -878,8 -879,17 +878,17 @@@ static inline bool module_sig_ok(struc } #endif /* CONFIG_MODULE_SIG */
+ #if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS) int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *, unsigned long), void *data); + #else + static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + struct module *, unsigned long), + void *data) + { + return -EOPNOTSUPP; + } + #endif /* CONFIG_MODULES && CONFIG_KALLSYMS */
#endif /* _LINUX_MODULE_H */ diff --combined include/linux/rcupdate.h index 4da98ca6273e,8822f06e4b40..03abf883a281 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@@ -108,15 -108,6 +108,15 @@@ static inline int rcu_preempt_depth(voi
#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
+#ifdef CONFIG_RCU_LAZY +void call_rcu_hurry(struct rcu_head *head, rcu_callback_t func); +#else +static inline void call_rcu_hurry(struct rcu_head *head, rcu_callback_t func) +{ + call_rcu(head, func); +} +#endif + /* Internal to kernel */ void rcu_init(void); extern int rcu_scheduler_active; @@@ -249,6 -240,18 +249,18 @@@ static inline void exit_tasks_rcu_start static inline void exit_tasks_rcu_finish(void) { } #endif /* #else #ifdef CONFIG_TASKS_RCU_GENERIC */
+ /** + * rcu_trace_implies_rcu_gp - does an RCU Tasks Trace grace period imply an RCU grace period? + * + * As an accident of implementation, an RCU Tasks Trace grace period also + * acts as an RCU grace period. However, this could change at any time. + * Code relying on this accident must call this function to verify that + * this accident is still happening. + * + * You have been warned! + */ + static inline bool rcu_trace_implies_rcu_gp(void) { return true; } + /** * cond_resched_tasks_rcu_qs - Report potential quiescent states to RCU * @@@ -349,11 -352,6 +361,11 @@@ static inline int rcu_read_lock_any_hel return !preemptible(); }
+static inline int debug_lockdep_rcu_enabled(void) +{ + return 0; +} + #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
#ifdef CONFIG_PROVE_RCU diff --combined include/net/mana/gdma.h index 989058340b07,d80c78506f19..b3ba04615caa --- a/include/net/mana/gdma.h +++ b/include/net/mana/gdma.h @@@ -65,6 -65,8 +65,6 @@@ enum GDMA_DEVICE_MANA = 2, };
-typedef u64 gdma_obj_handle_t; - struct gdma_resource { /* Protect the bitmap */ spinlock_t lock; @@@ -198,7 -200,7 +198,7 @@@ struct gdma_mem_info u64 length;
/* Allocated by the PF driver */ - gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle; };
#define REGISTER_ATB_MST_MKEY_LOWER_SIZE 8 @@@ -367,6 -369,7 +367,7 @@@ struct gdma_context void __iomem *db_page_base; phys_addr_t phys_db_page_base; u32 db_page_size; + int numa_node;
/* Shared memory chanenl (used to bootstrap HWC) */ struct shm_channel shm_channel; @@@ -629,7 -632,7 +630,7 @@@ struct gdma_create_queue_req u32 reserved1; u32 pdid; u32 doolbell_id; - gdma_obj_handle_t gdma_region; + u64 gdma_region; u32 reserved2; u32 queue_size; u32 log2_throttle_limit; @@@ -704,14 -707,14 +705,14 @@@ struct gdma_create_dma_region_req
struct gdma_create_dma_region_resp { struct gdma_resp_hdr hdr; - gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle; }; /* HW DATA */
/* GDMA_DMA_REGION_ADD_PAGES */ struct gdma_dma_region_add_pages_req { struct gdma_req_hdr hdr;
- gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle;
u32 page_addr_list_len; u32 reserved3; @@@ -723,7 -726,7 +724,7 @@@ struct gdma_destroy_dma_region_req { struct gdma_req_hdr hdr;
- gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle; }; /* HW DATA */
enum gdma_pd_flags { @@@ -738,14 -741,14 +739,14 @@@ struct gdma_create_pd_req
struct gdma_create_pd_resp { struct gdma_resp_hdr hdr; - gdma_obj_handle_t pd_handle; + u64 pd_handle; u32 pd_id; u32 reserved; };/* HW DATA */
struct gdma_destroy_pd_req { struct gdma_req_hdr hdr; - gdma_obj_handle_t pd_handle; + u64 pd_handle; };/* HW DATA */
struct gdma_destory_pd_resp { @@@ -761,11 -764,11 +762,11 @@@ enum gdma_mr_type };
struct gdma_create_mr_params { - gdma_obj_handle_t pd_handle; + u64 pd_handle; enum gdma_mr_type mr_type; union { struct { - gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle; u64 virtual_address; enum gdma_mr_access_flags access_flags; } gva; @@@ -774,13 -777,13 +775,13 @@@
struct gdma_create_mr_request { struct gdma_req_hdr hdr; - gdma_obj_handle_t pd_handle; + u64 pd_handle; enum gdma_mr_type mr_type; u32 reserved_1;
union { struct { - gdma_obj_handle_t dma_region_handle; + u64 dma_region_handle; u64 virtual_address; enum gdma_mr_access_flags access_flags; } gva; @@@ -791,14 -794,14 +792,14 @@@
struct gdma_create_mr_response { struct gdma_resp_hdr hdr; - gdma_obj_handle_t mr_handle; + u64 mr_handle; u32 lkey; u32 rkey; };/* HW DATA */
struct gdma_destroy_mr_request { struct gdma_req_hdr hdr; - gdma_obj_handle_t mr_handle; + u64 mr_handle; };/* HW DATA */
struct gdma_destroy_mr_response { @@@ -832,6 -835,7 +833,6 @@@ void mana_gd_free_memory(struct gdma_me int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, u32 resp_len, void *resp);
-int mana_gd_destroy_dma_region(struct gdma_context *gc, - gdma_obj_handle_t dma_region_handle); +int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle);
#endif /* _GDMA_H */ diff --combined include/net/mana/mana.h index 20212ffeefb9,575ea36ce606..3bb579962a14 --- a/include/net/mana/mana.h +++ b/include/net/mana/mana.h @@@ -390,7 -390,7 +390,7 @@@ struct mana_port_context struct mana_ethtool_stats eth_stats; };
- int mana_start_xmit(struct sk_buff *skb, struct net_device *ndev); + netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev); int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx, bool update_hash, bool update_tab);
@@@ -412,9 -412,6 +412,9 @@@ int mana_bpf(struct net_device *ndev, s
extern const struct ethtool_ops mana_ethtool_ops;
+/* A CQ can be created not associated with any EQ */ +#define GDMA_CQ_NO_EQ 0xffff + struct mana_obj_spec { u32 queue_index; u64 gdma_region; diff --combined kernel/bpf/core.c index 38159f39e2af,2e57fc839a5c..7f98dec6e90f --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@@ -34,6 -34,7 +34,7 @@@ #include <linux/log2.h> #include <linux/bpf_verifier.h> #include <linux/nodemask.h> + #include <linux/bpf_mem_alloc.h>
#include <asm/barrier.h> #include <asm/unaligned.h> @@@ -60,6 -61,9 +61,9 @@@ #define CTX regs[BPF_REG_CTX] #define IMM insn->imm
+ struct bpf_mem_alloc bpf_global_ma; + bool bpf_global_ma_set; + /* No hurry in this branch * * Exported for the bpf jit load helper. @@@ -1032,7 -1036,7 +1036,7 @@@ bpf_jit_binary_alloc(unsigned int progl hdr->size = size; hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)), PAGE_SIZE - sizeof(*hdr)); - start = prandom_u32_max(hole) & ~(alignment - 1); + start = get_random_u32_below(hole) & ~(alignment - 1);
/* Leave a random number of instructions before BPF code. */ *image_ptr = &hdr->image[start]; @@@ -1094,7 -1098,7 +1098,7 @@@ bpf_jit_binary_pack_alloc(unsigned int
hole = min_t(unsigned int, size - (proglen + sizeof(*ro_header)), BPF_PROG_CHUNK_SIZE - sizeof(*ro_header)); - start = prandom_u32_max(hole) & ~(alignment - 1); + start = get_random_u32_below(hole) & ~(alignment - 1);
*image_ptr = &ro_header->image[start]; *rw_image = &(*rw_header)->image[start]; @@@ -2251,8 -2255,14 +2255,14 @@@ static void __bpf_prog_array_free_sleep { struct bpf_prog_array *progs;
+ /* If RCU Tasks Trace grace period implies RCU grace period, there is + * no need to call kfree_rcu(), just call kfree() directly. + */ progs = container_of(rcu, struct bpf_prog_array, rcu); - kfree_rcu(progs, rcu); + if (rcu_trace_implies_rcu_gp()) + kfree(progs); + else + kfree_rcu(progs, rcu); }
void bpf_prog_array_free_sleepable(struct bpf_prog_array *progs) @@@ -2740,6 -2750,18 +2750,18 @@@ int __weak bpf_arch_text_invalidate(voi return -ENOTSUPP; }
+ #ifdef CONFIG_BPF_SYSCALL + static int __init bpf_global_ma_init(void) + { + int ret; + + ret = bpf_mem_alloc_init(&bpf_global_ma, 0, false); + bpf_global_ma_set = !ret; + return ret; + } + late_initcall(bpf_global_ma_init); + #endif + DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key); EXPORT_SYMBOL(bpf_stats_enabled_key);
diff --combined kernel/cgroup/cgroup.c index 15cc26513596,f1e6058089f5..c099cf3fa02d --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@@ -248,12 -248,6 +248,12 @@@ static int cgroup_addrm_files(struct cg struct cgroup *cgrp, struct cftype cfts[], bool is_add);
+#ifdef CONFIG_DEBUG_CGROUP_REF +#define CGROUP_REF_FN_ATTRS noinline +#define CGROUP_REF_EXPORT(fn) EXPORT_SYMBOL_GPL(fn); +#include <linux/cgroup_refcnt.h> +#endif + /** * cgroup_ssid_enabled - cgroup subsys enabled test by subsys ID * @ssid: subsys ID of interest @@@ -2866,12 -2860,14 +2866,12 @@@ int cgroup_migrate(struct task_struct * * take an rcu_read_lock. */ spin_lock_irq(&css_set_lock); - rcu_read_lock(); task = leader; do { cgroup_migrate_add_task(task, mgctx); if (!threadgroup) break; } while_each_thread(leader, task); - rcu_read_unlock(); spin_unlock_irq(&css_set_lock);
return cgroup_migrate_execute(mgctx); @@@ -5353,6 -5349,7 +5353,7 @@@ static void css_free_rwork_fn(struct wo atomic_dec(&cgrp->root->nr_cgrps); cgroup1_pidlist_destroy_all(cgrp); cancel_work_sync(&cgrp->release_agent_work); + bpf_cgrp_storage_free(cgrp);
if (cgroup_parent(cgrp)) { /* diff --combined kernel/rcu/tasks.h index b0b885e071fa,9435e5a7b53e..fe9840d90e96 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@@ -728,7 -728,7 +728,7 @@@ static void rcu_tasks_wait_gp(struct rc if (rtsi > 0 && !reported && time_after(j, lastinfo + rtsi)) { lastinfo = j; rtsi = rtsi * rcu_task_stall_info_mult; - pr_info("%s: %s grace period %lu is %lu jiffies old.\n", + pr_info("%s: %s grace period number %lu (since boot) is %lu jiffies old.\n", __func__, rtp->kname, rtp->tasks_gp_seq, j - rtp->gp_start); } } @@@ -1535,6 -1535,8 +1535,8 @@@ static void rcu_tasks_trace_postscan(st { // Wait for late-stage exiting tasks to finish exiting. // These might have passed the call to exit_tasks_rcu_finish(). + + // If you remove the following line, update rcu_trace_implies_rcu_gp()!!! synchronize_rcu(); // Any tasks that exit after this point will set // TRC_NEED_QS_CHECKED in ->trc_reader_special.b.need_qs. diff --combined kernel/trace/ftrace.c index acfa4e029bcc,f2260bc65226..8e842f68b9a5 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@@ -2488,13 -2488,14 +2488,13 @@@ ftrace_add_rec_direct(unsigned long ip static void call_direct_funcs(unsigned long ip, unsigned long pip, struct ftrace_ops *ops, struct ftrace_regs *fregs) { - struct pt_regs *regs = ftrace_get_regs(fregs); unsigned long addr;
addr = ftrace_find_rec_direct(ip); if (!addr) return;
- arch_ftrace_set_direct_caller(regs, addr); + arch_ftrace_set_direct_caller(fregs, addr); }
struct ftrace_ops direct_ops = { @@@ -8257,6 -8258,10 +8257,10 @@@ struct kallsyms_data size_t found; };
+ /* This function gets called for all kernel and module symbols + * and returns 1 in case we resolved all the requested symbols, + * 0 otherwise. + */ static int kallsyms_callback(void *data, const char *name, struct module *mod, unsigned long addr) { @@@ -8299,17 -8304,19 +8303,19 @@@ int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs) { struct kallsyms_data args; - int err; + int found_all;
memset(addrs, 0, sizeof(*addrs) * cnt); args.addrs = addrs; args.syms = sorted_syms; args.cnt = cnt; args.found = 0; - err = kallsyms_on_each_symbol(kallsyms_callback, &args); - if (err < 0) - return err; - return args.found == args.cnt ? 0 : -ESRCH; + + found_all = kallsyms_on_each_symbol(kallsyms_callback, &args); + if (found_all) + return 0; + found_all = module_kallsyms_on_each_symbol(kallsyms_callback, &args); + return found_all ? 0 : -ESRCH; }
#ifdef CONFIG_SYSCTL diff --combined lib/Kconfig index e69c2d819c44,cc969ef58a2a..48e021846472 --- a/lib/Kconfig +++ b/lib/Kconfig @@@ -24,6 -24,7 +24,7 @@@ config LINEAR_RANGE
config PACKING bool "Generic bitfield packing and unpacking" + select BITREVERSE default n help This option provides the packing() helper function, which permits @@@ -529,8 -530,8 +530,8 @@@ config CPUMASK_OFFSTAC stack overflow.
config FORCE_NR_CPUS - bool "NR_CPUS is set to an actual number of CPUs" - depends on SMP + bool "Set number of CPUs at compile time" + depends on SMP && EXPERT && !COMPILE_TEST help Say Yes if you have NR_CPUS set to an actual number of possible CPUs in your system, not to a default value. This forces the core @@@ -672,9 -673,6 +673,9 @@@ config ARCH_HAS_PMEM_AP config MEMREGION bool
+config ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION + bool + config ARCH_HAS_MEMREMAP_COMPAT_ALIGN bool
diff --combined lib/test_rhashtable.c index 6a8e445c8b55,3ae3399f3651..c20f6cb4bf55 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@@ -368,8 -368,8 +368,8 @@@ static int __init test_rhltable(unsigne
pr_info("test %d random rhlist add/delete operations\n", entries); for (j = 0; j < entries; j++) { - u32 i = prandom_u32_max(entries); - u32 prand = prandom_u32_max(4); + u32 i = get_random_u32_below(entries); + u32 prand = get_random_u32_below(4);
cond_resched();
@@@ -396,7 -396,7 +396,7 @@@ }
if (prand & 2) { - i = prandom_u32_max(entries); + i = get_random_u32_below(entries); if (test_bit(i, obj_in_table)) { err = rhltable_remove(&rhlt, &rhl_test_objects[i].list_node, test_rht_params); WARN(err, "cannot remove element at slot %d", i); @@@ -434,7 -434,7 +434,7 @@@ out_free static int __init test_rhashtable_max(struct test_obj *array, unsigned int entries) { - unsigned int i, insert_retries = 0; + unsigned int i; int err;
test_rht_params.max_size = roundup_pow_of_two(entries / 8); @@@ -447,9 -447,7 +447,7 @@@
obj->value.id = i * 2; err = insert_retry(&ht, obj, test_rht_params); - if (err > 0) - insert_retries += err; - else if (err) + if (err < 0) return err; }
diff --combined net/802/mrp.c index 8c6f0381023b,6c927d4b35f0..66fcbf23b486 --- a/net/802/mrp.c +++ b/net/802/mrp.c @@@ -592,7 -592,7 +592,7 @@@ static void mrp_join_timer_arm(struct m { unsigned long delay;
- delay = prandom_u32_max(msecs_to_jiffies(mrp_join_time)); + delay = get_random_u32_below(msecs_to_jiffies(mrp_join_time)); mod_timer(&app->join_timer, jiffies + delay); }
@@@ -606,7 -606,10 +606,10 @@@ static void mrp_join_timer(struct timer spin_unlock(&app->lock);
mrp_queue_xmit(app); - mrp_join_timer_arm(app); + spin_lock(&app->lock); + if (likely(app->active)) + mrp_join_timer_arm(app); + spin_unlock(&app->lock); }
static void mrp_periodic_timer_arm(struct mrp_applicant *app) @@@ -620,11 -623,12 +623,12 @@@ static void mrp_periodic_timer(struct t struct mrp_applicant *app = from_timer(app, t, periodic_timer);
spin_lock(&app->lock); - mrp_mad_event(app, MRP_EVENT_PERIODIC); - mrp_pdu_queue(app); + if (likely(app->active)) { + mrp_mad_event(app, MRP_EVENT_PERIODIC); + mrp_pdu_queue(app); + mrp_periodic_timer_arm(app); + } spin_unlock(&app->lock); - - mrp_periodic_timer_arm(app); }
static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset) @@@ -872,6 -876,7 +876,7 @@@ int mrp_init_applicant(struct net_devic app->dev = dev; app->app = appl; app->mad = RB_ROOT; + app->active = true; spin_lock_init(&app->lock); skb_queue_head_init(&app->queue); rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); @@@ -900,6 -905,9 +905,9 @@@ void mrp_uninit_applicant(struct net_de
RCU_INIT_POINTER(port->applicants[appl->type], NULL);
+ spin_lock_bh(&app->lock); + app->active = false; + spin_unlock_bh(&app->lock); /* Delete timer and generate a final TX event to flush out * all pending messages before the applicant is gone. */ diff --combined net/bluetooth/mgmt.c index 81ce668b0b77,0dd30a3beb77..d2ea8e19aa1b --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@@ -7373,8 -7373,9 +7373,8 @@@ static int get_conn_info(struct sock *s /* To avoid client trying to guess when to poll again for information we * calculate conn info age as random value between min/max set in hdev. */ - conn_info_age = hdev->conn_info_min_age + - prandom_u32_max(hdev->conn_info_max_age - - hdev->conn_info_min_age); + conn_info_age = get_random_u32_inclusive(hdev->conn_info_min_age, + hdev->conn_info_max_age - 1);
/* Query controller to refresh cached values if they are too old or were * never read. @@@ -8858,7 -8859,7 +8858,7 @@@ static int add_ext_adv_params(struct so * extra parameters we don't know about will be ignored in this request. */ if (data_len < MGMT_ADD_EXT_ADV_PARAMS_MIN_SIZE) - return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS, MGMT_STATUS_INVALID_PARAMS);
flags = __le32_to_cpu(cp->flags); diff --combined net/can/j1939/transport.c index 67d36776aff4,f26f4cfa9e63..5c722b55fe23 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@@ -987,7 -987,7 +987,7 @@@ static int j1939_session_tx_eoma(struc /* wait for the EOMA packet to come in */ j1939_tp_set_rxtimeout(session, 1250);
- netdev_dbg(session->priv->ndev, "%p: 0x%p\n", __func__, session); + netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
return 0; } @@@ -1168,7 -1168,7 +1168,7 @@@ static enum hrtimer_restart j1939_tp_tx if (session->tx_retry < J1939_XTP_TX_RETRY_LIMIT) { session->tx_retry++; j1939_tp_schedule_txtimer(session, - 10 + prandom_u32_max(16)); + 10 + get_random_u32_below(16)); } else { netdev_alert(priv->ndev, "%s: 0x%p: tx retry count reached\n", __func__, session); diff --combined net/core/dst.c index a4e738d321ba,bb14a0392388..6d2dd03dafa8 --- a/net/core/dst.c +++ b/net/core/dst.c @@@ -174,7 -174,7 +174,7 @@@ void dst_release(struct dst_entry *dst net_warn_ratelimited("%s: dst:%p refcnt:%d\n", __func__, dst, newrefcnt); if (!newrefcnt) - call_rcu(&dst->rcu_head, dst_destroy_rcu); + call_rcu_hurry(&dst->rcu_head, dst_destroy_rcu); } } EXPORT_SYMBOL(dst_release); @@@ -316,6 -316,8 +316,8 @@@ void metadata_dst_free(struct metadata_ if (md_dst->type == METADATA_IP_TUNNEL) dst_cache_destroy(&md_dst->u.tun_info.dst_cache); #endif + if (md_dst->type == METADATA_XFRM) + dst_release(md_dst->u.xfrm_info.dst_orig); kfree(md_dst); } EXPORT_SYMBOL_GPL(metadata_dst_free); @@@ -340,16 -342,18 +342,18 @@@ EXPORT_SYMBOL_GPL(metadata_dst_alloc_pe
void metadata_dst_free_percpu(struct metadata_dst __percpu *md_dst) { - #ifdef CONFIG_DST_CACHE int cpu;
for_each_possible_cpu(cpu) { struct metadata_dst *one_md_dst = per_cpu_ptr(md_dst, cpu);
+ #ifdef CONFIG_DST_CACHE if (one_md_dst->type == METADATA_IP_TUNNEL) dst_cache_destroy(&one_md_dst->u.tun_info.dst_cache); - } #endif + if (one_md_dst->type == METADATA_XFRM) + dst_release(one_md_dst->u.xfrm_info.dst_orig); + } free_percpu(md_dst); } EXPORT_SYMBOL_GPL(metadata_dst_free_percpu); diff --combined net/core/sock.c index c9c6af85d9c0,b0ab841e0aed..d2587d8712db --- a/net/core/sock.c +++ b/net/core/sock.c @@@ -901,13 -901,20 +901,20 @@@ int sock_set_timestamping(struct sock * if (val & ~SOF_TIMESTAMPING_MASK) return -EINVAL;
+ if (val & SOF_TIMESTAMPING_OPT_ID_TCP && + !(val & SOF_TIMESTAMPING_OPT_ID)) + return -EINVAL; + if (val & SOF_TIMESTAMPING_OPT_ID && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) { if (sk_is_tcp(sk)) { if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) return -EINVAL; - atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una); + if (val & SOF_TIMESTAMPING_OPT_ID_TCP) + atomic_set(&sk->sk_tskey, tcp_sk(sk)->write_seq); + else + atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una); } else { atomic_set(&sk->sk_tskey, 0); } @@@ -1436,7 -1443,7 +1443,7 @@@ set_sndbuf break; } case SO_INCOMING_CPU: - WRITE_ONCE(sk->sk_incoming_cpu, val); + reuseport_update_incoming_cpu(sk, val); break;
case SO_CNX_ADVICE: @@@ -1793,8 -1800,7 +1800,8 @@@ int sk_getsockopt(struct sock *sk, int break;
case SO_PEERSEC: - return security_socket_getpeersec_stream(sock, optval.user, optlen.user, len); + return security_socket_getpeersec_stream(sock, + optval, optlen, len);
case SO_MARK: v.val = sk->sk_mark; @@@ -2095,6 -2101,9 +2102,9 @@@ struct sock *sk_alloc(struct net *net, if (likely(sk->sk_net_refcnt)) { get_net_track(net, &sk->ns_tracker, priority); sock_inuse_add(net, 1); + } else { + __netns_tracker_alloc(net, &sk->ns_tracker, + false, priority); }
sock_net_set(sk, net); @@@ -2150,6 -2159,9 +2160,9 @@@ static void __sk_destruct(struct rcu_he
if (likely(sk->sk_net_refcnt)) put_net_track(sock_net(sk), &sk->ns_tracker); + else + __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); + sk_prot_free(sk->sk_prot_creator, sk); }
@@@ -2238,6 -2250,14 +2251,14 @@@ struct sock *sk_clone_lock(const struc if (likely(newsk->sk_net_refcnt)) { get_net_track(sock_net(newsk), &newsk->ns_tracker, priority); sock_inuse_add(sock_net(newsk), 1); + } else { + /* Kernel sockets are not elevating the struct net refcount. + * Instead, use a tracker to more easily detect if a layer + * is not properly dismantling its kernel sockets at netns + * destroy time. + */ + __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker, + false, priority); } sk_node_init(&newsk->sk_node); sock_lock_init(newsk); @@@ -2731,7 -2751,7 +2752,7 @@@ failure } EXPORT_SYMBOL(sock_alloc_send_pskb);
- int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, + int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg, struct sockcm_cookie *sockc) { u32 tsflags; @@@ -2785,7 -2805,7 +2806,7 @@@ int sock_cmsg_send(struct sock *sk, str return -EINVAL; if (cmsg->cmsg_level != SOL_SOCKET) continue; - ret = __sock_cmsg_send(sk, msg, cmsg, sockc); + ret = __sock_cmsg_send(sk, cmsg, sockc); if (ret) return ret; } diff --combined net/ipv4/inet_connection_sock.c index f22051219b50,4a34bc7cb15e..b366ab9148f2 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@@ -314,7 -314,7 +314,7 @@@ other_half_scan if (likely(remaining > 1)) remaining &= ~1U;
- offset = prandom_u32_max(remaining); + offset = get_random_u32_below(remaining); /* __inet_hash_connect() favors ports having @low parity * We do the opposite to not pollute connect() users. */ @@@ -471,11 -471,11 +471,11 @@@ int inet_csk_get_port(struct sock *sk, bool reuse = sk->sk_reuse && sk->sk_state != TCP_LISTEN; bool found_port = false, check_bind_conflict = true; bool bhash_created = false, bhash2_created = false; + int ret = -EADDRINUSE, port = snum, l3mdev; struct inet_bind_hashbucket *head, *head2; struct inet_bind2_bucket *tb2 = NULL; struct inet_bind_bucket *tb = NULL; bool head2_lock_acquired = false; - int ret = 1, port = snum, l3mdev; struct net *net = sock_net(sk);
l3mdev = inet_sk_bound_l3mdev(sk); @@@ -1186,7 -1186,7 +1186,7 @@@ int inet_csk_listen_start(struct sock * { struct inet_connection_sock *icsk = inet_csk(sk); struct inet_sock *inet = inet_sk(sk); - int err = -EADDRINUSE; + int err;
reqsk_queue_alloc(&icsk->icsk_accept_queue);
@@@ -1202,7 -1202,8 +1202,8 @@@ * after validation is complete. */ inet_sk_state_store(sk, TCP_LISTEN); - if (!sk->sk_prot->get_port(sk, inet->inet_num)) { + err = sk->sk_prot->get_port(sk, inet->inet_num); + if (!err) { inet->inet_sport = htons(inet->inet_num);
sk_dst_reset(sk); diff --combined net/ipv4/tcp.c index 3f570b25c53d,001947136b0a..c567d5e8053e --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@@ -2000,7 -2000,7 +2000,7 @@@ static int receive_fallback_to_copy(str if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(ITER_DEST, (void __user *)copy_address, inq, &iov, &msg.msg_iter); if (err) return err; @@@ -2034,7 -2034,7 +2034,7 @@@ static int tcp_copy_straggler_data(stru if (copy_address != zc->copybuf_address) return -EINVAL;
- err = import_single_range(READ, (void __user *)copy_address, + err = import_single_range(ITER_DEST, (void __user *)copy_address, copylen, &iov, &msg.msg_iter); if (err) return err; @@@ -3175,6 -3175,7 +3175,7 @@@ int tcp_disconnect(struct sock *sk, in tp->sacked_out = 0; tp->tlp_high_seq = 0; tp->last_oow_ack_time = 0; + tp->plb_rehash = 0; /* There's a bubble in the pipe until at least the first ACK. */ tp->app_limited = ~0U; tp->rack.mstamp = 0; @@@ -3938,6 -3939,8 +3939,8 @@@ void tcp_get_info(struct sock *sk, stru info->tcpi_reord_seen = tp->reord_seen; info->tcpi_rcv_ooopack = tp->rcv_ooopack; info->tcpi_snd_wnd = tp->snd_wnd; + info->tcpi_rcv_wnd = tp->rcv_wnd; + info->tcpi_rehash = tp->plb_rehash + tp->timeout_rehash; info->tcpi_fastopen_client_fail = tp->fastopen_client_fail; unlock_sock_fast(sk, slow); } @@@ -3972,6 -3975,7 +3975,7 @@@ static size_t tcp_opt_stats_get_size(vo nla_total_size(sizeof(u32)) + /* TCP_NLA_BYTES_NOTSENT */ nla_total_size_64bit(sizeof(u64)) + /* TCP_NLA_EDT */ nla_total_size(sizeof(u8)) + /* TCP_NLA_TTL */ + nla_total_size(sizeof(u32)) + /* TCP_NLA_REHASH */ 0; }
@@@ -4048,6 -4052,7 +4052,7 @@@ struct sk_buff *tcp_get_timestamping_op nla_put_u8(stats, TCP_NLA_TTL, tcp_skb_ttl_or_hop_limit(ack_skb));
+ nla_put_u32(stats, TCP_NLA_REHASH, tp->plb_rehash + tp->timeout_rehash); return stats; }
@@@ -4459,11 -4464,8 +4464,8 @@@ bool tcp_alloc_md5sig_pool(void if (unlikely(!READ_ONCE(tcp_md5sig_pool_populated))) { mutex_lock(&tcp_md5sig_mutex);
- if (!tcp_md5sig_pool_populated) { + if (!tcp_md5sig_pool_populated) __tcp_alloc_md5sig_pool(); - if (tcp_md5sig_pool_populated) - static_branch_inc(&tcp_md5_needed); - }
mutex_unlock(&tcp_md5sig_mutex); } diff --combined net/ipv4/tcp_input.c index 23cf418efe4f,1efacbe948da..cc072d2cfcd8 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@@ -3646,8 -3646,7 +3646,8 @@@ static void tcp_send_challenge_ack(stru u32 half = (ack_limit + 1) >> 1;
WRITE_ONCE(net->ipv4.tcp_challenge_timestamp, now); - WRITE_ONCE(net->ipv4.tcp_challenge_count, half + prandom_u32_max(ack_limit)); + WRITE_ONCE(net->ipv4.tcp_challenge_count, + get_random_u32_inclusive(half, ack_limit + half - 1)); } count = READ_ONCE(net->ipv4.tcp_challenge_count); if (count > 0) { @@@ -4765,8 -4764,8 +4765,8 @@@ static void tcp_ofo_queue(struct sock * } }
- static bool tcp_prune_ofo_queue(struct sock *sk); - static int tcp_prune_queue(struct sock *sk); + static bool tcp_prune_ofo_queue(struct sock *sk, const struct sk_buff *in_skb); + static int tcp_prune_queue(struct sock *sk, const struct sk_buff *in_skb);
static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, unsigned int size) @@@ -4774,11 -4773,11 +4774,11 @@@ if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || !sk_rmem_schedule(sk, skb, size)) {
- if (tcp_prune_queue(sk) < 0) + if (tcp_prune_queue(sk, skb) < 0) return -1;
while (!sk_rmem_schedule(sk, skb, size)) { - if (!tcp_prune_ofo_queue(sk)) + if (!tcp_prune_ofo_queue(sk, skb)) return -1; } } @@@ -5330,6 -5329,8 +5330,8 @@@ new_range * Clean the out-of-order queue to make room. * We drop high sequences packets to : * 1) Let a chance for holes to be filled. + * This means we do not drop packets from ooo queue if their sequence + * is before incoming packet sequence. * 2) not add too big latencies if thousands of packets sit there. * (But if application shrinks SO_RCVBUF, we could still end up * freeing whole queue here) @@@ -5337,24 -5338,31 +5339,31 @@@ * * Return true if queue has shrunk. */ - static bool tcp_prune_ofo_queue(struct sock *sk) + static bool tcp_prune_ofo_queue(struct sock *sk, const struct sk_buff *in_skb) { struct tcp_sock *tp = tcp_sk(sk); struct rb_node *node, *prev; + bool pruned = false; int goal;
if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) return false;
- NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED); goal = sk->sk_rcvbuf >> 3; node = &tp->ooo_last_skb->rbnode; + do { + struct sk_buff *skb = rb_to_skb(node); + + /* If incoming skb would land last in ofo queue, stop pruning. */ + if (after(TCP_SKB_CB(in_skb)->seq, TCP_SKB_CB(skb)->seq)) + break; + pruned = true; prev = rb_prev(node); rb_erase(node, &tp->out_of_order_queue); - goal -= rb_to_skb(node)->truesize; - tcp_drop_reason(sk, rb_to_skb(node), - SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE); + goal -= skb->truesize; + tcp_drop_reason(sk, skb, SKB_DROP_REASON_TCP_OFO_QUEUE_PRUNE); + tp->ooo_last_skb = rb_to_skb(prev); if (!prev || goal <= 0) { if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && !tcp_under_memory_pressure(sk)) @@@ -5363,16 -5371,18 +5372,18 @@@ } node = prev; } while (node); - tp->ooo_last_skb = rb_to_skb(prev);
- /* Reset SACK state. A conforming SACK implementation will - * do the same at a timeout based retransmit. When a connection - * is in a sad state like this, we care only about integrity - * of the connection not performance. - */ - if (tp->rx_opt.sack_ok) - tcp_sack_reset(&tp->rx_opt); - return true; + if (pruned) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED); + /* Reset SACK state. A conforming SACK implementation will + * do the same at a timeout based retransmit. When a connection + * is in a sad state like this, we care only about integrity + * of the connection not performance. + */ + if (tp->rx_opt.sack_ok) + tcp_sack_reset(&tp->rx_opt); + } + return pruned; }
/* Reduce allocated memory if we can, trying to get @@@ -5382,7 -5392,7 +5393,7 @@@ * until the socket owning process reads some of the data * to stabilize the situation. */ - static int tcp_prune_queue(struct sock *sk) + static int tcp_prune_queue(struct sock *sk, const struct sk_buff *in_skb) { struct tcp_sock *tp = tcp_sk(sk);
@@@ -5409,7 -5419,7 +5420,7 @@@ /* Collapsing did not help, destructive actions follow. * This must not ever occur. */
- tcp_prune_ofo_queue(sk); + tcp_prune_ofo_queue(sk, in_skb);
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) return 0; @@@ -6831,10 -6841,18 +6842,18 @@@ static bool tcp_syn_flood_action(const #endif __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPREQQFULLDROP);
- if (!queue->synflood_warned && syncookies != 2 && - xchg(&queue->synflood_warned, 1) == 0) - net_info_ratelimited("%s: Possible SYN flooding on port %d. %s. Check SNMP counters.\n", - proto, sk->sk_num, msg); + if (!READ_ONCE(queue->synflood_warned) && syncookies != 2 && + xchg(&queue->synflood_warned, 1) == 0) { + if (IS_ENABLED(CONFIG_IPV6) && sk->sk_family == AF_INET6) { + net_info_ratelimited("%s: Possible SYN flooding on port [%pI6c]:%u. %s.\n", + proto, inet6_rcv_saddr(sk), + sk->sk_num, msg); + } else { + net_info_ratelimited("%s: Possible SYN flooding on port %pI4:%u. %s.\n", + proto, &sk->sk_rcv_saddr, + sk->sk_num, msg); + } + }
return want_cookie; } diff --combined net/ipv6/addrconf.c index d720f6f5de3f,c338dfb05d2c..f7a84a4acffc --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@@ -104,7 -104,7 +104,7 @@@ static inline u32 cstamp_delta(unsigne static inline s32 rfc3315_s14_backoff_init(s32 irt) { /* multiply 'initial retransmission time' by 0.9 .. 1.1 */ - u64 tmp = (900000 + prandom_u32_max(200001)) * (u64)irt; + u64 tmp = get_random_u32_inclusive(900000, 1100000) * (u64)irt; do_div(tmp, 1000000); return (s32)tmp; } @@@ -112,11 -112,11 +112,11 @@@ static inline s32 rfc3315_s14_backoff_update(s32 rt, s32 mrt) { /* multiply 'retransmission timeout' by 1.9 .. 2.1 */ - u64 tmp = (1900000 + prandom_u32_max(200001)) * (u64)rt; + u64 tmp = get_random_u32_inclusive(1900000, 2100000) * (u64)rt; do_div(tmp, 1000000); if ((s32)tmp > mrt) { /* multiply 'maximum retransmission time' by 0.9 .. 1.1 */ - tmp = (900000 + prandom_u32_max(200001)) * (u64)mrt; + tmp = get_random_u32_inclusive(900000, 1100000) * (u64)mrt; do_div(tmp, 1000000); } return (s32)tmp; @@@ -3320,7 -3320,7 +3320,7 @@@ static void addrconf_addr_gen(struct in return;
/* no link local addresses on devices flagged as slaves */ - if (idev->dev->flags & IFF_SLAVE) + if (idev->dev->priv_flags & IFF_NO_ADDRCONF) return;
ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); @@@ -3560,7 -3560,7 +3560,7 @@@ static int addrconf_notify(struct notif if (idev && idev->cnf.disable_ipv6) break;
- if (dev->flags & IFF_SLAVE) { + if (dev->priv_flags & IFF_NO_ADDRCONF) { if (event == NETDEV_UP && !IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP && dev->flags & IFF_MULTICAST) ipv6_mc_up(idev); @@@ -3967,7 -3967,7 +3967,7 @@@ static void addrconf_dad_kick(struct in if (ifp->flags & IFA_F_OPTIMISTIC) rand_num = 0; else - rand_num = prandom_u32_max(idev->cnf.rtr_solicit_delay ?: 1); + rand_num = get_random_u32_below(idev->cnf.rtr_solicit_delay ? : 1);
nonce = 0; if (idev->cnf.enhanced_dad || diff --combined net/netfilter/nf_conntrack_core.c index 8006ca862551,5c3cf0834af0..496c4920505b --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@@ -211,28 -211,24 +211,24 @@@ static u32 hash_conntrack_raw(const str unsigned int zoneid, const struct net *net) { - struct { - struct nf_conntrack_man src; - union nf_inet_addr dst_addr; - unsigned int zone; - u32 net_mix; - u16 dport; - u16 proto; - } __aligned(SIPHASH_ALIGNMENT) combined; + u64 a, b, c, d;
get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd));
- memset(&combined, 0, sizeof(combined)); + /* The direction must be ignored, handle usable tuplehash members manually */ + a = (u64)tuple->src.u3.all[0] << 32 | tuple->src.u3.all[3]; + b = (u64)tuple->dst.u3.all[0] << 32 | tuple->dst.u3.all[3];
- /* The direction must be ignored, so handle usable members manually. */ - combined.src = tuple->src; - combined.dst_addr = tuple->dst.u3; - combined.zone = zoneid; - combined.net_mix = net_hash_mix(net); - combined.dport = (__force __u16)tuple->dst.u.all; - combined.proto = tuple->dst.protonum; + c = (__force u64)tuple->src.u.all << 32 | (__force u64)tuple->dst.u.all << 16; + c |= tuple->dst.protonum;
- return (u32)siphash(&combined, sizeof(combined), &nf_conntrack_hash_rnd); + d = (u64)zoneid << 32 | net_hash_mix(net); + + /* IPv4: u3.all[1,2,3] == 0 */ + c ^= (u64)tuple->src.u3.all[1] << 32 | tuple->src.u3.all[2]; + d += (u64)tuple->dst.u3.all[1] << 32 | tuple->dst.u3.all[2]; + + return (u32)siphash_4u64(a, b, c, d, &nf_conntrack_hash_rnd); }
static u32 scale_hash(u32 hash) @@@ -906,7 -902,7 +902,7 @@@ nf_conntrack_hash_check_insert(struct n nf_ct_zone_id(nf_ct_zone(ct), IP_CT_DIR_REPLY)); } while (nf_conntrack_double_lock(net, hash, reply_hash, sequence));
- max_chainlen = MIN_CHAINLEN + prandom_u32_max(MAX_CHAINLEN); + max_chainlen = MIN_CHAINLEN + get_random_u32_below(MAX_CHAINLEN);
/* See if there's one in the list already, including reverse */ hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[hash], hnnode) { @@@ -1227,7 -1223,7 +1223,7 @@@ __nf_conntrack_confirm(struct sk_buff * goto dying; }
- max_chainlen = MIN_CHAINLEN + prandom_u32_max(MAX_CHAINLEN); + max_chainlen = MIN_CHAINLEN + get_random_u32_below(MAX_CHAINLEN); /* See if there's one in the list already, including reverse: NAT could have grabbed it without realizing, since we're not in the hash. If there is, we lost race. */ diff --combined net/netlink/af_netlink.c index 7a401d94463a,d73091f6bb0f..bca2a470ccad --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@@ -812,6 -812,17 +812,17 @@@ static int netlink_release(struct socke }
sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); + + /* Because struct net might disappear soon, do not keep a pointer. */ + if (!sk->sk_net_refcnt && sock_net(sk) != &init_net) { + __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); + /* Because of deferred_put_nlk_sk and use of work queue, + * it is possible netns will be freed before this socket. + */ + sock_net_set(sk, &init_net); + __netns_tracker_alloc(&init_net, &sk->ns_tracker, + false, GFP_KERNEL); + } call_rcu(&nlk->rcu, deferred_put_nlk_sk); return 0; } @@@ -835,7 -846,7 +846,7 @@@ retry /* Bind collision, search negative portid values. */ if (rover == -4096) /* rover will be in range [S32_MIN, -4097] */ - rover = S32_MIN + prandom_u32_max(-4096 - S32_MIN); + rover = S32_MIN + get_random_u32_below(-4096 - S32_MIN); else if (rover >= -4096) rover = -4097; portid = rover--; @@@ -2488,19 -2499,24 +2499,24 @@@ void netlink_ack(struct sk_buff *in_skb flags |= NLM_F_ACK_TLVS;
skb = nlmsg_new(payload + tlvlen, GFP_KERNEL); - if (!skb) { - NETLINK_CB(in_skb).sk->sk_err = ENOBUFS; - sk_error_report(NETLINK_CB(in_skb).sk); - return; - } + if (!skb) + goto err_skb;
rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, - NLMSG_ERROR, payload, flags); + NLMSG_ERROR, sizeof(*errmsg), flags); + if (!rep) + goto err_bad_put; errmsg = nlmsg_data(rep); errmsg->error = err; - unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) - ? nlh->nlmsg_len : sizeof(*nlh), - /* Bounds checked by the skb layer. */); + errmsg->msg = *nlh; + + if (!(flags & NLM_F_CAPPED)) { + if (!nlmsg_append(skb, nlmsg_len(nlh))) + goto err_bad_put; + + memcpy(nlmsg_data(&errmsg->msg), nlmsg_data(nlh), + nlmsg_len(nlh)); + }
if (tlvlen) netlink_ack_tlv_fill(in_skb, skb, nlh, err, extack); @@@ -2508,6 -2524,14 +2524,14 @@@ nlmsg_end(skb, rep);
nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid); + + return; + + err_bad_put: + nlmsg_free(skb); + err_skb: + NETLINK_CB(in_skb).sk->sk_err = ENOBUFS; + sk_error_report(NETLINK_CB(in_skb).sk); } EXPORT_SYMBOL(netlink_ack);
diff --combined net/packet/af_packet.c index 96fea8afc004,41c4ccc3a5d6..b5ab98ca2511 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@@ -1350,7 -1350,7 +1350,7 @@@ static bool fanout_flow_is_huge(struct if (READ_ONCE(history[i]) == rxhash) count++;
- victim = prandom_u32_max(ROLLOVER_HLEN); + victim = get_random_u32_below(ROLLOVER_HLEN);
/* Avoid dirtying the cache line if possible */ if (READ_ONCE(history[victim]) != rxhash) @@@ -1386,7 -1386,7 +1386,7 @@@ static unsigned int fanout_demux_rnd(st struct sk_buff *skb, unsigned int num) { - return prandom_u32_max(num); + return get_random_u32_below(num); }
static unsigned int fanout_demux_rollover(struct packet_fanout *f, @@@ -1777,6 -1777,7 +1777,7 @@@ static int fanout_add(struct sock *sk, match->prot_hook.af_packet_net = read_pnet(&match->net); match->prot_hook.id_match = match_fanout_group; match->max_num_members = args->max_num_members; + match->prot_hook.ignore_outgoing = type_flags & PACKET_FANOUT_FLAG_IGNORE_OUTGOING; list_add(&match->list, &fanout_list); } err = -EINVAL; @@@ -3276,7 -3277,7 +3277,7 @@@ static int packet_bind_spkt(struct sock int addr_len) { struct sock *sk = sock->sk; - char name[sizeof(uaddr->sa_data) + 1]; + char name[sizeof(uaddr->sa_data_min) + 1];
/* * Check legality @@@ -3287,8 -3288,8 +3288,8 @@@ /* uaddr->sa_data comes from the userspace, it's not guaranteed to be * zero-terminated. */ - memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data)); - name[sizeof(uaddr->sa_data)] = 0; + memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data_min)); + name[sizeof(uaddr->sa_data_min)] = 0;
return packet_do_bind(sk, name, 0, pkt_sk(sk)->num); } @@@ -3559,11 -3560,11 +3560,11 @@@ static int packet_getname_spkt(struct s return -EOPNOTSUPP;
uaddr->sa_family = AF_PACKET; - memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); + memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data_min)); rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), READ_ONCE(pkt_sk(sk)->ifindex)); if (dev) - strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); + strscpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data_min)); rcu_read_unlock();
return sizeof(*uaddr); diff --combined net/sched/act_gact.c index be267ffaaba7,54f1b13b2360..904ab3d457ef --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@@ -18,6 -18,7 +18,7 @@@ #include <net/pkt_cls.h> #include <linux/tc_act/tc_gact.h> #include <net/tc_act/tc_gact.h> + #include <net/tc_wrapper.h>
static struct tc_action_ops act_gact_ops;
@@@ -25,7 -26,7 +26,7 @@@ static int gact_net_rand(struct tcf_gact *gact) { smp_rmb(); /* coupled with smp_wmb() in tcf_gact_init() */ - if (prandom_u32_max(gact->tcfg_pval)) + if (get_random_u32_below(gact->tcfg_pval)) return gact->tcf_action; return gact->tcfg_paction; } @@@ -145,8 -146,9 +146,9 @@@ release_idr return err; }
- static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a, - struct tcf_result *res) + TC_INDIRECT_SCOPE int tcf_gact_act(struct sk_buff *skb, + const struct tc_action *a, + struct tcf_result *res) { struct tcf_gact *gact = to_gact(a); int action = READ_ONCE(gact->tcf_action); diff --combined net/sched/act_sample.c index 4194480746b0,98dea08c1764..f7416b5598e0 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c @@@ -20,6 -20,7 +20,7 @@@ #include <net/tc_act/tc_sample.h> #include <net/psample.h> #include <net/pkt_cls.h> + #include <net/tc_wrapper.h>
#include <linux/if_arp.h>
@@@ -153,8 -154,9 +154,9 @@@ static bool tcf_sample_dev_ok_push(stru } }
- static int tcf_sample_act(struct sk_buff *skb, const struct tc_action *a, - struct tcf_result *res) + TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff *skb, + const struct tc_action *a, + struct tcf_result *res) { struct tcf_sample *s = to_sample(a); struct psample_group *psample_group; @@@ -168,7 -170,7 +170,7 @@@ psample_group = rcu_dereference_bh(s->psample_group);
/* randomly sample packets according to rate */ - if (psample_group && (prandom_u32_max(s->rate) == 0)) { + if (psample_group && (get_random_u32_below(s->rate) == 0)) { if (!skb_at_tc_ingress(skb)) { md.in_ifindex = skb->skb_iif; md.out_ifindex = skb->dev->ifindex; diff --combined net/sctp/socket.c index cfe72085fdc4,5acbdf0d38f3..84021a6c4f9d --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@@ -5098,13 -5098,17 +5098,17 @@@ static void sctp_destroy_sock(struct so }
/* Triggered when there are no references on the socket anymore */ - static void sctp_destruct_sock(struct sock *sk) + static void sctp_destruct_common(struct sock *sk) { struct sctp_sock *sp = sctp_sk(sk);
/* Free up the HMAC transform. */ crypto_free_shash(sp->hmac); + }
+ static void sctp_destruct_sock(struct sock *sk) + { + sctp_destruct_common(sk); inet_sock_destruct(sk); }
@@@ -5311,14 -5315,14 +5315,14 @@@ EXPORT_SYMBOL_GPL(sctp_for_each_endpoin
int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net, const union sctp_addr *laddr, - const union sctp_addr *paddr, void *p) + const union sctp_addr *paddr, void *p, int dif) { struct sctp_transport *transport; struct sctp_endpoint *ep; int err = -ENOENT;
rcu_read_lock(); - transport = sctp_addrs_lookup_transport(net, laddr, paddr); + transport = sctp_addrs_lookup_transport(net, laddr, paddr, dif, dif); if (!transport) { rcu_read_unlock(); return err; @@@ -8319,7 -8323,7 +8323,7 @@@ static int sctp_get_port_local(struct s
inet_get_local_port_range(net, &low, &high); remaining = (high - low) + 1; - rover = prandom_u32_max(remaining) + low; + rover = get_random_u32_below(remaining) + low;
do { rover++; @@@ -8394,6 -8398,7 +8398,7 @@@ pp_found * in an endpoint. */ sk_for_each_bound(sk2, &pp->owner) { + int bound_dev_if2 = READ_ONCE(sk2->sk_bound_dev_if); struct sctp_sock *sp2 = sctp_sk(sk2); struct sctp_endpoint *ep2 = sp2->ep;
@@@ -8404,7 -8409,9 +8409,9 @@@ uid_eq(uid, sock_i_uid(sk2)))) continue;
- if (sctp_bind_addr_conflict(&ep2->base.bind_addr, + if ((!sk->sk_bound_dev_if || !bound_dev_if2 || + sk->sk_bound_dev_if == bound_dev_if2) && + sctp_bind_addr_conflict(&ep2->base.bind_addr, addr, sp2, sp)) { ret = 1; goto fail_unlock; @@@ -9427,7 -9434,7 +9434,7 @@@ void sctp_copy_sock(struct sock *newsk sctp_sk(newsk)->reuse = sp->reuse;
newsk->sk_shutdown = sk->sk_shutdown; - newsk->sk_destruct = sctp_destruct_sock; + newsk->sk_destruct = sk->sk_destruct; newsk->sk_family = sk->sk_family; newsk->sk_protocol = IPPROTO_SCTP; newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv; @@@ -9662,11 -9669,20 +9669,20 @@@ struct proto sctp_prot =
#if IS_ENABLED(CONFIG_IPV6)
- #include <net/transp_v6.h> - static void sctp_v6_destroy_sock(struct sock *sk) + static void sctp_v6_destruct_sock(struct sock *sk) + { + sctp_destruct_common(sk); + inet6_sock_destruct(sk); + } + + static int sctp_v6_init_sock(struct sock *sk) { - sctp_destroy_sock(sk); - inet6_destroy_sock(sk); + int ret = sctp_init_sock(sk); + + if (!ret) + sk->sk_destruct = sctp_v6_destruct_sock; + + return ret; }
struct proto sctpv6_prot = { @@@ -9676,8 -9692,8 +9692,8 @@@ .disconnect = sctp_disconnect, .accept = sctp_accept, .ioctl = sctp_ioctl, - .init = sctp_init_sock, - .destroy = sctp_v6_destroy_sock, + .init = sctp_v6_init_sock, + .destroy = sctp_destroy_sock, .shutdown = sctp_shutdown, .setsockopt = sctp_setsockopt, .getsockopt = sctp_getsockopt, diff --combined net/socket.c index 73463c7c3702,55c5d536e5f6..888cd618a968 --- a/net/socket.c +++ b/net/socket.c @@@ -750,7 -750,7 +750,7 @@@ EXPORT_SYMBOL(sock_sendmsg) int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size) { - iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size); return sock_sendmsg(sock, msg); } EXPORT_SYMBOL(kernel_sendmsg); @@@ -776,7 -776,7 +776,7 @@@ int kernel_sendmsg_locked(struct sock * if (!sock->ops->sendmsg_locked) return sock_no_sendmsg_locked(sk, msg, size);
- iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_SOURCE, vec, num, size);
return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); } @@@ -1034,7 -1034,7 +1034,7 @@@ int kernel_recvmsg(struct socket *sock struct kvec *vec, size_t num, size_t size, int flags) { msg->msg_control_is_user = false; - iov_iter_kvec(&msg->msg_iter, READ, vec, num, size); + iov_iter_kvec(&msg->msg_iter, ITER_DEST, vec, num, size); return sock_recvmsg(sock, msg, flags); } EXPORT_SYMBOL(kernel_recvmsg); @@@ -2092,7 -2092,7 +2092,7 @@@ int __sys_sendto(int fd, void __user *b struct iovec iov; int fput_needed;
- err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter); + err = import_single_range(ITER_SOURCE, buff, len, &iov, &msg.msg_iter); if (unlikely(err)) return err; sock = sockfd_lookup_light(fd, &err, &fput_needed); @@@ -2157,7 -2157,7 +2157,7 @@@ int __sys_recvfrom(int fd, void __user int err, err2; int fput_needed;
- err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter); + err = import_single_range(ITER_DEST, ubuf, size, &iov, &msg.msg_iter); if (unlikely(err)) return err; sock = sockfd_lookup_light(fd, &err, &fput_needed); @@@ -2199,13 -2199,7 +2199,7 @@@ SYSCALL_DEFINE4(recv, int, fd, void __u
static bool sock_use_custom_sol_socket(const struct socket *sock) { - const struct sock *sk = sock->sk; - - /* Use sock->ops->setsockopt() for MPTCP */ - return IS_ENABLED(CONFIG_MPTCP) && - sk->sk_protocol == IPPROTO_MPTCP && - sk->sk_type == SOCK_STREAM && - (sk->sk_family == AF_INET || sk->sk_family == AF_INET6); + return test_bit(SOCK_CUSTOM_SOCKOPT, &sock->flags); }
/* @@@ -2417,7 -2411,7 +2411,7 @@@ static int copy_msghdr_from_user(struc if (err) return err;
- err = import_iovec(save_addr ? READ : WRITE, + err = import_iovec(save_addr ? ITER_DEST : ITER_SOURCE, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, iov, &kmsg->msg_iter); return err < 0 ? err : 0; diff --combined net/xfrm/xfrm_state.c index d63a3644ee1a,cc1d0ea42672..89c731f4f0c7 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@@ -84,6 -84,25 +84,25 @@@ static unsigned int xfrm_seq_hash(struc return __xfrm_seq_hash(seq, net->xfrm.state_hmask); }
+ #define XFRM_STATE_INSERT(by, _n, _h, _type) \ + { \ + struct xfrm_state *_x = NULL; \ + \ + if (_type != XFRM_DEV_OFFLOAD_PACKET) { \ + hlist_for_each_entry_rcu(_x, _h, by) { \ + if (_x->xso.type == XFRM_DEV_OFFLOAD_PACKET) \ + continue; \ + break; \ + } \ + } \ + \ + if (!_x || _x->xso.type == XFRM_DEV_OFFLOAD_PACKET) \ + /* SAD is empty or consist from HW SAs only */ \ + hlist_add_head_rcu(_n, _h); \ + else \ + hlist_add_before_rcu(_n, &_x->by); \ + } + static void xfrm_hash_transfer(struct hlist_head *list, struct hlist_head *ndsttable, struct hlist_head *nsrctable, @@@ -100,23 -119,25 +119,25 @@@ h = __xfrm_dst_hash(&x->id.daddr, &x->props.saddr, x->props.reqid, x->props.family, nhashmask); - hlist_add_head_rcu(&x->bydst, ndsttable + h); + XFRM_STATE_INSERT(bydst, &x->bydst, ndsttable + h, x->xso.type);
h = __xfrm_src_hash(&x->id.daddr, &x->props.saddr, x->props.family, nhashmask); - hlist_add_head_rcu(&x->bysrc, nsrctable + h); + XFRM_STATE_INSERT(bysrc, &x->bysrc, nsrctable + h, x->xso.type);
if (x->id.spi) { h = __xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family, nhashmask); - hlist_add_head_rcu(&x->byspi, nspitable + h); + XFRM_STATE_INSERT(byspi, &x->byspi, nspitable + h, + x->xso.type); }
if (x->km.seq) { h = __xfrm_seq_hash(x->km.seq, nhashmask); - hlist_add_head_rcu(&x->byseq, nseqtable + h); + XFRM_STATE_INSERT(byseq, &x->byseq, nseqtable + h, + x->xso.type); } } } @@@ -549,6 -570,8 +570,8 @@@ static enum hrtimer_restart xfrm_timer_ int err = 0;
spin_lock(&x->lock); + xfrm_dev_state_update_curlft(x); + if (x->km.state == XFRM_STATE_DEAD) goto out; if (x->km.state == XFRM_STATE_EXPIRED) @@@ -951,6 -974,49 +974,49 @@@ xfrm_init_tempstate(struct xfrm_state * x->props.family = tmpl->encap_family; }
+ static struct xfrm_state *__xfrm_state_lookup_all(struct net *net, u32 mark, + const xfrm_address_t *daddr, + __be32 spi, u8 proto, + unsigned short family, + struct xfrm_dev_offload *xdo) + { + unsigned int h = xfrm_spi_hash(net, daddr, spi, proto, family); + struct xfrm_state *x; + + hlist_for_each_entry_rcu(x, net->xfrm.state_byspi + h, byspi) { + #ifdef CONFIG_XFRM_OFFLOAD + if (xdo->type == XFRM_DEV_OFFLOAD_PACKET) { + if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) + /* HW states are in the head of list, there is + * no need to iterate further. + */ + break; + + /* Packet offload: both policy and SA should + * have same device. + */ + if (xdo->dev != x->xso.dev) + continue; + } else if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) + /* Skip HW policy for SW lookups */ + continue; + #endif + if (x->props.family != family || + x->id.spi != spi || + x->id.proto != proto || + !xfrm_addr_equal(&x->id.daddr, daddr, family)) + continue; + + if ((mark & x->mark.m) != x->mark.v) + continue; + if (!xfrm_state_hold_rcu(x)) + continue; + return x; + } + + return NULL; + } + static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark, const xfrm_address_t *daddr, __be32 spi, u8 proto, @@@ -1092,6 -1158,23 +1158,23 @@@ xfrm_state_find(const xfrm_address_t *d rcu_read_lock(); h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h, bydst) { + #ifdef CONFIG_XFRM_OFFLOAD + if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) { + if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) + /* HW states are in the head of list, there is + * no need to iterate further. + */ + break; + + /* Packet offload: both policy and SA should + * have same device. + */ + if (pol->xdo.dev != x->xso.dev) + continue; + } else if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) + /* Skip HW policy for SW lookups */ + continue; + #endif if (x->props.family == encap_family && x->props.reqid == tmpl->reqid && (mark & x->mark.m) == x->mark.v && @@@ -1109,6 -1192,23 +1192,23 @@@
h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family); hlist_for_each_entry_rcu(x, net->xfrm.state_bydst + h_wildcard, bydst) { + #ifdef CONFIG_XFRM_OFFLOAD + if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) { + if (x->xso.type != XFRM_DEV_OFFLOAD_PACKET) + /* HW states are in the head of list, there is + * no need to iterate further. + */ + break; + + /* Packet offload: both policy and SA should + * have same device. + */ + if (pol->xdo.dev != x->xso.dev) + continue; + } else if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET) + /* Skip HW policy for SW lookups */ + continue; + #endif if (x->props.family == encap_family && x->props.reqid == tmpl->reqid && (mark & x->mark.m) == x->mark.v && @@@ -1126,8 -1226,10 +1226,10 @@@ found x = best; if (!x && !error && !acquire_in_progress) { if (tmpl->id.spi && - (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, - tmpl->id.proto, encap_family)) != NULL) { + (x0 = __xfrm_state_lookup_all(net, mark, daddr, + tmpl->id.spi, tmpl->id.proto, + encap_family, + &pol->xdo)) != NULL) { to_put = x0; error = -EEXIST; goto out; @@@ -1161,21 -1263,53 +1263,53 @@@ x = NULL; goto out; } - + #ifdef CONFIG_XFRM_OFFLOAD + if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET) { + struct xfrm_dev_offload *xdo = &pol->xdo; + struct xfrm_dev_offload *xso = &x->xso; + + xso->type = XFRM_DEV_OFFLOAD_PACKET; + xso->dir = xdo->dir; + xso->dev = xdo->dev; + xso->real_dev = xdo->real_dev; + netdev_tracker_alloc(xso->dev, &xso->dev_tracker, + GFP_ATOMIC); + error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x); + if (error) { + xso->dir = 0; + netdev_put(xso->dev, &xso->dev_tracker); + xso->dev = NULL; + xso->real_dev = NULL; + xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; + x->km.state = XFRM_STATE_DEAD; + to_put = x; + x = NULL; + goto out; + } + } + #endif if (km_query(x, tmpl, pol) == 0) { spin_lock_bh(&net->xfrm.xfrm_state_lock); x->km.state = XFRM_STATE_ACQ; list_add(&x->km.all, &net->xfrm.state_all); - hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h); + XFRM_STATE_INSERT(bydst, &x->bydst, + net->xfrm.state_bydst + h, + x->xso.type); h = xfrm_src_hash(net, daddr, saddr, encap_family); - hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h); + XFRM_STATE_INSERT(bysrc, &x->bysrc, + net->xfrm.state_bysrc + h, + x->xso.type); if (x->id.spi) { h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family); - hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); + XFRM_STATE_INSERT(byspi, &x->byspi, + net->xfrm.state_byspi + h, + x->xso.type); } if (x->km.seq) { h = xfrm_seq_hash(net, x->km.seq); - hlist_add_head_rcu(&x->byseq, net->xfrm.state_byseq + h); + XFRM_STATE_INSERT(byseq, &x->byseq, + net->xfrm.state_byseq + h, + x->xso.type); } x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; hrtimer_start(&x->mtimer, @@@ -1185,6 -1319,18 +1319,18 @@@ xfrm_hash_grow_check(net, x->bydst.next != NULL); spin_unlock_bh(&net->xfrm.xfrm_state_lock); } else { + #ifdef CONFIG_XFRM_OFFLOAD + struct xfrm_dev_offload *xso = &x->xso; + + if (xso->type == XFRM_DEV_OFFLOAD_PACKET) { + xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); + xso->dir = 0; + netdev_put(xso->dev, &xso->dev_tracker); + xso->dev = NULL; + xso->real_dev = NULL; + xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; + } + #endif x->km.state = XFRM_STATE_DEAD; to_put = x; x = NULL; @@@ -1280,22 -1426,26 +1426,26 @@@ static void __xfrm_state_insert(struct
h = xfrm_dst_hash(net, &x->id.daddr, &x->props.saddr, x->props.reqid, x->props.family); - hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h); + XFRM_STATE_INSERT(bydst, &x->bydst, net->xfrm.state_bydst + h, + x->xso.type);
h = xfrm_src_hash(net, &x->id.daddr, &x->props.saddr, x->props.family); - hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h); + XFRM_STATE_INSERT(bysrc, &x->bysrc, net->xfrm.state_bysrc + h, + x->xso.type);
if (x->id.spi) { h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
- hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); + XFRM_STATE_INSERT(byspi, &x->byspi, net->xfrm.state_byspi + h, + x->xso.type); }
if (x->km.seq) { h = xfrm_seq_hash(net, x->km.seq);
- hlist_add_head_rcu(&x->byseq, net->xfrm.state_byseq + h); + XFRM_STATE_INSERT(byseq, &x->byseq, net->xfrm.state_byseq + h, + x->xso.type); }
hrtimer_start(&x->mtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT); @@@ -1409,9 -1559,11 +1559,11 @@@ static struct xfrm_state *__find_acq_co ktime_set(net->xfrm.sysctl_acq_expires, 0), HRTIMER_MODE_REL_SOFT); list_add(&x->km.all, &net->xfrm.state_all); - hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h); + XFRM_STATE_INSERT(bydst, &x->bydst, net->xfrm.state_bydst + h, + x->xso.type); h = xfrm_src_hash(net, daddr, saddr, family); - hlist_add_head_rcu(&x->bysrc, net->xfrm.state_bysrc + h); + XFRM_STATE_INSERT(bysrc, &x->bysrc, net->xfrm.state_bysrc + h, + x->xso.type);
net->xfrm.state_num++;
@@@ -1786,6 -1938,8 +1938,8 @@@ EXPORT_SYMBOL(xfrm_state_update)
int xfrm_state_check_expire(struct xfrm_state *x) { + xfrm_dev_state_update_curlft(x); + if (!x->curlft.use_time) x->curlft.use_time = ktime_get_real_seconds();
@@@ -2017,7 -2171,7 +2171,7 @@@ u32 xfrm_get_acqseq(void } EXPORT_SYMBOL(xfrm_get_acqseq);
- int verify_spi_info(u8 proto, u32 min, u32 max) + int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack) { switch (proto) { case IPPROTO_AH: @@@ -2026,22 -2180,28 +2180,28 @@@
case IPPROTO_COMP: /* IPCOMP spi is 16-bits. */ - if (max >= 0x10000) + if (max >= 0x10000) { + NL_SET_ERR_MSG(extack, "IPCOMP SPI must be <= 65535"); return -EINVAL; + } break;
default: + NL_SET_ERR_MSG(extack, "Invalid protocol, must be one of AH, ESP, IPCOMP"); return -EINVAL; }
- if (min > max) + if (min > max) { + NL_SET_ERR_MSG(extack, "Invalid SPI range: min > max"); return -EINVAL; + }
return 0; } EXPORT_SYMBOL(verify_spi_info);
- int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high) + int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high, + struct netlink_ext_ack *extack) { struct net *net = xs_net(x); unsigned int h; @@@ -2053,8 -2213,10 +2213,10 @@@ u32 mark = x->mark.v & x->mark.m;
spin_lock_bh(&x->lock); - if (x->km.state == XFRM_STATE_DEAD) + if (x->km.state == XFRM_STATE_DEAD) { + NL_SET_ERR_MSG(extack, "Target ACQUIRE is in DEAD state"); goto unlock; + }
err = 0; if (x->id.spi) @@@ -2065,6 -2227,7 +2227,7 @@@ if (minspi == maxspi) { x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family); if (x0) { + NL_SET_ERR_MSG(extack, "Requested SPI is already in use"); xfrm_state_put(x0); goto unlock; } @@@ -2072,7 -2235,7 +2235,7 @@@ } else { u32 spi = 0; for (h = 0; h < high-low+1; h++) { - spi = low + prandom_u32_max(high - low + 1); + spi = get_random_u32_inclusive(low, high); x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family); if (x0 == NULL) { newspi = htonl(spi); @@@ -2085,10 -2248,13 +2248,13 @@@ spin_lock_bh(&net->xfrm.xfrm_state_lock); x->id.spi = newspi; h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family); - hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); + XFRM_STATE_INSERT(byspi, &x->byspi, net->xfrm.state_byspi + h, + x->xso.type); spin_unlock_bh(&net->xfrm.xfrm_state_lock);
err = 0; + } else { + NL_SET_ERR_MSG(extack, "No SPI available in the requested range"); }
unlock: diff --combined tools/lib/bpf/Makefile index 7f5f7d2ebe1f,477666f3d496..cf7f02c67968 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@@ -255,7 -255,6 +255,7 @@@ $(INSTALL_GEN_HDRS): $(INSTALL_PFX)/%.h $(call do_install,$<,$(prefix)/include/bpf,644)
install_headers: $(BPF_GENERATED) $(INSTALL_SRC_HDRS) $(INSTALL_GEN_HDRS) + $(call QUIET_INSTALL, libbpf_headers)
install_pkgconfig: $(PC_FILE) $(call QUIET_INSTALL, $(PC_FILE)) \ @@@ -287,3 -286,20 +287,20 @@@ tags
# Delete partially updated (corrupted) files on error .DELETE_ON_ERROR: + + help: + @echo 'libbpf common targets:' + @echo ' HINT: use "V=1" to enable verbose build' + @echo ' all - build libraries and pkgconfig' + @echo ' clean - remove all generated files' + @echo ' check - check abi and version info' + @echo '' + @echo 'libbpf install targets:' + @echo ' HINT: use "prefix"(defaults to "/usr/local") or "DESTDIR" (defaults to "/")' + @echo ' to adjust target desitantion, e.g. "make prefix=/usr/local install"' + @echo ' install - build and install all headers, libraries and pkgconfig' + @echo ' install_headers - install only headers to include/bpf' + @echo '' + @echo 'libbpf make targets:' + @echo ' tags - use ctags to make tag information for source code browsing' + @echo ' cscope - use cscope to make interactive source code browsing database' diff --combined tools/perf/tests/expr.c index b6667501ebb4,c598f95aebf3..a9eb1ed6bd63 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@@ -2,7 -2,6 +2,7 @@@ #include "util/cputopo.h" #include "util/debug.h" #include "util/expr.h" +#include "util/hashmap.h" #include "util/header.h" #include "util/smt.h" #include "tests.h" @@@ -131,12 -130,9 +131,9 @@@ static int test__expr(struct test_suit expr__find_ids("FOO + BAR + BAZ + BOZO", "FOO", ctx) == 0); TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 3); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAR", - (void **)&val_ptr)); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAZ", - (void **)&val_ptr)); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BOZO", - (void **)&val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAR", &val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAZ", &val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BOZO", &val_ptr));
expr__ctx_clear(ctx); ctx->sctx.runtime = 3; @@@ -144,20 -140,16 +141,16 @@@ expr__find_ids("EVENT1\,param\=?@ + EVENT2\,param\=?@", NULL, ctx) == 0); TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 2); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1,param=3@", - (void **)&val_ptr)); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT2,param=3@", - (void **)&val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1,param=3@", &val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT2,param=3@", &val_ptr));
expr__ctx_clear(ctx); TEST_ASSERT_VAL("find ids", expr__find_ids("dash\-event1 - dash\-event2", NULL, ctx) == 0); TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 2); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event1", - (void **)&val_ptr)); - TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event2", - (void **)&val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event1", &val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event2", &val_ptr));
/* Only EVENT1 or EVENT2 need be measured depending on the value of smt_on. */ { @@@ -175,7 -167,7 +168,7 @@@ TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, smton ? "EVENT1" : "EVENT2", - (void **)&val_ptr)); + &val_ptr));
expr__ctx_clear(ctx); TEST_ASSERT_VAL("find ids", @@@ -184,7 -176,7 +177,7 @@@ TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, corewide ? "EVENT1" : "EVENT2", - (void **)&val_ptr)); + &val_ptr));
} /* The expression is a constant 1.0 without needing to evaluate EVENT1. */ @@@ -221,8 -213,7 +214,7 @@@ expr__find_ids("source_count(EVENT1)", NULL, ctx) == 0); TEST_ASSERT_VAL("source count", hashmap__size(ctx->ids) == 1); - TEST_ASSERT_VAL("source count", hashmap__find(ctx->ids, "EVENT1", - (void **)&val_ptr)); + TEST_ASSERT_VAL("source count", hashmap__find(ctx->ids, "EVENT1", &val_ptr));
expr__ctx_free(ctx);
diff --combined tools/perf/tests/pmu-events.c index f7b9dbbad97f,3c2ee55e75c7..e36d8b1610d4 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@@ -12,7 -12,6 +12,7 @@@ #include <perf/evlist.h> #include "util/evlist.h" #include "util/expr.h" +#include "util/hashmap.h" #include "util/parse-events.h" #include "metricgroup.h" #include "stat.h" @@@ -890,7 -889,7 +890,7 @@@ static int test__parsing_callback(cons goto out_err; }
- err = evlist__alloc_stats(evlist, false); + err = evlist__alloc_stats(/*config=*/NULL, evlist, /*alloc_raw=*/false); if (err) goto out_err; /* @@@ -987,10 -986,10 +987,10 @@@ static int metric_parse_fake(const cha */ i = 1; hashmap__for_each_entry(ctx->ids, cur, bkt) - expr__add_id_val(ctx, strdup(cur->key), i++); + expr__add_id_val(ctx, strdup(cur->pkey), i++);
hashmap__for_each_entry(ctx->ids, cur, bkt) { - if (check_parse_fake(cur->key)) { + if (check_parse_fake(cur->pkey)) { pr_err("check_parse_fake failed\n"); goto out; } @@@ -1004,7 -1003,7 +1004,7 @@@ */ i = 1024; hashmap__for_each_entry(ctx->ids, cur, bkt) - expr__add_id_val(ctx, strdup(cur->key), i--); + expr__add_id_val(ctx, strdup(cur->pkey), i--); if (expr__parse(&result, ctx, str)) { pr_err("expr__parse failed\n"); ret = -1; diff --combined tools/perf/util/bpf-loader.c index b3c8174360bf,a5dbd71cb9ab..6e9b06cf06ee --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@@ -27,7 -27,11 +27,7 @@@ #include "util.h" #include "llvm-utils.h" #include "c++/clang-c.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include <bpf/hashmap.h> -#else #include "util/hashmap.h" -#endif #include "asm/bug.h"
#include <internal/xyarray.h> @@@ -314,7 -318,7 +314,7 @@@ static void bpf_program_hash_free(void return;
hashmap__for_each_entry(bpf_program_hash, cur, bkt) - clear_prog_priv(cur->key, cur->value); + clear_prog_priv(cur->pkey, cur->pvalue);
hashmap__free(bpf_program_hash); bpf_program_hash = NULL; @@@ -335,13 -339,12 +335,12 @@@ void bpf__clear(void bpf_map_hash_free(); }
- static size_t ptr_hash(const void *__key, void *ctx __maybe_unused) + static size_t ptr_hash(const long __key, void *ctx __maybe_unused) { - return (size_t) __key; + return __key; }
- static bool ptr_equal(const void *key1, const void *key2, - void *ctx __maybe_unused) + static bool ptr_equal(long key1, long key2, void *ctx __maybe_unused) { return key1 == key2; } @@@ -1181,7 -1184,7 +1180,7 @@@ static void bpf_map_hash_free(void return;
hashmap__for_each_entry(bpf_map_hash, cur, bkt) - bpf_map_priv__clear(cur->key, cur->value); + bpf_map_priv__clear(cur->pkey, cur->pvalue);
hashmap__free(bpf_map_hash); bpf_map_hash = NULL; diff --combined tools/perf/util/evsel.c index 77b2cf5a214e,9e8a1294c981..999dd1700502 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@@ -12,6 -12,7 +12,6 @@@ #include <linux/bitops.h> #include <api/fs/fs.h> #include <api/fs/tracing_path.h> -#include <traceevent/event-parse.h> #include <linux/hw_breakpoint.h> #include <linux/perf_event.h> #include <linux/compiler.h> @@@ -45,21 -46,20 +45,21 @@@ #include "string2.h" #include "memswap.h" #include "util.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include <bpf/hashmap.h> -#else #include "util/hashmap.h" -#endif #include "pmu-hybrid.h" #include "off_cpu.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" #include <internal/xyarray.h> #include <internal/lib.h> +#include <internal/threadmap.h>
#include <linux/ctype.h>
+#ifdef HAVE_LIBTRACEEVENT +#include <traceevent/event-parse.h> +#endif + struct perf_missing_features perf_missing_features;
static clockid_t clockid; @@@ -442,9 -442,7 +442,9 @@@ struct evsel *evsel__clone(struct evse goto out_err; } evsel->cgrp = cgroup__get(orig->cgrp); +#ifdef HAVE_LIBTRACEEVENT evsel->tp_format = orig->tp_format; +#endif evsel->handler = orig->handler; evsel->core.leader = orig->core.leader;
@@@ -469,7 -467,6 +469,7 @@@ evsel->collect_stat = orig->collect_stat; evsel->weak_group = orig->weak_group; evsel->use_config_name = orig->use_config_name; + evsel->pmu = orig->pmu;
if (evsel__copy_config_terms(evsel, orig) < 0) goto out_err; @@@ -484,7 -481,6 +484,7 @@@ out_err /* * Returns pointer with encoded error via <linux/err.h> interface. */ +#ifdef HAVE_LIBTRACEEVENT struct evsel *evsel__newtp_idx(const char *sys, const char *name, int idx) { struct evsel *evsel = zalloc(perf_evsel__object.size); @@@ -522,7 -518,6 +522,7 @@@ out_free out_err: return ERR_PTR(err); } +#endif
const char *const evsel__hw_names[PERF_COUNT_HW_MAX] = { "cycles", @@@ -1530,8 -1525,13 +1530,8 @@@ void evsel__compute_deltas(struct evse if (!evsel->prev_raw_counts) return;
- if (cpu_map_idx == -1) { - tmp = evsel->prev_raw_counts->aggr; - evsel->prev_raw_counts->aggr = *count; - } else { - tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); - *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count; - } + tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); + *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count;
count->val = count->val - tmp.val; count->ena = count->ena - tmp.ena; @@@ -1966,16 -1966,17 +1966,16 @@@ bool evsel__detect_missing_features(str perf_missing_features.mmap2 = true; pr_debug2_peo("switching off mmap2\n"); return true; - } else if ((evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host) && - (evsel->pmu == NULL || evsel->pmu->missing_features.exclude_guest)) { - if (evsel->pmu == NULL) { + } else if (evsel->core.attr.exclude_guest || evsel->core.attr.exclude_host) { + if (evsel->pmu == NULL) evsel->pmu = evsel__find_pmu(evsel); - if (evsel->pmu) - evsel->pmu->missing_features.exclude_guest = true; - else { - /* we cannot find PMU, disable attrs now */ - evsel->core.attr.exclude_host = false; - evsel->core.attr.exclude_guest = false; - } + + if (evsel->pmu) + evsel->pmu->missing_features.exclude_guest = true; + else { + /* we cannot find PMU, disable attrs now */ + evsel->core.attr.exclude_host = false; + evsel->core.attr.exclude_guest = false; }
if (evsel->exclude_GH) { @@@ -2327,8 -2328,11 +2327,8 @@@ u64 evsel__bitfield_swap_branch_flags(u * as it has variable bit-field sizes. Instead the * macro takes the bit-field position/size, * swaps it based on the host endianness. - * - * tep_is_bigendian() is used here instead of - * bigendian() to avoid python test fails. */ - if (tep_is_bigendian()) { + if (host_is_bigendian()) { new_val = bitfield_swap(value, 0, 1); new_val |= bitfield_swap(value, 1, 1); new_val |= bitfield_swap(value, 2, 1); @@@ -2765,7 -2769,6 +2765,7 @@@ u16 evsel__id_hdr_size(struct evsel *ev return size; }
+#ifdef HAVE_LIBTRACEEVENT struct tep_format_field *evsel__field(struct evsel *evsel, const char *name) { return tep_find_field(evsel->tp_format, name); @@@ -2784,10 -2787,8 +2784,10 @@@ void *evsel__rawptr(struct evsel *evsel if (field->flags & TEP_FIELD_IS_DYNAMIC) { offset = *(int *)(sample->raw_data + field->offset); offset &= 0xffff; +#ifdef HAVE_LIBTRACEEVENT_TEP_FIELD_IS_RELATIVE if (field->flags & TEP_FIELD_IS_RELATIVE) offset += field->offset + field->size; +#endif }
return sample->raw_data + offset; @@@ -2841,7 -2842,6 +2841,7 @@@ u64 evsel__intval(struct evsel *evsel,
return field ? format_field__intval(field, sample, evsel->needs_swap) : 0; } +#endif
bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize) { @@@ -3123,13 -3123,13 +3123,13 @@@ void evsel__zero_per_pkg(struct evsel *
if (evsel->per_pkg_mask) { hashmap__for_each_entry(evsel->per_pkg_mask, cur, bkt) - free((char *)cur->key); + free((void *)cur->pkey);
hashmap__clear(evsel->per_pkg_mask); } }
-bool evsel__is_hybrid(struct evsel *evsel) +bool evsel__is_hybrid(const struct evsel *evsel) { return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name); } diff --combined tools/perf/util/expr.c index 140f2acdb325,2f05ecdcfe9a..00dcde35e0d3 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@@ -11,7 -11,6 +11,7 @@@ #include "expr.h" #include "expr-bison.h" #include "expr-flex.h" +#include "util/hashmap.h" #include "smt.h" #include "tsc.h" #include <linux/err.h> @@@ -47,7 -46,7 +47,7 @@@ struct expr_id_data } kind; };
- static size_t key_hash(const void *key, void *ctx __maybe_unused) + static size_t key_hash(long key, void *ctx __maybe_unused) { const char *str = (const char *)key; size_t hash = 0; @@@ -60,8 -59,7 +60,7 @@@ return hash; }
- static bool key_equal(const void *key1, const void *key2, - void *ctx __maybe_unused) + static bool key_equal(long key1, long key2, void *ctx __maybe_unused) { return !strcmp((const char *)key1, (const char *)key2); } @@@ -85,8 -83,8 +84,8 @@@ void ids__free(struct hashmap *ids return;
hashmap__for_each_entry(ids, cur, bkt) { - free((char *)cur->key); - free(cur->value); + free((void *)cur->pkey); + free((void *)cur->pvalue); }
hashmap__free(ids); @@@ -98,8 -96,7 +97,7 @@@ int ids__insert(struct hashmap *ids, co char *old_key = NULL; int ret;
- ret = hashmap__set(ids, id, data_ptr, - (const void **)&old_key, (void **)&old_data); + ret = hashmap__set(ids, id, data_ptr, &old_key, &old_data); if (ret) free(data_ptr); free(old_key); @@@ -128,8 -125,7 +126,7 @@@ struct hashmap *ids__union(struct hashm ids2 = tmp; } hashmap__for_each_entry(ids2, cur, bkt) { - ret = hashmap__set(ids1, cur->key, cur->value, - (const void **)&old_key, (void **)&old_data); + ret = hashmap__set(ids1, cur->key, cur->value, &old_key, &old_data); free(old_key); free(old_data);
@@@ -170,8 -166,7 +167,7 @@@ int expr__add_id_val_source_count(struc data_ptr->val.source_count = source_count; data_ptr->kind = EXPR_ID_DATA__VALUE;
- ret = hashmap__set(ctx->ids, id, data_ptr, - (const void **)&old_key, (void **)&old_data); + ret = hashmap__set(ctx->ids, id, data_ptr, &old_key, &old_data); if (ret) free(data_ptr); free(old_key); @@@ -206,8 -201,7 +202,7 @@@ int expr__add_ref(struct expr_parse_ct data_ptr->ref.metric_expr = ref->metric_expr; data_ptr->kind = EXPR_ID_DATA__REF;
- ret = hashmap__set(ctx->ids, name, data_ptr, - (const void **)&old_key, (void **)&old_data); + ret = hashmap__set(ctx->ids, name, data_ptr, &old_key, &old_data); if (ret) free(data_ptr);
@@@ -222,7 -216,7 +217,7 @@@ int expr__get_id(struct expr_parse_ctx *ctx, const char *id, struct expr_id_data **data) { - return hashmap__find(ctx->ids, id, (void **)data) ? 0 : -1; + return hashmap__find(ctx->ids, id, data) ? 0 : -1; }
bool expr__subset_of_ids(struct expr_parse_ctx *haystack, @@@ -233,7 -227,7 +228,7 @@@ struct expr_id_data *data;
hashmap__for_each_entry(needles->ids, cur, bkt) { - if (expr__get_id(haystack, cur->key, &data)) + if (expr__get_id(haystack, cur->pkey, &data)) return false; } return true; @@@ -283,8 -277,7 +278,7 @@@ void expr__del_id(struct expr_parse_ct struct expr_id_data *old_val = NULL; char *old_key = NULL;
- hashmap__delete(ctx->ids, id, - (const void **)&old_key, (void **)&old_val); + hashmap__delete(ctx->ids, id, &old_key, &old_val); free(old_key); free(old_val); } @@@ -315,8 -308,8 +309,8 @@@ void expr__ctx_clear(struct expr_parse_ size_t bkt;
hashmap__for_each_entry(ctx->ids, cur, bkt) { - free((char *)cur->key); - free(cur->value); + free((void *)cur->pkey); + free(cur->pvalue); } hashmap__clear(ctx->ids); } @@@ -331,8 -324,8 +325,8 @@@ void expr__ctx_free(struct expr_parse_c
free(ctx->sctx.user_requested_cpu_list); hashmap__for_each_entry(ctx->ids, cur, bkt) { - free((char *)cur->key); - free(cur->value); + free((void *)cur->pkey); + free(cur->pvalue); } hashmap__free(ctx->ids); free(ctx); diff --combined tools/perf/util/metricgroup.c index 6eac7a60ed27,6b3505b1b6ac..b9c273ed080a --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@@ -12,7 -12,6 +12,7 @@@ #include "strbuf.h" #include "pmu.h" #include "pmu-hybrid.h" +#include "print-events.h" #include "expr.h" #include "rblist.h" #include <string.h> @@@ -29,7 -28,6 +29,7 @@@ #include "util.h" #include <asm/bug.h> #include "cgroup.h" +#include "util/hashmap.h"
struct metric_event *metricgroup__lookup(struct rblist *metric_events, struct evsel *evsel, @@@ -290,7 -288,7 +290,7 @@@ static int setup_metric_events(struct h * combined or shared groups, this metric may not care * about this event. */ - if (hashmap__find(ids, metric_id, (void **)&val_ptr)) { + if (hashmap__find(ids, metric_id, &val_ptr)) { metric_events[matched_events++] = ev;
if (matched_events >= ids_size) @@@ -354,65 -352,51 +354,65 @@@ static bool match_pe_metric(const struc match_metric(pe->metric_name, metric); }
+/** struct mep - RB-tree node for building printing information. */ struct mep { + /** nd - RB-tree element. */ struct rb_node nd; - const char *name; - struct strlist *metrics; + /** @metric_group: Owned metric group name, separated others with ';'. */ + char *metric_group; + const char *metric_name; + const char *metric_desc; + const char *metric_long_desc; + const char *metric_expr; + const char *metric_unit; };
static int mep_cmp(struct rb_node *rb_node, const void *entry) { struct mep *a = container_of(rb_node, struct mep, nd); struct mep *b = (struct mep *)entry; + int ret; + + ret = strcmp(a->metric_group, b->metric_group); + if (ret) + return ret;
- return strcmp(a->name, b->name); + return strcmp(a->metric_name, b->metric_name); }
-static struct rb_node *mep_new(struct rblist *rl __maybe_unused, - const void *entry) +static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry) { struct mep *me = malloc(sizeof(struct mep));
if (!me) return NULL; + memcpy(me, entry, sizeof(struct mep)); - me->name = strdup(me->name); - if (!me->name) - goto out_me; - me->metrics = strlist__new(NULL, NULL); - if (!me->metrics) - goto out_name; return &me->nd; -out_name: - zfree(&me->name); -out_me: +} + +static void mep_delete(struct rblist *rl __maybe_unused, + struct rb_node *nd) +{ + struct mep *me = container_of(nd, struct mep, nd); + + zfree(&me->metric_group); free(me); - return NULL; }
-static struct mep *mep_lookup(struct rblist *groups, const char *name) +static struct mep *mep_lookup(struct rblist *groups, const char *metric_group, + const char *metric_name) { struct rb_node *nd; struct mep me = { - .name = name + .metric_group = strdup(metric_group), + .metric_name = metric_name, }; nd = rblist__find(groups, &me); - if (nd) + if (nd) { + free(me.metric_group); return container_of(nd, struct mep, nd); + } rblist__add_node(groups, &me); nd = rblist__find(groups, &me); if (nd) @@@ -420,37 -404,107 +420,37 @@@ return NULL; }
-static void mep_delete(struct rblist *rl __maybe_unused, - struct rb_node *nd) -{ - struct mep *me = container_of(nd, struct mep, nd); - - strlist__delete(me->metrics); - zfree(&me->name); - free(me); -} - -static void metricgroup__print_strlist(struct strlist *metrics, bool raw) -{ - struct str_node *sn; - int n = 0; - - strlist__for_each_entry (sn, metrics) { - if (raw) - printf("%s%s", n > 0 ? " " : "", sn->s); - else - printf(" %s\n", sn->s); - n++; - } - if (raw) - putchar('\n'); -} - -static int metricgroup__print_pmu_event(const struct pmu_event *pe, - bool metricgroups, char *filter, - bool raw, bool details, - struct rblist *groups, - struct strlist *metriclist) +static int metricgroup__add_to_mep_groups(const struct pmu_event *pe, + struct rblist *groups) { const char *g; char *omg, *mg;
- g = pe->metric_group; - if (!g && pe->metric_name) { - if (pe->name) - return 0; - g = "No_group"; - } - - if (!g) - return 0; - - mg = strdup(g); - + mg = strdup(pe->metric_group ?: "No_group"); if (!mg) return -ENOMEM; omg = mg; while ((g = strsep(&mg, ";")) != NULL) { struct mep *me; - char *s;
g = skip_spaces(g); - if (*g == 0) - g = "No_group"; - if (filter && !strstr(g, filter)) - continue; - if (raw) - s = (char *)pe->metric_name; - else { - if (asprintf(&s, "%s\n%*s%s]", - pe->metric_name, 8, "[", pe->desc) < 0) - return -1; - if (details) { - if (asprintf(&s, "%s\n%*s%s]", - s, 8, "[", pe->metric_expr) < 0) - return -1; - } - } - - if (!s) - continue; + if (strlen(g)) + me = mep_lookup(groups, g, pe->metric_name); + else + me = mep_lookup(groups, "No_group", pe->metric_name);
- if (!metricgroups) { - strlist__add(metriclist, s); - } else { - me = mep_lookup(groups, g); - if (!me) - continue; - strlist__add(me->metrics, s); + if (me) { + me->metric_desc = pe->desc; + me->metric_long_desc = pe->long_desc; + me->metric_expr = pe->metric_expr; + me->metric_unit = pe->unit; } - - if (!raw) - free(s); } free(omg);
return 0; }
-struct metricgroup_print_sys_idata { - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - struct metricgroup_iter_data { pmu_event_iter_fn fn; void *data; @@@ -473,26 -527,60 +473,26 @@@ static int metricgroup__sys_event_iter(
return d->fn(pe, table, d->data); } - return 0; }
-static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *data) -{ - struct metricgroup_print_sys_idata *d = data; - - return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw, - d->details, d->groups, d->metriclist); -} - -struct metricgroup_print_data { - const char *pmu_name; - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - -static int metricgroup__print_callback(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *vdata) +static int metricgroup__add_to_mep_groups_callback(const struct pmu_event *pe, + const struct pmu_events_table *table __maybe_unused, + void *vdata) { - struct metricgroup_print_data *data = vdata; - - if (!pe->metric_expr) - return 0; + struct rblist *groups = vdata;
- if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_name, pe->pmu)) + if (!pe->metric_name) return 0;
- return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, - data->raw, data->details, data->groups, - data->metriclist); + return metricgroup__add_to_mep_groups(pe, groups); }
-void metricgroup__print(bool metrics, bool metricgroups, char *filter, - bool raw, bool details, const char *pmu_name) +void metricgroup__print(const struct print_callbacks *print_cb, void *print_state) { struct rblist groups; - struct rb_node *node, *next; - struct strlist *metriclist = NULL; const struct pmu_events_table *table; - - if (!metricgroups) { - metriclist = strlist__new(NULL, NULL); - if (!metriclist) - return; - } + struct rb_node *node, *next;
rblist__init(&groups); groups.node_new = mep_new; @@@ -500,31 -588,56 +500,31 @@@ groups.node_delete = mep_delete; table = pmu_events_table__find(); if (table) { - struct metricgroup_print_data data = { - .pmu_name = pmu_name, - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }; - pmu_events_table_for_each_event(table, - metricgroup__print_callback, - &data); + metricgroup__add_to_mep_groups_callback, + &groups); } { struct metricgroup_iter_data data = { - .fn = metricgroup__print_sys_event_iter, - .data = (void *) &(struct metricgroup_print_sys_idata){ - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }, + .fn = metricgroup__add_to_mep_groups_callback, + .data = &groups, }; - pmu_for_each_sys_event(metricgroup__sys_event_iter, &data); }
- if (!filter || !rblist__empty(&groups)) { - if (metricgroups && !raw) - printf("\nMetric Groups:\n\n"); - else if (metrics && !raw) - printf("\nMetrics:\n\n"); - } - for (node = rb_first_cached(&groups.entries); node; node = next) { struct mep *me = container_of(node, struct mep, nd);
- if (metricgroups) - printf("%s%s%s", me->name, metrics && !raw ? ":" : "", raw ? " " : "\n"); - if (metrics) - metricgroup__print_strlist(me->metrics, raw); + print_cb->print_metric(print_state, + me->metric_group, + me->metric_name, + me->metric_desc, + me->metric_long_desc, + me->metric_expr, + me->metric_unit); next = rb_next(node); rblist__remove_node(&groups, node); } - if (!metricgroups) - metricgroup__print_strlist(metriclist, raw); - strlist__delete(metriclist); }
static const char *code_characters = ",-=@"; @@@ -651,7 -764,7 +651,7 @@@ static int metricgroup__build_event_str #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0)
hashmap__for_each_entry(ctx->ids, cur, bkt) { - const char *sep, *rsep, *id = cur->key; + const char *sep, *rsep, *id = cur->pkey; enum perf_tool_event ev;
pr_debug("found event %s\n", id); @@@ -832,14 -945,14 +832,14 @@@ static int resolve_metric(struct list_h hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) { struct pmu_event pe;
- if (metricgroup__find_metric(cur->key, table, &pe)) { + if (metricgroup__find_metric(cur->pkey, table, &pe)) { pending = realloc(pending, (pending_cnt + 1) * sizeof(struct to_resolve)); if (!pending) return -ENOMEM;
memcpy(&pending[pending_cnt].pe, &pe, sizeof(pe)); - pending[pending_cnt].key = cur->key; + pending[pending_cnt].key = cur->pkey; pending_cnt++; } } @@@ -1320,7 -1433,7 +1320,7 @@@ static int build_combined_expr_ctx(cons list_for_each_entry(m, metric_list, nd) { if (m->has_constraint && !m->modifier) { hashmap__for_each_entry(m->pctx->ids, cur, bkt) { - dup = strdup(cur->key); + dup = strdup(cur->pkey); if (!dup) { ret = -ENOMEM; goto err_out; diff --combined tools/perf/util/stat-shadow.c index 9bde9224a97c,0bf71b02aa06..cadb2df23c87 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@@ -14,7 -14,6 +14,7 @@@ #include "units.h" #include <linux/zalloc.h> #include "iostat.h" +#include "util/hashmap.h"
/* * AGGR_GLOBAL: Use CPU 0 @@@ -399,7 -398,7 +399,7 @@@ void perf_stat__collect_metric_expr(str
i = 0; hashmap__for_each_entry(ctx->ids, cur, bkt) { - const char *metric_name = (const char *)cur->key; + const char *metric_name = cur->pkey;
found = false; if (leader) { diff --combined tools/perf/util/stat.c index 673f017a211f,c0656f85bfa5..534d36d26fc3 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@@ -14,7 -14,11 +14,7 @@@ #include "evlist.h" #include "evsel.h" #include "thread_map.h" -#ifdef HAVE_LIBBPF_SUPPORT -#include <bpf/hashmap.h> -#else #include "util/hashmap.h" -#endif #include <linux/zalloc.h>
void update_stats(struct stats *stats, u64 val) @@@ -126,65 -130,18 +126,65 @@@ static void perf_stat_evsel_id_init(str } }
+static void evsel__reset_aggr_stats(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + struct perf_stat_aggr *aggr = ps->aggr; + + if (aggr) + memset(aggr, 0, sizeof(*aggr) * ps->nr_aggr); +} + static void evsel__reset_stat_priv(struct evsel *evsel) { struct perf_stat_evsel *ps = evsel->stats;
init_stats(&ps->res_stats); + evsel__reset_aggr_stats(evsel); +} + +static int evsel__alloc_aggr_stats(struct evsel *evsel, int nr_aggr) +{ + struct perf_stat_evsel *ps = evsel->stats; + + if (ps == NULL) + return 0; + + ps->nr_aggr = nr_aggr; + ps->aggr = calloc(nr_aggr, sizeof(*ps->aggr)); + if (ps->aggr == NULL) + return -ENOMEM; + + return 0; +} + +int evlist__alloc_aggr_stats(struct evlist *evlist, int nr_aggr) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) { + if (evsel__alloc_aggr_stats(evsel, nr_aggr) < 0) + return -1; + } + return 0; }
-static int evsel__alloc_stat_priv(struct evsel *evsel) +static int evsel__alloc_stat_priv(struct evsel *evsel, int nr_aggr) { - evsel->stats = zalloc(sizeof(struct perf_stat_evsel)); - if (evsel->stats == NULL) + struct perf_stat_evsel *ps; + + ps = zalloc(sizeof(*ps)); + if (ps == NULL) return -ENOMEM; + + evsel->stats = ps; + + if (nr_aggr && evsel__alloc_aggr_stats(evsel, nr_aggr) < 0) { + evsel->stats = NULL; + free(ps); + return -ENOMEM; + } + perf_stat_evsel_id_init(evsel); evsel__reset_stat_priv(evsel); return 0; @@@ -194,10 -151,8 +194,10 @@@ static void evsel__free_stat_priv(struc { struct perf_stat_evsel *ps = evsel->stats;
- if (ps) + if (ps) { + zfree(&ps->aggr); zfree(&ps->group_data); + } zfree(&evsel->stats); }
@@@ -226,9 -181,9 +226,9 @@@ static void evsel__reset_prev_raw_count perf_counts__reset(evsel->prev_raw_counts); }
-static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw) +static int evsel__alloc_stats(struct evsel *evsel, int nr_aggr, bool alloc_raw) { - if (evsel__alloc_stat_priv(evsel) < 0 || + if (evsel__alloc_stat_priv(evsel, nr_aggr) < 0 || evsel__alloc_counts(evsel) < 0 || (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0)) return -ENOMEM; @@@ -236,17 -191,12 +236,17 @@@ return 0; }
-int evlist__alloc_stats(struct evlist *evlist, bool alloc_raw) +int evlist__alloc_stats(struct perf_stat_config *config, + struct evlist *evlist, bool alloc_raw) { struct evsel *evsel; + int nr_aggr = 0; + + if (config && config->aggr_map) + nr_aggr = config->aggr_map->nr;
evlist__for_each_entry(evlist, evsel) { - if (evsel__alloc_stats(evsel, alloc_raw)) + if (evsel__alloc_stats(evsel, nr_aggr, alloc_raw)) goto out_free; }
@@@ -278,14 -228,6 +278,14 @@@ void evlist__reset_stats(struct evlist } }
+void evlist__reset_aggr_stats(struct evlist *evlist) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + evsel__reset_aggr_stats(evsel); +} + void evlist__reset_prev_raw_counts(struct evlist *evlist) { struct evsel *evsel; @@@ -304,6 -246,8 +304,6 @@@ static void evsel__copy_prev_raw_counts *perf_counts(evsel->prev_raw_counts, idx, thread); } } - - evsel->counts->aggr = evsel->prev_raw_counts->aggr; }
void evlist__copy_prev_raw_counts(struct evlist *evlist) @@@ -314,15 -258,34 +314,14 @@@ evsel__copy_prev_raw_counts(evsel); }
- static size_t pkg_id_hash(const void *__key, void *ctx __maybe_unused) -void evlist__save_aggr_prev_raw_counts(struct evlist *evlist) -{ - struct evsel *evsel; - - /* - * To collect the overall statistics for interval mode, - * we copy the counts from evsel->prev_raw_counts to - * evsel->counts. The perf_stat_process_counter creates - * aggr values from per cpu values, but the per cpu values - * are 0 for AGGR_GLOBAL. So we use a trick that saves the - * previous aggr value to the first member of perf_counts, - * then aggr calculation in process_counter_values can work - * correctly. - */ - evlist__for_each_entry(evlist, evsel) { - *perf_counts(evsel->prev_raw_counts, 0, 0) = - evsel->prev_raw_counts->aggr; - } -} - + static size_t pkg_id_hash(long __key, void *ctx __maybe_unused) { uint64_t *key = (uint64_t *) __key;
return *key & 0xffffffff; }
- static bool pkg_id_equal(const void *__key1, const void *__key2, - void *ctx __maybe_unused) + static bool pkg_id_equal(long __key1, long __key2, void *ctx __maybe_unused) { uint64_t *key1 = (uint64_t *) __key1; uint64_t *key2 = (uint64_t *) __key2; @@@ -383,40 -346,21 +382,40 @@@ static int check_per_pkg(struct evsel * return -ENOMEM;
*key = (uint64_t)d << 32 | s; - if (hashmap__find(mask, (void *)key, NULL)) { + if (hashmap__find(mask, key, NULL)) { *skip = true; free(key); } else - ret = hashmap__add(mask, (void *)key, (void *)1); + ret = hashmap__add(mask, key, 1);
return ret; }
+static bool evsel__count_has_error(struct evsel *evsel, + struct perf_counts_values *count, + struct perf_stat_config *config) +{ + /* the evsel was failed already */ + if (evsel->err || evsel->counts->scaled == -1) + return true; + + /* this is meaningful for CPU aggregation modes only */ + if (config->aggr_mode == AGGR_GLOBAL) + return false; + + /* it's considered ok when it actually ran */ + if (count->ena != 0 && count->run != 0) + return false; + + return true; +} + static int process_counter_values(struct perf_stat_config *config, struct evsel *evsel, int cpu_map_idx, int thread, struct perf_counts_values *count) { - struct perf_counts_values *aggr = &evsel->counts->aggr; + struct perf_stat_evsel *ps = evsel->stats; static struct perf_counts_values zero; bool skip = false;
@@@ -428,60 -372,34 +427,60 @@@ if (skip) count = &zero;
- switch (config->aggr_mode) { - case AGGR_THREAD: - case AGGR_CORE: - case AGGR_DIE: - case AGGR_SOCKET: - case AGGR_NODE: - case AGGR_NONE: - if (!evsel->snapshot) - evsel__compute_deltas(evsel, cpu_map_idx, thread, count); - perf_counts_values__scale(count, config->scale, NULL); - if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) { - perf_stat__update_shadow_stats(evsel, count->val, - cpu_map_idx, &rt_stat); - } + if (!evsel->snapshot) + evsel__compute_deltas(evsel, cpu_map_idx, thread, count); + perf_counts_values__scale(count, config->scale, NULL); + + if (config->aggr_mode == AGGR_THREAD) { + struct perf_counts_values *aggr_counts = &ps->aggr[thread].counts; + + /* + * Skip value 0 when enabling --per-thread globally, + * otherwise too many 0 output. + */ + if (count->val == 0 && config->system_wide) + return 0;
- if (config->aggr_mode == AGGR_THREAD) { - perf_stat__update_shadow_stats(evsel, count->val, - thread, &rt_stat); + ps->aggr[thread].nr++; + + aggr_counts->val += count->val; + aggr_counts->ena += count->ena; + aggr_counts->run += count->run; + return 0; + } + + if (ps->aggr) { + struct perf_cpu cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx); + struct aggr_cpu_id aggr_id = config->aggr_get_id(config, cpu); + struct perf_stat_aggr *ps_aggr; + int i; + + for (i = 0; i < ps->nr_aggr; i++) { + if (!aggr_cpu_id__equal(&aggr_id, &config->aggr_map->map[i])) + continue; + + ps_aggr = &ps->aggr[i]; + ps_aggr->nr++; + + /* + * When any result is bad, make them all to give consistent output + * in interval mode. But per-task counters can have 0 enabled time + * when some tasks are idle. + */ + if (evsel__count_has_error(evsel, count, config) && !ps_aggr->failed) { + ps_aggr->counts.val = 0; + ps_aggr->counts.ena = 0; + ps_aggr->counts.run = 0; + ps_aggr->failed = true; + } + + if (!ps_aggr->failed) { + ps_aggr->counts.val += count->val; + ps_aggr->counts.ena += count->ena; + ps_aggr->counts.run += count->run; + } + break; } - break; - case AGGR_GLOBAL: - aggr->val += count->val; - aggr->ena += count->ena; - aggr->run += count->run; - case AGGR_UNSET: - case AGGR_MAX: - default: - break; }
return 0; @@@ -508,10 -426,13 +507,10 @@@ static int process_counter_maps(struct int perf_stat_process_counter(struct perf_stat_config *config, struct evsel *counter) { - struct perf_counts_values *aggr = &counter->counts->aggr; struct perf_stat_evsel *ps = counter->stats; - u64 *count = counter->counts->aggr.values; + u64 *count; int ret;
- aggr->val = aggr->ena = aggr->run = 0; - if (counter->per_pkg) evsel__zero_per_pkg(counter);
@@@ -522,11 -443,10 +521,11 @@@ if (config->aggr_mode != AGGR_GLOBAL) return 0;
- if (!counter->snapshot) - evsel__compute_deltas(counter, -1, -1, aggr); - perf_counts_values__scale(aggr, config->scale, &counter->counts->scaled); - + /* + * GLOBAL aggregation mode only has a single aggr counts, + * so we can use ps->aggr[0] as the actual output. + */ + count = ps->aggr[0].counts.values; update_stats(&ps->res_stats, *count);
if (verbose > 0) { @@@ -534,194 -454,13 +533,194 @@@ evsel__name(counter), count[0], count[1], count[2]); }
- /* - * Save the full runtime - to allow normalization during printout: - */ - perf_stat__update_shadow_stats(counter, *count, 0, &rt_stat); + return 0; +} + +static int evsel__merge_aggr_counters(struct evsel *evsel, struct evsel *alias) +{ + struct perf_stat_evsel *ps_a = evsel->stats; + struct perf_stat_evsel *ps_b = alias->stats; + int i; + + if (ps_a->aggr == NULL && ps_b->aggr == NULL) + return 0; + + if (ps_a->nr_aggr != ps_b->nr_aggr) { + pr_err("Unmatched aggregation mode between aliases\n"); + return -1; + } + + for (i = 0; i < ps_a->nr_aggr; i++) { + struct perf_counts_values *aggr_counts_a = &ps_a->aggr[i].counts; + struct perf_counts_values *aggr_counts_b = &ps_b->aggr[i].counts; + + /* NB: don't increase aggr.nr for aliases */ + + aggr_counts_a->val += aggr_counts_b->val; + aggr_counts_a->ena += aggr_counts_b->ena; + aggr_counts_a->run += aggr_counts_b->run; + }
return 0; } +/* events should have the same name, scale, unit, cgroup but on different PMUs */ +static bool evsel__is_alias(struct evsel *evsel_a, struct evsel *evsel_b) +{ + if (strcmp(evsel__name(evsel_a), evsel__name(evsel_b))) + return false; + + if (evsel_a->scale != evsel_b->scale) + return false; + + if (evsel_a->cgrp != evsel_b->cgrp) + return false; + + if (strcmp(evsel_a->unit, evsel_b->unit)) + return false; + + if (evsel__is_clock(evsel_a) != evsel__is_clock(evsel_b)) + return false; + + return !!strcmp(evsel_a->pmu_name, evsel_b->pmu_name); +} + +static void evsel__merge_aliases(struct evsel *evsel) +{ + struct evlist *evlist = evsel->evlist; + struct evsel *alias; + + alias = list_prepare_entry(evsel, &(evlist->core.entries), core.node); + list_for_each_entry_continue(alias, &evlist->core.entries, core.node) { + /* Merge the same events on different PMUs. */ + if (evsel__is_alias(evsel, alias)) { + evsel__merge_aggr_counters(evsel, alias); + alias->merged_stat = true; + } + } +} + +static bool evsel__should_merge_hybrid(const struct evsel *evsel, + const struct perf_stat_config *config) +{ + return config->hybrid_merge && evsel__is_hybrid(evsel); +} + +static void evsel__merge_stats(struct evsel *evsel, struct perf_stat_config *config) +{ + /* this evsel is already merged */ + if (evsel->merged_stat) + return; + + if (evsel->auto_merge_stats || evsel__should_merge_hybrid(evsel, config)) + evsel__merge_aliases(evsel); +} + +/* merge the same uncore and hybrid events if requested */ +void perf_stat_merge_counters(struct perf_stat_config *config, struct evlist *evlist) +{ + struct evsel *evsel; + + if (config->no_merge) + return; + + evlist__for_each_entry(evlist, evsel) + evsel__merge_stats(evsel, config); +} + +static void evsel__update_percore_stats(struct evsel *evsel, struct aggr_cpu_id *core_id) +{ + struct perf_stat_evsel *ps = evsel->stats; + struct perf_counts_values counts = { 0, }; + struct aggr_cpu_id id; + struct perf_cpu cpu; + int idx; + + /* collect per-core counts */ + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + id = aggr_cpu_id__core(cpu, NULL); + if (!aggr_cpu_id__equal(core_id, &id)) + continue; + + counts.val += aggr->counts.val; + counts.ena += aggr->counts.ena; + counts.run += aggr->counts.run; + } + + /* update aggregated per-core counts for each CPU */ + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + id = aggr_cpu_id__core(cpu, NULL); + if (!aggr_cpu_id__equal(core_id, &id)) + continue; + + aggr->counts.val = counts.val; + aggr->counts.ena = counts.ena; + aggr->counts.run = counts.run; + + aggr->used = true; + } +} + +/* we have an aggr_map for cpu, but want to aggregate the counters per-core */ +static void evsel__process_percore(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + struct aggr_cpu_id core_id; + struct perf_cpu cpu; + int idx; + + if (!evsel->percore) + return; + + perf_cpu_map__for_each_cpu(cpu, idx, evsel->core.cpus) { + struct perf_stat_aggr *aggr = &ps->aggr[idx]; + + if (aggr->used) + continue; + + core_id = aggr_cpu_id__core(cpu, NULL); + evsel__update_percore_stats(evsel, &core_id); + } +} + +/* process cpu stats on per-core events */ +void perf_stat_process_percore(struct perf_stat_config *config, struct evlist *evlist) +{ + struct evsel *evsel; + + if (config->aggr_mode != AGGR_NONE) + return; + + evlist__for_each_entry(evlist, evsel) + evsel__process_percore(evsel); +} + +static void evsel__update_shadow_stats(struct evsel *evsel) +{ + struct perf_stat_evsel *ps = evsel->stats; + int i; + + if (ps->aggr == NULL) + return; + + for (i = 0; i < ps->nr_aggr; i++) { + struct perf_counts_values *aggr_counts = &ps->aggr[i].counts; + + perf_stat__update_shadow_stats(evsel, aggr_counts->val, i, &rt_stat); + } +} + +void perf_stat_process_shadow_stats(struct perf_stat_config *config __maybe_unused, + struct evlist *evlist) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) + evsel__update_shadow_stats(evsel); +}
int perf_event__process_stat_event(struct perf_session *session, union perf_event *event) diff --combined tools/testing/selftests/Makefile index 6dc9140e4954,b57b091d8026..7df3df9be039 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@@ -26,7 -26,6 +26,7 @@@ TARGETS += fp TARGETS += ftrace TARGETS += futex TARGETS += gpio +TARGETS += hid TARGETS += intel_pstate TARGETS += ipc TARGETS += ir @@@ -49,6 -48,7 +49,7 @@@ TARGETS += nc TARGETS += net TARGETS += net/af_unix TARGETS += net/forwarding + TARGETS += net/hsr TARGETS += net/mptcp TARGETS += net/openvswitch TARGETS += netfilter @@@ -75,7 -75,6 +76,7 @@@ TARGETS += syn TARGETS += syscall_user_dispatch TARGETS += sysctl TARGETS += tc-testing +TARGETS += tdx TARGETS += timens ifneq (1, $(quicktest)) TARGETS += timers