diff options
370 files changed, 10624 insertions, 6247 deletions
diff --git a/Documentation/arch/powerpc/index.rst b/Documentation/arch/powerpc/index.rst index 592efca7d8ec..53fc9f89f3e4 100644 --- a/Documentation/arch/powerpc/index.rst +++ b/Documentation/arch/powerpc/index.rst @@ -37,7 +37,6 @@ powerpc vas-api vcpudispatch_stats vmemmap_dedup - htm features diff --git a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml index fb5c39c79d28..c9f99e0df2b3 100644 --- a/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml +++ b/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml @@ -116,6 +116,36 @@ properties: - const: xlnx,zynqmp-zcu111 - const: xlnx,zynqmp + - description: Xilinx Kria SOMs K24 + minItems: 3 + items: + enum: + - xlnx,zynqmp-sm-k24-rev1 + - xlnx,zynqmp-sm-k24-revB + - xlnx,zynqmp-sm-k24-revA + - xlnx,zynqmp-sm-k24 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp + - contains: + const: xlnx,zynqmp-sm-k24 + + - description: Xilinx Kria SOMs K24 (starter) + minItems: 3 + items: + enum: + - xlnx,zynqmp-smk-k24-rev1 + - xlnx,zynqmp-smk-k24-revB + - xlnx,zynqmp-smk-k24-revA + - xlnx,zynqmp-smk-k24 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp + - contains: + const: xlnx,zynqmp-smk-k24 + - description: Xilinx Kria SOMs minItems: 3 items: @@ -148,6 +178,57 @@ properties: - contains: const: xlnx,zynqmp-smk-k26 + - description: Xilinx Kria SOM KD240 revA/B/1 + minItems: 3 + items: + enum: + - xlnx,zynqmp-sk-kd240-rev1 + - xlnx,zynqmp-sk-kd240-revB + - xlnx,zynqmp-sk-kd240-revA + - xlnx,zynqmp-sk-kd240 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp-sk-kd240-revA + - contains: + const: xlnx,zynqmp-sk-kd240 + - contains: + const: xlnx,zynqmp + + - description: Xilinx Kria SOM KR260 revA/Y/Z + minItems: 3 + items: + enum: + - xlnx,zynqmp-sk-kr260-revA + - xlnx,zynqmp-sk-kr260-revY + - xlnx,zynqmp-sk-kr260-revZ + - xlnx,zynqmp-sk-kr260 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp-sk-kr260-revA + - contains: + const: xlnx,zynqmp-sk-kr260 + - contains: + const: xlnx,zynqmp + + - description: Xilinx Kria SOM KR260 rev2/1/B + minItems: 3 + items: + enum: + - xlnx,zynqmp-sk-kr260-rev2 + - xlnx,zynqmp-sk-kr260-rev1 + - xlnx,zynqmp-sk-kr260-revB + - xlnx,zynqmp-sk-kr260 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp-sk-kr260-revB + - contains: + const: xlnx,zynqmp-sk-kr260 + - contains: + const: xlnx,zynqmp + - description: Xilinx Kria SOM KV260 revA/Y/Z minItems: 3 items: diff --git a/Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml b/Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml index 3ad10c5b66ba..3931054b42fb 100644 --- a/Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml +++ b/Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml @@ -221,10 +221,7 @@ properties: maxItems: 1 "#pwm-cells": - oneOf: - - const: 2 - deprecated: true - - const: 3 + const: 2 required: - compatible @@ -302,5 +299,5 @@ examples: clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>; power-domains = <&cpg>; resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>; - #pwm-cells = <3>; + #pwm-cells = <2>; }; diff --git a/Documentation/gpu/amdgpu/amd-hardware-list-info.rst b/Documentation/gpu/amdgpu/amd-hardware-list-info.rst index 1786544fe7c1..e72f4ff770c4 100644 --- a/Documentation/gpu/amdgpu/amd-hardware-list-info.rst +++ b/Documentation/gpu/amdgpu/amd-hardware-list-info.rst @@ -10,7 +10,7 @@ Accelerated Processing Units (APU) Info .. csv-table:: :header-rows: 1 - :widths: 3, 2, 2, 1, 1, 1, 1 + :widths: 3, 2, 2, 1, 1, 1, 1, 1 :file: ./apu-asic-info-table.csv Discrete GPU Info @@ -18,6 +18,6 @@ Discrete GPU Info .. csv-table:: :header-rows: 1 - :widths: 3, 2, 2, 1, 1, 1 + :widths: 3, 2, 2, 1, 1, 1, 1, 1 :file: ./dgpu-asic-info-table.csv diff --git a/Documentation/gpu/amdgpu/apu-asic-info-table.csv b/Documentation/gpu/amdgpu/apu-asic-info-table.csv index 1d50b539677f..b479c5629146 100644 --- a/Documentation/gpu/amdgpu/apu-asic-info-table.csv +++ b/Documentation/gpu/amdgpu/apu-asic-info-table.csv @@ -1,17 +1,17 @@ -Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version, MP0 version -Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3, n/a -Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0, 10.0.0 -Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2, 11.0.3 -Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1, 10.0.1 -SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1, 11.5.0 -Ryzen 5000 series / Ryzen 7x30 series, GREEN SARDINE / Cezanne / Barcelo / Barcelo-R, DCN 2.1, 9.3, VCN 2.2, 4.1.1, 12.0.1 -Ryzen 6000 series / Ryzen 7x35 series / Ryzen 7x36 series, YELLOW CARP / Rembrandt / Rembrandt-R, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3 -Ryzen 7000 series (AM5), Raphael, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 -Ryzen 9000 series (AM5), Granite Ridge, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 -Ryzen 7x45 series (FL1), Dragon Range, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5 -Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8 -Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11 -Ryzen 8x40 series, Hawk Point, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11 -Ryzen AI 300 series, Strix Point, 3.5.0, 11.5.0, 4.0.5, 6.1.0, 14.0.0 -Ryzen AI 350 series, Krackan Point, 3.5.0, 11.5.2, 4.0.5, 6.1.2, 14.0.4 -Ryzen AI Max 300 series, Strix Halo, 3.5.1, 11.5.1, 4.0.6, 6.1.1, 14.0.1 +Product Name, Code Reference, DCN/DCE version, GC version, VCE/UVD/VCN version, SDMA version, MP0 version, MP1 version +Radeon R* Graphics, CARRIZO/STONEY, DCE 11, 8, VCE 3 / UVD 6, 3, n/a, 8 +Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN/PICASSO, DCN 1.0, 9.1.0, VCN 1.0, 4.1.0, 10.0.0, 10.0.0 +Ryzen 4000 series, RENOIR, DCN 2.1, 9.3, VCN 2.2, 4.1.2, 11.0.3, 12.0.1 +Ryzen 3000 series / AMD Ryzen Embedded V1*/R1* with Radeon Vega Gfx, RAVEN2, DCN 1.0, 9.2.2, VCN 1.0.1, 4.1.1, 10.0.1, 10.0.1 +SteamDeck, VANGOGH, DCN 3.0.1, 10.3.1, VCN 3.1.0, 5.2.1, 11.5.0, 11.5.0 +Ryzen 5000 series / Ryzen 7x30 series, GREEN SARDINE / Cezanne / Barcelo / Barcelo-R, DCN 2.1, 9.3, VCN 2.2, 4.1.1, 12.0.1, 12.0.1 +Ryzen 6000 series / Ryzen 7x35 series / Ryzen 7x36 series, YELLOW CARP / Rembrandt / Rembrandt-R, 3.1.2, 10.3.3, VCN 3.1.1, 5.2.3, 13.0.3, 13.0.3 +Ryzen 7000 series (AM5), Raphael, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 +Ryzen 9000 series (AM5), Granite Ridge, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 +Ryzen 7x45 series (FL1), Dragon Range, 3.1.5, 10.3.6, 3.1.2, 5.2.6, 13.0.5, 13.0.5 +Ryzen 7x20 series, Mendocino, 3.1.6, 10.3.7, 3.1.1, 5.2.7, 13.0.8, 13.0.8 +Ryzen 7x40 series, Phoenix, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11, 13.0.4 / 13.0.11 +Ryzen 8x40 series, Hawk Point, 3.1.4, 11.0.1 / 11.0.4, 4.0.2, 6.0.1, 13.0.4 / 13.0.11, 13.0.4 / 13.0.11 +Ryzen AI 300 series, Strix Point, 3.5.0, 11.5.0, 4.0.5, 6.1.0, 14.0.0, 14.0.0 +Ryzen AI 350 series, Krackan Point, 3.5.0, 11.5.2, 4.0.5, 6.1.2, 14.0.4, 14.0.4 +Ryzen AI Max 300 series, Strix Halo, 3.5.1, 11.5.1, 4.0.6, 6.1.1, 14.0.1, 14.0.1 diff --git a/Documentation/gpu/amdgpu/dgpu-asic-info-table.csv b/Documentation/gpu/amdgpu/dgpu-asic-info-table.csv index d2f10ee69dfc..a3796daec9ec 100644 --- a/Documentation/gpu/amdgpu/dgpu-asic-info-table.csv +++ b/Documentation/gpu/amdgpu/dgpu-asic-info-table.csv @@ -1,28 +1,30 @@ -Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version -AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, -- -AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, -- -AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, -- -AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, -- -AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, -- -AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1 -AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1 -AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2 -AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3 -AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3 -Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 -Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 -Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3 -Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0 -AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0 -MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2 -MI200 Series, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0 -MI300 Series, AQUA_VANJARAM, *, 9.4.3, VCN 4.0.3, 4.4.2 -AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0 -AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2 -AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0 -AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2 -AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4 -AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5 -AMD Radeon RX 7900 XT /XTX, , DCN 3.2.0, 11.0.0, VCN 4.0.0, 6.0.0 -AMD Radeon RX 7800 XT, , DCN 3.2.0, 11.0.3, VCN 4.0.0, 6.0.3 -AMD Radeon RX 7600M (XT) /7700S /7600S, , DCN 3.2.1, 11.0.2, VCN 4.0.4, 6.0.2 +Product Name, Code Reference, DCN/DCE version, GC version, VCN version, SDMA version, MP0 version, MP1 version +AMD Radeon (TM) HD 8500M/ 8600M /M200 /M320 /M330 /M335 Series, HAINAN, --, 6, --, --, --, 6 +AMD Radeon HD 7800 /7900 /FireGL Series, TAHITI, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 +AMD Radeon R7 (TM|HD) M265 /M370 /8500M /8600 /8700 /8700M, OLAND, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 +AMD Radeon (TM) (HD|R7) 7800 /7970 /8800 /8970 /370/ Series, PITCAIRN, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 +AMD Radeon (TM|R7|R9|HD) E8860 /M360 /7700 /7800 /8800 /9000(M) /W4100 Series, VERDE, DCE 6, 6, VCE 1 / UVD 3, --, --, 6 +AMD Radeon HD M280X /M380 /7700 /8950 /W5100, BONAIRE, DCE 8, 7, VCE 2 / UVD 4.2, 1, --, 7 +AMD Radeon (R9|TM) 200 /390 /W8100 /W9100 Series, HAWAII, DCE 8, 7, VCE 2 / UVD 4.2, 1, --, 7 +AMD Radeon (TM) R(5|7) M315 /M340 /M360, TOPAZ, *, 8, --, 2, n/a, 7 +AMD Radeon (TM) R9 200 /380 /W7100 /S7150 /M390 /M395 Series, TONGA, DCE 10, 8, VCE 3 / UVD 5, 3, n/a, 7 +AMD Radeon (FirePro) (TM) R9 Fury Series, FIJI, DCE 10, 8, VCE 3 / UVD 6, 3, n/a, 7 +Radeon RX 470 /480 /570 /580 /590 Series - AMD Radeon (TM) (Pro WX) 5100 /E9390 /E9560 /E9565 /V7350 /7100 /P30PH, POLARIS10, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 +Radeon (TM) (RX|Pro WX) E9260 /460 /V5300X /550 /560(X) Series, POLARIS11, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 +Radeon (RX/Pro) 500 /540(X) /550 /640 /WX2100 /WX3100 /WX200 Series, POLARIS12, DCE 11.2, 8, VCE 3.4 / UVD 6.3, 3, n/a, 7 +Radeon (RX|TM) (PRO|WX) Vega /MI25 /V320 /V340L /8200 /9100 /SSG MxGPU, VEGA10, DCE 12, 9.0.1, VCE 4.0.0 / UVD 7.0.0, 4.0.0, 9.0.0, 9.0.0 +AMD Radeon (Pro) VII /MI50 /MI60, VEGA20, DCE 12, 9.4.0, VCE 4.1.0 / UVD 7.2.0, 4.2.0, 11.0.2, 11.0.2 +MI100, ARCTURUS, *, 9.4.1, VCN 2.5.0, 4.2.2, 11.0.4, 11.0.2 +MI200 Series, ALDEBARAN, *, 9.4.2, VCN 2.6.0, 4.4.0, 13.0.2, 13.0.2 +MI300 Series, AQUA_VANJARAM, *, 9.4.3, VCN 4.0.3, 4.4.2, 13.0.6, 13.0.6 +AMD Radeon (RX|Pro) 5600(M|XT) /5700 (M|XT|XTB) /W5700, NAVI10, DCN 2.0.0, 10.1.10, VCN 2.0.0, 5.0.0, 11.0.0, 11.0.0 +AMD Radeon (Pro) 5300 /5500XTB/5500(XT|M) /W5500M /W5500, NAVI14, DCN 2.0.0, 10.1.1, VCN 2.0.2, 5.0.2, 11.0.5, 11.0.5 +AMD Radeon RX 6800(XT) /6900(XT) /W6800, SIENNA_CICHLID, DCN 3.0.0, 10.3.0, VCN 3.0.0, 5.2.0, 11.0.7, 11.0.7 +AMD Radeon RX 6700 XT / 6800M / 6700M, NAVY_FLOUNDER, DCN 3.0.0, 10.3.2, VCN 3.0.0, 5.2.2, 11.0.11, 11.0.11 +AMD Radeon RX 6600(XT) /6600M /W6600 /W6600M, DIMGREY_CAVEFISH, DCN 3.0.2, 10.3.4, VCN 3.0.16, 5.2.4, 11.0.12, 11.0.12 +AMD Radeon RX 6500M /6300M /W6500M /W6300M, BEIGE_GOBY, DCN 3.0.3, 10.3.5, VCN 3.0.33, 5.2.5, 11.0.13, 11.0.13 +AMD Radeon RX 7900 XT /XTX, , DCN 3.2.0, 11.0.0, VCN 4.0.0, 6.0.0, 13.0.0, 13.0.0 +AMD Radeon RX 7800 XT, , DCN 3.2.0, 11.0.3, VCN 4.0.0, 6.0.3, 13.0.10, 13.0.10 +AMD Radeon RX 7600M (XT) /7700S /7600S, , DCN 3.2.1, 11.0.2, VCN 4.0.4, 6.0.2, 13.0.7, 13.0.7 +AMD Radeon RX 9070 (XT), , DCN 4.0.1, 12.0.1, VCN 5.0.0, 7.0.1, 14.0.3, 14.0.3 +AMD Radeon RX 9060 XT, , DCN 4.0.1, 12.0.0, VCN 5.0.0, 7.0.0, 14.0.2, 14.0.2 diff --git a/MAINTAINERS b/MAINTAINERS index 494b12c03de7..4912b8a83bbb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6713,7 +6713,7 @@ S: Supported F: drivers/input/keyboard/dlink-dir685-touchkeys.c DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK -M: Joshua Kinard <kumba@gentoo.org> +M: Joshua Kinard <linux@kumba.dev> S: Maintained F: drivers/rtc/rtc-ds1685.c F: include/linux/rtc/ds1685.h @@ -11439,6 +11439,7 @@ F: drivers/tty/hvc/ HUNG TASK DETECTOR M: Andrew Morton <akpm@linux-foundation.org> R: Lance Yang <lance.yang@linux.dev> +R: Masami Hiramatsu <mhiramat@kernel.org> L: linux-kernel@vger.kernel.org S: Maintained F: include/linux/hung_task.h @@ -26312,7 +26313,6 @@ S: Maintained F: include/linux/unwind*.h F: kernel/unwind/ - UTIL-LINUX PACKAGE M: Karel Zak <kzak@redhat.com> L: util-linux@vger.kernel.org @@ -26736,12 +26736,6 @@ S: Maintained F: drivers/iommu/virtio-iommu.c F: include/uapi/linux/virtio_iommu.h -VIRTIO MEDIA DRIVER -M: Alexandre Courbot <gnurou@gmail.com> -L: linux-media@vger.kernel.org -S: Maintained -F: drivers/media/virtio/ - VIRTIO MEM DRIVER M: David Hildenbrand <david@redhat.com> L: virtualization@lists.linux.dev diff --git a/Next/SHA1s b/Next/SHA1s new file mode 100644 index 000000000000..ce3f9b5a5e6c --- /dev/null +++ b/Next/SHA1s @@ -0,0 +1,407 @@ +Name SHA1 +---- ---- +origin 35a813e010b99894bb4706c56c16a580bf7959c2 +fixes 89be9a83ccf1f88522317ce02f854f30d6115c41 +ext4-fixes d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af +vfs-brauner-fixes 8b3c655fa2406b9853138142746a39b7615c54a2 +fscrypt-current 0af2f6be1b4281385b618cb86ad946eded089ac8 +fsverity-current 0af2f6be1b4281385b618cb86ad946eded089ac8 +btrfs-fixes 61d18d91dd4aed6df52fac2bf0683eab6784ef85 +vfs-fixes 33927f3d0ecdcff06326d6e4edb6166aed42811c +erofs-fixes 347e9f5043c89695b01e66b3ed111755afcf1911 +nfsd-fixes 94d10a4dba0bc482f2b01e39f06d5513d0f75742 +v9fs-fixes 2014c95afecee3e76ca4a56956a936e23283f05b +overlayfs-fixes 924577e4f6ca473de1528953a0e13505fae61d7b +bcachefs ae4d71be53dd5cb1495ebc52295c8942c2dfe238 +fscrypt fa65058063cbaba6e519b5291a7e2e9e0fa24ae3 +btrfs 442ee950ea05968ab5bfaeeb0c6660c567c61bfa +ceph b828b4bf29d10a3e505a76a39c4daea969e19dc9 +cifs da3d9a37f3cbb44f387b810bda8ca0094e135a2d +configfs c6b1908224593db76f77b904894cd51933559ae9 +ecryptfs fba133a3411847db49297c965218400c49571ebd +dlm 6f8b4788266c7df3b7cfc6c665f663b4c3d09aad +erofs df0ce6cefa453d2236381645e529a27ef2f0a573 +exfat b33f91c6276255ca0b90c42142828de05496ed1d +exportfs adc218676eef25575469234709c2d87185ca223a +ext3 17e58687367a5d9488106067112ef7dfb201d985 +ext4 261a2abe20b034c5383a1474133bad3110291ece +f2fs 078cad8212ce4f4ebbafcc0936475b8215e1ca2a +fsverity d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af +fuse f0e84022479b4700609e874cf220b5d7d0363403 +gfs2 a90f1b6ad6649d553c9d76f50a42e4ba5783164b +jfs 856db37592021e9155384094e331e2d4589f28b1 +ksmbd e5cf61fa6e2fb9ae6339eaa892612488c966baaf +nfs 99765233ab42bf7a4950377ad7894dce8a5c0e60 +nfs-anna 38074de35b015df5623f524d6f2b49a0cd395c40 +nfsd e339967eecf1305557f7c697e1bc10b5cc495454 +ntfs3 a49f0abd8959048af18c6c690b065eb0d65b2d21 +orangefs 2138e89cb066b40386b1d9ddd61253347d356474 +overlayfs 6f9ccdad0feaef58b05f07e0fc9d31004147177c +ubifs 99dbb2a1bd661418be33b1ff1462c09b7d2221cf +v9fs 4210030d8bc4834fcb774babc458d02a2432ee76 +v9fs-ericvh 2014c95afecee3e76ca4a56956a936e23283f05b +xfs ded74fddcaf685a9440c5612f7831d0c4c1473ca +zonefs 6982100bb8297c46122cac4f684dcf44cb7d0d8c +vfs-brauner 66639db858112bf6b0f76677f7517643d586e575 +vfs dd589648208a4deab9049805e94b680a15149e61 +mm-hotfixes 415d5ad3746153d0c45b2cd00bdbd801fcb1d4b2 +fs-current 7d46dcab452bfbdf4f16ba51db11ed31f8a5f60e +kbuild-current e04c78d86a9699d136910cfc0bdcf01087e3267e +arc-current d7b8f8e20813f0179d8ef519541a3527e7661d3a +arm-current 0c66c6f4e21cb22220cbd8821c5c73fc157d20dc +arm64-fixes d42e6c20de6192f8e4ab4cf10be8c694ef27e8cb +arm-soc-fixes 9f9d41d643224e1cc7eac89794cf5e5997f8171f +davinci-current 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +drivers-memory-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +sophgo-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +sophgo-soc-fixes 0af2f6be1b4281385b618cb86ad946eded089ac8 +m68k-current c8995932db2bad6fa093ac64dbaf7a3e8870eafa +powerpc-fixes ab107276607af90b13a5994997e19b7b9731e251 +s390-fixes 62355f1f87b8c7f8785a8dd3cd5ca6e5b513566a +net 1dbf1d590d10a6d1978e8184f8dfe20af22d680a +bpf 1b30d44417278196a90c79244bb43e8428586345 +ipsec 28712d6ed32028b0f2e0defe6681411496971ca3 +netfilter eccf7a3480a06eb698f064af829733bd8d0ec263 +ipvs eccf7a3480a06eb698f064af829733bd8d0ec263 +wireless 6832a9317eee280117cd695fa885b2b7a7a38daf +ath d9104cec3e8fe4b458b74709853231385779001f +iwlwifi 6832a9317eee280117cd695fa885b2b7a7a38daf +wpan 8ce4f287524c74a118b0af1eebd4b24a8efca57a +rdma-fixes a9a9e68954f29b1e197663f76289db4879fd51bb +sound-current dbe05428c4e54068a86e7e02405f3b30b1d2b3dd +sound-asoc-fixes 282528da82a0436f3bed0755338539ba5d7d730b +regmap-fixes 067aa458a064cd860baef7503c3264bb3482d37e +regulator-fixes 10dfd36f078423c51602a9a21ed85e8e6c947a00 +spi-fixes a49bfbecfde75fa95677d4dfe95de8b25f8de37f +pci-current 0bd0a41a5120f78685a132834865b0a631b9026a +driver-core.current d632ab86aff2cef21f794e337a8e7f2320ac3973 +tty.current 55a984928bfa30c7877e28f16910e6de1c170f1f +usb.current d632ab86aff2cef21f794e337a8e7f2320ac3973 +usb-serial-fixes ad1244e1ce18f8c1a5ebad8074bfcf10eacb0311 +phy 89be9a83ccf1f88522317ce02f854f30d6115c41 +staging.current d632ab86aff2cef21f794e337a8e7f2320ac3973 +iio-fixes 187d5553e33ea656c2a93d3e98309dfc166a0de5 +counter-current 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +char-misc.current d632ab86aff2cef21f794e337a8e7f2320ac3973 +soundwire-fixes 89be9a83ccf1f88522317ce02f854f30d6115c41 +thunderbolt-fixes 038d61fd642278bab63ee8ef722c50d10ab01e8f +input-current bcce05041b21888f10b80ea903dcfe51a25c586e +crypto-current 9d9b193ed73a65ec47cf1fd39925b09da8216461 +libcrypto-fixes 68279380266a5fa70e664de754503338e2ec3f43 +vfio-fixes c1d9dac0db168198b6f63f460665256dedad9b6e +kselftest-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +dmaengine-fixes 89be9a83ccf1f88522317ce02f854f30d6115c41 +backlight-fixes 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0 +mtd-fixes 6463cbe08b0cbf9bba8763306764f5fd643023e1 +mfd-fixes d9d79e4f7dc935fea96dbf3de524404c08d08b03 +v4l-dvb-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +reset-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +mips-fixes 86731a2a651e58953fc949573895f2fa6d456841 +at91-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +omap-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +kvm-fixes 038d61fd642278bab63ee8ef722c50d10ab01e8f +kvms390-fixes d8dfda5af0be6e48178b6f4b46c6af30b06335b2 +hwmon-fixes 9c62e2282900332c8b711d9f9e37af369a8ef71b +nvdimm-fixes d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af +cxl-fixes d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af +dma-mapping-fixes aa807b9f22df2eee28593cbbabba0f93f4aa26c1 +drivers-x86-fixes e2967b50b709970547b5cdfa1b42526835327f36 +samsung-krzk-fixes 8d2c2fa2209e83d0eb10f7330d8a0bbdc1df32ff +pinctrl-samsung-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +devicetree-fixes 79aef1a3705bbc95b36dad892af1f313490bd65c +dt-krzk-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +scsi-fixes 021f243627ead17eb6500170256d3d9be787dad8 +drm-fixes 038d61fd642278bab63ee8ef722c50d10ab01e8f +drm-intel-fixes 038d61fd642278bab63ee8ef722c50d10ab01e8f +mmc-fixes 4b290aae788e06561754b28c6842e4080957d3f7 +rtc-fixes 08d82d0cad51c2b1d454fe41ea1ff96ade676961 +gnss-fixes 86731a2a651e58953fc949573895f2fa6d456841 +hyperv-fixes a4131a50d072b369bfed0b41e741c41fd8048641 +risc-v-fixes b65ca21835ed615907ba231a60db80a2605b94dc +riscv-dt-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +riscv-soc-fixes 0af2f6be1b4281385b618cb86ad946eded089ac8 +fpga-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +spdx beb6c8326eb4e7006c4aa16b0fee3e303d42e685 +gpio-brgl-fixes 89be9a83ccf1f88522317ce02f854f30d6115c41 +gpio-intel-fixes 9ab29ed505557bd106e292184fa4917955eb8e6e +pinctrl-intel-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +auxdisplay-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +kunit-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +memblock-fixes da8bf5daa5e55a6af2b285ecda460d6454712ff4 +renesas-fixes 379c590113ce46f605439d4887996c60ab8820cc +perf-current 6235ce77749f45cac27f630337e2fdf04e8a6c73 +efi-fixes 64e135f1eaba0bbb0cdee859af3328c68d5b9789 +battery-fixes 0af2f6be1b4281385b618cb86ad946eded089ac8 +iommufd-fixes 9a96876e3c6578031fa5dc5dde7759d383b2fb75 +rust-fixes d2eedaa3909be9102d648a4a0a50ccf64f96c54f +w1-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +pmdomain-fixes 621a88dbfe9006c318a0cafbd12e677ccfe006e7 +i2c-host-fixes 0ae982df67760cd08affa935c0fe86c8a9311797 +sparc-fixes 6613476e225e090cc9aad49be7fa504e290dd33d +clk-fixes e4b2a0c2b9be6d10b0e50a7485fe9f569a6f2436 +thead-clk-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +pwrseq-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +thead-dt-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +ftrace-fixes 327e28664307d49ce3fa71ba30dcc0007c270974 +ring-buffer-fixes e4d4b8670c44cdd22212cab3c576e2d317efa67c +trace-fixes b5e8acc14dcb314a9b61ff19dcd9fdd0d88f70df +tracefs-fixes 8b55572e51805184353ee7d587c720a51818fb82 +spacemit-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +tip-fixes f88a000d5409e74dec51e2b1793a0e708d1920b4 +slab-fixes be8250786ca94952a19ce87f98ad9906448bc9ef +drm-msm-fixes 8290d37ad2b087bbcfe65fa5bcaf260e184b250a +uml-fixes 2dca89df0d1116f722b4be100e4bfcff858058e8 +fwctl-fixes 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +devsec-tsm-fixes fba4ceaa242d2bdf4c04b77bda41d32d02d3925d +drm-misc-fixes 038d61fd642278bab63ee8ef722c50d10ab01e8f +linus ffd294d346d185b70e28b1a28abe367bbfe53c04 +mm-stable a2152fef29020e740ba0276930f3a24440012505 +mm-nonmm-stable 085dece6cc88b5c6fc6f2eca0403bfd2c5fbc7cb +mm-unstable 66b994de3cf1c4520fd249e861bc83b1f902d20b +mm-nonmm-unstable 021cf32328d6583f3a75fb4f136e7a6f8efe8192 +kbuild dae742fa564b7f53de83c16dce033d547c84c0f3 +clang-format c147f663b6a5813b9860f3917cc473fb2c462d8d +perf 6235ce77749f45cac27f630337e2fdf04e8a6c73 +compiler-attributes 98f7e32f20d28ec452afb208f9cffc08448a2652 +dma-mapping fbf5e2234169067a811ab38dc89cc0d260499622 +asm-generic 582847f9702461b0a1cba3efdb2b8135bf940d53 +alpha 1523226edda566057bdd3264ceb56631ddf5f6f7 +arm 8dd85887ad83438750fa09237da9342ce966dd0f +arm64 5b1ae9de71335865d06ff0e60eadcf368a735edf +arm-perf e480898e767c54a883e965fc306e2ece013cbca5 +arm-soc 9f9d41d643224e1cc7eac89794cf5e5997f8171f +amlogic 58abdca0eb653c1a2e755ba9ba406ee475d87636 +asahi-soc 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +at91 e99113d11171a03c865ca5b10e0ae9b587034ae2 +bmc acba3fae64fd9c9862e1452c1a4f788055fab0e9 +broadcom 89abb622d518a917e16b6cd441dc75f547300303 +davinci 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +drivers-memory 93a7aedc4cc4476da54ea45f3ed5308aabafef75 +fsl 8b3da0519ae664dd7e3d840c3a6851ec5a7f42de +imx-mxs cdc22fb12efffa2357cea791a7c4a1a4407a66a7 +mediatek 6cbb623586d5cd1abf2b1b8500294546b8543058 +mvebu 88084e0358ff6f5c39accddf3f0da4162e6d0ccf +omap db91121f001a3a1fad41ff816bdbddb7da443297 +qcom ba94ec807b071becbed7377f8c84308f1b6ccd51 +renesas 7a323accaf6bf40f0d345694978e3657363c3772 +reset 335bb23abed39d9ec174ea520bc2337e2fe605ef +rockchip 1f0c7abd82357d425e34645fa086280f552ae822 +samsung-krzk 94f19ac4670d5867609484329ee62f6bf254c090 +scmi d2eedaa3909be9102d648a4a0a50ccf64f96c54f +sophgo 349ae53a949ce96d0e1453170d31d26ed54ba68e +sophgo-soc c8754c7deab4cbfa947fa2d656cbaf83771828ef +spacemit 6be7a5a768aafcb07d177bd2ae36ab84e4e0acde +stm32 1a32f7427eb3d1248bc64cd745b93f88cc838933 +sunxi cbe908fc8ebbea52f2d674773c2ddaf8cbfa4757 +tee 84c5f44d24c6a26d38642d996507f08ac92eb3ed +tegra 499b75defe5654ba29e838bd2f5e79d3a16229af +thead-dt c31f2899eab084b3557e9f9e10fc7898113ef18d +ti 65f6e3eb6351ff402a03f2b6b56ab1fd61511334 +xilinx 3a0e3f82b8ee4386bfbc2cdcdf4243a3e8de4bad +clk 64c21f253a3737c15ab745e9276b2352d86aed26 +clk-imx c78865241ecffaff7ce5db00ed5b71c1a70c0ff1 +clk-renesas 0ab2d84f94dae48c3e7605cdc99dbb4e7c7b206a +thead-clk 54edba916e2913b0893b0f6404b73155d48374ea +csky 2b48804336be69272d43939ff0dc3b0c0a703395 +loongarch bcfdf97c1abcb0147e4ed00350a25ad3393c2c33 +m68k c8995932db2bad6fa093ac64dbaf7a3e8870eafa +m68knommu 89be9a83ccf1f88522317ce02f854f30d6115c41 +microblaze c0e7bb02f7962cd4b2327196aa1b0f9568c783e4 +mips 3ebcbf079c26ab6e82faa7f896b66def55547eee +openrisc f0eedcf22581ca1cc438fb38a479ff41ab882d51 +parisc-hd 89f686a0fb6e473a876a9a60a13aec67a62b9a7e +powerpc cf2a6de32cabbf84a889e24a9ee7c51dee4a1f70 +risc-v fda589c286040d9ba2d72a0eaf0a13945fc48026 +riscv-dt 28fa0dcb571ab8f3be4d919f0e20e01d4e44bcb1 +riscv-soc bd4d5d3faadcdf5d65377f14dcbaa4dbb27ee637 +s390 d3a0de1a9dbc77623ffeb4d478204c4df0470236 +sh c32969d0362a790fbc6117e0b6a737a7e510b843 +sparc 2cec2c4dc90cbf5194c1acef08c1e74f0437af95 +uml fc9ed2f6589dc2c11f05883e5c323be5f39fd241 +xtensa 44a4ef59d5506c6dc7599d876a3a1014697ec480 +fs-next 0264e7f5188b34d7ffce79c364667e69a663013f +printk dcc3191a3dde4027ac3a995d852b957e398cf6cc +pci 0bd0a41a5120f78685a132834865b0a631b9026a +pstore d679c2e1e8d96f71f85e2ef3877407d264212cc3 +hid 1330eb33bddca5f8dd163bbe3a8f8e828697c0fd +i2c 976990f4120c220816b46650d840019451698a28 +i2c-host 85c34532849dae0fdcf880900ac9d7718a73fd1b +i3c 3b661ca549b9e5bb11d0bc97ada6110aac3282d2 +dmi 4d1b28a8119c615f1e932520f9ee1f80bdda5204 +hwmon-staging de1fffd88600c5ee1c095c84b86484cd0329a9e8 +jc_docs 35293ebbb65e0295d3b9357f786004ae1026d00f +v4l-dvb d968e50b5c26642754492dea23cbd3592bde62d8 +v4l-dvb-next b36c41c51e9d763393634359b90f02414ef470a3 +pm 77d832285656c59238e7992f12296e18657251ee +cpufreq-arm bbd67be5546d6080a7dc9903355a54ac4b865caa +cpupower e6c3f96141ebab688d96cf582bcab67f930e0baa +devfreq 7da2fdaaa1e6062686ac96a9f096c2d7847533e4 +pmdomain 05e35bd07d56780f0a5119973995b97a16843579 +opp 22679d807dea5c065d8019acfce48f20e87ba5ca +thermal 1d264d3a198839c7483580acdce17e1015d0ef91 +rdma ee235923d205c6de73bf5035f3cdcaee22f3291c +net-next d9104cec3e8fe4b458b74709853231385779001f +bpf-next 821c9e515db512904250e1d460109a1dc4c7ef6b +ipsec-next 95cfe23285a6de17f11715378c93e6aee6d0ca75 +mlx5-next 888a7776f4fb04c19bec70c737c61c2f383c6b1e +netfilter-next e3f96b3556e4856dc4125ce875e87c5b5028b40b +ipvs-next e3f96b3556e4856dc4125ce875e87c5b5028b40b +bluetooth df18778595f9423542f38784749feca5471f9de7 +wireless-next 126d85fb040559ba6654f51c0b587d280b041abb +ath-next 708243c62efde8241e2c66e9c3f377658855149d +iwlwifi-next d2af710d6d50b3a3e691c4e2b262ed9de3038e96 +wpan-next 1dd9291eb90378f8096669d9cb33761fd84599e0 +wpan-staging 1dd9291eb90378f8096669d9cb33761fd84599e0 +mtd 9cf9db888f387844e063efc6296e9fa5c042995e +nand fb2fae70e7e985c4acb1ad96110d8b98bb64a87c +spi-nor 2e3a7476ec3989e77270b9481e76e137824b17c0 +crypto 9d9b193ed73a65ec47cf1fd39925b09da8216461 +libcrypto 2a1a127aecf628a7629c860e2ad645174b5d3211 +drm 6531a2cf07ef156956840853692755cc7e1621b7 +drm-exynos 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +drm-misc 584460393efbcccb6388b1cd5d37284b5326709c +amdgpu 1c2efae2f855e348d772c071c8c30217d8a0dbae +drm-intel 5a569ef4d4ab184a481dd8ecb58f464a89b44d2f +drm-msm 8290d37ad2b087bbcfe65fa5bcaf260e184b250a +drm-msm-lumag cd86e80b77b2f3d9e72c2d27a967b666d2c47a44 +drm-nova 14ae91a81ec8fa0bc23170d4aa16dd2a20d54105 +drm-xe bcddb12c027434fdf0491c1a05a3fe4fd2263d71 +etnaviv 6bde14ba5f7ef59e103ac317df6cc5ac4291ff4a +fbdev e4fc307d8e24f122402907ebf585248cad52841d +regmap 067aa458a064cd860baef7503c3264bb3482d37e +sound dbe05428c4e54068a86e7e02405f3b30b1d2b3dd +ieee1394 95a042a0c8ecd3c1e886648f6f6ab9c7e4403db9 +sound-asoc 282528da82a0436f3bed0755338539ba5d7d730b +modules 40a826bd6c82ae45cfd3a19cd2a60a10f56b74c0 +input a7bee4e7f78089c101be2ad51f4b5ec64782053e +block 20c74c07321713217b2f84c55dfd717729aa6111 +device-mapper 55a0fbd2ac3fe8f61a30ea697b2eb3034f6778c8 +libata 6cb43739b93c64c4a2148222bd606e6920257752 +pcmcia 0630e3bc0e91b57288921df2927859b23184ca45 +mmc 4b290aae788e06561754b28c6842e4080957d3f7 +mfd b6bf74c821780259495b1f86e319854ef5bee0db +backlight 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +battery 7b41a2341fa62babda5d5c7a32c632e9eba2ee11 +regulator 10dfd36f078423c51602a9a21ed85e8e6c947a00 +security 5d8b97c946777118930e1cfb075cab59a139ca7c +apparmor 5f49c2d1f422c660c726ac5e0499c66c901633c2 +integrity aa9bb1b32594cd67cafd29b330b158128b503882 +selinux 850dada4b3afd014e2c69226bf9bb85469338000 +smack 6ddd169d0288ebee8ec9afcd75825ce8476edb00 +tomoyo 038d61fd642278bab63ee8ef722c50d10ab01e8f +tpmdd 7f0c6675b3194461ad7bb8db1d822445121fb029 +watchdog 48defdf6b083f74a44e1f742db284960d3444aec +iommu b9e6e8ae0a5f9edae7cc1b5972a1d3dea9223fe2 +audit ae1ae11fb277f1335d6bcd4935ba0ea985af3c32 +devicetree 0121898ec05fa4c1f566fc05c7e8b3caf0998f97 +dt-krzk 6cd594ed969d5cfc7f97029f8ca0d240637ebb8d +mailbox 872798f61d8bfea857e54aa17baa7b0d3ee24b65 +spi a49bfbecfde75fa95677d4dfe95de8b25f8de37f +tip 40d6e791ba3ac9f66eba33833710a2e2f1aa8a66 +clockevents d7b8f8e20813f0179d8ef519541a3527e7661d3a +edac 1fb0ddddf5d139089675b86702933cbca992b4d4 +ftrace 39f069d5a466cb9a572ee10c5391e822cdccaf05 +rcu cc1d1365f0f414f6522378867baa997642a7e6b2 +paulmck b706eec9304fc3cbc48a6a09aff8533081815ebc +kvm 196d9e72c4b0bd68b74a4ec7f52d248f37d0f030 +kvm-arm 7b8346bd9fce6b76a96c6780d2e5bba76687f97f +kvms390 57d88f02eb4449d96dfee3af4b7cd4287998bdbd +kvm-ppc fac04efc5c793dccbd07e2d59af9f90b7fc0dca4 +kvm-riscv 07a289a031404ec583c01d8e87680d434fc62c1f +kvm-x86 33f843444e28920d6e624c6c24637b4bb5d3c8de +xen-tip 114a2de6fa86d99ed9546cc9113a3cad58beef79 +percpu 87d6aab2389e5ce0197d8257d5f8ee965a67c4cd +workqueues 324cee0c272cb3fa6c4d3c0de4b68a9c5357d2e7 +sched-ext 9f0744a0e87e4e74725d495bba2aa540dec4a77a +drivers-x86 1798561befd8be1e52feb54f850efcab5a595f43 +chrome-platform cc2d5b72b13b3af2b9b4bed3d5dfd0de14414230 +chrome-platform-firmware 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +hsi 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +leds-lj 4903924ac7ef31fbbe48b3261b1bc86ce6cd7e97 +ipmi ec50ec378e3fd83bde9b3d622ceac3509a60b6b5 +driver-core d632ab86aff2cef21f794e337a8e7f2320ac3973 +usb d632ab86aff2cef21f794e337a8e7f2320ac3973 +thunderbolt 2d1beba54fdaac0d624b016025d4ec5856713fb1 +usb-serial bdf2ab177e2fca85394fce86629f5e35aa7fa33a +tty 89748acdf226fd1a8775ff6fa2703f8412b286c8 +char-misc d632ab86aff2cef21f794e337a8e7f2320ac3973 +accel f03eee5fc922158654405318a02db9982c0ddf07 +coresight a80198ba650f50d266d7fc4a6c5262df9970f9f2 +fastrpc 0af2f6be1b4281385b618cb86ad946eded089ac8 +fpga 37e00703228ab44d0aacc32a97809a4f6f58df1b +icc ca652cf0c2612add5d3c9283bbc742dabc704a77 +iio 0a686b9c4f847dc21346df8e56d5b119918fefef +phy-next 4a3556b81b99f0c8c0358f7cc6801a62b4538fe2 +soundwire 34b1cb4ec286603127aa8c4191ea527eb8dd3567 +extcon 5f09caafc652bcee7a5247e40dd34d1de1ad7d7f +gnss e326371f3002dbf54befd8ada9570fa489a46991 +vfio d2272d898186fa96c6fa4ad067219b45b8c2ef5f +w1 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +spmi 0ff41df1cb268fc69e703a08a57ee14ae967d0ca +staging d632ab86aff2cef21f794e337a8e7f2320ac3973 +counter-next 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +siox db418d5f1ca5b7bafc8eaa9393ea18a7901bb0ed +mux 59b723cd2adbac2a34fc8e12c74ae26ae45bf230 +dmaengine e3a9ccd21897a59d02cf2b7a95297086249306d6 +cgroup d445d2ab8129b1da93f25a9a71e36f43223d5543 +scsi b3a40acce7b3d0a7e9d0b2042a33129a7e3d6e41 +scsi-mkp 383cd6d879a18acdaa84c29330b25c49cbc0b490 +vhost 06a1fa9a0b79be71b7426ed792cf189b2b0ffac6 +rpmsg 01d7d9241256597eb38ec8a119ff89062b9fa10a +gpio-brgl 63c7bc53a35e785accdc2ceab8f72d94501931ab +gpio-intel 9ab29ed505557bd106e292184fa4917955eb8e6e +pinctrl a3fe1324c3c5c292ec79bd756497c1c44ff247d2 +pinctrl-intel 3b4408038da935be7b1efb7589cc1badb6d10a67 +pinctrl-renesas 7000167796a00d64322dc3ed0c0970e31d481ed6 +pinctrl-samsung 683d532dfc9657ab8aae25204f378352ed144646 +pwm 65c6f742ab14ab1a2679fba72b82dcc0289d96f1 +ktest a5e71638ddd7f1dc0b9f3a5ac8ab8bef48b9f0ee +kselftest 30fb5e134f05800dc424f8aa1d69841a6bdd9a54 +kunit 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +kunit-next 34db4fba81916a2001d7a503dfcf718c08ed5c42 +livepatching a8e905a819fdfb4ce674363896320e36657d0f16 +rtc bb5b0b4317c9516bdc5e9a4235e3b5f1a73b7e48 +nvdimm 9f97e61bde6a91a429f48da1a461488a15b01813 +at24 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +ntb 0cadf92e93d4caed1714faac53e9a0051810f4b0 +seccomp b0c9bfbab925ac6385d4d06a134fd89cadf771fe +slimbus 0af2f6be1b4281385b618cb86ad946eded089ac8 +nvmem 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +xarray 6684aba0780da9f505c202f27e68ee6d18c0aa66 +hyperv d9016a249be5316ec2476f9947356711e70a16ec +auxdisplay 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +kgdb afdbe49276accb87a0c7414e75864c78289ece2f +hmm 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +cfi 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +mhi 00559ba3ae740e7544b48fb509b2b97f56615892 +memblock 3b394dff15e14550a26b133fc7b556b5b526f6a5 +cxl f11a5f89910a7ae970fbce4fdc02d86a8ba8570f +zstd 65d1f5507ed2c78c64fce40e44e5574a9419eb09 +efi 02eb7a8eee20b9ec6aafd5e17c5c41b53e8b13ef +unicode 6b56a63d286f6f57066c4b5648d8fbec9510beae +slab 8185696483dcb29688fc23c45c99d86b73754982 +random 3778dcb2dcc1ce03a2b25e5d951fe9912e843d1e +landlock 6dde339a3df80a57ac3d780d8cfc14d9262e2acd +rust d2eedaa3909be9102d648a4a0a50ccf64f96c54f +rust-alloc d49ac7744f578bcc8708a845cce24d3b91f86260 +rust-io 86731a2a651e58953fc949573895f2fa6d456841 +rust-pin-init fc3870dc5cadb701b4122e4a8daa85f9fa2f57b9 +rust-timekeeping d4b29ddf82a458935f1bd4909b8a7a13df9d3bdc +rust-xarray fa616196fbea12462107774fb6a1908c95f71cf0 +sysctl 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +execve 7f71195c15dcf5f34c4c7f056603659374e3a525 +bitmap 89748acdf226fd1a8775ff6fa2703f8412b286c8 +hte 9e4259716f60c96c069a38e826884ad783dc4eb4 +kspp f627b51aaa041cba715b59026cf2d9cb1476c7ed +nolibc b9e50363178a40c76bebaf2f00faa2b0b6baf8d1 +iommufd 2c78e74493d33b002312296fbab1d688bfd0f76f +turbostat 447c98c1ca4a4b0d43be99f76c558c09956484f3 +pwrseq 07d59dec6795428983a840de85aa02febaf7e01b +capabilities-next cdd73b1666079a73d061396f361df55d59fe96e6 +ipe 038d61fd642278bab63ee8ef722c50d10ab01e8f +kcsan 9872916ad1a1a5e7d089e05166c85dbd65e5b0e8 +crc 118da22eb6fbd48f896d17411f942399283d600c +fwctl 19272b37aa4f83ca52bdf9c16d5d81bdd1354494 +devsec-tsm 9d948b8804096d940022b1a3c483a5beb8b46574 +hisilicon b1136432c97241f0e5c40d58597da00d49cd9917 +kthread d8b4bf4ea04dd96fe43f6010c614149aba4c9b91 diff --git a/Next/Trees b/Next/Trees new file mode 100644 index 000000000000..2477ec47fb71 --- /dev/null +++ b/Next/Trees @@ -0,0 +1,409 @@ +Trees included into this release: + +Name Type Url +---- ---- --- +origin git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git#master +fixes git git://git.kernel.org/pub/scm/linux/kernel/git/sfr/next-fixes.git#fixes +ext4-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git#fixes +vfs-brauner-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git#vfs.fixes +fscrypt-current git git://git.kernel.org/pub/scm/fs/fscrypt/linux.git#for-current +fsverity-current git git://git.kernel.org/pub/scm/fs/fsverity/linux.git#for-current +btrfs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git#next-fixes +vfs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git#fixes +erofs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git#fixes +nfsd-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux#nfsd-fixes +v9fs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git#fixes/next +overlayfs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs.git#ovl-fixes +bcachefs git git://evilpiepirate.org/bcachefs.git#for-next +fscrypt git git://git.kernel.org/pub/scm/fs/fscrypt/linux.git#for-next +btrfs git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git#for-next +ceph git git://github.com/ceph/ceph-client.git#master +cifs git git://git.samba.org/sfrench/cifs-2.6.git#for-next +configfs git git://git.kernel.org/pub/scm/linux/kernel/git/a.hindborg/linux.git#configfs-next +ecryptfs git git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git#next +dlm git git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git#next +erofs git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git#dev +exfat git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git#dev +exportfs git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux#exportfs-next +ext3 git git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git#for_next +ext4 git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git#dev +f2fs git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git#dev +fsverity git git://git.kernel.org/pub/scm/fs/fsverity/linux.git#for-next +fuse git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next +gfs2 git git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git#for-next +jfs git git://github.com/kleikamp/linux-shaggy.git#jfs-next +ksmbd git https://github.com/smfrench/smb3-kernel.git#ksmbd-for-next +nfs git git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git#linux-next +nfs-anna git git://git.linux-nfs.org/projects/anna/linux-nfs.git#linux-next +nfsd git git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux#nfsd-next +ntfs3 git https://github.com/Paragon-Software-Group/linux-ntfs3.git#master +orangefs git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux#for-next +overlayfs git git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs.git#overlayfs-next +ubifs git git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git#next +v9fs git git://github.com/martinetd/linux#9p-next +v9fs-ericvh git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git#ericvh/for-next +xfs git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git#for-next +zonefs git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs.git#for-next +vfs-brauner git git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git#vfs.all +vfs git git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git#for-next +mm-hotfixes git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm#mm-hotfixes-unstable +fs-current git linux-next +kbuild-current git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git#fixes +arc-current git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git#for-curr +arm-current git git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux.git#fixes +arm64-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux#for-next/fixes +arm-soc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#arm/fixes +davinci-current git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#davinci/for-current +drivers-memory-fixes git https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git#fixes +sophgo-fixes git https://github.com/sophgo/linux.git#fixes +sophgo-soc-fixes git https://github.com/sophgo/linux.git#soc-fixes +m68k-current git git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-linus +powerpc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#fixes +s390-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#fixes +net git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git#main +bpf git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git#master +ipsec git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git#master +netfilter git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git#main +ipvs git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git#main +wireless git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git#for-next +ath git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git#for-current +iwlwifi git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git#fixes +wpan git git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan.git#master +rdma-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#for-rc +sound-current git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-linus +sound-asoc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-linus +regmap-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-linus +regulator-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-linus +spi-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git#for-linus +pci-current git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git#for-linus +driver-core.current git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git#driver-core-linus +tty.current git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-linus +usb.current git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-linus +usb-serial-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-linus +phy git git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git#fixes +staging.current git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-linus +iio-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git#fixes-togreg +counter-current git git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter.git#counter-current +char-misc.current git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-linus +soundwire-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git#fixes +thunderbolt-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git#fixes +input-current git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#for-linus +crypto-current git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git#master +libcrypto-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git#libcrypto-fixes +vfio-fixes git git://github.com/awilliam/linux-vfio.git#for-linus +kselftest-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#fixes +dmaengine-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git#fixes +backlight-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-fixes +mtd-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#mtd/fixes +mfd-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-fixes +v4l-dvb-fixes git git://linuxtv.org/media-ci/media-pending.git#fixes +reset-fixes git https://git.pengutronix.de/git/pza/linux#reset/fixes +mips-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git#mips-fixes +at91-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git#at91-fixes +omap-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap.git#fixes +kvm-fixes git git://git.kernel.org/pub/scm/virt/kvm/kvm.git#master +kvms390-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git#master +hwmon-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon +nvdimm-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git#libnvdimm-fixes +cxl-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl.git#fixes +dma-mapping-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux.git#dma-mapping-fixes +drivers-x86-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git#fixes +samsung-krzk-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git#fixes +pinctrl-samsung-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git#fixes +devicetree-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git#dt/linus +dt-krzk-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-dt.git#fixes +scsi-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git#fixes +drm-fixes git https://gitlab.freedesktop.org/drm/kernel.git#drm-fixes +drm-intel-fixes git https://gitlab.freedesktop.org/drm/i915/kernel#for-linux-next-fixes +mmc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git#fixes +rtc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git#rtc-fixes +gnss-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git#gnss-linus +hyperv-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git#hyperv-fixes +risc-v-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git#fixes +riscv-dt-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git#riscv-dt-fixes +riscv-soc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git#riscv-soc-fixes +fpga-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git#fixes +spdx git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/spdx.git#spdx-linus +gpio-brgl-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#gpio/for-current +gpio-intel-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#fixes +pinctrl-intel-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#fixes +auxdisplay-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-auxdisplay.git#fixes +kunit-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#kunit-fixes +memblock-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git#fixes +renesas-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git#fixes +perf-current git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools#perf-tools +efi-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git#urgent +battery-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git#fixes +iommufd-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git#for-rc +rust-fixes git https://github.com/Rust-for-Linux/linux.git#rust-fixes +w1-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-w1.git#fixes +pmdomain-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git#fixes +i2c-host-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git#i2c/i2c-host-fixes +sparc-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc.git#for-linus +clk-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git#clk-fixes +thead-clk-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git#thead-clk-fixes +pwrseq-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#pwrseq/for-current +thead-dt-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git#thead-dt-fixes +ftrace-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git#ftrace/fixes +ring-buffer-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git#ring-buffer/fixes +trace-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git#trace/fixes +tracefs-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git#tracefs/fixes +spacemit-fixes git https://github.com/spacemit-com/linux#fixes +tip-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#tip/urgent +slab-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git#slab/for-next-fixes +drm-msm-fixes git https://gitlab.freedesktop.org/drm/msm.git#msm-fixes +uml-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git#fixes +fwctl-fixes git git//git.kernel.org/pub/scm/linux/kernel/git/fwctl/fwctl.git#for-rc +devsec-tsm-fixes git git://git.kernel.org/pub/scm/linux/kernel/git/devsec/tsm.git#fixes +drm-misc-fixes git https://gitlab.freedesktop.org/drm/misc/kernel.git#for-linux-next-fixes +linus git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git#for-next +mm-stable git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm#mm-stable +mm-nonmm-stable git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm#mm-nonmm-stable +mm-unstable git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm#mm-unstable +mm-nonmm-unstable git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm#mm-nonmm-unstable +kbuild git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git#for-next +clang-format git https://github.com/ojeda/linux.git#clang-format +perf git git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git#perf-tools-next +compiler-attributes git https://github.com/ojeda/linux.git#compiler-attributes +dma-mapping git git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux.git#dma-mapping-for-next +asm-generic git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git#master +alpha git git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha.git#alpha-next +arm git git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux.git#for-next +arm64 git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux#for-next/core +arm-perf git git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git#for-next/perf +arm-soc git git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#for-next +amlogic git git://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git#for-next +asahi-soc git https://github.com/AsahiLinux/linux.git#asahi-soc/for-next +at91 git git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git#at91-next +bmc git git://git.kernel.org/pub/scm/linux/kernel/git/bmc/linux.git#for-next +broadcom git https://github.com/Broadcom/stblinux.git#next +davinci git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#davinci/for-next +drivers-memory git https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git#for-next +fsl git https://github.com/chleroy/linux.git#soc_fsl +imx-mxs git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git#for-next +mediatek git git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git#for-next +mvebu git git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git#for-next +omap git git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap.git#for-next +qcom git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git#for-next +renesas git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git#next +reset git https://git.pengutronix.de/git/pza/linux#reset/next +rockchip git git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git#for-next +samsung-krzk git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git#for-next +scmi git git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git#for-linux-next +sophgo git https://github.com/sophgo/linux.git#for-next +sophgo-soc git https://github.com/sophgo/linux.git#soc-for-next +spacemit git https://github.com/spacemit-com/linux#for-next +stm32 git git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git#stm32-next +sunxi git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git#sunxi/for-next +tee git git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git#next +tegra git git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git#for-next +thead-dt git git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git#thead-dt-for-next +ti git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git#ti-next +xilinx git git://github.com/Xilinx/linux-xlnx.git#for-next +clk git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git#clk-next +clk-imx git git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git#for-next +clk-renesas git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git#renesas-clk +thead-clk git git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git#thead-clk-for-next +csky git git://github.com/c-sky/csky-linux.git#linux-next +loongarch git git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git#loongarch-next +m68k git git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-next +m68knommu git git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git#for-next +microblaze git git://git.monstr.eu/linux-2.6-microblaze.git#next +mips git git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git#mips-next +openrisc git git://github.com/openrisc/linux.git#for-next +parisc-hd git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git#for-next +powerpc git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#next +risc-v git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git#for-next +riscv-dt git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git#riscv-dt-for-next +riscv-soc git git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git#riscv-soc-for-next +s390 git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#for-next +sh git git:git.kernel.org/pub/scm/linux/kernel/git/glaubitz/sh-linux.git#for-next +sparc git git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc.git#for-next +uml git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git#next +xtensa git git://github.com/jcmvbkbc/linux-xtensa.git#xtensa-for-next +fs-next git linux-next +printk git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git#for-next +pci git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git#next +pstore git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/pstore +hid git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git#for-next +i2c git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git#i2c/for-next +i2c-host git git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git#i2c/i2c-host +i3c git git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git#i3c/next +dmi git git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging.git#dmi-for-next +hwmon-staging git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon-next +jc_docs git git://git.lwn.net/linux.git#docs-next +v4l-dvb git git://linuxtv.org/media-ci/media-pending.git#next +v4l-dvb-next git git://linuxtv.org/mchehab/media-next.git#master +pm git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git#linux-next +cpufreq-arm git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git#cpufreq/arm/linux-next +cpupower git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux.git#cpupower +devfreq git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git#devfreq-next +pmdomain git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git#next +opp git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git#opp/linux-next +thermal git git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git#thermal/linux-next +rdma git git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#for-next +net-next git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git#main +bpf-next git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git#for-next +ipsec-next git git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git#master +mlx5-next git git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git#mlx5-next +netfilter-next git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git#main +ipvs-next git git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git#main +bluetooth git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git#master +wireless-next git git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git#for-next +ath-next git git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git#for-next +iwlwifi-next git https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git#next +wpan-next git git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan-next.git#master +wpan-staging git git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan-next.git#staging +mtd git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#mtd/next +nand git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#nand/next +spi-nor git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#spi-nor/next +crypto git git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git#master +libcrypto git git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git#libcrypto-next +drm git https://gitlab.freedesktop.org/drm/kernel.git#drm-next +drm-exynos git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git#for-linux-next +drm-misc git https://gitlab.freedesktop.org/drm/misc/kernel.git#for-linux-next +amdgpu git https://gitlab.freedesktop.org/agd5f/linux#drm-next +drm-intel git https://gitlab.freedesktop.org/drm/i915/kernel#for-linux-next +drm-msm git https://gitlab.freedesktop.org/drm/msm.git#msm-next +drm-msm-lumag git https://gitlab.freedesktop.org/lumag/msm.git#msm-next-lumag +drm-nova git https://gitlab.freedesktop.org/drm/nova.git#nova-next +drm-xe git https://gitlab.freedesktop.org/drm/xe/kernel#drm-xe-next +etnaviv git https://git.pengutronix.de/git/lst/linux#etnaviv/next +fbdev git git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev.git#for-next +regmap git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-next +sound git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-next +ieee1394 git https://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git#for-next +sound-asoc git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-next +modules git git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux.git#modules-next +input git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#next +block git git://git.kernel.dk/linux-block.git#for-next +device-mapper git git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git#for-next +libata git git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux#for-next +pcmcia git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git#pcmcia-next +mmc git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git#next +mfd git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git#for-mfd-next +backlight git git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git#for-backlight-next +battery git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git#for-next +regulator git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-next +security git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git#next +apparmor git git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor#apparmor-next +integrity git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity#next-integrity +selinux git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git#next +smack git git://github.com/cschaufler/smack-next#next +tomoyo git git://git.code.sf.net/p/tomoyo/tomoyo.git#master +tpmdd git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git#next +watchdog git git://www.linux-watchdog.org/linux-watchdog-next.git#master +iommu git git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git#next +audit git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git#next +devicetree git git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git#for-next +dt-krzk git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-dt.git#for-next +mailbox git git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox.git#for-next +spi git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git#for-next +tip git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#master +clockevents git git://git.kernel.org/pub/scm/linux/kernel/git/daniel.lezcano/linux.git#timers/drivers/next +edac git git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git#edac-for-next +ftrace git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git#for-next +rcu git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git#next +paulmck git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git#non-rcu/next +kvm git git://git.kernel.org/pub/scm/virt/kvm/kvm.git#next +kvm-arm git git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git#next +kvms390 git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git#next +kvm-ppc git git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git#topic/ppc-kvm +kvm-riscv git https://github.com/kvm-riscv/linux.git#riscv_kvm_next +kvm-x86 git https://github.com/kvm-x86/linux.git#next +xen-tip git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git#linux-next +percpu git git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git#for-next +workqueues git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git#for-next +sched-ext git git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext.git#for-next +drivers-x86 git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git#for-next +chrome-platform git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git#for-next +chrome-platform-firmware git git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git#for-firmware-next +hsi git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git#for-next +leds-lj git git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git#for-leds-next +ipmi git git://github.com/cminyard/linux-ipmi.git#for-next +driver-core git git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git#driver-core-next +usb git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-next +thunderbolt git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git#next +usb-serial git git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git#usb-next +tty git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-next +char-misc git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-next +accel git git://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/linux.git#habanalabs-next +coresight git git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git#next +fastrpc git git://git.kernel.org/pub/scm/linux/kernel/git/srini/fastrpc.git#for-next +fpga git git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git#for-next +icc git git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc.git#icc-next +iio git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git#togreg +phy-next git git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git#next +soundwire git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git#next +extcon git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git#extcon-next +gnss git git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git#gnss-next +vfio git git://github.com/awilliam/linux-vfio.git#next +w1 git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-w1.git#for-next +spmi git git://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git#spmi-next +staging git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-next +counter-next git git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter.git#counter-next +siox git git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git#siox/for-next +mux git https://gitlab.com/peda-linux/mux.git#for-next +dmaengine git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git#next +cgroup git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git#for-next +scsi git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git#for-next +scsi-mkp git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git#for-next +vhost git git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git#linux-next +rpmsg git git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git#for-next +gpio-brgl git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#gpio/for-next +gpio-intel git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#for-next +pinctrl git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git#for-next +pinctrl-intel git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#for-next +pinctrl-renesas git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git#renesas-pinctrl +pinctrl-samsung git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git#for-next +pwm git git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git#pwm/for-next +ktest git git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest.git#for-next +kselftest git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#next +kunit git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#test +kunit-next git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git#kunit +livepatching git git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching#for-next +rtc git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git#rtc-next +nvdimm git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git#libnvdimm-for-next +at24 git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#at24/for-next +ntb git https://github.com/jonmason/ntb.git#ntb-next +seccomp git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/seccomp +slimbus git git://git.kernel.org/pub/scm/linux/kernel/git/srini/slimbus.git#for-next +nvmem git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git#for-next +xarray git git://git.infradead.org/users/willy/xarray.git#main +hyperv git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git#hyperv-next +auxdisplay git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-auxdisplay.git#for-next +kgdb git git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux.git#kgdb/for-next +hmm git git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git#hmm +cfi git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git#cfi/next +mhi git git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git#mhi-next +memblock git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git#for-next +cxl git git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl.git#next +zstd git https://github.com/terrelln/linux.git#zstd-next +efi git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git#next +unicode git git://git.kernel.org/pub/scm/linux/kernel/git/krisman/unicode.git#for-next +slab git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git#slab/for-next +random git git://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git#master +landlock git git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git#next +rust git https://github.com/Rust-for-Linux/linux.git#rust-next +rust-alloc git https://github.com/Rust-for-Linux/linux.git#alloc-next +rust-io git https://github.com/Rust-for-Linux/linux.git#io-next +rust-pin-init git https://github.com/Rust-for-Linux/linux.git#pin-init-next +rust-timekeeping git https://github.com/Rust-for-Linux/linux.git#timekeeping-next +rust-xarray git https://github.com/Rust-for-Linux/linux.git#xarray-next +sysctl git git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl.git#sysctl-next +execve git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/execve +bitmap git https://github.com/norov/linux.git#bitmap-for-next +hte git git://git.kernel.org/pub/scm/linux/kernel/git/pateldipen1984/linux.git#for-next +kspp git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git#for-next/kspp +nolibc git git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc.git#for-next +iommufd git git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git#for-next +turbostat git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git#next +pwrseq git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git#pwrseq/for-next +capabilities-next git git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux.git#caps-next +ipe git https://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git#next +kcsan git git://git.kernel.org/pub/scm/linux/kernel/git/melver/linux.git#next +crc git git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git#crc-next +fwctl git git//git.kernel.org/pub/scm/linux/kernel/git/fwctl/fwctl.git#for-next +devsec-tsm git git://git.kernel.org/pub/scm/linux/kernel/git/devsec/tsm.git#next +hisilicon git https://github.com/hisilicon/linux-hisi.git#for-next +kthread git git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git#for-next diff --git a/Next/merge.log b/Next/merge.log new file mode 100644 index 000000000000..03828a662f7b --- /dev/null +++ b/Next/merge.log @@ -0,0 +1,3094 @@ +$ date -R +Tue, 05 Aug 2025 09:05:52 +1000 +$ git checkout master +Already on 'master' +$ git reset --hard stable +HEAD is now at 3c4a063b1f8a Merge tag 'trace-v6.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace +Merging origin/master (35a813e010b9 Merge tag 'printk-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git origin/master +Updating 3c4a063b1f8a..35a813e010b9 +Fast-forward (no commit created; -m option ignored) + .mailmap | 1 + + Documentation/accounting/delay-accounting.rst | 56 ++ + .../device-mapper/thin-provisioning.rst | 16 +- + Documentation/admin-guide/kdump/kdump.rst | 21 + + Documentation/admin-guide/kernel-parameters.txt | 86 +- + Documentation/admin-guide/sysctl/kernel.rst | 20 +- + .../devicetree/bindings/rtc/amlogic,a4-rtc.yaml | 11 +- + .../devicetree/bindings/rtc/nxp,lpc1788-rtc.yaml | 7 +- + .../devicetree/bindings/rtc/nxp,lpc3220-rtc.yaml | 49 ++ + .../devicetree/bindings/rtc/nxp,pcf85063.yaml | 33 +- + .../{soc/sophgo => rtc}/sophgo,cv1800b-rtc.yaml | 2 +- + .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - + MAINTAINERS | 14 +- + arch/alpha/kernel/core_marvel.c | 11 +- + arch/arm/kernel/setup.c | 2 +- + arch/arm64/mm/init.c | 2 +- + arch/loongarch/kernel/setup.c | 2 +- + arch/mips/kernel/setup.c | 2 +- + arch/openrisc/include/asm/mmu.h | 2 +- + arch/openrisc/include/asm/page.h | 8 +- + arch/openrisc/include/asm/pgtable.h | 4 +- + arch/openrisc/include/asm/processor.h | 4 +- + arch/openrisc/include/asm/ptrace.h | 4 +- + arch/openrisc/include/asm/setup.h | 2 +- + arch/openrisc/include/asm/thread_info.h | 8 +- + arch/openrisc/include/uapi/asm/ptrace.h | 2 +- + arch/powerpc/include/asm/ppc-opcode.h | 1 + + arch/powerpc/kernel/eeh.c | 1 + + arch/powerpc/kernel/eeh_driver.c | 48 +- + arch/powerpc/kernel/eeh_pe.c | 10 +- + arch/powerpc/kernel/fadump.c | 2 +- + arch/powerpc/kernel/pci-hotplug.c | 3 + + arch/powerpc/kexec/core.c | 2 +- + arch/powerpc/mm/nohash/kaslr_booke.c | 2 +- + arch/powerpc/net/bpf_jit_comp64.c | 82 ++ + arch/riscv/Kconfig | 1 + + arch/riscv/kernel/kexec_elf.c | 1 + + arch/riscv/kernel/setup.c | 5 + + arch/riscv/mm/init.c | 2 +- + arch/s390/kernel/setup.c | 2 +- + arch/sh/kernel/machine_kexec.c | 2 +- + arch/x86/kernel/crash.c | 26 +- + arch/x86/kernel/setup.c | 5 +- + arch/x86/kvm/i8254.c | 4 +- + crypto/async_tx/async_pq.c | 2 +- + crypto/async_tx/async_raid6_recov.c | 4 +- + drivers/cxl/core/mce.h | 2 +- + drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 3 +- + drivers/gpu/drm/xe/xe_vm_types.h | 2 +- + drivers/md/dm-flakey.c | 9 +- + drivers/md/dm-ima.c | 42 +- + drivers/md/dm-path-selector.c | 8 +- + drivers/md/dm-path-selector.h | 2 +- + drivers/md/dm-ps-historical-service-time.c | 9 +- + drivers/md/dm-ps-io-affinity.c | 5 +- + drivers/md/dm-ps-queue-length.c | 9 +- + drivers/md/dm-ps-round-robin.c | 9 +- + drivers/md/dm-ps-service-time.c | 9 +- + drivers/md/dm-raid.c | 7 +- + drivers/md/dm-table.c | 10 +- + drivers/md/dm-thin.c | 7 +- + drivers/md/dm-vdo/funnel-workqueue.c | 3 +- + drivers/md/dm-verity-fec.c | 4 +- + drivers/md/dm-verity-target.c | 185 +---- + drivers/md/dm-verity.h | 22 +- + drivers/md/dm-zone.c | 2 - + drivers/md/dm-zoned-target.c | 2 +- + drivers/md/dm.c | 11 +- + drivers/net/ethernet/marvell/mvneta.c | 2 +- + drivers/net/wwan/iosm/iosm_ipc_trace.c | 3 +- + drivers/net/wwan/t7xx/t7xx_port_trace.c | 2 +- + drivers/pci/hotplug/pnv_php.c | 250 +++++- + drivers/rtc/Kconfig | 21 +- + drivers/rtc/Makefile | 2 +- + drivers/rtc/lib.c | 40 +- + drivers/rtc/rtc-ds1307.c | 30 +- + drivers/rtc/rtc-ds1685.c | 4 +- + drivers/rtc/rtc-hym8563.c | 15 +- + drivers/rtc/rtc-m41t80.c | 25 +- + drivers/rtc/rtc-max31335.c | 12 +- + drivers/rtc/rtc-nct3018y.c | 15 +- + drivers/rtc/rtc-pcf85063.c | 351 ++++++--- + drivers/rtc/rtc-pcf8563.c | 15 +- + drivers/rtc/rtc-rv3028.c | 15 +- + drivers/rtc/rtc-rv3032.c | 21 +- + drivers/rtc/rtc-s3c.c | 8 +- + drivers/rtc/rtc-sh.c | 8 +- + drivers/rtc/sysfs.c | 64 +- + drivers/rtc/{lib_test.c => test_rtc_lib.c} | 0 + fs/fat/fatent.c | 2 +- + fs/fat/misc.c | 6 +- + fs/ocfs2/aops.c | 1 + + fs/ocfs2/dir.c | 8 + + fs/ocfs2/dlm/dlmrecovery.c | 2 +- + fs/ocfs2/inode.c | 70 +- + fs/ocfs2/move_extents.c | 19 +- + fs/ocfs2/namei.c | 11 +- + fs/ocfs2/stack_user.c | 15 +- + fs/proc/vmcore.c | 29 +- + fs/squashfs/block.c | 47 +- + fs/squashfs/file.c | 7 +- + include/linux/compiler-gcc.h | 2 + + include/linux/crash_reserve.h | 15 +- + include/linux/gcd.h | 3 + + include/linux/hung_task.h | 18 +- + include/linux/jhash.h | 8 +- + include/linux/kexec.h | 10 + + include/linux/raid/pq.h | 12 +- + include/linux/relay.h | 24 +- + include/linux/rtc/ds1685.h | 2 +- + include/linux/rwsem.h | 12 + + include/linux/sprintf.h | 2 +- + include/linux/sys_info.h | 28 + + include/linux/xxhash.h | 26 - + include/uapi/linux/kexec.h | 1 + + include/xen/xenbus.h | 2 +- + init/Kconfig | 4 + + init/main.c | 6 +- + kernel/crash_core.c | 15 + + kernel/crash_reserve.c | 68 +- + kernel/events/uprobes.c | 4 +- + kernel/exit.c | 7 +- + kernel/fork.c | 95 ++- + kernel/hung_task.c | 29 +- + kernel/kcov.c | 2 +- + kernel/kexec.c | 2 +- + kernel/kexec_core.c | 100 ++- + kernel/kexec_file.c | 51 +- + kernel/kexec_internal.h | 2 +- + kernel/kthread.c | 11 +- + kernel/locking/rwsem.c | 31 +- + kernel/panic.c | 71 +- + kernel/printk/internal.h | 2 + + kernel/printk/nbcon.c | 89 ++- + kernel/printk/printk.c | 20 +- + kernel/relay.c | 69 +- + kernel/sched/psi.c | 6 +- + kernel/trace/blktrace.c | 22 +- + kernel/ucount.c | 16 +- + lib/Kconfig.debug | 20 + + lib/Makefile | 3 +- + lib/math/div64.c | 13 +- + lib/math/gcd.c | 27 +- + lib/raid6/algos.c | 3 - + lib/raid6/recov.c | 6 +- + lib/raid6/recov_avx2.c | 6 +- + lib/raid6/recov_avx512.c | 6 +- + lib/raid6/recov_loongarch_simd.c | 12 +- + lib/raid6/recov_neon.c | 6 +- + lib/raid6/recov_rvv.c | 6 +- + lib/raid6/recov_s390xc.c | 6 +- + lib/raid6/recov_ssse3.c | 6 +- + lib/stackdepot.c | 67 +- + lib/sys_info.c | 122 +++ + lib/test_kho.c | 305 ++++++++ + lib/vsprintf.c | 70 +- + lib/xxhash.c | 107 --- + mm/slub.c | 5 +- + samples/Kconfig | 9 +- + samples/hung_task/hung_task_tests.c | 81 +- + scripts/checkpatch.pl | 33 +- + scripts/coccinelle/misc/secs_to_jiffies.cocci | 49 +- + scripts/gdb/linux/constants.py.in | 12 +- + scripts/spelling.txt | 1 + + security/apparmor/Makefile | 6 +- + security/apparmor/af_unix.c | 799 +++++++++++++++++++ + security/apparmor/apparmorfs.c | 39 +- + security/apparmor/audit.c | 2 +- + security/apparmor/capability.c | 61 +- + security/apparmor/domain.c | 203 +++-- + security/apparmor/file.c | 92 ++- + security/apparmor/include/af_unix.h | 55 ++ + security/apparmor/include/apparmor.h | 4 +- + security/apparmor/include/audit.h | 5 +- + security/apparmor/include/capability.h | 1 + + security/apparmor/include/cred.h | 31 +- + security/apparmor/include/file.h | 11 +- + security/apparmor/include/ipc.h | 3 + + security/apparmor/include/label.h | 51 +- + security/apparmor/include/lib.h | 46 +- + security/apparmor/include/match.h | 10 +- + security/apparmor/include/net.h | 36 +- + security/apparmor/include/path.h | 1 + + security/apparmor/include/perms.h | 8 +- + security/apparmor/include/policy.h | 63 +- + security/apparmor/include/sig_names.h | 6 +- + security/apparmor/include/signal.h | 19 + + security/apparmor/ipc.c | 13 +- + security/apparmor/label.c | 37 +- + security/apparmor/lib.c | 114 +++ + security/apparmor/lsm.c | 468 ++++++++--- + security/apparmor/match.c | 23 +- + security/apparmor/mount.c | 12 +- + security/apparmor/net.c | 189 ++++- + security/apparmor/policy.c | 93 ++- + security/apparmor/policy_compat.c | 6 +- + security/apparmor/policy_ns.c | 2 +- + security/apparmor/policy_unpack.c | 67 +- + security/apparmor/policy_unpack_test.c | 6 +- + security/apparmor/procattr.c | 6 +- + security/apparmor/resource.c | 11 +- + security/apparmor/task.c | 11 +- + tools/accounting/Makefile | 2 +- + tools/accounting/delaytop.c | 862 +++++++++++++++++++++ + tools/accounting/getdelays.c | 167 ++-- + tools/testing/selftests/bpf/progs/bpf_misc.h | 3 +- + tools/testing/selftests/kho/arm64.conf | 9 + + tools/testing/selftests/kho/init.c | 100 +++ + tools/testing/selftests/kho/vmtest.sh | 183 +++++ + tools/testing/selftests/kho/x86.conf | 7 + + tools/testing/selftests/ptrace/.gitignore | 1 + + .../intel/workload_hint/workload_hint_test.c | 16 +- + 212 files changed, 6222 insertions(+), 1664 deletions(-) + create mode 100644 Documentation/devicetree/bindings/rtc/nxp,lpc3220-rtc.yaml + rename Documentation/devicetree/bindings/{soc/sophgo => rtc}/sophgo,cv1800b-rtc.yaml (96%) + rename drivers/rtc/{lib_test.c => test_rtc_lib.c} (100%) + create mode 100644 include/linux/sys_info.h + create mode 100644 lib/sys_info.c + create mode 100644 lib/test_kho.c + create mode 100644 security/apparmor/af_unix.c + create mode 100644 security/apparmor/include/af_unix.h + create mode 100644 security/apparmor/include/signal.h + create mode 100644 tools/accounting/delaytop.c + create mode 100644 tools/testing/selftests/kho/arm64.conf + create mode 100644 tools/testing/selftests/kho/init.c + create mode 100755 tools/testing/selftests/kho/vmtest.sh + create mode 100644 tools/testing/selftests/kho/x86.conf +Merging fixes/fixes (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/sfr/next-fixes.git fixes/fixes +Already up to date. +Merging ext4-fixes/fixes (d0b3b7b22dfa Linux 6.16-rc4) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git ext4-fixes/fixes +Already up to date. +Merging vfs-brauner-fixes/vfs.fixes (8b3c655fa240 afs: Set vllist to NULL if addr parsing fails) +$ git merge -m Merge branch 'vfs.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs-brauner-fixes/vfs.fixes +Already up to date. +Merging fscrypt-current/for-current (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'for-current' of git://git.kernel.org/pub/scm/fs/fscrypt/linux.git fscrypt-current/for-current +Already up to date. +Merging fsverity-current/for-current (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'for-current' of git://git.kernel.org/pub/scm/fs/fsverity/linux.git fsverity-current/for-current +Already up to date. +Merging btrfs-fixes/next-fixes (61d18d91dd4a Merge branch 'misc-6.17' into next-fixes) +$ git merge -m Merge branch 'next-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git btrfs-fixes/next-fixes +Merge made by the 'ort' strategy. +Merging vfs-fixes/fixes (33927f3d0ecd habanalabs: fix UAF in export_dmabuf()) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git vfs-fixes/fixes +Merge made by the 'ort' strategy. + drivers/accel/habanalabs/common/memory.c | 23 +++++++---------------- + 1 file changed, 7 insertions(+), 16 deletions(-) +Merging erofs-fixes/fixes (347e9f5043c8 Linux 6.16-rc6) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git erofs-fixes/fixes +Already up to date. +Merging nfsd-fixes/nfsd-fixes (94d10a4dba0b sunrpc: handle SVC_GARBAGE during svc auth processing as auth error) +$ git merge -m Merge branch 'nfsd-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux nfsd-fixes/nfsd-fixes +Already up to date. +Merging v9fs-fixes/fixes/next (2014c95afece Linux 6.14-rc1) +$ git merge -m Merge branch 'fixes/next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git v9fs-fixes/fixes/next +Already up to date. +Merging overlayfs-fixes/ovl-fixes (924577e4f6ca ovl: Fix nested backing file paths) +$ git merge -m Merge branch 'ovl-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs.git overlayfs-fixes/ovl-fixes +Already up to date. +Merging bcachefs/for-next (ae4d71be53dd bcachefs: Don't lock inode around page_symlink) +$ git merge -m Merge branch 'for-next' of git://evilpiepirate.org/bcachefs.git bcachefs/for-next +Auto-merging fs/bcachefs/fs-io-buffered.c +Auto-merging fs/bcachefs/fs.c +Merge made by the 'ort' strategy. + fs/bcachefs/acl.c | 29 +- + fs/bcachefs/alloc_background.c | 570 +++++++++---------- + fs/bcachefs/alloc_background.h | 9 +- + fs/bcachefs/alloc_foreground.c | 258 ++++----- + fs/bcachefs/alloc_foreground.h | 9 +- + fs/bcachefs/async_objs.c | 29 +- + fs/bcachefs/async_objs.h | 7 +- + fs/bcachefs/async_objs_types.h | 2 +- + fs/bcachefs/backpointers.c | 167 +++--- + fs/bcachefs/bcachefs.h | 91 ++-- + fs/bcachefs/bcachefs_format.h | 42 +- + fs/bcachefs/bkey.c | 4 +- + fs/bcachefs/bkey_methods.c | 6 +- + fs/bcachefs/bkey_types.h | 5 + + fs/bcachefs/bset.c | 74 ++- + fs/bcachefs/btree_cache.c | 44 +- + fs/bcachefs/btree_cache.h | 19 + + fs/bcachefs/btree_gc.c | 258 ++++----- + fs/bcachefs/btree_io.c | 123 +++-- + fs/bcachefs/btree_iter.c | 424 ++++++++------- + fs/bcachefs/btree_iter.h | 348 ++++++------ + fs/bcachefs/btree_journal_iter.c | 20 +- + fs/bcachefs/btree_key_cache.c | 69 ++- + fs/bcachefs/btree_locking.c | 17 +- + fs/bcachefs/btree_node_scan.c | 36 +- + fs/bcachefs/btree_trans_commit.c | 125 +++-- + fs/bcachefs/btree_types.h | 43 +- + fs/bcachefs/btree_update.c | 339 ++++++------ + fs/bcachefs/btree_update.h | 150 +++-- + fs/bcachefs/btree_update_interior.c | 387 ++++++------- + fs/bcachefs/btree_update_interior.h | 12 +- + fs/bcachefs/btree_write_buffer.c | 78 ++- + fs/bcachefs/btree_write_buffer.h | 8 +- + fs/bcachefs/buckets.c | 258 ++++----- + fs/bcachefs/buckets_waiting_for_journal.c | 30 +- + fs/bcachefs/chardev.c | 120 ++-- + fs/bcachefs/checksum.c | 54 +- + fs/bcachefs/clock.c | 17 +- + fs/bcachefs/compress.c | 29 +- + fs/bcachefs/compress.h | 36 +- + fs/bcachefs/data_update.c | 58 +- + fs/bcachefs/data_update.h | 1 + + fs/bcachefs/debug.c | 88 ++- + fs/bcachefs/dirent.c | 88 ++- + fs/bcachefs/dirent.h | 4 +- + fs/bcachefs/disk_accounting.c | 270 +++++---- + fs/bcachefs/disk_accounting.h | 19 +- + fs/bcachefs/disk_groups.c | 27 +- + fs/bcachefs/ec.c | 396 ++++++-------- + fs/bcachefs/ec.h | 2 +- + fs/bcachefs/enumerated_ref.c | 4 +- + fs/bcachefs/errcode.c | 3 +- + fs/bcachefs/errcode.h | 14 + + fs/bcachefs/error.c | 65 +-- + fs/bcachefs/error.h | 3 +- + fs/bcachefs/extent_update.c | 67 ++- + fs/bcachefs/extent_update.h | 2 - + fs/bcachefs/extents.c | 55 +- + fs/bcachefs/extents.h | 4 + + fs/bcachefs/fast_list.c | 32 +- + fs/bcachefs/fast_list.h | 2 +- + fs/bcachefs/fs-io-buffered.c | 96 ++-- + fs/bcachefs/fs-io-direct.c | 26 +- + fs/bcachefs/fs-io-pagecache.c | 55 +- + fs/bcachefs/fs-io.c | 141 +++-- + fs/bcachefs/fs-io.h | 19 +- + fs/bcachefs/fs-ioctl.c | 33 +- + fs/bcachefs/fs.c | 254 ++++----- + fs/bcachefs/fsck.c | 649 +++++++++++----------- + fs/bcachefs/inode.c | 252 ++++----- + fs/bcachefs/io_misc.c | 83 ++- + fs/bcachefs/io_read.c | 235 ++++---- + fs/bcachefs/io_read.h | 24 +- + fs/bcachefs/io_write.c | 97 ++-- + fs/bcachefs/journal.c | 253 ++++----- + fs/bcachefs/journal.h | 3 +- + fs/bcachefs/journal_io.c | 248 +++++---- + fs/bcachefs/journal_io.h | 7 + + fs/bcachefs/journal_reclaim.c | 220 ++++---- + fs/bcachefs/journal_seq_blacklist.c | 56 +- + fs/bcachefs/journal_seq_blacklist.h | 3 + + fs/bcachefs/logged_ops.c | 16 +- + fs/bcachefs/logged_ops.h | 2 +- + fs/bcachefs/lru.c | 48 +- + fs/bcachefs/lru.h | 10 + + fs/bcachefs/migrate.c | 31 +- + fs/bcachefs/move.c | 316 +++++------ + fs/bcachefs/move.h | 14 +- + fs/bcachefs/movinggc.c | 218 +++++--- + fs/bcachefs/namei.c | 154 +++--- + fs/bcachefs/nocow_locking.c | 10 +- + fs/bcachefs/opts.c | 33 +- + fs/bcachefs/opts.h | 8 +- + fs/bcachefs/printbuf.h | 4 + + fs/bcachefs/progress.c | 6 +- + fs/bcachefs/progress.h | 3 + + fs/bcachefs/quota.c | 103 ++-- + fs/bcachefs/rebalance.c | 216 ++++---- + fs/bcachefs/recovery.c | 412 ++++---------- + fs/bcachefs/recovery_passes.c | 68 +-- + fs/bcachefs/recovery_passes.h | 9 +- + fs/bcachefs/reflink.c | 137 ++--- + fs/bcachefs/replicas.c | 161 +++--- + fs/bcachefs/sb-clean.c | 36 +- + fs/bcachefs/sb-counters_format.h | 12 +- + fs/bcachefs/sb-downgrade.c | 19 +- + fs/bcachefs/sb-errors.c | 45 +- + fs/bcachefs/sb-errors_format.h | 11 +- + fs/bcachefs/sb-members.c | 164 +++--- + fs/bcachefs/sb-members.h | 44 +- + fs/bcachefs/sb-members_format.h | 2 +- + fs/bcachefs/six.c | 21 +- + fs/bcachefs/snapshot.c | 435 ++++++--------- + fs/bcachefs/snapshot.h | 32 +- + fs/bcachefs/snapshot_types.h | 2 +- + fs/bcachefs/str_hash.c | 57 +- + fs/bcachefs/str_hash.h | 47 +- + fs/bcachefs/subvolume.c | 246 ++++----- + fs/bcachefs/subvolume.h | 20 +- + fs/bcachefs/super-io.c | 112 ++-- + fs/bcachefs/super.c | 871 +++++++++++++++++------------- + fs/bcachefs/sysfs.c | 28 +- + fs/bcachefs/tests.c | 340 +++++------- + fs/bcachefs/thread_with_file.c | 48 +- + fs/bcachefs/time_stats.c | 7 +- + fs/bcachefs/trace.h | 157 ++---- + fs/bcachefs/util.c | 28 +- + fs/bcachefs/util.h | 10 +- + fs/bcachefs/xattr.c | 58 +- + lib/closure.c | 12 +- + 130 files changed, 6357 insertions(+), 6790 deletions(-) +Merging fscrypt/for-next (fa65058063cb ceph: Remove gfp_t argument from ceph_fscrypt_encrypt_*()) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/fs/fscrypt/linux.git fscrypt/for-next +Already up to date. +Merging btrfs/for-next (442ee950ea05 Merge branch 'for-next-current-v6.15-20250722' into for-next-20250722) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git btrfs/for-next +Merge made by the 'ort' strategy. +Merging ceph/master (b828b4bf29d1 ceph: fix variable dereferenced before check in ceph_umount_begin()) +$ git merge -m Merge branch 'master' of git://github.com/ceph/ceph-client.git ceph/master +Already up to date. +Merging cifs/for-next (da3d9a37f3cb smb: client: let recv_done() avoid touching data_transfer after cleanup/move) +$ git merge -m Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6.git cifs/for-next +Merge made by the 'ort' strategy. + fs/smb/client/cifs_debug.c | 6 +-- + fs/smb/client/cifsfs.c | 2 +- + fs/smb/client/cifsglob.h | 5 ++ + fs/smb/client/cifssmb.c | 4 +- + fs/smb/client/fs_context.c | 19 +------ + fs/smb/client/fs_context.h | 18 ++++++- + fs/smb/client/link.c | 13 ++--- + fs/smb/client/reparse.c | 2 +- + fs/smb/client/smb1ops.c | 2 +- + fs/smb/client/smb2inode.c | 5 +- + fs/smb/client/smb2ops.c | 5 +- + fs/smb/client/smbdirect.c | 124 +++++++++++++++------------------------------ + fs/smb/client/smbdirect.h | 4 -- + 13 files changed, 78 insertions(+), 131 deletions(-) +Merging configfs/configfs-next (c6b190822459 MAINTAINERS: add configfs Rust abstractions) +$ git merge -m Merge branch 'configfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/a.hindborg/linux.git configfs/configfs-next +Already up to date. +Merging ecryptfs/next (fba133a34118 ecryptfs: Remove unused declartion ecryptfs_fill_zeros()) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git ecryptfs/next +Auto-merging fs/ecryptfs/crypto.c +Auto-merging fs/ecryptfs/ecryptfs_kernel.h +Merge made by the 'ort' strategy. + fs/ecryptfs/crypto.c | 2 +- + fs/ecryptfs/ecryptfs_kernel.h | 1 - + fs/ecryptfs/keystore.c | 4 ++-- + 3 files changed, 3 insertions(+), 4 deletions(-) +Merging dlm/next (6f8b4788266c dlm: drop SCTP Kconfig dependency) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git dlm/next +Already up to date. +Merging erofs/dev (df0ce6cefa45 erofs: support to readahead dirent blocks in erofs_readdir()) +$ git merge -m Merge branch 'dev' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git erofs/dev +Already up to date. +Merging exfat/dev (b33f91c62762 exfat: optimize allocation bitmap loading time) +$ git merge -m Merge branch 'dev' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git exfat/dev +Merge made by the 'ort' strategy. + fs/exfat/balloc.c | 12 +++++++++++- + fs/exfat/dir.c | 13 ++++++++++++- + fs/exfat/exfat_fs.h | 1 + + fs/exfat/fatent.c | 10 ++++++++++ + fs/exfat/file.c | 5 ++--- + fs/exfat/namei.c | 5 +++++ + fs/exfat/super.c | 32 +++++++++++++++++++++----------- + 7 files changed, 62 insertions(+), 16 deletions(-) +Merging exportfs/exportfs-next (adc218676eef Linux 6.12) +$ git merge -m Merge branch 'exportfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux exportfs/exportfs-next +Already up to date. +Merging ext3/for_next (17e58687367a Merge fsnotify changes with fixed up authorship.) +$ git merge -m Merge branch 'for_next' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git ext3/for_next +Merge made by the 'ort' strategy. +Merging ext4/dev (261a2abe20b0 ext4: fix unused variable warning in ext4_init_new_dir) +$ git merge -m Merge branch 'dev' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git ext4/dev +Merge made by the 'ort' strategy. + fs/ext4/namei.c | 2 -- + 1 file changed, 2 deletions(-) +Merging f2fs/dev (078cad8212ce f2fs: drop inode from the donation list when the last file is closed) +$ git merge -m Merge branch 'dev' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git f2fs/dev +Auto-merging Documentation/filesystems/f2fs.rst +Auto-merging fs/f2fs/data.c +Auto-merging fs/f2fs/f2fs.h +Auto-merging fs/f2fs/file.c +Auto-merging include/linux/fscrypt.h +Merge made by the 'ort' strategy. + Documentation/ABI/testing/sysfs-fs-f2fs | 22 + + Documentation/filesystems/f2fs.rst | 6 +- + fs/f2fs/checkpoint.c | 8 +- + fs/f2fs/compress.c | 120 +- + fs/f2fs/data.c | 183 +-- + fs/f2fs/debug.c | 21 +- + fs/f2fs/dir.c | 4 +- + fs/f2fs/extent_cache.c | 10 +- + fs/f2fs/f2fs.h | 151 ++- + fs/f2fs/file.c | 107 +- + fs/f2fs/gc.c | 54 +- + fs/f2fs/gc.h | 5 +- + fs/f2fs/inline.c | 20 +- + fs/f2fs/inode.c | 84 +- + fs/f2fs/namei.c | 12 +- + fs/f2fs/node.c | 261 ++-- + fs/f2fs/node.h | 77 +- + fs/f2fs/recovery.c | 116 +- + fs/f2fs/segment.c | 62 +- + fs/f2fs/segment.h | 59 +- + fs/f2fs/super.c | 2185 +++++++++++++++++-------------- + fs/f2fs/sysfs.c | 48 + + include/linux/f2fs_fs.h | 2 +- + include/linux/fscrypt.h | 10 +- + 24 files changed, 2056 insertions(+), 1571 deletions(-) +Merging fsverity/for-next (d0b3b7b22dfa Linux 6.16-rc4) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/fs/fsverity/linux.git fsverity/for-next +Already up to date. +Merging fuse/for-next (f0e84022479b virtio_fs: Remove redundant spinlock in virtio_fs_request_complete()) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git fuse/for-next +Auto-merging MAINTAINERS +Auto-merging fs/fuse/file.c +Auto-merging fs/fuse/virtio_fs.c +Auto-merging include/linux/wait.h +Auto-merging tools/testing/selftests/Makefile +Merge made by the 'ort' strategy. + .../filesystems/{ => fuse}/fuse-io-uring.rst | 0 + Documentation/filesystems/{ => fuse}/fuse-io.rst | 2 +- + .../filesystems/{ => fuse}/fuse-passthrough.rst | 0 + Documentation/filesystems/{ => fuse}/fuse.rst | 20 ++- + Documentation/filesystems/fuse/index.rst | 14 ++ + Documentation/filesystems/index.rst | 5 +- + MAINTAINERS | 3 +- + fs/fuse/dev.c | 5 +- + fs/fuse/file.c | 1 - + fs/fuse/virtio_fs.c | 3 - + include/linux/wait.h | 12 ++ + tools/testing/selftests/Makefile | 1 + + .../testing/selftests/filesystems/fuse/.gitignore | 3 + + tools/testing/selftests/filesystems/fuse/Makefile | 21 +++ + .../testing/selftests/filesystems/fuse/fuse_mnt.c | 146 +++++++++++++++++++++ + .../selftests/filesystems/fuse/fusectl_test.c | 140 ++++++++++++++++++++ + 16 files changed, 361 insertions(+), 15 deletions(-) + rename Documentation/filesystems/{ => fuse}/fuse-io-uring.rst (100%) + rename Documentation/filesystems/{ => fuse}/fuse-io.rst (99%) + rename Documentation/filesystems/{ => fuse}/fuse-passthrough.rst (100%) + rename Documentation/filesystems/{ => fuse}/fuse.rst (95%) + create mode 100644 Documentation/filesystems/fuse/index.rst + create mode 100644 tools/testing/selftests/filesystems/fuse/.gitignore + create mode 100644 tools/testing/selftests/filesystems/fuse/Makefile + create mode 100644 tools/testing/selftests/filesystems/fuse/fuse_mnt.c + create mode 100644 tools/testing/selftests/filesystems/fuse/fusectl_test.c +Merging gfs2/for-next (a90f1b6ad664 Merge tag 'gfs2-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git gfs2/for-next +Already up to date. +Merging jfs/jfs-next (856db3759202 jfs: fix metapage reference count leak in dbAllocCtl) +$ git merge -m Merge branch 'jfs-next' of git://github.com/kleikamp/linux-shaggy.git jfs/jfs-next +Already up to date. +Merging ksmbd/ksmbd-for-next (e5cf61fa6e2f Merge tag 'v6.17-rc-smb3-server-fixes' of git://git.samba.org/ksmbd) +$ git merge -m Merge branch 'ksmbd-for-next' of https://github.com/smfrench/smb3-kernel.git ksmbd/ksmbd-for-next +Already up to date. +Merging nfs/linux-next (99765233ab42 NFS: Fixup allocation flags for nfsiod's __GFP_NORETRY) +$ git merge -m Merge branch 'linux-next' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git nfs/linux-next +Auto-merging fs/nfs/internal.h +Auto-merging fs/nfs/nfs4file.c +Auto-merging fs/nfs/write.c +Auto-merging include/linux/sunrpc/xdr.h +Auto-merging net/sunrpc/xdr.c +Merge made by the 'ort' strategy. + fs/nfs/blocklayout/blocklayout.c | 4 +- + fs/nfs/blocklayout/dev.c | 5 +- + fs/nfs/blocklayout/extent_tree.c | 104 +++++++++++++++--- + fs/nfs/client.c | 3 +- + fs/nfs/delegation.c | 114 ++++++++++++-------- + fs/nfs/delegation.h | 3 + + fs/nfs/dir.c | 4 +- + fs/nfs/export.c | 11 +- + fs/nfs/flexfilelayout/flexfilelayout.c | 26 +++-- + fs/nfs/flexfilelayout/flexfilelayoutdev.c | 6 +- + fs/nfs/fs_context.c | 42 ++++++++ + fs/nfs/inode.c | 69 +++++++++++- + fs/nfs/internal.h | 10 +- + fs/nfs/mount_clnt.c | 68 ------------ + fs/nfs/nfs4client.c | 165 ++++++++++++++--------------- + fs/nfs/nfs4file.c | 25 +---- + fs/nfs/nfs4proc.c | 50 +++++++-- + fs/nfs/nfs4trace.c | 2 + + fs/nfs/nfs4trace.h | 168 +++++++++++++++++++++++++++++- + fs/nfs/nfs4xdr.c | 24 +++++ + fs/nfs/nfstrace.h | 11 +- + fs/nfs/pnfs.c | 39 ++++--- + fs/nfs/pnfs_nfs.c | 14 ++- + fs/nfs/write.c | 8 +- + include/linux/nfs_fs.h | 8 ++ + include/linux/nfs_fs_sb.h | 8 +- + include/linux/nfs_xdr.h | 57 +++++----- + include/linux/sunrpc/xdr.h | 9 -- + net/sunrpc/auth_gss/gss_krb5_crypto.c | 4 +- + net/sunrpc/xdr.c | 110 ------------------- + 30 files changed, 715 insertions(+), 456 deletions(-) +Merging nfs-anna/linux-next (38074de35b01 NFSv4/flexfiles: Fix handling of NFS level errors in I/O) +$ git merge -m Merge branch 'linux-next' of git://git.linux-nfs.org/projects/anna/linux-nfs.git nfs-anna/linux-next +Already up to date. +Merging nfsd/nfsd-next (e339967eecf1 nfsd: Drop dprintk in blocklayout xdr functions) +$ git merge -m Merge branch 'nfsd-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux nfsd/nfsd-next +Already up to date. +Merging ntfs3/master (a49f0abd8959 Revert "fs/ntfs3: Replace inode_trylock with inode_lock") +$ git merge -m Merge branch 'master' of https://github.com/Paragon-Software-Group/linux-ntfs3.git ntfs3/master +Already up to date. +Merging orangefs/for-next (2138e89cb066 fs/orangefs: Allow 2 more characters in do_c_string()) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux orangefs/for-next +Already up to date. +Merging overlayfs/overlayfs-next (6f9ccdad0fea ovl: Annotate struct ovl_entry with __counted_by()) +$ git merge -m Merge branch 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs.git overlayfs/overlayfs-next +Already up to date. +Merging ubifs/next (99dbb2a1bd66 ubifs: stop using write_cache_pages) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git ubifs/next +Already up to date. +Merging v9fs/9p-next (4210030d8bc4 docs: fs/9p: Add missing "not" in cache documentation) +$ git merge -m Merge branch '9p-next' of git://github.com/martinetd/linux v9fs/9p-next +Already up to date. +Merging v9fs-ericvh/ericvh/for-next (2014c95afece Linux 6.14-rc1) +$ git merge -m Merge branch 'ericvh/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git v9fs-ericvh/ericvh/for-next +Already up to date. +Merging xfs/for-next (ded74fddcaf6 xfs: don't use a xfs_log_iovec for ri_buf in log recovery) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git xfs/for-next +Already up to date. +Merging zonefs/for-next (6982100bb829 zonefs: use ZONEFS_SUPER_SIZE instead of PAGE_SIZE) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/zonefs.git zonefs/for-next +Already up to date. +Merging vfs-brauner/vfs.all (66639db85811 Merge branch 'vfs-6.17.iomap' into vfs.all) +$ git merge -m Merge branch 'vfs.all' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs-brauner/vfs.all +Auto-merging Documentation/filesystems/porting.rst +CONFLICT (content): Merge conflict in Documentation/filesystems/porting.rst +Auto-merging fs/coredump.c +CONFLICT (content): Merge conflict in fs/coredump.c +Auto-merging fs/fuse/file.c +Auto-merging net/unix/af_unix.c +Auto-merging tools/testing/selftests/coredump/stackdump_test.c +CONFLICT (content): Merge conflict in tools/testing/selftests/coredump/stackdump_test.c +Resolved 'Documentation/filesystems/porting.rst' using previous resolution. +Resolved 'fs/coredump.c' using previous resolution. +Resolved 'tools/testing/selftests/coredump/stackdump_test.c' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[fs-next 3eae920dc7dd] Merge branch 'vfs.all' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git +$ git diff -M --stat --summary HEAD^.. + +Merging vfs/for-next (dd589648208a Merge branch 'work.mount' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git vfs/for-next +Auto-merging Documentation/filesystems/porting.rst +CONFLICT (content): Merge conflict in Documentation/filesystems/porting.rst +Resolved 'Documentation/filesystems/porting.rst' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[fs-next 0264e7f5188b] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git +$ git diff -M --stat --summary HEAD^.. + +Merging mm-hotfixes/mm-hotfixes-unstable (415d5ad37461 mm/kmemleak: avoid soft lockup in __kmemleak_do_cleanup()) +$ git merge -m Merge branch 'mm-hotfixes-unstable' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm mm-hotfixes/mm-hotfixes-unstable +Auto-merging MAINTAINERS +Auto-merging mm/debug_vm_pgtable.c +Auto-merging mm/kasan/kasan_test_c.c +Auto-merging mm/memory_hotplug.c +Auto-merging mm/userfaultfd.c +Merge made by the 'ort' strategy. + MAINTAINERS | 1 + + mm/debug_vm_pgtable.c | 9 +++++++-- + mm/kasan/kasan_test_c.c | 4 +++- + mm/kmemleak.c | 10 +++++++++- + mm/memory_hotplug.c | 21 +++++++++++++-------- + mm/userfaultfd.c | 9 +++++++-- + 6 files changed, 40 insertions(+), 14 deletions(-) +Merging fs-current (7d46dcab452b Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git) +$ git merge -m Merge branch 'fs-current' of linux-next fs-current +Merge made by the 'ort' strategy. + drivers/accel/habanalabs/common/memory.c | 23 +++++++---------------- + 1 file changed, 7 insertions(+), 16 deletions(-) +Merging kbuild-current/fixes (e04c78d86a96 Linux 6.16-rc2) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kbuild-current/fixes +Already up to date. +Merging arc-current/for-curr (d7b8f8e20813 Linux 6.16-rc5) +$ git merge -m Merge branch 'for-curr' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git arc-current/for-curr +Already up to date. +Merging arm-current/fixes (0c66c6f4e21c ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux.git arm-current/fixes +Already up to date. +Merging arm64-fixes/for-next/fixes (d42e6c20de61 arm64/entry: Mask DAIF in cpu_switch_to(), call_on_irq_stack()) +$ git merge -m Merge branch 'for-next/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux arm64-fixes/for-next/fixes +Already up to date. +Merging arm-soc-fixes/arm/fixes (9f9d41d64322 Merge tag 'arm-soc/for-6.17/drivers-part2' of https://github.com/Broadcom/stblinux into arm/fixes) +$ git merge -m Merge branch 'arm/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm-soc-fixes/arm/fixes +Merge made by the 'ort' strategy. + arch/arm/boot/dts/broadcom/bcm7445.dtsi | 9 +- + arch/arm/mach-s3c/gpio-samsung.c | 2 +- + drivers/clk/clk-rp1.c | 976 ++++++++++++++++++++- + include/dt-bindings/clock/raspberrypi,rp1-clocks.h | 4 + + 4 files changed, 979 insertions(+), 12 deletions(-) +Merging davinci-current/davinci/for-current (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'davinci/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git davinci-current/davinci/for-current +Already up to date. +Merging drivers-memory-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git drivers-memory-fixes/fixes +Already up to date. +Merging sophgo-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of https://github.com/sophgo/linux.git sophgo-fixes/fixes +Already up to date. +Merging sophgo-soc-fixes/soc-fixes (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'soc-fixes' of https://github.com/sophgo/linux.git sophgo-soc-fixes/soc-fixes +Already up to date. +Merging m68k-current/for-linus (c8995932db2b m68k: mac: Improve clocksource driver commentary) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git m68k-current/for-linus +Already up to date. +Merging powerpc-fixes/fixes (ab107276607a powerpc: Fix struct termio related ioctl macros) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git powerpc-fixes/fixes +Already up to date. +Merging s390-fixes/fixes (62355f1f87b8 s390/pci: Allow automatic recovery with minimal driver support) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git s390-fixes/fixes +Already up to date. +Merging net/main (1dbf1d590d10 net: Add locking to protect skb->dev access in ip_output) +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git net/main +Merge made by the 'ort' strategy. + Documentation/netlink/specs/ethtool.yaml | 6 ++--- + drivers/dpll/zl3073x/Kconfig | 10 ++++----- + drivers/net/ethernet/airoha/airoha_ppe.c | 26 +++++++++++++++++----- + drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 4 +++- + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 14 ++++++++++-- + drivers/net/ethernet/freescale/gianfar_ethtool.c | 4 +++- + drivers/net/ethernet/mediatek/mtk_wed.c | 1 - + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 1 + + drivers/net/ethernet/sfc/tc_encap_actions.c | 2 +- + drivers/net/ethernet/ti/icssg/icss_iep.c | 23 ++++++++++++++----- + drivers/net/ipa/ipa_sysfs.c | 6 ++++- + drivers/net/mdio/mdio-bcm-unimac.c | 5 ++--- + drivers/net/phy/mdio_bus.c | 4 ++-- + drivers/net/phy/mscc/mscc_ptp.c | 1 + + drivers/net/phy/mscc/mscc_ptp.h | 1 + + drivers/net/phy/smsc.c | 1 + + drivers/net/ppp/pptp.c | 15 ++++++++----- + include/linux/skbuff.h | 23 +++++++++++++++++++ + include/net/dst.h | 12 ++++++++++ + include/net/udp.h | 24 +++++++++++++++----- + net/core/netpoll.c | 7 ++++++ + net/ipv4/ip_output.c | 15 ++++++++----- + net/ipv6/ip6_offload.c | 4 +++- + net/kcm/kcmsock.c | 6 +++++ + net/netlink/af_netlink.c | 2 +- + net/sched/sch_taprio.c | 21 ++++++++++++++--- + tools/testing/selftests/net/test_neigh.sh | 6 ++--- + tools/testing/selftests/net/vlan_hw_filter.sh | 16 ++++++------- + 28 files changed, 196 insertions(+), 64 deletions(-) +Merging bpf/master (1b30d4441727 bpf: Fix memory leak of bpf_scc_info objects) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git bpf/master +Merge made by the 'ort' strategy. + kernel/bpf/verifier.c | 3 +++ + 1 file changed, 3 insertions(+) +Merging ipsec/master (28712d6ed320 Merge branch 'ipsec: fix splat due to ipcomp fallback tunnel') +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git ipsec/master +Already up to date. +Merging netfilter/main (eccf7a3480a0 Merge tag 'linux-can-fixes-for-6.16-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can) +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git netfilter/main +Already up to date. +Merging ipvs/main (eccf7a3480a0 Merge tag 'linux-can-fixes-for-6.16-20250725' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can) +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git ipvs/main +Already up to date. +Merging wireless/for-next (6832a9317eee Merge tag 'net-6.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git wireless/for-next +Already up to date. +Merging ath/for-current (d9104cec3e8f Merge tag 'bpf-next-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next) +$ git merge -m Merge branch 'for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git ath/for-current +Already up to date. +Merging iwlwifi/fixes (6832a9317eee Merge tag 'net-6.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net) +$ git merge -m Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git iwlwifi/fixes +Already up to date. +Merging wpan/master (8ce4f287524c net: libwx: fix firmware mailbox abnormal return) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan.git wpan/master +Already up to date. +Merging rdma-fixes/for-rc (a9a9e68954f2 RDMA/mlx5: Fix vport loopback for MPV device) +$ git merge -m Merge branch 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git rdma-fixes/for-rc +Already up to date. +Merging sound-current/for-linus (dbe05428c4e5 ALSA: hda/realtek: add LG gram 16Z90R-A to alc269 fixup table) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git sound-current/for-linus +Merge made by the 'ort' strategy. + sound/hda/codecs/realtek/alc269.c | 1 + + sound/usb/pcm.c | 9 ++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) +Merging sound-asoc-fixes/for-linus (282528da82a0 Merge remote-tracking branch 'asoc/for-6.16' into asoc-linus) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git sound-asoc-fixes/for-linus +Merge made by the 'ort' strategy. + drivers/spi/spi-cs42l43.c | 2 +- + sound/soc/codecs/wm8962.c | 11 +++++++++++ + sound/soc/intel/avs/core.c | 3 ++- + sound/soc/sof/amd/acp-loader.c | 6 +++--- + 4 files changed, 17 insertions(+), 5 deletions(-) +Merging regmap-fixes/for-linus (067aa458a064 Merge remote-tracking branch 'regmap/for-6.16' into regmap-linus) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git regmap-fixes/for-linus +Merge made by the 'ort' strategy. + drivers/base/regmap/regmap-irq.c | 30 +++++++++++++++++++++--------- + 1 file changed, 21 insertions(+), 9 deletions(-) +Merging regulator-fixes/for-linus (10dfd36f0784 regulator: core: correct convergence check in regulator_set_voltage()) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git regulator-fixes/for-linus +Merge made by the 'ort' strategy. + drivers/regulator/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +Merging spi-fixes/for-linus (a49bfbecfde7 Merge remote-tracking branch 'spi/for-6.16' into spi-linus) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git spi-fixes/for-linus +Auto-merging MAINTAINERS +Merge made by the 'ort' strategy. + MAINTAINERS | 8 ++++++++ + 1 file changed, 8 insertions(+) +Merging pci-current/for-linus (0bd0a41a5120 Merge tag 'pci-v6.17-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git pci-current/for-linus +Already up to date. +Merging driver-core.current/driver-core-linus (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'driver-core-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git driver-core.current/driver-core-linus +Already up to date. +Merging tty.current/tty-linus (55a984928bfa Revert "tty: vt: use _IO() to define ioctl numbers") +$ git merge -m Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty.current/tty-linus +Merge made by the 'ort' strategy. + include/uapi/linux/vt.h | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) +Merging usb.current/usb-linus (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb.current/usb-linus +Already up to date. +Merging usb-serial-fixes/usb-linus (ad1244e1ce18 USB: serial: option: add Foxconn T99W709) +$ git merge -m Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git usb-serial-fixes/usb-linus +Already up to date. +Merging phy/fixes (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git phy/fixes +Already up to date. +Merging staging.current/staging-linus (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'staging-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git staging.current/staging-linus +Already up to date. +Merging iio-fixes/fixes-togreg (187d5553e33e iio: adc: ad7124: fix channel lookup in syscalib functions) +$ git merge -m Merge branch 'fixes-togreg' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git iio-fixes/fixes-togreg +Merge made by the 'ort' strategy. + drivers/iio/accel/sca3300.c | 2 +- + drivers/iio/adc/ad7124.c | 14 ++--- + drivers/iio/adc/ad7173.c | 87 ++++++++++++++++++++++++---- + drivers/iio/proximity/isl29501.c | 14 +++-- + drivers/iio/temperature/maxim_thermocouple.c | 26 +++++---- + 5 files changed, 109 insertions(+), 34 deletions(-) +Merging counter-current/counter-current (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'counter-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter.git counter-current/counter-current +Already up to date. +Merging char-misc.current/char-misc-linus (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'char-misc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc.current/char-misc-linus +Already up to date. +Merging soundwire-fixes/fixes (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git soundwire-fixes/fixes +Already up to date. +Merging thunderbolt-fixes/fixes (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git thunderbolt-fixes/fixes +Already up to date. +Merging input-current/for-linus (bcce05041b21 Input: xpad - set correct controller type for Acer NGR200) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git input-current/for-linus +Already up to date. +Merging crypto-current/master (9d9b193ed73a crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390)) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git crypto-current/master +Auto-merging include/crypto/hash.h +Merge made by the 'ort' strategy. + include/crypto/hash.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +Merging libcrypto-fixes/libcrypto-fixes (68279380266a crypto: s390/sha - Fix uninitialized variable in SHA-1 and SHA-2) +$ git merge -m Merge branch 'libcrypto-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git libcrypto-fixes/libcrypto-fixes +Already up to date. +Merging vfio-fixes/for-linus (c1d9dac0db16 vfio/pci: Align huge faults to order) +$ git merge -m Merge branch 'for-linus' of git://github.com/awilliam/linux-vfio.git vfio-fixes/for-linus +Already up to date. +Merging kselftest-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git kselftest-fixes/fixes +Already up to date. +Merging dmaengine-fixes/fixes (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git dmaengine-fixes/fixes +Already up to date. +Merging backlight-fixes/for-backlight-fixes (1613e604df0c Linux 6.10-rc1) +$ git merge -m Merge branch 'for-backlight-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git backlight-fixes/for-backlight-fixes +Already up to date. +Merging mtd-fixes/mtd/fixes (6463cbe08b0c mtd: spinand: fix memory leak of ECC engine conf) +$ git merge -m Merge branch 'mtd/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd-fixes/mtd/fixes +Already up to date. +Merging mfd-fixes/for-mfd-fixes (d9d79e4f7dc9 mfd: Fix building without CONFIG_OF) +$ git merge -m Merge branch 'for-mfd-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git mfd-fixes/for-mfd-fixes +Already up to date. +Merging v4l-dvb-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://linuxtv.org/media-ci/media-pending.git v4l-dvb-fixes/fixes +Already up to date. +Merging reset-fixes/reset/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'reset/fixes' of https://git.pengutronix.de/git/pza/linux reset-fixes/reset/fixes +Already up to date. +Merging mips-fixes/mips-fixes (86731a2a651e Linux 6.16-rc3) +$ git merge -m Merge branch 'mips-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git mips-fixes/mips-fixes +Already up to date. +Merging at91-fixes/at91-fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'at91-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git at91-fixes/at91-fixes +Already up to date. +Merging omap-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap.git omap-fixes/fixes +Already up to date. +Merging kvm-fixes/master (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/virt/kvm/kvm.git kvm-fixes/master +Already up to date. +Merging kvms390-fixes/master (d8dfda5af0be KVM: s390: pv: fix race when making a page secure) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git kvms390-fixes/master +Already up to date. +Merging hwmon-fixes/hwmon (9c62e2282900 hwmon: (gsc-hwmon) fix fan pwm setpoint show functions) +$ git merge -m Merge branch 'hwmon' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-fixes/hwmon +Already up to date. +Merging nvdimm-fixes/libnvdimm-fixes (d0b3b7b22dfa Linux 6.16-rc4) +$ git merge -m Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git nvdimm-fixes/libnvdimm-fixes +Already up to date. +Merging cxl-fixes/fixes (d0b3b7b22dfa Linux 6.16-rc4) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl.git cxl-fixes/fixes +Already up to date. +Merging dma-mapping-fixes/dma-mapping-fixes (aa807b9f22df dma-contiguous: hornor the cma address limit setup by user) +$ git merge -m Merge branch 'dma-mapping-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux.git dma-mapping-fixes/dma-mapping-fixes +Already up to date. +Merging drivers-x86-fixes/fixes (e2967b50b709 MAINTAINERS: Update entries for IFS and SBL drivers) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git drivers-x86-fixes/fixes +Already up to date. +Merging samsung-krzk-fixes/fixes (8d2c2fa2209e firmware: exynos-acpm: fix timeouts on xfers handling) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git samsung-krzk-fixes/fixes +Already up to date. +Merging pinctrl-samsung-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git pinctrl-samsung-fixes/fixes +Already up to date. +Merging devicetree-fixes/dt/linus (79aef1a3705b of: Clarify OF device context in of_match_device() comment) +$ git merge -m Merge branch 'dt/linus' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git devicetree-fixes/dt/linus +Merge made by the 'ort' strategy. + drivers/of/device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) +Merging dt-krzk-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-dt.git dt-krzk-fixes/fixes +Already up to date. +Merging scsi-fixes/fixes (021f243627ea scsi: ufs: core: Fix spelling of a sysfs attribute name) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git scsi-fixes/fixes +Already up to date. +Merging drm-fixes/drm-fixes (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'drm-fixes' of https://gitlab.freedesktop.org/drm/kernel.git drm-fixes/drm-fixes +Already up to date. +Merging drm-intel-fixes/for-linux-next-fixes (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'for-linux-next-fixes' of https://gitlab.freedesktop.org/drm/i915/kernel drm-intel-fixes/for-linux-next-fixes +Already up to date. +Merging mmc-fixes/fixes (4b290aae788e Merge tag 'sysctl-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git mmc-fixes/fixes +Already up to date. +Merging rtc-fixes/rtc-fixes (08d82d0cad51 rtc: pcf2127: add missing semicolon after statement) +$ git merge -m Merge branch 'rtc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-fixes/rtc-fixes +Already up to date. +Merging gnss-fixes/gnss-linus (86731a2a651e Linux 6.16-rc3) +$ git merge -m Merge branch 'gnss-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git gnss-fixes/gnss-linus +Already up to date. +Merging hyperv-fixes/hyperv-fixes (a4131a50d072 tools/hv: fcopy: Fix irregularities with size of ring buffer) +$ git merge -m Merge branch 'hyperv-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git hyperv-fixes/hyperv-fixes +Already up to date. +Merging risc-v-fixes/fixes (b65ca21835ed riscv: uaccess: Fix -Wuninitialized and -Wshadow in __put_user_nocheck) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git risc-v-fixes/fixes +Already up to date. +Merging riscv-dt-fixes/riscv-dt-fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'riscv-dt-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git riscv-dt-fixes/riscv-dt-fixes +Already up to date. +Merging riscv-soc-fixes/riscv-soc-fixes (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'riscv-soc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git riscv-soc-fixes/riscv-soc-fixes +Already up to date. +Merging fpga-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git fpga-fixes/fixes +Already up to date. +Merging spdx/spdx-linus (beb6c8326eb4 Merge tag 'uml-for-linux-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux) +$ git merge -m Merge branch 'spdx-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/spdx.git spdx/spdx-linus +Already up to date. +Merging gpio-brgl-fixes/gpio/for-current (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'gpio/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git gpio-brgl-fixes/gpio/for-current +Already up to date. +Merging gpio-intel-fixes/fixes (9ab29ed50555 gpiolib: acpi: Add a quirk for Acer Nitro V15) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git gpio-intel-fixes/fixes +Already up to date. +Merging pinctrl-intel-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git pinctrl-intel-fixes/fixes +Already up to date. +Merging auxdisplay-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-auxdisplay.git auxdisplay-fixes/fixes +Already up to date. +Merging kunit-fixes/kunit-fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'kunit-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git kunit-fixes/kunit-fixes +Already up to date. +Merging memblock-fixes/fixes (da8bf5daa5e5 memblock: Accept allocated memory before use in memblock_double_array()) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git memblock-fixes/fixes +Already up to date. +Merging renesas-fixes/fixes (379c590113ce ARM: shmobile: smp: Enforce shmobile_smp_* alignment) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git renesas-fixes/fixes +Already up to date. +Merging perf-current/perf-tools (6235ce77749f perf record: Cache build-ID of hit DSOs only) +$ git merge -m Merge branch 'perf-tools' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools perf-current/perf-tools +Already up to date. +Merging efi-fixes/urgent (64e135f1eaba efivarfs: Fix memory leak of efivarfs_fs_info in fs_context error paths) +$ git merge -m Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git efi-fixes/urgent +Already up to date. +Merging battery-fixes/fixes (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git battery-fixes/fixes +Already up to date. +Merging iommufd-fixes/for-rc (9a96876e3c65 iommufd/selftest: Fix build warnings due to uninitialized mfd) +$ git merge -m Merge branch 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git iommufd-fixes/for-rc +Already up to date. +Merging rust-fixes/rust-fixes (d2eedaa3909b Merge tag 'rtc-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux) +$ git merge -m Merge branch 'rust-fixes' of https://github.com/Rust-for-Linux/linux.git rust-fixes/rust-fixes +Already up to date. +Merging w1-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-w1.git w1-fixes/fixes +Already up to date. +Merging pmdomain-fixes/fixes (621a88dbfe90 cpuidle: psci: Fix cpuhotplug routine with PREEMPT_RT=y) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git pmdomain-fixes/fixes +Already up to date. +Merging i2c-host-fixes/i2c/i2c-host-fixes (0ae982df6776 Merge tag 'i2c-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux) +$ git merge -m Merge branch 'i2c/i2c-host-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c-host-fixes/i2c/i2c-host-fixes +Already up to date. +Merging sparc-fixes/for-linus (6613476e225e Linux 6.8-rc1) +$ git merge -m Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc.git sparc-fixes/for-linus +Already up to date. +Merging clk-fixes/clk-fixes (e4b2a0c2b9be Merge tag 'sunxi-clk-fixes-for-6.16' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-fixes) +$ git merge -m Merge branch 'clk-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-fixes/clk-fixes +Already up to date. +Merging thead-clk-fixes/thead-clk-fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'thead-clk-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git thead-clk-fixes/thead-clk-fixes +Already up to date. +Merging pwrseq-fixes/pwrseq/for-current (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'pwrseq/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git pwrseq-fixes/pwrseq/for-current +Already up to date. +Merging thead-dt-fixes/thead-dt-fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'thead-dt-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git thead-dt-fixes/thead-dt-fixes +Already up to date. +Merging ftrace-fixes/ftrace/fixes (327e28664307 fgraph: Do not enable function_graph tracer when setting funcgraph-args) +$ git merge -m Merge branch 'ftrace/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git ftrace-fixes/ftrace/fixes +Already up to date. +Merging ring-buffer-fixes/ring-buffer/fixes (e4d4b8670c44 ring-buffer: Use flush_kernel_vmap_range() over flush_dcache_folio()) +$ git merge -m Merge branch 'ring-buffer/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git ring-buffer-fixes/ring-buffer/fixes +Already up to date. +Merging trace-fixes/trace/fixes (b5e8acc14dcb tracing: Add down_write(trace_event_sem) when adding trace event) +$ git merge -m Merge branch 'trace/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git trace-fixes/trace/fixes +Already up to date. +Merging tracefs-fixes/tracefs/fixes (8b55572e5180 tracing/selftests: Add tracefs mount options test) +$ git merge -m Merge branch 'tracefs/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git tracefs-fixes/tracefs/fixes +Already up to date. +Merging spacemit-fixes/fixes (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'fixes' of https://github.com/spacemit-com/linux spacemit-fixes/fixes +Already up to date. +Merging tip-fixes/tip/urgent (f88a000d5409 Merge branch into tip/master: 'x86/urgent') +$ git merge -m Merge branch 'tip/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git tip-fixes/tip/urgent +Auto-merging kernel/fork.c +Merge made by the 'ort' strategy. + arch/x86/include/asm/hw_irq.h | 6 +-- + arch/x86/include/asm/intel-family.h | 5 +++ + arch/x86/kernel/irq.c | 63 +++++++++++++++++++++++------- + drivers/irqchip/irq-riscv-imsic-platform.c | 2 +- + kernel/fork.c | 2 +- + kernel/smp.c | 2 +- + 6 files changed, 59 insertions(+), 21 deletions(-) +Merging slab-fixes/slab/for-next-fixes (be8250786ca9 mm, slab: clean up slab->obj_exts always) +$ git merge -m Merge branch 'slab/for-next-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git slab-fixes/slab/for-next-fixes +Already up to date. +Merging drm-msm-fixes/msm-fixes (8290d37ad2b0 drm/msm: Small function param doc fix) +$ git merge -m Merge branch 'msm-fixes' of https://gitlab.freedesktop.org/drm/msm.git drm-msm-fixes/msm-fixes +Already up to date. +Merging uml-fixes/fixes (2dca89df0d11 Merge tag 'uml-for-6.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git uml-fixes/fixes +Already up to date. +Merging fwctl-fixes/for-rc (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-rc' of git//git.kernel.org/pub/scm/linux/kernel/git/fwctl/fwctl.git fwctl-fixes/for-rc +Already up to date. +Merging devsec-tsm-fixes/fixes (fba4ceaa242d configfs-tsm-report: Fix NULL dereference of tsm_ops) +$ git merge -m Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/devsec/tsm.git devsec-tsm-fixes/fixes +Already up to date. +Merging drm-misc-fixes/for-linux-next-fixes (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'for-linux-next-fixes' of https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc-fixes/for-linux-next-fixes +Already up to date. +Merging linus/for-next (ffd294d346d1 Linux 6.13) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linus/for-next +Already up to date. +Merging mm-stable/mm-stable (a2152fef2902 mm: mempool: fix crash in mempool_free() for zero-minimum pools) +$ git merge -m Merge branch 'mm-stable' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm mm-stable/mm-stable +Auto-merging Documentation/core-api/mm-api.rst +Auto-merging arch/x86/kernel/alternative.c +Auto-merging include/linux/mm.h +Auto-merging kernel/fork.c +Auto-merging kernel/module/main.c +Auto-merging mm/internal.h +Auto-merging mm/memory-failure.c +Auto-merging mm/nommu.c +Auto-merging mm/shmem.c +Auto-merging mm/vma.c +Auto-merging tools/testing/vma/vma_internal.h +Merge made by the 'ort' strategy. + Documentation/core-api/mm-api.rst | 1 - + arch/arm64/mm/mmu.c | 4 +- + arch/x86/kernel/alternative.c | 3 +- + arch/x86/kernel/ftrace.c | 2 +- + arch/x86/kernel/kprobes/core.c | 18 -- + arch/x86/mm/init.c | 24 +- + include/linux/execmem.h | 54 ++-- + include/linux/io-mapping.h | 3 - + include/linux/mm.h | 6 +- + include/linux/mmap_lock.h | 30 ++ + include/linux/page-flags.h | 2 - + include/linux/pgtable.h | 45 +++ + include/linux/rmap.h | 22 ++ + kernel/fork.c | 9 +- + kernel/module/main.c | 13 +- + mm/Kconfig | 4 - + mm/Makefile | 1 - + mm/damon/vaddr.c | 4 + + mm/execmem.c | 212 +++++++++---- + mm/internal.h | 2 +- + mm/io-mapping.c | 30 -- + mm/kasan/common.c | 25 +- + mm/khugepaged.c | 58 ++-- + mm/madvise.c | 71 ++++- + mm/memory-failure.c | 12 +- + mm/mempool.c | 24 +- + mm/mincore.c | 3 + + mm/mmap_lock.c | 10 +- + mm/mprotect.c | 2 +- + mm/mremap.c | 4 +- + mm/mseal.c | 170 +++------- + mm/nommu.c | 2 +- + mm/rmap.c | 2 +- + mm/shmem.c | 281 +++++++++-------- + mm/vma.c | 4 +- + mm/vma.h | 27 +- + tools/testing/selftests/cachestat/test_cachestat.c | 62 +++- + tools/testing/selftests/mm/.gitignore | 1 + + tools/testing/selftests/mm/Makefile | 1 + + tools/testing/selftests/mm/process_madv.c | 344 +++++++++++++++++++++ + tools/testing/selftests/mm/run_vmtests.sh | 5 + + tools/testing/vma/vma_internal.h | 6 +- + 42 files changed, 1086 insertions(+), 517 deletions(-) + delete mode 100644 mm/io-mapping.c + create mode 100644 tools/testing/selftests/mm/process_madv.c +Merging mm-nonmm-stable/mm-nonmm-stable (085dece6cc88 tools/getdelays: add backward compatibility for taskstats version) +$ git merge -m Merge branch 'mm-nonmm-stable' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm mm-nonmm-stable/mm-nonmm-stable +Already up to date. +Merging mm-unstable/mm-unstable (66b994de3cf1 mm-filemap-align-last_index-to-folio-size-fix) +$ git merge -m Merge branch 'mm-unstable' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm mm-unstable/mm-unstable +Auto-merging include/linux/pagemap.h +Auto-merging mm/filemap.c +Merge made by the 'ort' strategy. + include/linux/pagemap.h | 6 ++++++ + mm/filemap.c | 5 +++-- + 2 files changed, 9 insertions(+), 2 deletions(-) +Merging mm-nonmm-unstable/mm-nonmm-unstable (021cf32328d6 selftests/mm: use __auto_type in swap() macro) +$ git merge -m Merge branch 'mm-nonmm-unstable' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm mm-nonmm-unstable/mm-nonmm-unstable +Auto-merging fs/ocfs2/super.c +Merge made by the 'ort' strategy. + Documentation/dev-tools/kcov.rst | 7 ++- + fs/ocfs2/ocfs2.h | 2 - + fs/ocfs2/super.c | 2 - + fs/ocfs2/sysfile.c | 9 ++-- + kernel/hung_task.c | 78 +++++++++++++++++--------------- + kernel/kcov.c | 9 ++++ + tools/testing/selftests/mm/uffd-stress.c | 2 +- + 7 files changed, 60 insertions(+), 49 deletions(-) +Merging kbuild/for-next (dae742fa564b kheaders: make it possible to override TAR) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kbuild/for-next +Auto-merging Makefile +Auto-merging arch/s390/kernel/vmlinux.lds.S +Auto-merging drivers/pinctrl/meson/pinctrl-amlogic-a4.c +Auto-merging include/asm-generic/vmlinux.lds.h +Auto-merging include/linux/module.h +Auto-merging include/linux/moduleparam.h +CONFLICT (content): Merge conflict in include/linux/moduleparam.h +Auto-merging include/net/tcp.h +Auto-merging kernel/Makefile +Auto-merging rust/kernel/device_id.rs +Resolved 'include/linux/moduleparam.h' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[master 0299ce683b8c] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git +$ git diff -M --stat --summary HEAD^.. + Documentation/kbuild/kconfig.rst | 8 +- + Makefile | 5 +- + arch/s390/kernel/vmlinux.lds.S | 10 +- + drivers/pinctrl/meson/pinctrl-amlogic-a4.c | 2 +- + drivers/scsi/BusLogic.c | 2 - + include/asm-generic/vmlinux.lds.h | 2 +- + include/crypto/algapi.h | 4 +- + include/linux/module.h | 21 +- + include/linux/moduleparam.h | 9 +- + include/net/tcp.h | 4 +- + kernel/.gitignore | 2 + + kernel/Makefile | 47 +- + kernel/gen_kheaders.sh | 93 +- + rust/kernel/device_id.rs | 8 +- + scripts/Makefile.vmlinux | 77 +- + scripts/Makefile.vmlinux_o | 26 +- + scripts/extract-vmlinux | 13 +- + scripts/gendwarfksyms/cache.c | 2 +- + scripts/gendwarfksyms/die.c | 4 +- + scripts/gendwarfksyms/dwarf.c | 2 +- + scripts/gendwarfksyms/kabi.c | 2 +- + scripts/gendwarfksyms/symbols.c | 2 +- + scripts/gendwarfksyms/types.c | 33 +- + scripts/kconfig/conf.c | 2 +- + scripts/kconfig/confdata.c | 2 +- + scripts/kconfig/gconf-cfg.sh | 11 +- + scripts/kconfig/gconf.c | 1783 +++++++++++++--------------- + scripts/kconfig/{gconf.glade => gconf.ui} | 361 ++---- + scripts/kconfig/lkc.h | 2 + + scripts/kconfig/lxdialog/inputbox.c | 6 +- + scripts/kconfig/lxdialog/menubox.c | 2 +- + scripts/kconfig/lxdialog/util.c | 3 +- + scripts/kconfig/menu.c | 94 ++ + scripts/kconfig/nconf.c | 2 + + scripts/kconfig/nconf.gui.c | 1 + + scripts/kconfig/qconf.cc | 36 +- + scripts/kconfig/qconf.h | 1 + + scripts/kconfig/symbol.c | 4 + + scripts/link-vmlinux.sh | 5 +- + scripts/mksysmap | 6 + + scripts/mod/file2alias.c | 34 +- + scripts/mod/modpost.c | 17 +- + scripts/mod/modpost.h | 2 + + 43 files changed, 1342 insertions(+), 1410 deletions(-) + rename scripts/kconfig/{gconf.glade => gconf.ui} (57%) +$ git am -3 ../patches/kbuild__modpost__Fix_the_order_of_includes_in_.vmlinux.export.c.patch +Applying: kbuild: modpost: Fix the order of includes in .vmlinux.export.c +$ git reset HEAD^ +Unstaged changes after reset: +M scripts/mod/modpost.c +$ git add -A . +$ git commit -v -a --amend +[master ae6e3eb8ab69] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git + Date: Tue Aug 5 10:32:21 2025 +1000 +Merging clang-format/clang-format (c147f663b6a5 clang-format: Update with v6.11-rc1's `for_each` macro list) +$ git merge -m Merge branch 'clang-format' of https://github.com/ojeda/linux.git clang-format/clang-format +Already up to date. +Merging perf/perf-tools-next (6235ce77749f perf record: Cache build-ID of hit DSOs only) +$ git merge -m Merge branch 'perf-tools-next' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git perf/perf-tools-next +Already up to date. +Merging compiler-attributes/compiler-attributes (98f7e32f20d2 Linux 6.11) +$ git merge -m Merge branch 'compiler-attributes' of https://github.com/ojeda/linux.git compiler-attributes/compiler-attributes +Already up to date. +Merging dma-mapping/dma-mapping-for-next (fbf5e2234169 dma-mapping: properly calculate offset in the page) +$ git merge -m Merge branch 'dma-mapping-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux.git dma-mapping/dma-mapping-for-next +Auto-merging Documentation/core-api/dma-api.rst +Auto-merging drivers/virtio/virtio_ring.c +Auto-merging mm/hmm.c +Merge made by the 'ort' strategy. + Documentation/core-api/dma-api.rst | 4 +-- + arch/powerpc/kernel/dma-iommu.c | 4 +-- + drivers/iommu/dma-iommu.c | 14 ++++---- + drivers/virtio/virtio_ring.c | 4 +-- + include/linux/dma-map-ops.h | 8 ++--- + include/linux/dma-mapping.h | 13 ++++++++ + include/linux/iommu-dma.h | 7 ++-- + include/linux/kmsan.h | 12 ++++--- + include/trace/events/dma.h | 4 +-- + kernel/dma/debug.c | 28 ++++++++++------ + kernel/dma/debug.h | 16 ++++----- + kernel/dma/direct.c | 6 ++-- + kernel/dma/direct.h | 13 ++++---- + kernel/dma/mapping.c | 68 +++++++++++++++++++++++++++----------- + kernel/dma/ops_helpers.c | 6 ++-- + mm/hmm.c | 8 ++--- + mm/kmsan/hooks.c | 36 ++++++++++++++++---- + tools/virtio/linux/kmsan.h | 2 +- + 18 files changed, 160 insertions(+), 93 deletions(-) +Merging asm-generic/master (582847f97024 Makefile.kcov: apply needed compiler option unconditionally in CFLAGS_KCOV) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git asm-generic/master +Already up to date. +Merging alpha/alpha-next (1523226edda5 alpha: Use str_yes_no() helper in pci_dac_dma_supported()) +$ git merge -m Merge branch 'alpha-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha.git alpha/alpha-next +Already up to date. +Merging arm/for-next (8dd85887ad83 Merge branches 'fixes' and 'misc' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux.git arm/for-next +Merge made by the 'ort' strategy. + arch/arm/include/asm/cti.h | 160 --------------------------------------------- + 1 file changed, 160 deletions(-) + delete mode 100644 arch/arm/include/asm/cti.h +Merging arm64/for-next/core (5b1ae9de7133 Merge branch 'for-next/feat_mte_store_only' into for-next/core) +$ git merge -m Merge branch 'for-next/core' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux arm64/for-next/core +Already up to date. +Merging arm-perf/for-next/perf (e480898e767c drivers/perf: hisi: Support PMUs with no interrupt) +$ git merge -m Merge branch 'for-next/perf' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git arm-perf/for-next/perf +Already up to date. +Merging arm-soc/for-next (9f9d41d64322 Merge tag 'arm-soc/for-6.17/drivers-part2' of https://github.com/Broadcom/stblinux into arm/fixes) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm-soc/for-next +Already up to date. +Merging amlogic/for-next (58abdca0eb65 Merge branch 'v6.17/arm64-dt' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git amlogic/for-next +Merge made by the 'ort' strategy. +Merging asahi-soc/asahi-soc/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'asahi-soc/for-next' of https://github.com/AsahiLinux/linux.git asahi-soc/asahi-soc/for-next +Already up to date. +Merging at91/at91-next (e99113d11171 Merge branch 'clk-microchip' into at91-next) +$ git merge -m Merge branch 'at91-next' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git at91/at91-next +Merge made by the 'ort' strategy. +Merging bmc/for-next (acba3fae64fd Merge branches 'aspeed/drivers', 'aspeed/dt', 'nuvoton/arm/dt' and 'nuvoton/arm64/dt' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/bmc/linux.git bmc/for-next +Auto-merging arch/arm64/boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi +Merge made by the 'ort' strategy. + .../devicetree/bindings/arm/aspeed/aspeed.yaml | 3 + + arch/arm/boot/dts/aspeed/Makefile | 3 + + .../boot/dts/aspeed/aspeed-bmc-facebook-darwin.dts | 72 ++ + .../boot/dts/aspeed/aspeed-bmc-facebook-elbert.dts | 12 + + .../dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts | 1256 ++++++++++++++++++++ + .../boot/dts/aspeed/aspeed-bmc-facebook-fuji.dts | 1247 +------------------ + .../aspeed/aspeed-bmc-facebook-wedge400-data64.dts | 375 ++++++ + .../dts/aspeed/aspeed-bmc-facebook-wedge400.dts | 366 +----- + .../arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts | 24 +- + .../boot/dts/aspeed/aspeed-bmc-inspur-fp5280g2.dts | 3 +- + .../dts/aspeed/aspeed-bmc-nvidia-gb200nvl-bmc.dts | 54 +- + .../arm/boot/dts/aspeed/aspeed-bmc-opp-lanyang.dts | 2 +- + arch/arm/boot/dts/aspeed/aspeed-bmc-opp-mowgli.dts | 2 +- + arch/arm/boot/dts/aspeed/aspeed-bmc-opp-nicole.dts | 3 +- + .../boot/dts/aspeed/aspeed-bmc-opp-palmetto.dts | 2 +- + .../arm/boot/dts/aspeed/aspeed-bmc-opp-romulus.dts | 3 +- + .../boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts | 2 +- + arch/arm/boot/dts/aspeed/aspeed-bmc-opp-zaius.dts | 2 +- + arch/arm/boot/dts/aspeed/aspeed-g6.dtsi | 4 +- + .../dts/aspeed/ast2600-facebook-netbmc-common.dtsi | 22 +- + .../facebook-bmc-flash-layout-128-data64.dtsi | 60 + + arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi | 12 +- + arch/arm/boot/dts/aspeed/ibm-power10-quad.dtsi | 12 +- + .../boot/dts/nuvoton/nuvoton-common-npcm7xx.dtsi | 2 +- + arch/arm/boot/dts/nuvoton/nuvoton-npcm750.dtsi | 2 +- + .../boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi | 669 ++++++++++- + .../arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts | 6 + + drivers/soc/aspeed/aspeed-lpc-ctrl.c | 14 +- + drivers/soc/aspeed/aspeed-p2a-ctrl.c | 14 +- + 29 files changed, 2561 insertions(+), 1687 deletions(-) + create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-darwin.dts + create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji-data64.dts + create mode 100644 arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-wedge400-data64.dts + create mode 100644 arch/arm/boot/dts/aspeed/facebook-bmc-flash-layout-128-data64.dtsi +Merging broadcom/next (89abb622d518 Merge branch 'drivers/next' into next) +$ git merge -m Merge branch 'next' of https://github.com/Broadcom/stblinux.git broadcom/next +Merge made by the 'ort' strategy. +Merging davinci/davinci/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'davinci/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git davinci/davinci/for-next +Already up to date. +Merging drivers-memory/for-next (93a7aedc4cc4 dt-bindings: memory: renesas,rzg3e-xspi: Document RZ/V2H(P) and RZ/V2N support) +$ git merge -m Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git drivers-memory/for-next +Already up to date. +Merging fsl/soc_fsl (8b3da0519ae6 soc: fsl: qe: convert set_multiple() to returning an integer) +$ git merge -m Merge branch 'soc_fsl' of https://github.com/chleroy/linux.git fsl/soc_fsl +Merge made by the 'ort' strategy. +Merging imx-mxs/for-next (cdc22fb12eff Merge branch 'imx/defconfig' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git imx-mxs/for-next +Merge made by the 'ort' strategy. +Merging mediatek/for-next (6cbb623586d5 Merge branches 'v6.16-next/arm32', 'v6.16-next/dts32', 'v6.16-next/dts64' and 'v6.16-next/soc' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mediatek/linux.git mediatek/for-next +Merge made by the 'ort' strategy. +Merging mvebu/for-next (88084e0358ff Merge branch 'mvebu/dt' into mvebu/for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git mvebu/for-next +Merge made by the 'ort' strategy. +Merging omap/for-next (db91121f001a Merge branch 'omap-for-v6.17/soc' into tmp/omap-next-20250707.142928) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap.git omap/for-next +Auto-merging arch/arm/configs/multi_v7_defconfig +Auto-merging arch/arm/configs/omap2plus_defconfig +Merge made by the 'ort' strategy. +Merging qcom/for-next (ba94ec807b07 Merge branches 'arm32-for-6.17', 'arm64-defconfig-fixes-for-6.16', 'arm64-defconfig-for-6.17', 'arm64-fixes-for-6.16', 'arm64-for-6.17', 'clk-for-6.17' and 'drivers-for-6.17' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git qcom/for-next +Merge made by the 'ort' strategy. + Documentation/devicetree/bindings/arm/qcom.yaml | 9 + + arch/arm/boot/dts/qcom/Makefile | 1 + + arch/arm/boot/dts/qcom/pm8921.dtsi | 6 + + arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi | 40 +++ + .../dts/qcom/qcom-msm8960-samsung-expressatt.dts | 5 + + .../boot/dts/qcom/qcom-msm8960-sony-huashan.dts | 361 +++++++++++++++++++++ + arch/arm/boot/dts/qcom/qcom-msm8960.dtsi | 32 ++ + arch/arm64/boot/dts/qcom/ipq5018.dtsi | 226 ++++++++++++- + arch/arm64/boot/dts/qcom/ipq5424-rdp466.dts | 26 +- + arch/arm64/boot/dts/qcom/ipq5424.dtsi | 27 +- + arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 - + arch/arm64/boot/dts/qcom/qcs615-ride.dts | 4 +- + arch/arm64/boot/dts/qcom/sa8775p.dtsi | 2 +- + arch/arm64/boot/dts/qcom/sar2130p.dtsi | 23 +- + arch/arm64/boot/dts/qcom/sc7180.dtsi | 8 - + arch/arm64/boot/dts/qcom/sdm845.dtsi | 16 +- + .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts | 104 +++++- + .../boot/dts/qcom/{qcs615.dtsi => sm6150.dtsi} | 6 + + arch/arm64/boot/dts/qcom/sm6350.dtsi | 11 + + arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts | 36 ++ + arch/arm64/boot/dts/qcom/sm8250.dtsi | 8 - + .../boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts | 143 ++++++++ + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 7 + + arch/arm64/boot/dts/qcom/x1p42100-crd.dts | 4 + + arch/arm64/boot/dts/qcom/x1p42100.dtsi | 120 ++++++- + 25 files changed, 1173 insertions(+), 60 deletions(-) + create mode 100644 arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts + rename arch/arm64/boot/dts/qcom/{qcs615.dtsi => sm6150.dtsi} (99%) +Merging renesas/next (7a323accaf6b Merge branches 'renesas-arm-defconfig-for-v6.17', 'renesas-drivers-for-v6.17', 'renesas-dt-bindings-for-v6.17' and 'renesas-dts-for-v6.17' into renesas-next) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git renesas/next +Merge made by the 'ort' strategy. +Merging reset/reset/next (335bb23abed3 MAINTAINERS: Use https:// protocol for Reset Controller Framework tree) +$ git merge -m Merge branch 'reset/next' of https://git.pengutronix.de/git/pza/linux reset/reset/next +Auto-merging MAINTAINERS +Merge made by the 'ort' strategy. + MAINTAINERS | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +Merging rockchip/for-next (1f0c7abd8235 Merge branch 'v6.16-armsoc/dtsfixes' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git rockchip/for-next +Merge made by the 'ort' strategy. +Merging samsung-krzk/for-next (94f19ac4670d Merge branch 'next/drivers' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git samsung-krzk/for-next +Merge made by the 'ort' strategy. +Merging scmi/for-linux-next (d2eedaa3909b Merge tag 'rtc-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux) +$ git merge -m Merge branch 'for-linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git scmi/for-linux-next +Already up to date. +Merging sophgo/for-next (349ae53a949c Merge branch 'dt/riscv' into for-next) +$ git merge -m Merge branch 'for-next' of https://github.com/sophgo/linux.git sophgo/for-next +Merge made by the 'ort' strategy. +Merging sophgo-soc/soc-for-next (c8754c7deab4 soc: sophgo: cv1800: rtcsys: New driver (handling RTC only)) +$ git merge -m Merge branch 'soc-for-next' of https://github.com/sophgo/linux.git sophgo-soc/soc-for-next +Already up to date. +Merging spacemit/for-next (6be7a5a768aa Merge branch 'spacemit-clk-for-6.17' into spacemit-for-next) +$ git merge -m Merge branch 'for-next' of https://github.com/spacemit-com/linux spacemit/for-next +Merge made by the 'ort' strategy. +Merging stm32/stm32-next (1a32f7427eb3 arm64: dts: st: remove empty line in stm32mp251.dtsi) +$ git merge -m Merge branch 'stm32-next' of git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32/stm32-next +Already up to date. +Merging sunxi/sunxi/for-next (cbe908fc8ebb Merge branch 'sunxi/dt-for-6.17' into sunxi/for-next) +$ git merge -m Merge branch 'sunxi/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git sunxi/sunxi/for-next +Merge made by the 'ort' strategy. +Merging tee/next (84c5f44d24c6 Merge branch 'tee_fixes_for_v6.17' into next) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee.git tee/next +Merge made by the 'ort' strategy. + drivers/tee/optee/core.c | 2 +- + drivers/tee/tee_core.c | 2 +- + drivers/tee/tee_shm.c | 14 ++++++++++---- + 3 files changed, 12 insertions(+), 6 deletions(-) +Merging tegra/for-next (499b75defe56 Merge branch for-6.17/arm64/defconfig into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tegra/for-next +Merge made by the 'ort' strategy. + Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml | 4 ++++ + arch/arm64/boot/dts/nvidia/tegra264.dtsi | 3 --- + drivers/firmware/tegra/bpmp-tegra186.c | 5 ++++- + 3 files changed, 8 insertions(+), 4 deletions(-) +Merging thead-dt/thead-dt-for-next (c31f2899eab0 riscv: dts: thead: Add PVT node) +$ git merge -m Merge branch 'thead-dt-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git thead-dt/thead-dt-for-next +Already up to date. +Merging ti/ti-next (65f6e3eb6351 Merge branch 'ti-k3-dts-next' into ti-next) +$ git merge -m Merge branch 'ti-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git ti/ti-next +Merge made by the 'ort' strategy. +Merging xilinx/for-next (3a0e3f82b8ee Merge branch 'zynqmp/dt' into for-next) +$ git merge -m Merge branch 'for-next' of git://github.com/Xilinx/linux-xlnx.git xilinx/for-next +Merge made by the 'ort' strategy. + .../devicetree/bindings/soc/xilinx/xilinx.yaml | 81 ++++ + arch/arm64/boot/dts/xilinx/Makefile | 24 ++ + arch/arm64/boot/dts/xilinx/versal-net.dtsi | 2 +- + .../boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso | 390 ++++++++++++++++++ + .../boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso | 438 ++++++++++++++++++++ + .../boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso | 451 +++++++++++++++++++++ + .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso | 19 +- + .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso | 35 +- + arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts | 23 ++ + arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts | 7 +- + arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts | 21 + + .../boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts | 1 - + .../boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts | 1 - + arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts | 21 + + arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts | 18 + + arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts | 18 + + arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts | 18 + + arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts | 10 +- + arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts | 20 +- + arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 14 +- + drivers/firmware/xilinx/zynqmp-debug.c | 13 + + drivers/firmware/xilinx/zynqmp.c | 114 ++++-- + drivers/pinctrl/pinctrl-zynqmp.c | 7 +- + drivers/soc/xilinx/xlnx_event_manager.c | 8 +- + drivers/soc/xilinx/zynqmp_power.c | 10 +- + include/linux/firmware/xlnx-zynqmp.h | 30 +- + 26 files changed, 1713 insertions(+), 81 deletions(-) + create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso + create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso + create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso + create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts + create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts +Merging clk/clk-next (64c21f253a37 Merge branch 'clk-fixes' into clk-next) +$ git merge -m Merge branch 'clk-next' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk/clk-next +Already up to date. +Merging clk-imx/for-next (c78865241ecf MAINTAINERS: Update i.MX Clock Entry) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk-imx/for-next +Already up to date. +Merging clk-renesas/renesas-clk (0ab2d84f94da clk: renesas: r9a08g045: Add MSTOP for coupled clocks as well) +$ git merge -m Merge branch 'renesas-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas/renesas-clk +Already up to date. +Merging thead-clk/thead-clk-for-next (54edba916e29 clk: thead: th1520-ap: Describe mux clocks with clk_mux) +$ git merge -m Merge branch 'thead-clk-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git thead-clk/thead-clk-for-next +Already up to date. +Merging csky/linux-next (2b48804336be csky: fix csky_cmpxchg_fixup not working) +$ git merge -m Merge branch 'linux-next' of git://github.com/c-sky/csky-linux.git csky/linux-next +Merge made by the 'ort' strategy. + arch/csky/mm/fault.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) +Merging loongarch/loongarch-next (bcfdf97c1abc LoongArch: vDSO: Remove -nostdlib complier flag) +$ git merge -m Merge branch 'loongarch-next' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git loongarch/loongarch-next +Auto-merging arch/loongarch/kernel/setup.c +Merge made by the 'ort' strategy. + arch/loongarch/boot/dts/loongson-2k0500-ref.dts | 9 + + arch/loongarch/boot/dts/loongson-2k0500.dtsi | 28 +- + arch/loongarch/boot/dts/loongson-2k1000-ref.dts | 13 + + arch/loongarch/boot/dts/loongson-2k1000.dtsi | 24 +- + arch/loongarch/boot/dts/loongson-2k2000-ref.dts | 10 + + arch/loongarch/boot/dts/loongson-2k2000.dtsi | 18 + + arch/loongarch/include/asm/inst.h | 3 + + arch/loongarch/include/asm/loongarch.h | 7 + + arch/loongarch/kernel/env.c | 13 +- + arch/loongarch/kernel/inst.c | 55 ++ + arch/loongarch/kernel/relocate_kernel.S | 2 +- + arch/loongarch/kernel/setup.c | 18 +- + arch/loongarch/kernel/unwind_orc.c | 2 +- + arch/loongarch/net/bpf_jit.c | 699 +++++++++++++++++++++--- + arch/loongarch/net/bpf_jit.h | 6 + + arch/loongarch/vdso/Makefile | 2 +- + 16 files changed, 820 insertions(+), 89 deletions(-) +Merging m68k/for-next (c8995932db2b m68k: mac: Improve clocksource driver commentary) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git m68k/for-next +Already up to date. +Merging m68knommu/for-next (89be9a83ccf1 Linux 6.16-rc7) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git m68knommu/for-next +Already up to date. +Merging microblaze/next (c0e7bb02f796 microblaze: Replace __ASSEMBLY__ with __ASSEMBLER__ in non-uapi headers) +$ git merge -m Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze.git microblaze/next +Auto-merging arch/microblaze/include/asm/pgtable.h +Merge made by the 'ort' strategy. + arch/microblaze/Kconfig.platform | 10 +++++----- + arch/microblaze/include/asm/asm-compat.h | 2 +- + arch/microblaze/include/asm/current.h | 4 ++-- + arch/microblaze/include/asm/entry.h | 4 ++-- + arch/microblaze/include/asm/exceptions.h | 4 ++-- + arch/microblaze/include/asm/fixmap.h | 4 ++-- + arch/microblaze/include/asm/ftrace.h | 2 +- + arch/microblaze/include/asm/kgdb.h | 4 ++-- + arch/microblaze/include/asm/mmu.h | 4 ++-- + arch/microblaze/include/asm/page.h | 8 ++++---- + arch/microblaze/include/asm/pgtable.h | 18 +++++++++--------- + arch/microblaze/include/asm/processor.h | 8 ++++---- + arch/microblaze/include/asm/ptrace.h | 4 ++-- + arch/microblaze/include/asm/sections.h | 4 ++-- + arch/microblaze/include/asm/setup.h | 4 ++-- + arch/microblaze/include/asm/thread_info.h | 4 ++-- + arch/microblaze/include/asm/unistd.h | 4 ++-- + arch/microblaze/include/asm/xilinx_mb_manager.h | 4 ++-- + arch/microblaze/include/uapi/asm/ptrace.h | 4 ++-- + 19 files changed, 50 insertions(+), 50 deletions(-) +Merging mips/mips-next (3ebcbf079c26 MIPS: Don't use %pK through printk) +$ git merge -m Merge branch 'mips-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git mips/mips-next +Already up to date. +Merging openrisc/for-next (f0eedcf22581 openrisc: Replace __ASSEMBLY__ with __ASSEMBLER__ in non-uapi headers) +$ git merge -m Merge branch 'for-next' of git://github.com/openrisc/linux.git openrisc/for-next +Already up to date. +Merging parisc-hd/for-next (89f686a0fb6e parisc: Revise __get_user() to probe user read access) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git parisc-hd/for-next +Already up to date. +Merging powerpc/next (cf2a6de32cab powerpc64/bpf: Add jit support for load_acquire and store_release) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git powerpc/next +Already up to date. +Merging risc-v/for-next (fda589c28604 Merge patch series "Move duplicated instructions macros into asm/insn.h") +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git risc-v/for-next +Auto-merging arch/riscv/configs/defconfig +Auto-merging arch/riscv/kernel/traps_misaligned.c +Merge made by the 'ort' strategy. + arch/riscv/configs/defconfig | 5 +- + arch/riscv/include/asm/insn.h | 206 +++++++++++++++++++++++++++++---- + arch/riscv/kernel/machine_kexec_file.c | 2 +- + arch/riscv/kernel/traps_misaligned.c | 144 +---------------------- + arch/riscv/kernel/vector.c | 2 +- + arch/riscv/kvm/vcpu_insn.c | 128 +------------------- + 6 files changed, 190 insertions(+), 297 deletions(-) +Merging riscv-dt/riscv-dt-for-next (28fa0dcb571a dt-bindings: riscv: cpus: Add AMD MicroBlaze V 64bit compatible) +$ git merge -m Merge branch 'riscv-dt-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git riscv-dt/riscv-dt-for-next +Already up to date. +Merging riscv-soc/riscv-soc-for-next (bd4d5d3faadc riscv: defconfig: spacemit: enable sdhci driver for K1 SoC) +$ git merge -m Merge branch 'riscv-soc-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git riscv-soc/riscv-soc-for-next +Already up to date. +Merging s390/for-next (d3a0de1a9dbc Merge branch 'features' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git s390/for-next +Auto-merging arch/s390/Kconfig +Auto-merging arch/s390/kernel/setup.c +Merge made by the 'ort' strategy. + arch/s390/Kconfig | 3 +++ + arch/s390/include/asm/ap.h | 2 +- + arch/s390/include/asm/pgtable.h | 45 +++++++++++++++++++++++++++++++++++++++++ + arch/s390/kernel/setup.c | 6 ++++++ + drivers/s390/crypto/ap_bus.h | 2 +- + 5 files changed, 56 insertions(+), 2 deletions(-) +Merging sh/for-next (c32969d0362a sh: Do not use hyphen in exported variable name) +$ git merge -m Merge branch 'for-next' of git:git.kernel.org/pub/scm/linux/kernel/git/glaubitz/sh-linux.git sh/for-next +Already up to date. +Merging sparc/for-next (2cec2c4dc90c sparc/irq: Remove unneeded if check in sun4v_cookie_only_virqs()) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/alarsson/linux-sparc.git sparc/for-next +Already up to date. +Merging uml/next (fc9ed2f6589d um: Replace __ASSEMBLY__ with __ASSEMBLER__ in the usermode headers) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git uml/next +Already up to date. +Merging xtensa/xtensa-for-next (44a4ef59d550 xtensa: Replace __ASSEMBLY__ with __ASSEMBLER__ in non-uapi headers) +$ git merge -m Merge branch 'xtensa-for-next' of git://github.com/jcmvbkbc/linux-xtensa.git xtensa/xtensa-for-next +Auto-merging arch/xtensa/include/asm/pgtable.h +Auto-merging arch/xtensa/include/asm/ptrace.h +Merge made by the 'ort' strategy. + arch/xtensa/include/asm/bootparam.h | 2 +- + arch/xtensa/include/asm/cmpxchg.h | 4 ++-- + arch/xtensa/include/asm/coprocessor.h | 8 ++++---- + arch/xtensa/include/asm/current.h | 2 +- + arch/xtensa/include/asm/ftrace.h | 8 ++++---- + arch/xtensa/include/asm/initialize_mmu.h | 4 ++-- + arch/xtensa/include/asm/jump_label.h | 4 ++-- + arch/xtensa/include/asm/kasan.h | 2 +- + arch/xtensa/include/asm/kmem_layout.h | 2 +- + arch/xtensa/include/asm/page.h | 4 ++-- + arch/xtensa/include/asm/pgtable.h | 8 ++++---- + arch/xtensa/include/asm/processor.h | 4 ++-- + arch/xtensa/include/asm/ptrace.h | 6 +++--- + arch/xtensa/include/asm/signal.h | 4 ++-- + arch/xtensa/include/asm/thread_info.h | 8 ++++---- + arch/xtensa/include/asm/tlbflush.h | 4 ++-- + arch/xtensa/include/uapi/asm/ptrace.h | 2 +- + arch/xtensa/include/uapi/asm/signal.h | 6 +++--- + arch/xtensa/include/uapi/asm/types.h | 4 ++-- + 19 files changed, 43 insertions(+), 43 deletions(-) +Merging fs-next (0264e7f5188b Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git) +$ git merge -m Merge branch 'fs-next' of linux-next fs-next +Auto-merging MAINTAINERS +Merge made by the 'ort' strategy. + Documentation/ABI/testing/sysfs-fs-f2fs | 22 + + Documentation/filesystems/f2fs.rst | 6 +- + .../filesystems/{ => fuse}/fuse-io-uring.rst | 0 + Documentation/filesystems/{ => fuse}/fuse-io.rst | 2 +- + .../filesystems/{ => fuse}/fuse-passthrough.rst | 0 + Documentation/filesystems/{ => fuse}/fuse.rst | 20 +- + Documentation/filesystems/fuse/index.rst | 14 + + Documentation/filesystems/index.rst | 5 +- + MAINTAINERS | 3 +- + fs/bcachefs/acl.c | 29 +- + fs/bcachefs/alloc_background.c | 570 +++-- + fs/bcachefs/alloc_background.h | 9 +- + fs/bcachefs/alloc_foreground.c | 258 +-- + fs/bcachefs/alloc_foreground.h | 9 +- + fs/bcachefs/async_objs.c | 29 +- + fs/bcachefs/async_objs.h | 7 +- + fs/bcachefs/async_objs_types.h | 2 +- + fs/bcachefs/backpointers.c | 167 +- + fs/bcachefs/bcachefs.h | 91 +- + fs/bcachefs/bcachefs_format.h | 42 +- + fs/bcachefs/bkey.c | 4 +- + fs/bcachefs/bkey_methods.c | 6 +- + fs/bcachefs/bkey_types.h | 5 + + fs/bcachefs/bset.c | 74 +- + fs/bcachefs/btree_cache.c | 44 +- + fs/bcachefs/btree_cache.h | 19 + + fs/bcachefs/btree_gc.c | 258 +-- + fs/bcachefs/btree_io.c | 123 +- + fs/bcachefs/btree_iter.c | 424 ++-- + fs/bcachefs/btree_iter.h | 348 ++-- + fs/bcachefs/btree_journal_iter.c | 20 +- + fs/bcachefs/btree_key_cache.c | 69 +- + fs/bcachefs/btree_locking.c | 17 +- + fs/bcachefs/btree_node_scan.c | 36 +- + fs/bcachefs/btree_trans_commit.c | 125 +- + fs/bcachefs/btree_types.h | 43 +- + fs/bcachefs/btree_update.c | 339 +-- + fs/bcachefs/btree_update.h | 150 +- + fs/bcachefs/btree_update_interior.c | 387 ++-- + fs/bcachefs/btree_update_interior.h | 12 +- + fs/bcachefs/btree_write_buffer.c | 78 +- + fs/bcachefs/btree_write_buffer.h | 8 +- + fs/bcachefs/buckets.c | 258 +-- + fs/bcachefs/buckets_waiting_for_journal.c | 30 +- + fs/bcachefs/chardev.c | 120 +- + fs/bcachefs/checksum.c | 54 +- + fs/bcachefs/clock.c | 17 +- + fs/bcachefs/compress.c | 29 +- + fs/bcachefs/compress.h | 36 +- + fs/bcachefs/data_update.c | 58 +- + fs/bcachefs/data_update.h | 1 + + fs/bcachefs/debug.c | 88 +- + fs/bcachefs/dirent.c | 88 +- + fs/bcachefs/dirent.h | 4 +- + fs/bcachefs/disk_accounting.c | 270 ++- + fs/bcachefs/disk_accounting.h | 19 +- + fs/bcachefs/disk_groups.c | 27 +- + fs/bcachefs/ec.c | 396 ++-- + fs/bcachefs/ec.h | 2 +- + fs/bcachefs/enumerated_ref.c | 4 +- + fs/bcachefs/errcode.c | 3 +- + fs/bcachefs/errcode.h | 14 + + fs/bcachefs/error.c | 65 +- + fs/bcachefs/error.h | 3 +- + fs/bcachefs/extent_update.c | 67 +- + fs/bcachefs/extent_update.h | 2 - + fs/bcachefs/extents.c | 55 +- + fs/bcachefs/extents.h | 4 + + fs/bcachefs/fast_list.c | 32 +- + fs/bcachefs/fast_list.h | 2 +- + fs/bcachefs/fs-io-buffered.c | 96 +- + fs/bcachefs/fs-io-direct.c | 26 +- + fs/bcachefs/fs-io-pagecache.c | 55 +- + fs/bcachefs/fs-io.c | 141 +- + fs/bcachefs/fs-io.h | 19 +- + fs/bcachefs/fs-ioctl.c | 33 +- + fs/bcachefs/fs.c | 254 +-- + fs/bcachefs/fsck.c | 649 +++--- + fs/bcachefs/inode.c | 252 +-- + fs/bcachefs/io_misc.c | 83 +- + fs/bcachefs/io_read.c | 235 ++- + fs/bcachefs/io_read.h | 24 +- + fs/bcachefs/io_write.c | 97 +- + fs/bcachefs/journal.c | 253 ++- + fs/bcachefs/journal.h | 3 +- + fs/bcachefs/journal_io.c | 248 +-- + fs/bcachefs/journal_io.h | 7 + + fs/bcachefs/journal_reclaim.c | 220 +- + fs/bcachefs/journal_seq_blacklist.c | 56 +- + fs/bcachefs/journal_seq_blacklist.h | 3 + + fs/bcachefs/logged_ops.c | 16 +- + fs/bcachefs/logged_ops.h | 2 +- + fs/bcachefs/lru.c | 48 +- + fs/bcachefs/lru.h | 10 + + fs/bcachefs/migrate.c | 31 +- + fs/bcachefs/move.c | 316 ++- + fs/bcachefs/move.h | 14 +- + fs/bcachefs/movinggc.c | 218 +- + fs/bcachefs/namei.c | 154 +- + fs/bcachefs/nocow_locking.c | 10 +- + fs/bcachefs/opts.c | 33 +- + fs/bcachefs/opts.h | 8 +- + fs/bcachefs/printbuf.h | 4 + + fs/bcachefs/progress.c | 6 +- + fs/bcachefs/progress.h | 3 + + fs/bcachefs/quota.c | 103 +- + fs/bcachefs/rebalance.c | 216 +- + fs/bcachefs/recovery.c | 412 +--- + fs/bcachefs/recovery_passes.c | 68 +- + fs/bcachefs/recovery_passes.h | 9 +- + fs/bcachefs/reflink.c | 137 +- + fs/bcachefs/replicas.c | 161 +- + fs/bcachefs/sb-clean.c | 36 +- + fs/bcachefs/sb-counters_format.h | 12 +- + fs/bcachefs/sb-downgrade.c | 19 +- + fs/bcachefs/sb-errors.c | 45 +- + fs/bcachefs/sb-errors_format.h | 11 +- + fs/bcachefs/sb-members.c | 164 +- + fs/bcachefs/sb-members.h | 44 +- + fs/bcachefs/sb-members_format.h | 2 +- + fs/bcachefs/six.c | 21 +- + fs/bcachefs/snapshot.c | 435 ++-- + fs/bcachefs/snapshot.h | 32 +- + fs/bcachefs/snapshot_types.h | 2 +- + fs/bcachefs/str_hash.c | 57 +- + fs/bcachefs/str_hash.h | 47 +- + fs/bcachefs/subvolume.c | 246 +-- + fs/bcachefs/subvolume.h | 20 +- + fs/bcachefs/super-io.c | 112 +- + fs/bcachefs/super.c | 871 ++++---- + fs/bcachefs/sysfs.c | 28 +- + fs/bcachefs/tests.c | 340 ++- + fs/bcachefs/thread_with_file.c | 48 +- + fs/bcachefs/time_stats.c | 7 +- + fs/bcachefs/trace.h | 157 +- + fs/bcachefs/util.c | 28 +- + fs/bcachefs/util.h | 10 +- + fs/bcachefs/xattr.c | 58 +- + fs/ecryptfs/crypto.c | 2 +- + fs/ecryptfs/ecryptfs_kernel.h | 1 - + fs/ecryptfs/keystore.c | 4 +- + fs/exfat/balloc.c | 12 +- + fs/exfat/dir.c | 13 +- + fs/exfat/exfat_fs.h | 1 + + fs/exfat/fatent.c | 10 + + fs/exfat/file.c | 5 +- + fs/exfat/namei.c | 5 + + fs/exfat/super.c | 32 +- + fs/ext4/namei.c | 2 - + fs/f2fs/checkpoint.c | 8 +- + fs/f2fs/compress.c | 120 +- + fs/f2fs/data.c | 183 +- + fs/f2fs/debug.c | 21 +- + fs/f2fs/dir.c | 4 +- + fs/f2fs/extent_cache.c | 10 +- + fs/f2fs/f2fs.h | 151 +- + fs/f2fs/file.c | 107 +- + fs/f2fs/gc.c | 54 +- + fs/f2fs/gc.h | 5 +- + fs/f2fs/inline.c | 20 +- + fs/f2fs/inode.c | 84 +- + fs/f2fs/namei.c | 12 +- + fs/f2fs/node.c | 261 ++- + fs/f2fs/node.h | 77 +- + fs/f2fs/recovery.c | 116 +- + fs/f2fs/segment.c | 62 +- + fs/f2fs/segment.h | 59 +- + fs/f2fs/super.c | 2185 +++++++++++--------- + fs/f2fs/sysfs.c | 48 + + fs/fuse/dev.c | 5 +- + fs/fuse/file.c | 1 - + fs/fuse/virtio_fs.c | 3 - + fs/nfs/blocklayout/blocklayout.c | 4 +- + fs/nfs/blocklayout/dev.c | 5 +- + fs/nfs/blocklayout/extent_tree.c | 104 +- + fs/nfs/client.c | 3 +- + fs/nfs/delegation.c | 114 +- + fs/nfs/delegation.h | 3 + + fs/nfs/dir.c | 4 +- + fs/nfs/export.c | 11 +- + fs/nfs/flexfilelayout/flexfilelayout.c | 26 +- + fs/nfs/flexfilelayout/flexfilelayoutdev.c | 6 +- + fs/nfs/fs_context.c | 42 + + fs/nfs/inode.c | 69 +- + fs/nfs/internal.h | 10 +- + fs/nfs/mount_clnt.c | 68 - + fs/nfs/nfs4client.c | 165 +- + fs/nfs/nfs4file.c | 25 +- + fs/nfs/nfs4proc.c | 50 +- + fs/nfs/nfs4trace.c | 2 + + fs/nfs/nfs4trace.h | 168 +- + fs/nfs/nfs4xdr.c | 24 + + fs/nfs/nfstrace.h | 11 +- + fs/nfs/pnfs.c | 39 +- + fs/nfs/pnfs_nfs.c | 14 +- + fs/nfs/write.c | 8 +- + fs/smb/client/cifs_debug.c | 6 +- + fs/smb/client/cifsfs.c | 2 +- + fs/smb/client/cifsglob.h | 5 + + fs/smb/client/cifssmb.c | 4 +- + fs/smb/client/fs_context.c | 19 +- + fs/smb/client/fs_context.h | 18 +- + fs/smb/client/link.c | 13 +- + fs/smb/client/reparse.c | 2 +- + fs/smb/client/smb1ops.c | 2 +- + fs/smb/client/smb2inode.c | 5 +- + fs/smb/client/smb2ops.c | 5 +- + fs/smb/client/smbdirect.c | 124 +- + fs/smb/client/smbdirect.h | 4 - + include/linux/f2fs_fs.h | 2 +- + include/linux/fscrypt.h | 10 +- + include/linux/nfs_fs.h | 8 + + include/linux/nfs_fs_sb.h | 8 +- + include/linux/nfs_xdr.h | 57 +- + include/linux/sunrpc/xdr.h | 9 - + include/linux/wait.h | 12 + + lib/closure.c | 12 +- + net/sunrpc/auth_gss/gss_krb5_crypto.c | 4 +- + net/sunrpc/xdr.c | 110 - + tools/testing/selftests/Makefile | 1 + + .../testing/selftests/filesystems/fuse/.gitignore | 3 + + tools/testing/selftests/filesystems/fuse/Makefile | 21 + + .../testing/selftests/filesystems/fuse/fuse_mnt.c | 146 ++ + .../selftests/filesystems/fuse/fusectl_test.c | 140 ++ + 224 files changed, 9632 insertions(+), 8985 deletions(-) + rename Documentation/filesystems/{ => fuse}/fuse-io-uring.rst (100%) + rename Documentation/filesystems/{ => fuse}/fuse-io.rst (99%) + rename Documentation/filesystems/{ => fuse}/fuse-passthrough.rst (100%) + rename Documentation/filesystems/{ => fuse}/fuse.rst (95%) + create mode 100644 Documentation/filesystems/fuse/index.rst + create mode 100644 tools/testing/selftests/filesystems/fuse/.gitignore + create mode 100644 tools/testing/selftests/filesystems/fuse/Makefile + create mode 100644 tools/testing/selftests/filesystems/fuse/fuse_mnt.c + create mode 100644 tools/testing/selftests/filesystems/fuse/fusectl_test.c +Merging printk/for-next (dcc3191a3dde Merge branch 'rework/ringbuffer-kunit-test' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git printk/for-next +Auto-merging init/Kconfig +Merge made by the 'ort' strategy. + init/Kconfig | 12 + + kernel/printk/.kunitconfig | 3 + + kernel/printk/Makefile | 2 + + kernel/printk/printk_ringbuffer.c | 5 + + kernel/printk/printk_ringbuffer_kunit_test.c | 315 +++++++++++++++++++++++++++ + 5 files changed, 337 insertions(+) + create mode 100644 kernel/printk/.kunitconfig + create mode 100644 kernel/printk/printk_ringbuffer_kunit_test.c +Merging pci/next (0bd0a41a5120 Merge tag 'pci-v6.17-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git pci/next +Already up to date. +Merging pstore/for-next/pstore (d679c2e1e8d9 pstore/zone: rewrite some comments for better understanding) +$ git merge -m Merge branch 'for-next/pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git pstore/for-next/pstore +Merge made by the 'ort' strategy. + fs/pstore/zone.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) +Merging hid/for-next (1330eb33bddc Merge branch 'for-6.17/core' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git hid/for-next +Merge made by the 'ort' strategy. +Merging i2c/i2c/for-next (976990f4120c Merge branch 'i2c/for-mergewindow' into i2c/for-next) +$ git merge -m Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/i2c/for-next +Merge made by the 'ort' strategy. + .../devicetree/bindings/i2c/apple,i2c.yaml | 5 ++ + drivers/i2c/busses/Kconfig | 1 - + drivers/i2c/busses/i2c-qcom-geni.c | 6 +- + drivers/i2c/busses/i2c-stm32f7.c | 32 +++++++---- + drivers/i2c/busses/i2c-tegra.c | 64 +++++++++++++++------- + drivers/i2c/i2c-core-acpi.c | 1 + + drivers/i2c/muxes/i2c-mux-mule.c | 3 +- + 7 files changed, 75 insertions(+), 37 deletions(-) +Merging i2c-host/i2c/i2c-host (85c34532849d i2c: qcom-geni: fix I2C frequency table to achieve accurate bus rates) +$ git merge -m Merge branch 'i2c/i2c-host' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c-host/i2c/i2c-host +Already up to date. +Merging i3c/i3c/next (3b661ca549b9 i3c: add missing include to internal header) +$ git merge -m Merge branch 'i3c/next' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux.git i3c/i3c/next +Already up to date. +Merging dmi/dmi-for-next (4d1b28a8119c firmware: dmi: Add info message for number of populated and total memory slots) +$ git merge -m Merge branch 'dmi-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging.git dmi/dmi-for-next +Already up to date. +Merging hwmon-staging/hwmon-next (de1fffd88600 dt-bindings: hwmon: Replace bouncing Alexandru Tachici emails) +$ git merge -m Merge branch 'hwmon-next' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-staging/hwmon-next +Already up to date. +Merging jc_docs/docs-next (35293ebbb65e scripts: add origin commit identification based on specific patterns) +$ git merge -m Merge branch 'docs-next' of git://git.lwn.net/linux.git jc_docs/docs-next +Already up to date. +Merging v4l-dvb/next (d968e50b5c26 media: rkvdec: Unstage the driver) +$ git merge -m Merge branch 'next' of git://linuxtv.org/media-ci/media-pending.git v4l-dvb/next +Already up to date. +Merging v4l-dvb-next/master (b36c41c51e9d media: atomisp: set lock before calling vb2_queue_init()) +$ git merge -m Merge branch 'master' of git://linuxtv.org/mchehab/media-next.git v4l-dvb-next/master +Already up to date. +Merging pm/linux-next (77d832285656 Merge branch 'pm-cpufreq' into linux-next) +$ git merge -m Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git pm/linux-next +Merge made by the 'ort' strategy. +Merging cpufreq-arm/cpufreq/arm/linux-next (bbd67be5546d cpufreq: mediatek-hw: Add support for MT8196) +$ git merge -m Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git cpufreq-arm/cpufreq/arm/linux-next +Merge made by the 'ort' strategy. + .../cpufreq/mediatek,mt8196-cpufreq-hw.yaml | 82 +++++++++++++ + drivers/cpufreq/mediatek-cpufreq-hw.c | 132 +++++++++++++++++---- + 2 files changed, 191 insertions(+), 23 deletions(-) + create mode 100644 Documentation/devicetree/bindings/cpufreq/mediatek,mt8196-cpufreq-hw.yaml +Merging cpupower/cpupower (e6c3f96141eb cpupower: Allow control of boost feature on non-x86 based systems with boost support.) +$ git merge -m Merge branch 'cpupower' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux.git cpupower/cpupower +Merge made by the 'ort' strategy. + tools/power/cpupower/man/cpupower-set.1 | 7 +-- + tools/power/cpupower/utils/cpufreq-info.c | 16 +++++- + tools/power/cpupower/utils/cpupower-set.c | 5 +- + tools/power/cpupower/utils/helpers/helpers.h | 14 ++--- + tools/power/cpupower/utils/helpers/misc.c | 76 ++++++++++++++++++++-------- + 5 files changed, 83 insertions(+), 35 deletions(-) +Merging devfreq/devfreq-next (7da2fdaaa1e6 PM / devfreq: Add HiSilicon uncore frequency scaling driver) +$ git merge -m Merge branch 'devfreq-next' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git devfreq/devfreq-next +Already up to date. +Merging pmdomain/next (05e35bd07d56 pmdomain: qcom: rpmhpd: Add Glymur RPMh Power Domains) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git pmdomain/next +Already up to date. +Merging opp/opp/linux-next (22679d807dea rust: opp: use c_* types via kernel prelude) +$ git merge -m Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git opp/opp/linux-next +Already up to date. +Merging thermal/thermal/linux-next (1d264d3a1988 dt-bindings: thermal: tegra: Document Tegra210B01) +$ git merge -m Merge branch 'thermal/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git thermal/thermal/linux-next +Already up to date. +Merging rdma/for-next (ee235923d205 RDMA/siw: Change maintainer email address) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git rdma/for-next +Already up to date. +Merging net-next/main (d9104cec3e8f Merge tag 'bpf-next-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next) +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git net-next/main +Already up to date. +Merging bpf-next/for-next (821c9e515db5 Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git bpf-next/for-next +Already up to date. +Merging ipsec-next/master (95cfe23285a6 xfrm: Skip redundant statistics update for crypto offload) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git ipsec-next/master +Already up to date. +Merging mlx5-next/mlx5-next (888a7776f4fb net/mlx5: Add support for device steering tag) +$ git merge -m Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git mlx5-next/mlx5-next +Already up to date. +Merging netfilter-next/main (e3f96b3556e4 Merge branch 'net-dsa-microchip-add-ksz8463-switch-support') +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git netfilter-next/main +Already up to date. +Merging ipvs-next/main (e3f96b3556e4 Merge branch 'net-dsa-microchip-add-ksz8463-switch-support') +$ git merge -m Merge branch 'main' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git ipvs-next/main +Already up to date. +Merging bluetooth/master (df18778595f9 Bluetooth: btintel_pcie: Define hdev->wakeup() callback) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git bluetooth/master +Merge made by the 'ort' strategy. + drivers/bluetooth/btintel.c | 3 ++ + drivers/bluetooth/btintel_pcie.c | 103 +++++++++++++++++++++++++++++++++++++++ + drivers/bluetooth/btmtk.c | 7 +-- + drivers/bluetooth/btusb.c | 2 + + net/bluetooth/hci_conn.c | 14 +++++- + net/bluetooth/hci_event.c | 7 ++- + net/bluetooth/hci_sync.c | 9 ++-- + net/bluetooth/iso.c | 2 +- + 8 files changed, 134 insertions(+), 13 deletions(-) +Merging wireless-next/for-next (126d85fb0405 Merge tag 'wireless-next-2025-07-24' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git wireless-next/for-next +Already up to date. +Merging ath-next/for-next (708243c62efd wifi: mac80211: fix unassigned variable access) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git ath-next/for-next +Already up to date. +Merging iwlwifi-next/next (d2af710d6d50 wifi: iwlwifi: mvm/fw: Avoid -Wflex-array-member-not-at-end warnings) +$ git merge -m Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git iwlwifi-next/next +Already up to date. +Merging wpan-next/master (1dd9291eb903 ieee802154: Remove WARN_ON() in cfg802154_pernet_exit()) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan-next.git wpan-next/master +Merge made by the 'ort' strategy. + net/ieee802154/core.c | 49 ++++++++++++++++++++++++++++--------------------- + 1 file changed, 28 insertions(+), 21 deletions(-) +Merging wpan-staging/staging (1dd9291eb903 ieee802154: Remove WARN_ON() in cfg802154_pernet_exit()) +$ git merge -m Merge branch 'staging' of git://git.kernel.org/pub/scm/linux/kernel/git/wpan/wpan-next.git wpan-staging/staging +Already up to date. +Merging mtd/mtd/next (9cf9db888f38 Merge tag 'nand/for-6.17' into mtd/next) +$ git merge -m Merge branch 'mtd/next' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/mtd/next +Already up to date. +Merging nand/nand/next (fb2fae70e7e9 mtd: spinand: winbond: Add comment about the maximum frequency) +$ git merge -m Merge branch 'nand/next' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/nand/next +Already up to date. +Merging spi-nor/spi-nor/next (2e3a7476ec39 mtd: spi-nor: Fix spi_nor_try_unlock_all()) +$ git merge -m Merge branch 'spi-nor/next' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git spi-nor/spi-nor/next +Already up to date. +Merging crypto/master (9d9b193ed73a crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390)) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git crypto/master +Already up to date. +Merging libcrypto/libcrypto-next (2a1a127aecf6 Merge branches 'libcrypto-conversions' and 'libcrypto-tests' into libcrypto-next) +$ git merge -m Merge branch 'libcrypto-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git libcrypto/libcrypto-next +Merge made by the 'ort' strategy. +Merging drm/drm-next (6531a2cf07ef Merge tag 'drm-xe-next-fixes-2025-07-31' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next) +$ git merge -m Merge branch 'drm-next' of https://gitlab.freedesktop.org/drm/kernel.git drm/drm-next +Already up to date. +Merging drm-exynos/for-linux-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git drm-exynos/for-linux-next +Already up to date. +Merging drm-misc/for-linux-next (584460393efb drm/bridge: Describe the newly introduced drm_connector parameter for drm_bridge_detect) +$ git merge -m Merge branch 'for-linux-next' of https://gitlab.freedesktop.org/drm/misc/kernel.git drm-misc/for-linux-next +Merge made by the 'ort' strategy. + drivers/gpu/drm/bridge/aux-bridge.c | 2 ++ + drivers/gpu/drm/drm_bridge.c | 1 + + 2 files changed, 3 insertions(+) +Merging amdgpu/drm-next (1c2efae2f855 drm/amd/pm: Make static table support conditional) +$ git merge -m Merge branch 'drm-next' of https://gitlab.freedesktop.org/agd5f/linux amdgpu/drm-next +Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +Auto-merging drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +Auto-merging drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +Merge made by the 'ort' strategy. + .../gpu/amdgpu/amd-hardware-list-info.rst | 4 +- + Documentation/gpu/amdgpu/apu-asic-info-table.csv | 34 +-- + Documentation/gpu/amdgpu/dgpu-asic-info-table.csv | 58 +++-- + Documentation/gpu/amdgpu/display/dc-glossary.rst | 2 +- + .../gpu/amdgpu/display/display-contributing.rst | 4 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c | 51 ++-- + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 7 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c | 8 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 20 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 45 ++-- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 26 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 37 +-- + drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h | 1 - + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 15 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 7 - + drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c | 3 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 282 +++++++++++++++++---- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 21 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 6 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 11 + + drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 8 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 87 +++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 8 + + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 17 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 4 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 38 +++ + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 17 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c | 1 + + drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 5 +- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 3 + + drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c | 12 + + drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.h | 1 + + drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 57 ++--- + drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 57 ++--- + drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 47 ++-- + drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 4 +- + drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 4 +- + drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 10 +- + drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 61 +++-- + drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c | 2 +- + drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 23 +- + drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c | 57 +++-- + drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c | 121 ++++++++- + drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 2 +- + drivers/gpu/drm/amd/amdgpu/soc15.c | 2 + + drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 89 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 93 ++----- + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 88 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 90 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 92 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c | 90 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c | 96 +------ + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h | 5 - + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 72 +++++- + .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 2 +- + drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 61 ++++- + .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 20 +- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 13 +- + drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c | 56 +++- + drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h | 1 + + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 105 +++++--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 15 ++ + .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 2 +- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 9 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 35 ++- + .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.h | 1 + + .../amd/display/amdgpu_dm/amdgpu_dm_irq_params.h | 1 + + .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 10 +- + .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.h | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 1 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 2 +- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_replay.c | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_replay.h | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_services.c | 1 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_trace.h | 1 + + drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 1 - + .../amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 5 + + .../drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 16 ++ + drivers/gpu/drm/amd/display/dc/core/dc.c | 182 ++++--------- + .../gpu/drm/amd/display/dc/core/dc_link_exports.c | 7 + + drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 8 +- + drivers/gpu/drm/amd/display/dc/dc.h | 73 +++++- + drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 4 +- + drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 16 +- + drivers/gpu/drm/amd/display/dc/dc_helper.c | 2 +- + drivers/gpu/drm/amd/display/dc/dc_types.h | 14 + + drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c | 56 ++-- + drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h | 2 +- + .../gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c | 20 +- + .../drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c | 31 +++ + .../drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h | 6 + + .../drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c | 2 + + .../drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c | 2 + + .../drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c | 2 + + .../amd/display/dc/hubbub/dcn401/dcn401_hubbub.c | 2 + + .../gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h | 9 +- + .../gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h | 1 + + .../gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c | 26 ++ + .../gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h | 8 +- + .../gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c | 15 ++ + .../gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h | 6 +- + .../gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c | 3 + + .../gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c | 3 + + .../drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c | 41 +++ + .../drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h | 8 +- + .../drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 39 ++- + .../drm/amd/display/dc/hwss/dce110/dce110_hwseq.h | 7 + + .../drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c | 63 ++++- + .../drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c | 2 + + .../drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c | 48 ++++ + .../drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h | 5 + + .../gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c | 1 + + .../gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c | 1 + + .../drm/amd/display/dc/hwss/dcn314/dcn314_init.c | 1 + + .../gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c | 1 + + .../gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c | 1 + + .../drm/amd/display/dc/hwss/dcn351/dcn351_init.c | 1 + + .../drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 34 ++- + .../drm/amd/display/dc/hwss/dcn401/dcn401_init.c | 1 + + drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h | 4 + + drivers/gpu/drm/amd/display/dc/inc/core_types.h | 7 +- + drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 2 + + drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 21 +- + drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 11 + + drivers/gpu/drm/amd/display/dc/inc/link.h | 5 +- + .../amd/display/dc/link/accessories/link_dp_cts.c | 30 ++- + drivers/gpu/drm/amd/display/dc/link/link_dpms.c | 3 - + drivers/gpu/drm/amd/display/dc/link/link_factory.c | 2 + + .../gpu/drm/amd/display/dc/link/link_validation.c | 6 +- + .../display/dc/link/protocols/link_dp_capability.c | 37 +++ + .../display/dc/link/protocols/link_dp_capability.h | 6 + + .../display/dc/link/protocols/link_dp_dpia_bw.c | 71 +++--- + .../display/dc/link/protocols/link_dp_training.c | 9 +- + .../dc/link/protocols/link_edp_panel_control.c | 10 +- + .../amd/display/dc/resource/dce60/dce60_resource.c | 34 ++- + .../amd/display/dc/resource/dcn31/dcn31_resource.c | 5 +- + .../amd/display/dc/resource/dcn31/dcn31_resource.h | 3 +- + .../amd/display/dc/resource/dcn32/dcn32_resource.h | 3 +- + .../display/dc/resource/dcn401/dcn401_resource.c | 1 + + .../display/dc/resource/dcn401/dcn401_resource.h | 3 +- + .../display/dc/virtual/virtual_stream_encoder.c | 7 + + drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 1 + + drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 114 ++++++--- + drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 1 + + drivers/gpu/drm/amd/display/include/dal_asic_id.h | 5 + + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 16 ++ + drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 2 +- + drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 2 +- + .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 30 ++- + 159 files changed, 2171 insertions(+), 1412 deletions(-) +Merging drm-intel/for-linux-next (5a569ef4d4ab drm/i915/display: Set C10_VDR_CTRL_MSGBUS_ACCESS before phy reg read) +$ git merge -m Merge branch 'for-linux-next' of https://gitlab.freedesktop.org/drm/i915/kernel drm-intel/for-linux-next +Merge made by the 'ort' strategy. + drivers/gpu/drm/i915/display/intel_cx0_phy.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) +Merging drm-msm/msm-next (8290d37ad2b0 drm/msm: Small function param doc fix) +$ git merge -m Merge branch 'msm-next' of https://gitlab.freedesktop.org/drm/msm.git drm-msm/msm-next +Already up to date. +Merging drm-msm-lumag/msm-next-lumag (cd86e80b77b2 drm/msm/dp: add linux/io.h header to fix build errors) +$ git merge -m Merge branch 'msm-next-lumag' of https://gitlab.freedesktop.org/lumag/msm.git drm-msm-lumag/msm-next-lumag +Already up to date. +Merging drm-nova/nova-next (14ae91a81ec8 gpu: nova-core: fix bounds check in PmuLookupTableEntry::new) +$ git merge -m Merge branch 'nova-next' of https://gitlab.freedesktop.org/drm/nova.git drm-nova/nova-next +Already up to date. +Merging drm-xe/drm-xe-next (bcddb12c0274 drm/xe: Extend wa_13012615864 to additional Xe2 and Xe3 platforms) +$ git merge -m Merge branch 'drm-xe-next' of https://gitlab.freedesktop.org/drm/xe/kernel drm-xe/drm-xe-next +Auto-merging drivers/gpu/drm/xe/Makefile +Auto-merging drivers/gpu/drm/xe/display/xe_fb_pin.c +Auto-merging drivers/gpu/drm/xe/display/xe_plane_initial.c +Auto-merging drivers/gpu/drm/xe/xe_configfs.c +Auto-merging drivers/gpu/drm/xe/xe_device.c +Auto-merging drivers/gpu/drm/xe/xe_guc_submit.c +Auto-merging drivers/gpu/drm/xe/xe_hw_engine_group.c +Merge made by the 'ort' strategy. + drivers/gpu/drm/xe/Kconfig | 1 + + drivers/gpu/drm/xe/Makefile | 4 + + drivers/gpu/drm/xe/abi/guc_actions_abi.h | 8 + + drivers/gpu/drm/xe/abi/guc_errors_abi.h | 3 + + drivers/gpu/drm/xe/abi/guc_klvs_abi.h | 1 + + drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +- + drivers/gpu/drm/xe/display/xe_plane_initial.c | 3 +- + drivers/gpu/drm/xe/instructions/xe_mi_commands.h | 1 + + drivers/gpu/drm/xe/regs/xe_engine_regs.h | 3 + + drivers/gpu/drm/xe/regs/xe_gt_regs.h | 2 +- + drivers/gpu/drm/xe/regs/xe_pmt.h | 10 + + drivers/gpu/drm/xe/xe_assert.h | 4 +- + drivers/gpu/drm/xe/xe_bb.c | 35 +++ + drivers/gpu/drm/xe/xe_bb.h | 3 + + drivers/gpu/drm/xe/xe_bo.c | 52 +++- + drivers/gpu/drm/xe/xe_bo.h | 4 +- + drivers/gpu/drm/xe/xe_bo_types.h | 4 + + drivers/gpu/drm/xe/xe_configfs.c | 15 +- + drivers/gpu/drm/xe/xe_debugfs.c | 107 +++++++ + drivers/gpu/drm/xe/xe_dep_job_types.h | 29 ++ + drivers/gpu/drm/xe/xe_dep_scheduler.c | 143 +++++++++ + drivers/gpu/drm/xe/xe_dep_scheduler.h | 21 ++ + drivers/gpu/drm/xe/xe_device.c | 32 +- + drivers/gpu/drm/xe/xe_device_types.h | 69 +---- + drivers/gpu/drm/xe/xe_exec_queue.c | 96 ++++++ + drivers/gpu/drm/xe/xe_exec_queue.h | 4 + + drivers/gpu/drm/xe/xe_exec_queue_types.h | 15 + + drivers/gpu/drm/xe/xe_ggtt.c | 3 +- + drivers/gpu/drm/xe/xe_gpu_scheduler.c | 13 + + drivers/gpu/drm/xe/xe_gpu_scheduler.h | 1 + + drivers/gpu/drm/xe/xe_gt.c | 16 +- + drivers/gpu/drm/xe/xe_gt_debugfs.c | 56 +++- + drivers/gpu/drm/xe/xe_gt_mcr.c | 4 +- + drivers/gpu/drm/xe/xe_gt_pagefault.c | 13 +- + drivers/gpu/drm/xe/xe_gt_sriov_pf.c | 79 ++++- + drivers/gpu/drm/xe/xe_gt_sriov_pf.h | 1 + + drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 13 +- + drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c | 4 +- + drivers/gpu/drm/xe/xe_gt_sriov_vf.c | 14 + + drivers/gpu/drm/xe/xe_gt_sriov_vf.h | 1 + + drivers/gpu/drm/xe/xe_gt_tlb_inval_job.c | 274 +++++++++++++++++ + drivers/gpu/drm/xe/xe_gt_tlb_inval_job.h | 34 +++ + drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 + + drivers/gpu/drm/xe/xe_gt_types.h | 2 + + drivers/gpu/drm/xe/xe_guc.c | 19 +- + drivers/gpu/drm/xe/xe_guc_ads.c | 35 +++ + drivers/gpu/drm/xe/xe_guc_buf.c | 2 +- + drivers/gpu/drm/xe/xe_guc_capture.c | 6 + + drivers/gpu/drm/xe/xe_guc_fwif.h | 5 + + drivers/gpu/drm/xe/xe_guc_submit.c | 209 ++++++++++++- + drivers/gpu/drm/xe/xe_guc_submit.h | 10 + + drivers/gpu/drm/xe/xe_guc_types.h | 6 + + drivers/gpu/drm/xe/xe_hw_engine_group.c | 4 +- + drivers/gpu/drm/xe/xe_lrc.c | 172 ++++++++++- + drivers/gpu/drm/xe/xe_lrc.h | 9 + + drivers/gpu/drm/xe/xe_migrate.c | 301 +++++++++++++++--- + drivers/gpu/drm/xe/xe_migrate.h | 24 +- + drivers/gpu/drm/xe/xe_mmio_gem.c | 226 ++++++++++++++ + drivers/gpu/drm/xe/xe_mmio_gem.h | 20 ++ + drivers/gpu/drm/xe/xe_module.c | 8 +- + drivers/gpu/drm/xe/xe_pci.c | 11 + + drivers/gpu/drm/xe/xe_pci_sriov.c | 7 +- + drivers/gpu/drm/xe/xe_pm.c | 4 + + drivers/gpu/drm/xe/xe_pt.c | 178 +++++------ + drivers/gpu/drm/xe/xe_query.c | 9 +- + drivers/gpu/drm/xe/xe_ring_ops.c | 8 +- + drivers/gpu/drm/xe/xe_sa.c | 1 - + drivers/gpu/drm/xe/xe_sa.h | 15 +- + drivers/gpu/drm/xe/xe_sa_types.h | 1 - + drivers/gpu/drm/xe/xe_sriov.c | 19 ++ + drivers/gpu/drm/xe/xe_sriov.h | 1 + + drivers/gpu/drm/xe/xe_sriov_pf.c | 27 ++ + drivers/gpu/drm/xe/xe_sriov_pf.h | 1 + + drivers/gpu/drm/xe/xe_sriov_vf.c | 78 ++++- + drivers/gpu/drm/xe/xe_sriov_vf_ccs.c | 372 +++++++++++++++++++++++ + drivers/gpu/drm/xe/xe_sriov_vf_ccs.h | 17 ++ + drivers/gpu/drm/xe/xe_sriov_vf_ccs_types.h | 53 ++++ + drivers/gpu/drm/xe/xe_sriov_vf_types.h | 6 + + drivers/gpu/drm/xe/xe_svm.c | 63 ++-- + drivers/gpu/drm/xe/xe_tile.c | 62 ++-- + drivers/gpu/drm/xe/xe_tile.h | 14 +- + drivers/gpu/drm/xe/xe_trace.h | 16 - + drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c | 10 +- + drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 22 +- + drivers/gpu/drm/xe/xe_ttm_vram_mgr.h | 3 +- + drivers/gpu/drm/xe/xe_vm.c | 6 +- + drivers/gpu/drm/xe/xe_vram.c | 211 +++++++++---- + drivers/gpu/drm/xe/xe_vram.h | 11 + + drivers/gpu/drm/xe/xe_vram_types.h | 85 ++++++ + drivers/gpu/drm/xe/xe_wa.c | 13 +- + drivers/gpu/drm/xe/xe_wa_oob.rules | 3 + + include/uapi/drm/xe_drm.h | 6 +- + 92 files changed, 3133 insertions(+), 466 deletions(-) + create mode 100644 drivers/gpu/drm/xe/xe_dep_job_types.h + create mode 100644 drivers/gpu/drm/xe/xe_dep_scheduler.c + create mode 100644 drivers/gpu/drm/xe/xe_dep_scheduler.h + create mode 100644 drivers/gpu/drm/xe/xe_gt_tlb_inval_job.c + create mode 100644 drivers/gpu/drm/xe/xe_gt_tlb_inval_job.h + create mode 100644 drivers/gpu/drm/xe/xe_mmio_gem.c + create mode 100644 drivers/gpu/drm/xe/xe_mmio_gem.h + create mode 100644 drivers/gpu/drm/xe/xe_sriov_vf_ccs.c + create mode 100644 drivers/gpu/drm/xe/xe_sriov_vf_ccs.h + create mode 100644 drivers/gpu/drm/xe/xe_sriov_vf_ccs_types.h + create mode 100644 drivers/gpu/drm/xe/xe_vram_types.h +Merging etnaviv/etnaviv/next (6bde14ba5f7e drm/etnaviv: add optional reset support) +$ git merge -m Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux etnaviv/etnaviv/next +Already up to date. +Merging fbdev/for-next (e4fc307d8e24 Revert "vgacon: Add check for vc_origin address range in vgacon_scroll()") +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev.git fbdev/for-next +Auto-merging drivers/video/fbdev/core/fbcon.c +Merge made by the 'ort' strategy. + drivers/video/console/vgacon.c | 2 +- + drivers/video/fbdev/core/fbcon.c | 9 +++++---- + 2 files changed, 6 insertions(+), 5 deletions(-) +Merging regmap/for-next (067aa458a064 Merge remote-tracking branch 'regmap/for-6.16' into regmap-linus) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git regmap/for-next +Already up to date. +Merging sound/for-next (dbe05428c4e5 ALSA: hda/realtek: add LG gram 16Z90R-A to alc269 fixup table) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git sound/for-next +Already up to date. +Merging ieee1394/for-next (95a042a0c8ec firewire: ohci: reduce the size of common context structure by extracting members into AT structure) +$ git merge -m Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git ieee1394/for-next +Already up to date. +Merging sound-asoc/for-next (282528da82a0 Merge remote-tracking branch 'asoc/for-6.16' into asoc-linus) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git sound-asoc/for-next +Already up to date. +Merging modules/modules-next (40a826bd6c82 module: Rename MAX_PARAM_PREFIX_LEN to __MODULE_NAME_LEN) +$ git merge -m Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux.git modules/modules-next +Already up to date. +Merging input/next (a7bee4e7f780 Merge tag 'ib-mfd-gpio-input-pwm-v6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into next) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git input/next +Auto-merging MAINTAINERS +Auto-merging drivers/hid/hid-debug.c +Auto-merging drivers/input/joystick/xpad.c +Auto-merging drivers/input/keyboard/atkbd.c +Auto-merging drivers/input/misc/cs40l50-vibra.c +Merge made by the 'ort' strategy. + .../devicetree/bindings/input/syna,rmi4.yaml | 20 ++ + .../bindings/input/touchscreen/edt-ft5x06.yaml | 1 + + .../bindings/input/touchscreen/lpc32xx-tsc.txt | 16 -- + .../input/touchscreen/nxp,lpc3220-tsc.yaml | 43 ++++ + .../input/touchscreen/sitronix,st1232.yaml | 29 +++ + .../bindings/input/touchscreen/ti.tsc2007.yaml | 75 ++++++ + .../bindings/input/touchscreen/touchscreen.yaml | 119 +++++++++ + .../bindings/input/touchscreen/tsc2007.txt | 39 --- + Documentation/input/devices/edt-ft5x06.rst | 21 +- + Documentation/input/gamepad.rst | 19 +- + Documentation/userspace-api/media/rc/rc-protos.rst | 4 +- + MAINTAINERS | 7 + + drivers/hid/hid-debug.c | 2 + + drivers/input/Makefile | 2 +- + drivers/input/evdev.c | 8 +- + drivers/input/input.c | 2 +- + drivers/input/joystick/xpad.c | 64 ++--- + drivers/input/keyboard/adp5588-keys.c | 9 +- + drivers/input/keyboard/atkbd.c | 12 +- + drivers/input/keyboard/mtk-pmic-keys.c | 17 ++ + drivers/input/keyboard/samsung-keypad.c | 137 +++++----- + drivers/input/misc/Kconfig | 7 - + drivers/input/misc/Makefile | 1 - + drivers/input/misc/cs40l50-vibra.c | 1 - + drivers/input/misc/max77693-haptic.c | 41 ++- + drivers/input/misc/max8997_haptic.c | 98 ++++---- + drivers/input/misc/pcf50633-input.c | 113 --------- + drivers/input/rmi4/Kconfig | 15 ++ + drivers/input/rmi4/Makefile | 2 + + drivers/input/rmi4/rmi_bus.c | 6 + + drivers/input/rmi4/rmi_driver.h | 2 + + drivers/input/rmi4/rmi_f1a.c | 143 +++++++++++ + drivers/input/rmi4/rmi_f21.c | 179 +++++++++++++ + drivers/input/touch-overlay.c | 277 +++++++++++++++++++++ + drivers/input/touchscreen/ad7879.c | 11 +- + drivers/input/touchscreen/edt-ft5x06.c | 26 +- + drivers/input/touchscreen/goodix.c | 50 +++- + drivers/input/touchscreen/st1232.c | 35 ++- + include/linux/input/touch-overlay.h | 25 ++ + include/uapi/linux/input-event-codes.h | 5 + + 40 files changed, 1277 insertions(+), 406 deletions(-) + delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/lpc32xx-tsc.txt + create mode 100644 Documentation/devicetree/bindings/input/touchscreen/nxp,lpc3220-tsc.yaml + create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ti.tsc2007.yaml + delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt + delete mode 100644 drivers/input/misc/pcf50633-input.c + create mode 100644 drivers/input/rmi4/rmi_f1a.c + create mode 100644 drivers/input/rmi4/rmi_f21.c + create mode 100644 drivers/input/touch-overlay.c + create mode 100644 include/linux/input/touch-overlay.h +Merging block/for-next (20c74c073217 Merge branch 'block-6.17' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.dk/linux-block.git block/for-next +Auto-merging drivers/md/dm-raid.c +Merge made by the 'ort' strategy. + block/bfq-iosched.c | 31 +----- + block/bfq-iosched.h | 10 +- + block/blk-ioc.c | 16 ++- + block/blk-mq-sched.c | 223 ++++++++++++++++++++++++++++------------- + block/blk-mq-sched.h | 12 ++- + block/blk-mq.c | 16 ++- + block/blk-settings.c | 33 ++++-- + block/blk.h | 4 +- + block/elevator.c | 38 +++++-- + block/elevator.h | 16 ++- + block/kyber-iosched.c | 11 +- + block/mq-deadline.c | 14 +-- + drivers/block/zloop.c | 3 +- + drivers/md/dm-raid.c | 42 ++++---- + drivers/md/md-bitmap.c | 8 +- + drivers/md/md-cluster.c | 16 +-- + drivers/md/md.c | 73 ++++++++------ + drivers/md/md.h | 2 +- + drivers/md/raid0.c | 6 +- + drivers/md/raid1-10.c | 2 +- + drivers/md/raid1.c | 94 +++++++---------- + drivers/md/raid1.h | 22 +--- + drivers/md/raid10.c | 16 +-- + drivers/md/raid5-ppl.c | 6 +- + drivers/md/raid5.c | 30 +++--- + drivers/nvme/host/auth.c | 4 +- + drivers/nvme/host/core.c | 16 +++ + drivers/nvme/host/fc.c | 4 +- + drivers/nvme/host/pci.c | 2 +- + drivers/nvme/host/tcp.c | 2 +- + drivers/nvme/target/core.c | 16 +-- + drivers/nvme/target/fc.c | 6 +- + drivers/nvme/target/passthru.c | 2 + + drivers/nvme/target/rdma.c | 6 +- + include/linux/ioprio.h | 3 +- + include/uapi/linux/io_uring.h | 4 + + include/uapi/linux/raid/md_p.h | 2 +- + io_uring/net.c | 9 +- + 38 files changed, 465 insertions(+), 355 deletions(-) +Merging device-mapper/for-next (55a0fbd2ac3f dm: set DM_TARGET_PASSES_CRYPTO feature for dm-thin) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git device-mapper/for-next +Already up to date. +Merging libata/for-next (6cb43739b93c ata: pata_pdc2027x: Remove space before newline and abbreviations) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux libata/for-next +Merge made by the 'ort' strategy. + drivers/ata/ata_piix.c | 1 + + drivers/ata/libahci.c | 1 + + drivers/ata/libata-core.c | 2 +- + drivers/ata/libata-sata.c | 53 +++++++++++++++++++++++++++++++++++---------- + drivers/ata/libata-scsi.c | 38 ++++++++++++++++---------------- + drivers/ata/pata_macio.c | 2 +- + drivers/ata/pata_pdc2027x.c | 12 +++++----- + include/linux/libata.h | 1 + + 8 files changed, 71 insertions(+), 39 deletions(-) +Merging pcmcia/pcmcia-next (0630e3bc0e91 pcmcia: add missing MODULE_DESCRIPTION() macros) +$ git merge -m Merge branch 'pcmcia-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git pcmcia/pcmcia-next +Already up to date. +Merging mmc/next (4b290aae788e Merge tag 'sysctl-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git mmc/next +Already up to date. +Merging mfd/for-mfd-next (b6bf74c82178 mfd: dt-bindings: Convert TPS65910 to DT schema) +$ git merge -m Merge branch 'for-mfd-next' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git mfd/for-mfd-next +Auto-merging drivers/mfd/Kconfig +Merge made by the 'ort' strategy. + drivers/mfd/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) +Merging backlight/for-backlight-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-backlight-next' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git backlight/for-backlight-next +Already up to date. +Merging battery/for-next (7b41a2341fa6 power: supply: core: fix static checker warning) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git battery/for-next +Already up to date. +Merging regulator/for-next (10dfd36f0784 regulator: core: correct convergence check in regulator_set_voltage()) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git regulator/for-next +Already up to date. +Merging security/next (5d8b97c94677 MAINTAINERS: Add Xiu and myself as Lockdown maintainers) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git security/next +Already up to date. +Merging apparmor/apparmor-next (5f49c2d1f422 apparmor: fix: oops when trying to free null ruleset) +$ git merge -m Merge branch 'apparmor-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor apparmor/apparmor-next +Already up to date. +Merging integrity/next-integrity (aa9bb1b32594 ima: add a knob ima= to allow disabling IMA in kdump kernel) +$ git merge -m Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity integrity/next-integrity +Already up to date. +Merging selinux/next (850dada4b3af Automated merge of 'dev' into 'next') +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git selinux/next +Merge made by the 'ort' strategy. +Merging smack/next (6ddd169d0288 smack: fix kernel-doc warnings for smk_import_valid_label()) +$ git merge -m Merge branch 'next' of git://github.com/cschaufler/smack-next smack/next +Merge made by the 'ort' strategy. + Documentation/admin-guide/LSM/Smack.rst | 16 +- + security/smack/smack.h | 3 + + security/smack/smack_access.c | 95 ++++++++--- + security/smack/smack_lsm.c | 277 +++++++++++++++++++++----------- + 4 files changed, 273 insertions(+), 118 deletions(-) +Merging tomoyo/master (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'master' of git://git.code.sf.net/p/tomoyo/tomoyo.git tomoyo/master +Already up to date. +Merging tpmdd/next (7f0c6675b319 tpm_crb_ffa: handle tpm busy return code) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tpmdd/next +Already up to date. +Merging watchdog/master (48defdf6b083 watchdog: sbsa: Adjust keepalive timeout to avoid MediaTek WS0 race condition) +$ git merge -m Merge branch 'master' of git://www.linux-watchdog.org/linux-watchdog-next.git watchdog/master +Already up to date. +Merging iommu/next (b9e6e8ae0a5f Merge branch 'arm/smmu/updates' into next) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux.git iommu/next +Already up to date. +Merging audit/next (ae1ae11fb277 audit,module: restore audit logging in load failure case) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git audit/next +Already up to date. +Merging devicetree/for-next (0121898ec05f dt-bindings: Correct indentation and style in DTS example) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git devicetree/for-next +Already up to date. +Merging dt-krzk/for-next (6cd594ed969d ARM: dts: vt8500: Add L2 cache controller on WM8850/WM8950) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-dt.git dt-krzk/for-next +Already up to date. +Merging mailbox/for-next (872798f61d8b dt-bindings: mailbox: qcom-ipcc: document the SM7635 Inter-Processor Communication Controller) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox.git mailbox/for-next +Auto-merging Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.yaml +Auto-merging drivers/mailbox/Kconfig +CONFLICT (content): Merge conflict in drivers/mailbox/Kconfig +Auto-merging drivers/mailbox/Makefile +CONFLICT (content): Merge conflict in drivers/mailbox/Makefile +Resolved 'drivers/mailbox/Kconfig' using previous resolution. +Resolved 'drivers/mailbox/Makefile' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[master 8f18ef7a57ef] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jassibrar/mailbox.git +$ git diff -M --stat --summary HEAD^.. + .../mailbox/allwinner,sun6i-a31-msgbox.yaml | 14 +- + .../bindings/mailbox/amlogic,meson-gxbb-mhu.yaml | 10 +- + .../devicetree/bindings/mailbox/apple,mailbox.yaml | 16 +- + .../bindings/mailbox/brcm,bcm74110-mbox.yaml | 64 ++ + .../bindings/mailbox/nvidia,tegra186-hsp.yaml | 9 +- + .../bindings/mailbox/qcom,apcs-kpss-global.yaml | 9 +- + .../devicetree/bindings/mailbox/qcom-ipcc.yaml | 2 + + .../bindings/mailbox/ti,omap-mailbox.yaml | 10 +- + .../bindings/mailbox/ti,secure-proxy.yaml | 18 +- + drivers/mailbox/Kconfig | 10 + + drivers/mailbox/Makefile | 2 + + drivers/mailbox/bcm74110-mailbox.c | 656 +++++++++++++++++++++ + drivers/mailbox/mtk-cmdq-mailbox.c | 10 +- + drivers/mailbox/qcom-ipcc.c | 3 +- + 14 files changed, 774 insertions(+), 59 deletions(-) + create mode 100644 Documentation/devicetree/bindings/mailbox/brcm,bcm74110-mbox.yaml + create mode 100644 drivers/mailbox/bcm74110-mailbox.c +Merging spi/for-next (a49bfbecfde7 Merge remote-tracking branch 'spi/for-6.16' into spi-linus) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git spi/for-next +Already up to date. +Merging tip/master (40d6e791ba3a Merge branch into tip/master: 'timers/clocksource') +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git tip/master +Auto-merging arch/riscv/include/asm/bug.h +CONFLICT (content): Merge conflict in arch/riscv/include/asm/bug.h +Auto-merging arch/x86/include/asm/bug.h +CONFLICT (content): Merge conflict in arch/x86/include/asm/bug.h +Auto-merging drivers/of/irq.c +Auto-merging kernel/panic.c +Auto-merging lib/Kconfig.debug +Resolved 'arch/riscv/include/asm/bug.h' using previous resolution. +Resolved 'arch/x86/include/asm/bug.h' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[master c5ecd1e52ab4] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git +$ git diff -M --stat --summary HEAD^.. + .../devicetree/bindings/timer/faraday,fttmr010.txt | 38 --------- + .../bindings/timer/faraday,fttmr010.yaml | 89 ++++++++++++++++++++ + .../devicetree/bindings/timer/fsl,ftm-timer.yaml | 7 +- + .../devicetree/bindings/timer/fsl,timrot.yaml | 48 +++++++++++ + .../devicetree/bindings/timer/mediatek,timer.yaml | 2 + + arch/arm64/include/asm/bug.h | 2 +- + arch/loongarch/include/asm/bug.h | 27 +++--- + arch/parisc/include/asm/bug.h | 6 +- + arch/powerpc/include/asm/bug.h | 12 +-- + arch/riscv/include/asm/bug.h | 10 +-- + arch/s390/include/asm/bug.h | 96 +++++++++------------- + arch/sh/include/asm/bug.h | 4 +- + arch/x86/include/asm/bug.h | 12 +-- + drivers/clocksource/exynos_mct.c | 24 ++++-- + drivers/clocksource/scx200_hrt.c | 1 + + drivers/clocksource/timer-cs5535.c | 1 + + drivers/clocksource/timer-econet-en751221.c | 2 +- + drivers/clocksource/timer-nxp-stm.c | 2 + + drivers/clocksource/timer-stm32-lp.c | 1 + + drivers/clocksource/timer-sun5i.c | 2 + + drivers/clocksource/timer-tegra186.c | 30 ++++--- + drivers/of/irq.c | 1 + + include/asm-generic/bug.h | 13 ++- + kernel/panic.c | 16 ++-- + kernel/time/sched_clock.c | 4 +- + lib/Kconfig.debug | 10 +++ + 26 files changed, 299 insertions(+), 161 deletions(-) + delete mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.txt + create mode 100644 Documentation/devicetree/bindings/timer/faraday,fttmr010.yaml + create mode 100644 Documentation/devicetree/bindings/timer/fsl,timrot.yaml +Merging clockevents/timers/drivers/next (d7b8f8e20813 Linux 6.16-rc5) +$ git merge -m Merge branch 'timers/drivers/next' of git://git.kernel.org/pub/scm/linux/kernel/git/daniel.lezcano/linux.git clockevents/timers/drivers/next +Already up to date. +Merging edac/edac-for-next (1fb0ddddf5d1 Merge branch 'edac-drivers' into edac-for-next) +$ git merge -m Merge branch 'edac-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git edac/edac-for-next +Auto-merging drivers/edac/mem_repair.c +CONFLICT (content): Merge conflict in drivers/edac/mem_repair.c +Resolved 'drivers/edac/mem_repair.c' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[master a94726fef172] Merge branch 'edac-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git +$ git diff -M --stat --summary HEAD^.. + +Merging ftrace/for-next (39f069d5a466 Merge unwind/for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git ftrace/for-next +Merge made by the 'ort' strategy. +Merging rcu/next (cc1d1365f0f4 Merge branches 'rcu-exp.23.07.2025', 'rcu.22.07.2025', 'torture-scripts.16.07.2025', 'srcu.19.07.2025', 'rcu.nocb.18.07.2025' and 'refscale.07.07.2025' into rcu.merge.23.07.2025) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/next +Already up to date. +Merging paulmck/non-rcu/next (b706eec9304f Merge branches 'lkmm.2025.07.09a', 'ratelimit.2025.06.24a' and 'stop-machine.2025.07.17a' into HEAD) +$ git merge -m Merge branch 'non-rcu/next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git paulmck/non-rcu/next +Merge made by the 'ort' strategy. +Merging kvm/next (196d9e72c4b0 Merge tag 'kvm-s390-next-6.17-1' of https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/virt/kvm/kvm.git kvm/next +Already up to date. +Merging kvm-arm/next (7b8346bd9fce KVM: arm64: Don't attempt vLPI mappings when vPE allocation is disabled) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git kvm-arm/next +Merge made by the 'ort' strategy. + arch/arm64/kvm/vgic/vgic-mmio-v3.c | 8 ++++++++ + arch/arm64/kvm/vgic/vgic.h | 10 +--------- + 2 files changed, 9 insertions(+), 9 deletions(-) +Merging kvms390/next (57d88f02eb44 KVM: s390: Rework guest entry logic) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git kvms390/next +Already up to date. +Merging kvm-ppc/topic/ppc-kvm (fac04efc5c79 Linux 6.13-rc2) +$ git merge -m Merge branch 'topic/ppc-kvm' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git kvm-ppc/topic/ppc-kvm +Already up to date. +Merging kvm-riscv/riscv_kvm_next (07a289a03140 RISC-V: KVM: Avoid re-acquiring memslot in kvm_riscv_gstage_map()) +$ git merge -m Merge branch 'riscv_kvm_next' of https://github.com/kvm-riscv/linux.git kvm-riscv/riscv_kvm_next +Already up to date. +Merging kvm-x86/next (33f843444e28 Merge branch 'vmx') +$ git merge -m Merge branch 'next' of https://github.com/kvm-x86/linux.git kvm-x86/next +Merge made by the 'ort' strategy. + Documentation/virt/kvm/x86/intel-tdx.rst | 22 ++++++++++++++++++- + arch/x86/include/uapi/asm/kvm.h | 7 ++++++- + arch/x86/kvm/vmx/tdx.c | 36 +++++++++++++++++++++++++------- + 3 files changed, 55 insertions(+), 10 deletions(-) +Merging xen-tip/linux-next (114a2de6fa86 xen/netfront: Fix TX response spurious interrupts) +$ git merge -m Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git xen-tip/linux-next +Already up to date. +Merging percpu/for-next (87d6aab2389e Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/dennis/percpu.git percpu/for-next +Already up to date. +Merging workqueues/for-next (324cee0c272c Merge branch 'for-6.17' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git workqueues/for-next +Merge made by the 'ort' strategy. +Merging sched-ext/for-next (9f0744a0e87e Merge branch 'for-6.17' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext.git sched-ext/for-next +Merge made by the 'ort' strategy. +Merging drivers-x86/for-next (1798561befd8 platform/x86: oxpec: Add support for OneXPlayer X1 Mini Pro (Strix Point)) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git drivers-x86/for-next +Already up to date. +Merging chrome-platform/for-next (cc2d5b72b13b platform/chrome: Fix typo in CROS_USBPD_NOTIFY help text) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git chrome-platform/for-next +Already up to date. +Merging chrome-platform-firmware/for-firmware-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-firmware-next' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git chrome-platform-firmware/for-firmware-next +Already up to date. +Merging hsi/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git hsi/for-next +Already up to date. +Merging leds-lj/for-leds-next (4903924ac7ef dt-bindings: leds: ncp5623: Add 0x39 as a valid I2C address) +$ git merge -m Merge branch 'for-leds-next' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git leds-lj/for-leds-next +Already up to date. +Merging ipmi/for-next (ec50ec378e3f ipmi: Use dev_warn_ratelimited() for incorrect message warnings) +$ git merge -m Merge branch 'for-next' of git://github.com/cminyard/linux-ipmi.git ipmi/for-next +Auto-merging drivers/char/ipmi/ipmi_si_intf.c +Merge made by the 'ort' strategy. + drivers/char/ipmi/ipmi_msghandler.c | 8 ++--- + drivers/char/ipmi/ipmi_si_intf.c | 4 --- + drivers/char/ipmi/ipmi_watchdog.c | 59 ++++++++++++++++++++++++++----------- + 3 files changed, 46 insertions(+), 25 deletions(-) +Merging driver-core/driver-core-next (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git driver-core/driver-core-next +Already up to date. +Merging usb/usb-next (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb/usb-next +Already up to date. +Merging thunderbolt/next (2d1beba54fda thunderbolt: Fix typos in documentation comments) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git thunderbolt/next +Already up to date. +Merging usb-serial/usb-next (bdf2ab177e2f USB: serial: cp210x: use new GPIO line value setter callbacks) +$ git merge -m Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git usb-serial/usb-next +Already up to date. +Merging tty/tty-next (89748acdf226 Merge tag 'drm-next-2025-08-01' of https://gitlab.freedesktop.org/drm/kernel) +$ git merge -m Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty/tty-next +Already up to date. +Merging char-misc/char-misc-next (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'char-misc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc/char-misc-next +Already up to date. +Merging accel/habanalabs-next (f03eee5fc922 Merge tag 'drm-xe-next-fixes-2024-05-02' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next) +$ git merge -m Merge branch 'habanalabs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/linux.git accel/habanalabs-next +Already up to date. +Merging coresight/next (a80198ba650f coresight: fix indentation error in cscfg_remove_owned_csdev_configs()) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git coresight/next +Merge made by the 'ort' strategy. + .../bindings/arm/qcom,coresight-tnoc.yaml | 113 ++++++++++ + drivers/hwtracing/coresight/Kconfig | 12 + + drivers/hwtracing/coresight/Makefile | 1 + + drivers/hwtracing/coresight/coresight-core.c | 6 +- + drivers/hwtracing/coresight/coresight-etm-perf.c | 4 +- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 + + .../hwtracing/coresight/coresight-etm4x-sysfs.c | 1 + + drivers/hwtracing/coresight/coresight-stm.c | 8 +- + drivers/hwtracing/coresight/coresight-syscfg.c | 2 +- + drivers/hwtracing/coresight/coresight-tmc-core.c | 22 +- + drivers/hwtracing/coresight/coresight-tnoc.c | 242 +++++++++++++++++++++ + drivers/hwtracing/coresight/coresight-trbe.c | 1 + + drivers/hwtracing/coresight/ultrasoc-smb.h | 1 + + 13 files changed, 389 insertions(+), 25 deletions(-) + create mode 100644 Documentation/devicetree/bindings/arm/qcom,coresight-tnoc.yaml + create mode 100644 drivers/hwtracing/coresight/coresight-tnoc.c +Merging fastrpc/for-next (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/srini/fastrpc.git fastrpc/for-next +Already up to date. +Merging fpga/for-next (37e00703228a zynq_fpga: use sgtable-based scatterlist wrappers) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git fpga/for-next +Already up to date. +Merging icc/icc-next (ca652cf0c261 Merge branch 'icc-milos' into icc-next) +$ git merge -m Merge branch 'icc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/djakov/icc.git icc/icc-next +Already up to date. +Merging iio/togreg (0a686b9c4f84 iio: adc: ad_sigma_delta: Select IIO_BUFFER_DMAENGINE and SPI_OFFLOAD) +$ git merge -m Merge branch 'togreg' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git iio/togreg +Already up to date. +Merging phy-next/next (4a3556b81b99 phy: qcom: phy-qcom-m31: Update IPQ5332 M31 USB phy initialization sequence) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git phy-next/next +Already up to date. +Merging soundwire/next (34b1cb4ec286 soundwire: amd: Add support for acp7.2 platform) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git soundwire/next +Already up to date. +Merging extcon/extcon-next (5f09caafc652 extcon: fsa9480: Avoid buffer overflow in fsa9480_handle_change()) +$ git merge -m Merge branch 'extcon-next' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git extcon/extcon-next +Merge made by the 'ort' strategy. + .../devicetree/bindings/extcon/maxim,max14526.yaml | 80 ++++++ + drivers/extcon/Kconfig | 13 + + drivers/extcon/Makefile | 1 + + drivers/extcon/extcon-adc-jack.c | 2 + + drivers/extcon/extcon-axp288.c | 2 +- + drivers/extcon/extcon-fsa9480.c | 6 +- + drivers/extcon/extcon-max14526.c | 302 +++++++++++++++++++++ + drivers/extcon/extcon-qcom-spmi-misc.c | 2 +- + 8 files changed, 404 insertions(+), 4 deletions(-) + create mode 100644 Documentation/devicetree/bindings/extcon/maxim,max14526.yaml + create mode 100644 drivers/extcon/extcon-max14526.c +Merging gnss/gnss-next (e326371f3002 dt-bindings: gnss: u-blox: add u-blox,neo-9m compatible) +$ git merge -m Merge branch 'gnss-next' of git://git.kernel.org/pub/scm/linux/kernel/git/johan/gnss.git gnss/gnss-next +Already up to date. +Merging vfio/next (d2272d898186 vfio/type1: correct logic of vfio_find_vpfn()) +$ git merge -m Merge branch 'next' of git://github.com/awilliam/linux-vfio.git vfio/next +Auto-merging MAINTAINERS +Auto-merging drivers/vfio/pci/vfio_pci_core.c +Auto-merging include/linux/mm.h +Merge made by the 'ort' strategy. + MAINTAINERS | 1 - + drivers/vfio/device_cdev.c | 38 +++++++- + drivers/vfio/group.c | 7 +- + drivers/vfio/iommufd.c | 4 + + drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 1 + + drivers/vfio/pci/mlx5/cmd.c | 4 +- + drivers/vfio/pci/mlx5/main.c | 1 + + drivers/vfio/pci/nvgrace-gpu/main.c | 2 + + drivers/vfio/pci/pds/vfio_dev.c | 2 + + drivers/vfio/pci/qat/main.c | 5 +- + drivers/vfio/pci/vfio_pci.c | 1 + + drivers/vfio/pci/vfio_pci_core.c | 24 +++-- + drivers/vfio/pci/virtio/main.c | 3 + + drivers/vfio/vfio_iommu_type1.c | 118 ++++++++++++++++++++----- + drivers/vfio/vfio_main.c | 3 +- + include/linux/mm.h | 23 +++++ + include/linux/vfio.h | 4 + + include/linux/vfio_pci_core.h | 2 + + include/uapi/linux/vfio.h | 12 ++- + 19 files changed, 212 insertions(+), 43 deletions(-) +Merging w1/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-w1.git w1/for-next +Already up to date. +Merging spmi/spmi-next (0ff41df1cb26 Linux 6.15) +$ git merge -m Merge branch 'spmi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git spmi/spmi-next +Already up to date. +Merging staging/staging-next (d632ab86aff2 Merge tag 'for-6.17/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm) +$ git merge -m Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git staging/staging-next +Already up to date. +Merging counter-next/counter-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'counter-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wbg/counter.git counter-next/counter-next +Already up to date. +Merging siox/siox/for-next (db418d5f1ca5 siox: bus-gpio: Simplify using devm_siox_* functions) +$ git merge -m Merge branch 'siox/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git siox/siox/for-next +Already up to date. +Merging mux/for-next (59b723cd2adb Linux 6.12-rc6) +$ git merge -m Merge branch 'for-next' of https://gitlab.com/peda-linux/mux.git mux/for-next +Already up to date. +Merging dmaengine/next (e3a9ccd21897 dt-bindings: dma: fsl-mxs-dma: allow interrupt-names for fsl,imx23-dma-apbx) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git dmaengine/next +Already up to date. +Merging cgroup/for-next (d445d2ab8129 Merge branch 'for-6.17' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git cgroup/for-next +Merge made by the 'ort' strategy. +Merging scsi/for-next (b3a40acce7b3 Merge branch 'misc' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git scsi/for-next +Auto-merging MAINTAINERS +Auto-merging drivers/scsi/libsas/sas_ata.c +Auto-merging drivers/scsi/sd.c +Auto-merging drivers/ufs/host/ufs-qcom.c +Merge made by the 'ort' strategy. + .../devicetree/bindings/ufs/mediatek,ufs.yaml | 46 ++- + MAINTAINERS | 2 +- + arch/arm64/boot/dts/mediatek/mt8195.dtsi | 25 ++ + drivers/scsi/aacraid/comminit.c | 3 +- + drivers/scsi/libsas/sas_ata.c | 10 +- + drivers/scsi/libsas/sas_discover.c | 2 +- + drivers/scsi/libsas/sas_internal.h | 78 ++++- + drivers/scsi/libsas/sas_phy.c | 6 +- + drivers/scsi/libsas/sas_port.c | 13 +- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +- + drivers/scsi/scsi_scan.c | 2 +- + drivers/scsi/scsi_transport_iscsi.c | 2 + + drivers/scsi/scsi_transport_sas.c | 62 +++- + drivers/scsi/sd.c | 4 +- + drivers/target/target_core_fabric_lib.c | 65 +++- + drivers/target/target_core_iblock.c | 33 ++- + drivers/target/target_core_iblock.h | 1 + + drivers/target/target_core_internal.h | 4 +- + drivers/target/target_core_pr.c | 18 +- + drivers/ufs/core/ufs-sysfs.c | 3 +- + drivers/ufs/core/ufshcd.c | 105 +++---- + drivers/ufs/host/ufs-mediatek.c | 330 ++++++++++++++++++--- + drivers/ufs/host/ufs-mediatek.h | 32 ++ + drivers/ufs/host/ufs-qcom.c | 8 - + drivers/ufs/host/ufshcd-pci.c | 33 +-- + include/scsi/sas_ata.h | 91 +----- + 26 files changed, 703 insertions(+), 278 deletions(-) +Merging scsi-mkp/for-next (383cd6d879a1 scsi: scsi_debug: Make read-only arrays static const) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git scsi-mkp/for-next +Auto-merging drivers/scsi/scsi_sysfs.c +Merge made by the 'ort' strategy. + drivers/scsi/scsi_debug.c | 91 +++++++++++++++++++++++++++++------------------ + drivers/scsi/scsi_sysfs.c | 4 +-- + 2 files changed, 59 insertions(+), 36 deletions(-) +Merging vhost/linux-next (06a1fa9a0b79 vhost: initialize vq->nheads properly) +$ git merge -m Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost/linux-next +Auto-merging drivers/pci/pci.h +Auto-merging drivers/vhost/vhost.c +Auto-merging drivers/virtio/virtio.c +Auto-merging drivers/virtio/virtio_pci_modern.c +Auto-merging include/linux/pci.h +Auto-merging include/linux/virtio.h +Auto-merging include/linux/virtio_config.h +Merge made by the 'ort' strategy. + drivers/pci/pci.h | 6 +++++ + drivers/vhost/vhost.c | 1 + + drivers/virtio/virtio.c | 18 ++++++++++++++- + drivers/virtio/virtio_pci_common.c | 45 ++++++++++++++++++++++++++++++++++++++ + drivers/virtio/virtio_pci_common.h | 3 +++ + drivers/virtio/virtio_pci_legacy.c | 2 ++ + drivers/virtio/virtio_pci_modern.c | 2 ++ + include/linux/pci.h | 45 ++++++++++++++++++++++++++++++++++++++ + include/linux/virtio.h | 11 +++++++--- + include/linux/virtio_config.h | 32 +++++++++++++++++++++++++++ + 10 files changed, 161 insertions(+), 4 deletions(-) +Merging rpmsg/for-next (01d7d9241256 Merge branches 'rproc-next' and 'rpmsg-next' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git rpmsg/for-next +Merge made by the 'ort' strategy. + drivers/rpmsg/qcom_glink_native.c | 2 +- + drivers/rpmsg/qcom_smd.c | 2 +- + drivers/rpmsg/rpmsg_char.c | 3 ++- + 3 files changed, 4 insertions(+), 3 deletions(-) +Merging gpio-brgl/gpio/for-next (63c7bc53a35e gpio: mlxbf2: use platform_get_irq_optional()) +$ git merge -m Merge branch 'gpio/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git gpio-brgl/gpio/for-next +Merge made by the 'ort' strategy. + drivers/gpio/gpio-mlxbf2.c | 2 +- + drivers/gpio/gpio-pxa.c | 8 +------- + 2 files changed, 2 insertions(+), 8 deletions(-) +Merging gpio-intel/for-next (9ab29ed50555 gpiolib: acpi: Add a quirk for Acer Nitro V15) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git gpio-intel/for-next +Already up to date. +Merging pinctrl/for-next (a3fe1324c3c5 pinctrl: mediatek: Add pinctrl driver for mt8189) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git pinctrl/for-next +Already up to date. +Merging pinctrl-intel/for-next (3b4408038da9 pinctrl: intel: fix build warnings about export.h) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git pinctrl-intel/for-next +Already up to date. +Merging pinctrl-renesas/renesas-pinctrl (7000167796a0 pinctrl: renesas: Simplify PINCTRL_RZV2M logic) +$ git merge -m Merge branch 'renesas-pinctrl' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git pinctrl-renesas/renesas-pinctrl +Already up to date. +Merging pinctrl-samsung/for-next (683d532dfc96 pinctrl: samsung: Fix gs101 irq chip) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git pinctrl-samsung/for-next +Already up to date. +Merging pwm/pwm/for-next (65c6f742ab14 pwm: imx-tpm: Reset counter if CMOD is 0) +$ git merge -m Merge branch 'pwm/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/pwm/for-next +Already up to date. +Merging ktest/for-next (a5e71638ddd7 ktest.pl: Add new PATCHCHECK_SKIP option to skip testing individual commits) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest.git ktest/for-next +Already up to date. +Merging kselftest/next (30fb5e134f05 selftests/pidfd: Fix duplicate-symbol warnings for SCHED_ CPP symbols) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git kselftest/next +Already up to date. +Merging kunit/test (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'test' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git kunit/test +Already up to date. +Merging kunit-next/kunit (34db4fba8191 kunit: fix longest symbol length test) +$ git merge -m Merge branch 'kunit' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git kunit-next/kunit +Already up to date. +Merging livepatching/for-next (a8e905a819fd Merge branch 'for-6.15/ftrace-test' into for-next) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching livepatching/for-next +Merge made by the 'ort' strategy. +Merging rtc/rtc-next (bb5b0b4317c9 rtc: ds1685: Update Joshua Kinard's email address.) +$ git merge -m Merge branch 'rtc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc/rtc-next +Already up to date. +Merging nvdimm/libnvdimm-for-next (9f97e61bde6a cxl: Include range.h in cxl.h) +$ git merge -m Merge branch 'libnvdimm-for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git nvdimm/libnvdimm-for-next +Already up to date. +Merging at24/at24/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'at24/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git at24/at24/for-next +Already up to date. +Merging ntb/ntb-next (0cadf92e93d4 NTB/msi: Remove unused functions) +$ git merge -m Merge branch 'ntb-next' of https://github.com/jonmason/ntb.git ntb/ntb-next +Auto-merging drivers/ntb/msi.c +Merge made by the 'ort' strategy. + drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 14 ++++++-- + drivers/ntb/msi.c | 64 ---------------------------------- + include/linux/ntb.h | 14 -------- + 3 files changed, 11 insertions(+), 81 deletions(-) +Merging seccomp/for-next/seccomp (b0c9bfbab925 selftests/seccomp: Add a test for the WAIT_KILLABLE_RECV fast reply race) +$ git merge -m Merge branch 'for-next/seccomp' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp/for-next/seccomp +Merge made by the 'ort' strategy. + kernel/seccomp.c | 12 +-- + tools/testing/selftests/seccomp/seccomp_bpf.c | 131 ++++++++++++++++++++++++++ + 2 files changed, 136 insertions(+), 7 deletions(-) +Merging slimbus/for-next (0af2f6be1b42 Linux 6.15-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/srini/slimbus.git slimbus/for-next +Already up to date. +Merging nvmem/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git nvmem/for-next +Already up to date. +Merging xarray/main (6684aba0780d XArray: Add extra debugging check to xas_lock and friends) +$ git merge -m Merge branch 'main' of git://git.infradead.org/users/willy/xarray.git xarray/main +Auto-merging include/linux/xarray.h +Auto-merging lib/xarray.c +Merge made by the 'ort' strategy. + include/linux/xarray.h | 60 +++++++++++++++++++++++++++----------------------- + lib/xarray.c | 3 +-- + 2 files changed, 34 insertions(+), 29 deletions(-) +Merging hyperv/hyperv-next (d9016a249be5 hv/hv_kvp_daemon: Prevent similar logs in kvp_key_add_or_modify()) +$ git merge -m Merge branch 'hyperv-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git hyperv/hyperv-next +Merge made by the 'ort' strategy. + tools/hv/hv_get_dhcp_info.sh | 87 ++++++++++++++++++++++++++++++++++++++------ + tools/hv/hv_kvp_daemon.c | 18 ++++----- + 2 files changed, 82 insertions(+), 23 deletions(-) +Merging auxdisplay/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-auxdisplay.git auxdisplay/for-next +Already up to date. +Merging kgdb/kgdb/for-next (afdbe49276ac kdb: Remove optional size arguments from strscpy() calls) +$ git merge -m Merge branch 'kgdb/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux.git kgdb/kgdb/for-next +Already up to date. +Merging hmm/hmm (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git hmm/hmm +Already up to date. +Merging cfi/cfi/next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'cfi/next' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git cfi/cfi/next +Already up to date. +Merging mhi/mhi-next (00559ba3ae74 bus: mhi: host: pci_generic: Add Telit FN990B40 modem support) +$ git merge -m Merge branch 'mhi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi.git mhi/mhi-next +Already up to date. +Merging memblock/for-next (3b394dff15e1 memblock tests: add test for memblock_set_node) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git memblock/for-next +Already up to date. +Merging cxl/next (f11a5f89910a Documentation/ABI/testing/debugfs-cxl: Add 'cxl' to clear_poison path) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl.git cxl/next +Already up to date. +Merging zstd/zstd-next (65d1f5507ed2 zstd: Import upstream v1.5.7) +$ git merge -m Merge branch 'zstd-next' of https://github.com/terrelln/linux.git zstd/zstd-next +Already up to date. +Merging efi/next (02eb7a8eee20 efi: add API doc entry for ovmf_debug_log) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git efi/next +Auto-merging drivers/firmware/efi/Kconfig +Auto-merging include/linux/efi.h +Merge made by the 'ort' strategy. + Documentation/ABI/testing/sysfs-firmware-efi | 7 ++ + drivers/firmware/efi/Kconfig | 8 ++ + drivers/firmware/efi/Makefile | 1 + + drivers/firmware/efi/efi.c | 8 ++ + drivers/firmware/efi/libstub/printk.c | 4 +- + drivers/firmware/efi/ovmf-debug-log.c | 111 +++++++++++++++++++++++++++ + include/linux/efi.h | 4 + + 7 files changed, 141 insertions(+), 2 deletions(-) + create mode 100644 drivers/firmware/efi/ovmf-debug-log.c +Merging unicode/for-next (6b56a63d286f MAINTAINERS: Add Unicode tree) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/krisman/unicode.git unicode/for-next +Already up to date. +Merging slab/slab/for-next (8185696483dc MAINTAINERS: add missing files to slab section) +$ git merge -m Merge branch 'slab/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git slab/slab/for-next +Already up to date. +Merging random/master (3778dcb2dcc1 random: use offstack cpumask when necessary) +$ git merge -m Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git random/master +Auto-merging drivers/media/test-drivers/vivid/vivid-vid-cap.c +Merge made by the 'ort' strategy. + drivers/char/random.c | 23 ++++++++++++++--------- + drivers/media/test-drivers/vivid/vivid-vid-cap.c | 4 +++- + include/linux/prandom.h | 6 ------ + 3 files changed, 17 insertions(+), 16 deletions(-) +Merging landlock/next (6dde339a3df8 landlock: Minor comments improvements) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git landlock/next +Auto-merging fs/namei.c +Auto-merging include/linux/fs.h +Merge made by the 'ort' strategy. + fs/namei.c | 2 +- + include/linux/fs.h | 1 + + security/landlock/errata/abi-1.h | 16 + + security/landlock/fs.c | 194 +++- + security/landlock/ruleset.c | 12 +- + security/landlock/ruleset.h | 2 +- + tools/testing/selftests/landlock/fs_test.c | 1317 +++++++++++++++++++++++++++- + 7 files changed, 1503 insertions(+), 41 deletions(-) + create mode 100644 security/landlock/errata/abi-1.h +Merging rust/rust-next (d2eedaa3909b Merge tag 'rtc-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux) +$ git merge -m Merge branch 'rust-next' of https://github.com/Rust-for-Linux/linux.git rust/rust-next +Already up to date. +Merging rust-alloc/alloc-next (d49ac7744f57 MAINTAINERS: add mm folks as reviewers to rust alloc) +$ git merge -m Merge branch 'alloc-next' of https://github.com/Rust-for-Linux/linux.git rust-alloc/alloc-next +Already up to date. +Merging rust-io/io-next (86731a2a651e Linux 6.16-rc3) +$ git merge -m Merge branch 'io-next' of https://github.com/Rust-for-Linux/linux.git rust-io/io-next +Already up to date. +Merging rust-pin-init/pin-init-next (fc3870dc5cad rust: pin-init: examples, tests: use `ignore` instead of conditionally compiling tests) +$ git merge -m Merge branch 'pin-init-next' of https://github.com/Rust-for-Linux/linux.git rust-pin-init/pin-init-next +Already up to date. +Merging rust-timekeeping/timekeeping-next (d4b29ddf82a4 rust: time: Add wrapper for fsleep() function) +$ git merge -m Merge branch 'timekeeping-next' of https://github.com/Rust-for-Linux/linux.git rust-timekeeping/timekeeping-next +Already up to date. +Merging rust-xarray/xarray-next (fa616196fbea MAINTAINERS: add entry for Rust XArray API) +$ git merge -m Merge branch 'xarray-next' of https://github.com/Rust-for-Linux/linux.git rust-xarray/xarray-next +Already up to date. +Merging sysctl/sysctl-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'sysctl-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl.git sysctl/sysctl-next +Already up to date. +Merging execve/for-next/execve (7f71195c15dc fork: reorder function qualifiers for copy_clone_args_from_user) +$ git merge -m Merge branch 'for-next/execve' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git execve/for-next/execve +Already up to date. +Merging bitmap/bitmap-for-next (89748acdf226 Merge tag 'drm-next-2025-08-01' of https://gitlab.freedesktop.org/drm/kernel) +$ git merge -m Merge branch 'bitmap-for-next' of https://github.com/norov/linux.git bitmap/bitmap-for-next +Already up to date. +Merging hte/for-next (9e4259716f60 hte: tegra-194: add missing MODULE_DESCRIPTION() macro) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/pateldipen1984/linux.git hte/for-next +Already up to date. +Merging kspp/for-next/kspp (f627b51aaa04 compiler_types: Provide __no_kstack_erase to disable coverage only on Clang) +$ git merge -m Merge branch 'for-next/kspp' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git kspp/for-next/kspp +Already up to date. +Merging nolibc/for-next (b9e50363178a selftests/nolibc: add x32 test configuration) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nolibc/linux-nolibc.git nolibc/for-next +Already up to date. +Merging iommufd/for-next (2c78e74493d3 iommu/arm-smmu-v3: Replace vsmmu_size/type with get_viommu_size) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd.git iommufd/for-next +Already up to date. +Merging turbostat/next (447c98c1ca4a tools/power turbostat: Add idle governor statistics reporting) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat/next +Auto-merging tools/power/x86/turbostat/turbostat.8 +CONFLICT (content): Merge conflict in tools/power/x86/turbostat/turbostat.8 +Auto-merging tools/power/x86/turbostat/turbostat.c +CONFLICT (content): Merge conflict in tools/power/x86/turbostat/turbostat.c +Resolved 'tools/power/x86/turbostat/turbostat.8' using previous resolution. +Resolved 'tools/power/x86/turbostat/turbostat.c' using previous resolution. +Automatic merge failed; fix conflicts and then commit the result. +$ git commit --no-edit -v -a +[master 8c553edd403c] Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git +$ git diff -M --stat --summary HEAD^.. + tools/power/x86/turbostat/turbostat.8 | 17 +- + tools/power/x86/turbostat/turbostat.c | 534 ++++++++-------------------------- + 2 files changed, 131 insertions(+), 420 deletions(-) +Merging pwrseq/pwrseq/for-next (07d59dec6795 power: sequencing: qcom-wcn: fix bluetooth-wifi copypasta for WCN6855) +$ git merge -m Merge branch 'pwrseq/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git pwrseq/pwrseq/for-next +Already up to date. +Merging capabilities-next/caps-next (cdd73b166607 uapi: fix broken link in linux/capability.h) +$ git merge -m Merge branch 'caps-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux.git capabilities-next/caps-next +Already up to date. +Merging ipe/next (038d61fd6422 Linux 6.16) +$ git merge -m Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git ipe/next +Already up to date. +Merging kcsan/next (9872916ad1a1 kcsan: test: Initialize dummy variable) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/melver/linux.git kcsan/next +Already up to date. +Merging crc/crc-next (118da22eb6fb lib/crc: x86/crc32c: Enable VPCLMULQDQ optimization where beneficial) +$ git merge -m Merge branch 'crc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git crc/crc-next +Already up to date. +Merging fwctl/for-next (19272b37aa4f Linux 6.16-rc1) +$ git merge -m Merge branch 'for-next' of git//git.kernel.org/pub/scm/linux/kernel/git/fwctl/fwctl.git fwctl/for-next +Already up to date. +Merging devsec-tsm/next (9d948b880409 Merge branch 'for-6.16/tsm-mr' into tsm-next) +$ git merge -m Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/devsec/tsm.git devsec-tsm/next +Already up to date. +Merging hisilicon/for-next (b1136432c972 soc: hisilicon: kunpeng_hccs: Fix incorrect log information) +$ git merge -m Merge branch 'for-next' of https://github.com/hisilicon/linux-hisi.git hisilicon/for-next +Already up to date. +Merging kthread/for-next (d8b4bf4ea04d kthread: modify kernel-doc function name to match code) +$ git merge -m Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git kthread/for-next +Already up to date. diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts index 4d9e2cd11f44..9f144f527f03 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-ibm-everest.dts @@ -2808,6 +2808,7 @@ #size-cells = <0>; cfam4_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -2824,6 +2825,7 @@ }; cfam4_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -2840,8 +2842,8 @@ }; cfam4_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -2857,8 +2859,8 @@ }; cfam4_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3181,6 +3183,7 @@ #size-cells = <0>; cfam5_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -3197,6 +3200,7 @@ }; cfam5_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -3213,8 +3217,8 @@ }; cfam5_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3230,8 +3234,8 @@ }; cfam5_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3554,6 +3558,7 @@ #size-cells = <0>; cfam6_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -3570,6 +3575,7 @@ }; cfam6_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -3586,8 +3592,8 @@ }; cfam6_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3603,8 +3609,8 @@ }; cfam6_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3927,6 +3933,7 @@ #size-cells = <0>; cfam7_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -3943,6 +3950,7 @@ }; cfam7_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -3959,8 +3967,8 @@ }; cfam7_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -3976,8 +3984,8 @@ }; cfam7_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-inspur-fp5280g2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-inspur-fp5280g2.dts index 78a5656ef75d..79c6919b3570 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-inspur-fp5280g2.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-inspur-fp5280g2.dts @@ -54,10 +54,9 @@ }; fsi: gpio-fsi { - compatible = "aspeed,ast2500-cf-fsi-master", "fsi-master"; + compatible = "aspeed,ast2500-cf-fsi-master"; #address-cells = <2>; #size-cells = <0>; - no-gpio-delays; memory-region = <&coldfire_memory>; aspeed,sram = <&sram>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-lanyang.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-lanyang.dts index 65b2208f5a90..9f2ad551255d 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-lanyang.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-lanyang.dts @@ -63,7 +63,7 @@ }; fsi: gpio-fsi { - compatible = "fsi-master-gpio", "fsi-master"; + compatible = "fsi-master-gpio"; #address-cells = <2>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-mowgli.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-mowgli.dts index 31ff19ef87a0..6c8b966ffccc 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-mowgli.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-mowgli.dts @@ -165,7 +165,7 @@ }; fsi: gpio-fsi { - compatible = "fsi-master-gpio", "fsi-master"; + compatible = "fsi-master-gpio"; #address-cells = <2>; #size-cells = <0>; no-gpio-delays; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-nicole.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-nicole.dts index 1a7c61750d0d..ce6d30ddf07c 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-nicole.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-nicole.dts @@ -77,10 +77,9 @@ }; fsi: gpio-fsi { - compatible = "aspeed,ast2500-cf-fsi-master", "fsi-master"; + compatible = "aspeed,ast2500-cf-fsi-master"; #address-cells = <2>; #size-cells = <0>; - no-gpio-delays; memory-region = <&coldfire_memory>; aspeed,sram = <&sram>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-palmetto.dts index 123da82c04d5..a1d3e046d4a2 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-palmetto.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-palmetto.dts @@ -55,7 +55,7 @@ }; fsi: gpio-fsi { - compatible = "aspeed,ast2400-cf-fsi-master", "fsi-master"; + compatible = "aspeed,ast2400-cf-fsi-master"; #address-cells = <2>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-romulus.dts index e6b383f6e977..a0263d969e51 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-romulus.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-romulus.dts @@ -68,10 +68,9 @@ }; fsi: gpio-fsi { - compatible = "aspeed,ast2500-cf-fsi-master", "fsi-master"; + compatible = "aspeed,ast2500-cf-fsi-master"; #address-cells = <2>; #size-cells = <0>; - no-gpio-delays; memory-region = <&coldfire_memory>; aspeed,sram = <&sram>; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts index 8b1e82c8cdfe..89907b628b65 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts @@ -173,7 +173,7 @@ }; fsi: gpio-fsi { - compatible = "fsi-master-gpio", "fsi-master"; + compatible = "fsi-master-gpio"; #address-cells = <2>; #size-cells = <0>; no-gpio-delays; diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-zaius.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-zaius.dts index 6ac7b0aa6e54..627c91f178e6 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-zaius.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-zaius.dts @@ -96,7 +96,7 @@ }; fsi: gpio-fsi { - compatible = "fsi-master-gpio", "fsi-master"; + compatible = "fsi-master-gpio"; #address-cells = <2>; #size-cells = <0>; no-gpio-delays; diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi index 8ed715bd53aa..acdb6ae74b27 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi +++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi @@ -847,7 +847,7 @@ fsim0: fsi@1e79b000 { #interrupt-cells = <1>; - compatible = "aspeed,ast2600-fsi-master", "fsi-master"; + compatible = "aspeed,ast2600-fsi-master"; reg = <0x1e79b000 0x94>; interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; @@ -859,7 +859,7 @@ fsim1: fsi@1e79b100 { #interrupt-cells = <1>; - compatible = "aspeed,ast2600-fsi-master", "fsi-master"; + compatible = "aspeed,ast2600-fsi-master"; reg = <0x1e79b100 0x94>; interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi b/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi index 07ce3b2bc62a..06fac236773f 100644 --- a/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi +++ b/arch/arm/boot/dts/aspeed/ibm-power10-dual.dtsi @@ -82,6 +82,7 @@ #size-cells = <0>; cfam0_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -98,6 +99,7 @@ }; cfam0_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -114,8 +116,8 @@ }; cfam0_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -131,8 +133,8 @@ }; cfam0_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -249,6 +251,7 @@ #size-cells = <0>; cfam1_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -265,6 +268,7 @@ }; cfam1_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -281,8 +285,8 @@ }; cfam1_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -298,8 +302,8 @@ }; cfam1_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/aspeed/ibm-power10-quad.dtsi b/arch/arm/boot/dts/aspeed/ibm-power10-quad.dtsi index 57494c744b5d..9501f66d0030 100644 --- a/arch/arm/boot/dts/aspeed/ibm-power10-quad.dtsi +++ b/arch/arm/boot/dts/aspeed/ibm-power10-quad.dtsi @@ -733,6 +733,7 @@ #size-cells = <0>; cfam2_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -749,6 +750,7 @@ }; cfam2_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -765,8 +767,8 @@ }; cfam2_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -782,8 +784,8 @@ }; cfam2_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -1106,6 +1108,7 @@ #size-cells = <0>; cfam3_spi0: spi@0 { + compatible = "ibm,spi-fsi"; reg = <0x0>; #address-cells = <1>; #size-cells = <0>; @@ -1122,6 +1125,7 @@ }; cfam3_spi1: spi@20 { + compatible = "ibm,spi-fsi"; reg = <0x20>; #address-cells = <1>; #size-cells = <0>; @@ -1138,8 +1142,8 @@ }; cfam3_spi2: spi@40 { + compatible = "ibm,spi-fsi"; reg = <0x40>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; @@ -1155,8 +1159,8 @@ }; cfam3_spi3: spi@60 { + compatible = "ibm,spi-fsi"; reg = <0x60>; - compatible = "ibm,fsi2spi"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile index 7f5a8801cad1..70fac0b276df 100644 --- a/arch/arm64/boot/dts/xilinx/Makefile +++ b/arch/arm64/boot/dts/xilinx/Makefile @@ -30,4 +30,28 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revA.dtb zynqmp-smk-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revB.dtb +zynqmp-sm-k26-revA-sck-kr-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kr-g-revA.dtb +zynqmp-sm-k26-revA-sck-kr-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kr-g-revB.dtb +zynqmp-smk-k26-revA-sck-kr-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kr-g-revA.dtb +zynqmp-smk-k26-revA-sck-kr-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kr-g-revB.dtb + +zynqmp-sm-k24-revA-sck-kd-g-revA-dtbs := zynqmp-sm-k24-revA.dtb zynqmp-sck-kd-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA-sck-kd-g-revA.dtb +zynqmp-smk-k24-revA-sck-kd-g-revA-dtbs := zynqmp-smk-k24-revA.dtb zynqmp-sck-kd-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA-sck-kd-g-revA.dtb + +zynqmp-sm-k24-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k24-revA.dtb zynqmp-sck-kv-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA-sck-kv-g-revB.dtb +zynqmp-smk-k24-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k24-revA.dtb zynqmp-sck-kv-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA-sck-kv-g-revB.dtb + +zynqmp-sm-k24-revA-sck-kr-g-revB-dtbs := zynqmp-sm-k24-revA.dtb zynqmp-sck-kr-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA-sck-kr-g-revB.dtb +zynqmp-smk-k24-revA-sck-kr-g-revB-dtbs := zynqmp-smk-k24-revA.dtb zynqmp-sck-kr-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA-sck-kr-g-revB.dtb + dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-x-b2197-01-revA.dtb diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso new file mode 100644 index 000000000000..02be5e1e8686 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KD240 revA Carrier Card + * + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h> + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kd240-rev1", + "xlnx,zynqmp-sk-kd240-revB", + "xlnx,zynqmp-sk-kd240-revA", + "xlnx,zynqmp-sk-kd240", "xlnx,zynqmp"; + model = "ZynqMP KD240 revA/B/1"; + + aliases { + ethernet0 = "/axi/ethernet@ff0c0000"; /* &gem1 */ + }; + + ina260-u3 { + compatible = "iio-hwmon"; + io-channels = <&u3 0>, <&u3 1>, <&u3 2>; + }; + + clk_26: clock2 { /* u17 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_25_0: clock4 { /* u92/u91 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: clock5 { /* u92/u91 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&can0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u3: ina260@40 { /* u3 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u13 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "", + "SD_RESET_B", "USB0_HUB_RESET_B", + "", "PS_GEM0_RESET_B", + "", ""; + }; + + hub: usb-hub@2d { /* u36 */ + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; +}; + +/* USB 3.0 */ +&psgtr { + status = "okay"; + /* usb */ + clocks = <&clk_26>; + clock-names = "ref2"; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&gem1 { /* mdio mio50/51 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + assigned-clock-rates = <250000000>; + + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@8 { /* Adin u31 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id0283.bc30"; + reg = <8>; + adi,rx-internal-delay-ps = <2000>; + adi,tx-internal-delay-ps = <2000>; + adi,fifo-depth-bits = <8>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; + reset-gpios = <&gpio 77 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* 2 more ethernet phys u32@2 and u34@3 */ + +&pinctrl0 { /* required by spec */ + status = "okay"; + + pinctrl_can0_default: can0-default { + mux { + function = "can0"; + groups = "can0_16_grp"; + }; + + conf { + groups = "can0_16_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO66"; + bias-pull-up; + }; + + conf-tx { + pins = "MIO67"; + bias-pull-up; + drive-strength = <4>; + }; + }; + + pinctrl_uart0_default: uart0-default { + conf { + groups = "uart0_17_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO70"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO71"; + bias-disable; + }; + + mux { + groups = "uart0_17_grp"; + function = "uart0"; + }; + }; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO45", "MIO46", "MIO47", "MIO48"; + bias-disable; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO44", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart0 { + status = "okay"; + rts-gpios = <&gpio 72 GPIO_ACTIVE_HIGH>; + linux,rs485-enabled-at-boot-time; + rs485-rts-delay = <10 10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0_default>; + assigned-clock-rates = <100000000>; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; + +&zynqmp_dpsub { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso new file mode 100644 index 000000000000..fbacfa984d76 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revA Carrier Card + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h> + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revA", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + model = "ZynqMP KR260 revA"; + + aliases { + ethernet0 = "/axi/ethernet@ff0b0000"; /* &gem0 */ + ethernet1 = "/axi/ethernet@ff0c0000"; /* &gem1 */ + }; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + clk_27: clock0 { /* u86 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_125: si5332-0 { /* u17 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk_74: si5332-5 { /* u17 - SLVC-EC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + clk_26: si5332-2 { /* u17 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_156: si5332-3 { /* u17 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + clk_25_0: si5332-1 { /* u17 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: si5332-4 { /* u17 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + hub_1: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + hub_2: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&clk_125>, <&clk_27>, <&clk_26>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub1_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub1_3_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub1_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub1_2_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + assigned-clock-rates = <250000000>; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + assigned-clock-rates = <250000000>; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <300>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso new file mode 100644 index 000000000000..b7cda216b179 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revB Carrier Card (A03 revision) + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h> + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revB", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + model = "ZynqMP KR260 revB"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + clk_125: clock0 { /* u87 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk_27: clock1 { /* u86 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_26: clock2 { /* u89 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_156: clock3 { /* u90 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + clk_25_0: clock4 { /* u92/u91 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: clock5 { /* u92/u91 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_74: clock6 { /* u88 - SLVC-EC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + hub_1: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + hub_2: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&clk_125>, <&clk_27>, <&clk_26>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub1_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub1_3_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub1_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub1_2_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + assigned-clock-rates = <250000000>; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + assigned-clock-rates = <250000000>; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <300>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = <SLEW_RATE_SLOW>; + power-source = <IO_STANDARD_LVCMOS18>; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = <IO_STANDARD_LVCMOS18>; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = <SLEW_RATE_FAST>; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = <SLEW_RATE_SLOW>; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso index 95d16904d765..a98a888d1385 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso @@ -129,7 +129,6 @@ pinctrl-0 = <&pinctrl_usb0_default>; phy-names = "usb3-phy"; phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; - /* missing usb5744 - u43 */ }; &dwc3_0 { @@ -137,6 +136,24 @@ dr_mode = "host"; snps,usb3_lpm_capable; maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; }; &sdhci1 { /* on CC with tuned parameters */ diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso index a74d0ac7e07a..1d2b46d7949e 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso @@ -92,7 +92,10 @@ label = "ina260-u14"; reg = <0x40>; }; - /* u43 - 0x2d - USB hub */ + hub: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ }; @@ -109,13 +112,11 @@ phy-names = "dp-phy0", "dp-phy1"; phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>; assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; - ports { - port@5 { - dpsub_dp_out: endpoint { - remote-endpoint = <&dpcon_in>; - }; - }; +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; }; }; @@ -138,6 +139,26 @@ dr_mode = "host"; snps,usb3_lpm_capable; maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; }; &sdhci1 { /* on CC with tuned parameters */ diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts new file mode 100644 index 000000000000..653bd9362264 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP SM-K24 RevA + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include "zynqmp-sm-k26-revA.dts" + +/ { + model = "ZynqMP SM-K24 RevA/B/1"; + compatible = "xlnx,zynqmp-sm-k24-rev1", "xlnx,zynqmp-sm-k24-revB", + "xlnx,zynqmp-sm-k24-revA", "xlnx,zynqmp-sm-k24", + "xlnx,zynqmp"; + + memory@0 { + device_type = "memory"; /* 2GB */ + reg = <0 0 0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts index bfa7ea6b9224..500af1d2232f 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts @@ -90,10 +90,10 @@ }; }; - pwm-fan { + pwm_fan: pwm-fan { compatible = "pwm-fan"; status = "okay"; - pwms = <&ttc0 2 40000 0>; + pwms = <&ttc0 2 40000 1>; }; }; @@ -233,6 +233,9 @@ pinctrl-0 = <&pinctrl_sdhci0_default>; non-removable; disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; bus-width = <8>; xlnx,mio-bank = <0>; assigned-clock-rates = <187498123>; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts new file mode 100644 index 000000000000..7308983b15a0 --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP SMK-K24 RevA + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include "zynqmp-sm-k24-revA.dts" + +/ { + model = "ZynqMP SMK-K24 RevA"; + compatible = "xlnx,zynqmp-smk-k24-revA", "xlnx,zynqmp-smk-k24", + "xlnx,zynqmp"; +}; + +&sdhci0 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts index 1850325e1d6c..2ad7423c2f05 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts @@ -135,7 +135,6 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand0_default>; - arasan,has-mdma; nand@0 { reg = <0x0>; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts index f553b317e6b2..8fbc33562bc4 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts @@ -129,7 +129,6 @@ /* MT29F64G08AECDBJ4-6 */ &nand0 { status = "okay"; - arasan,has-mdma; num-cs = <2>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts index 62c2503a502a..4ec8a400494e 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts @@ -134,6 +134,18 @@ #clock-cells = <0>; clock-frequency = <27000000>; }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; }; &dcc { @@ -509,6 +521,9 @@ xlnx,mio-bank = <0>; non-removable; disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; cap-power-off-card; mmc-pwrseq = <&sdio_pwrseq>; vqmmc-supply = <&wmmcsdio_fixed>; @@ -604,3 +619,9 @@ phys = <&psgtr 1 PHY_TYPE_DP 0 1>, <&psgtr 0 PHY_TYPE_DP 1 1>; }; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts index 7e26489a1539..e172a30e7b21 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts @@ -151,6 +151,18 @@ #clock-cells = <0>; clock-frequency = <114285000>; }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; }; &can1 { @@ -1045,3 +1057,9 @@ phy-names = "dp-phy0"; phys = <&psgtr 1 PHY_TYPE_DP 0 3>; }; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts index eb2090673ec1..fe8f151ed706 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts @@ -60,6 +60,18 @@ #clock-cells = <0>; clock-frequency = <27000000>; }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; }; &can1 { @@ -529,3 +541,9 @@ phys = <&psgtr 1 PHY_TYPE_DP 0 3>, <&psgtr 0 PHY_TYPE_DP 1 3>; }; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts index 4694d0a841f1..3ee8ab224722 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts @@ -65,6 +65,18 @@ #clock-cells = <0>; clock-frequency = <27000000>; }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; }; &can1 { @@ -541,3 +553,9 @@ phys = <&psgtr 1 PHY_TYPE_DP 0 3>, <&psgtr 0 PHY_TYPE_DP 1 3>; }; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts index 7beedd730f94..cd132abf6e00 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts @@ -1042,12 +1042,10 @@ phy-names = "dp-phy0", "dp-phy1"; phys = <&psgtr 1 PHY_TYPE_DP 0 3>, <&psgtr 0 PHY_TYPE_DP 1 3>; +}; - ports { - port@5 { - dpsub_dp_out: endpoint { - remote-endpoint = <&dpcon_in>; - }; - }; +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; }; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts index b67ff7ecf3c3..428b5558fbba 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts @@ -129,6 +129,18 @@ #clock-cells = <0>; clock-frequency = <48000000>; }; + + dpcon { + compatible = "dp-connector"; + label = "P11"; + type = "full-size"; + + port { + dpcon_in: endpoint { + remote-endpoint = <&dpsub_dp_out>; + }; + }; + }; }; &dcc { @@ -494,7 +506,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <5>; - sc18is603@2f { /* sc18is602 - u93 */ + sc18is603: spi@2f { /* sc18is602 - u93 */ compatible = "nxp,sc18is603"; reg = <0x2f>; /* 4 gpios for CS not handled by driver */ @@ -864,3 +876,9 @@ phys = <&psgtr 1 PHY_TYPE_DP 0 1>, <&psgtr 0 PHY_TYPE_DP 1 1>; }; + +&out_dp { + dpsub_dp_out: endpoint { + remote-endpoint = <&dpcon_in>; + }; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index e11d282462bd..5f26649c9e11 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -187,7 +187,7 @@ }; psci { - compatible = "arm,psci-0.2"; + compatible = "arm,psci-1.0", "arm,psci-0.2"; method = "smc"; }; @@ -1319,22 +1319,22 @@ #address-cells = <1>; #size-cells = <0>; - port@0 { + live_video: port@0 { reg = <0>; }; - port@1 { + live_gfx: port@1 { reg = <1>; }; - port@2 { + live_audio: port@2 { reg = <2>; }; - port@3 { + out_video: port@3 { reg = <3>; }; - port@4 { + out_audio: port@4 { reg = <4>; }; - port@5 { + out_dp: port@5 { reg = <5>; }; }; diff --git a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts index a34734a6c3ce..018ed904352a 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts +++ b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts @@ -41,6 +41,15 @@ }; }; +&apbdma3 { + status = "okay"; +}; + +&mmc0 { + status = "okay"; + bus-width = <4>; +}; + &gmac0 { status = "okay"; diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi index 760c60eebb89..588ebc3bded4 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi @@ -104,7 +104,7 @@ status = "disabled"; }; - dma-controller@1fe10c20 { + apbdma2: dma-controller@1fe10c20 { compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma"; reg = <0 0x1fe10c20 0 0x8>; interrupt-parent = <&eiointc>; @@ -114,7 +114,7 @@ status = "disabled"; }; - dma-controller@1fe10c30 { + apbdma3: dma-controller@1fe10c30 { compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma"; reg = <0 0x1fe10c30 0 0x8>; interrupt-parent = <&eiointc>; @@ -437,6 +437,30 @@ status = "disabled"; }; + mmc0: mmc@1ff64000 { + compatible = "loongson,ls2k0500-mmc"; + reg = <0 0x1ff64000 0 0x2000>, + <0 0x1fe10100 0 0x4>; + interrupt-parent = <&eiointc>; + interrupts = <57>; + dmas = <&apbdma3 0>; + dma-names = "rx-tx"; + clocks = <&clk LOONGSON2_APB_CLK>; + status = "disabled"; + }; + + mmc@1ff66000 { + compatible = "loongson,ls2k0500-mmc"; + reg = <0 0x1ff66000 0 0x2000>, + <0 0x1fe10100 0 0x4>; + interrupt-parent = <&eiointc>; + interrupts = <58>; + dmas = <&apbdma2 0>; + dma-names = "rx-tx"; + clocks = <&clk LOONGSON2_APB_CLK>; + status = "disabled"; + }; + pmc: power-management@1ff6c000 { compatible = "loongson,ls2k0500-pmc", "syscon"; reg = <0x0 0x1ff6c000 0x0 0x58>; diff --git a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts index 78ea995abf1c..d9a452ada5d7 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts +++ b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts @@ -48,6 +48,19 @@ }; }; +&apbdma1 { + status = "okay"; +}; + +&mmc { + status = "okay"; + + pinctrl-0 = <&sdio_pins_default>; + pinctrl-names = "default"; + bus-width = <4>; + cd-gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; +}; + &gmac0 { status = "okay"; diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi index 1da3beb00f0e..d8e01e2534dd 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi @@ -187,14 +187,14 @@ <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, - <>, - <26 IRQ_TYPE_LEVEL_HIGH>, + <0 IRQ_TYPE_NONE>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, + <26 IRQ_TYPE_NONE>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, @@ -209,13 +209,13 @@ <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, - <>, + <0 IRQ_TYPE_NONE>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, - <>, - <>, + <0 IRQ_TYPE_NONE>, + <0 IRQ_TYPE_NONE>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, <27 IRQ_TYPE_LEVEL_HIGH>, @@ -256,7 +256,7 @@ status = "disabled"; }; - dma-controller@1fe00c10 { + apbdma1: dma-controller@1fe00c10 { compatible = "loongson,ls2k1000-apbdma"; reg = <0x0 0x1fe00c10 0x0 0x8>; interrupt-parent = <&liointc1>; @@ -405,6 +405,18 @@ status = "disabled"; }; + mmc: mmc@1fe2c000 { + compatible = "loongson,ls2k1000-mmc"; + reg = <0 0x1fe2c000 0 0x68>, + <0 0x1fe00438 0 0x8>; + interrupt-parent = <&liointc0>; + interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LOONGSON2_APB_CLK>; + dmas = <&apbdma1 0>; + dma-names = "rx-tx"; + status = "disabled"; + }; + spi0: spi@1fff0220 { compatible = "loongson,ls2k1000-spi"; reg = <0x0 0x1fff0220 0x0 0x10>; diff --git a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts index ea9e6985d0e9..3c6b12220386 100644 --- a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts +++ b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts @@ -39,6 +39,16 @@ }; }; +&emmc { + status = "okay"; + + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + no-sd; + no-sdio; +}; + &sata { status = "okay"; }; diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi index 9e0411f2754c..00cc485b753b 100644 --- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi @@ -259,6 +259,24 @@ status = "disabled"; }; + emmc: mmc@79990000 { + compatible = "loongson,ls2k2000-mmc"; + reg = <0x0 0x79990000 0x0 0x1000>; + interrupt-parent = <&pic>; + interrupts = <51 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LOONGSON2_EMMC_CLK>; + status = "disabled"; + }; + + mmc@79991000 { + compatible = "loongson,ls2k2000-mmc"; + reg = <0x0 0x79991000 0x0 0x1000>; + interrupt-parent = <&pic>; + interrupts = <50 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LOONGSON2_EMMC_CLK>; + status = "disabled"; + }; + pcie@1a000000 { compatible = "loongson,ls2k-pci"; reg = <0x0 0x1a000000 0x0 0x02000000>, diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 3089785ca97e..277d2140676b 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -497,6 +497,7 @@ void arch_simulate_insn(union loongarch_instruction insn, struct pt_regs *regs); int larch_insn_read(void *addr, u32 *insnp); int larch_insn_write(void *addr, u32 insn); int larch_insn_patch_text(void *addr, u32 insn); +int larch_insn_text_copy(void *dst, void *src, size_t len); u32 larch_insn_gen_nop(void); u32 larch_insn_gen_b(unsigned long pc, unsigned long dest); @@ -510,6 +511,8 @@ u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj); u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); +u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); +u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); static inline bool signed_imm_check(long val, unsigned int bit) diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h index a0994d226eff..09dfd7eb406e 100644 --- a/arch/loongarch/include/asm/loongarch.h +++ b/arch/loongarch/include/asm/loongarch.h @@ -451,6 +451,13 @@ #define LOONGARCH_CSR_KS6 0x36 #define LOONGARCH_CSR_KS7 0x37 #define LOONGARCH_CSR_KS8 0x38 +#define LOONGARCH_CSR_KS9 0x39 +#define LOONGARCH_CSR_KS10 0x3a +#define LOONGARCH_CSR_KS11 0x3b +#define LOONGARCH_CSR_KS12 0x3c +#define LOONGARCH_CSR_KS13 0x3d +#define LOONGARCH_CSR_KS14 0x3e +#define LOONGARCH_CSR_KS15 0x3f /* Exception allocated KS0, KS1 and KS2 statically */ #define EXCEPTION_KS0 LOONGARCH_CSR_KS0 diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 27144de5c5fe..c0a5dc9aeae2 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -39,16 +39,19 @@ void __init init_environ(void) static int __init init_cpu_fullname(void) { - struct device_node *root; int cpu, ret; - char *model; + char *cpuname; + const char *model; + struct device_node *root; /* Parsing cpuname from DTS model property */ root = of_find_node_by_path("/"); - ret = of_property_read_string(root, "model", (const char **)&model); + ret = of_property_read_string(root, "model", &model); + if (ret == 0) { + cpuname = kstrdup(model, GFP_KERNEL); + loongson_sysconf.cpuname = strsep(&cpuname, " "); + } of_node_put(root); - if (ret == 0) - loongson_sysconf.cpuname = strsep(&model, " "); if (loongson_sysconf.cpuname && !strncmp(loongson_sysconf.cpuname, "Loongson", 8)) { for (cpu = 0; cpu < NR_CPUS; cpu++) diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 14d7d700bcb9..e61c482068fe 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -4,6 +4,7 @@ */ #include <linux/sizes.h> #include <linux/uaccess.h> +#include <linux/set_memory.h> #include <asm/cacheflush.h> #include <asm/inst.h> @@ -218,6 +219,32 @@ int larch_insn_patch_text(void *addr, u32 insn) return ret; } +int larch_insn_text_copy(void *dst, void *src, size_t len) +{ + int ret; + unsigned long flags; + unsigned long dst_start, dst_end, dst_len; + + dst_start = round_down((unsigned long)dst, PAGE_SIZE); + dst_end = round_up((unsigned long)dst + len, PAGE_SIZE); + dst_len = dst_end - dst_start; /* page-aligned */ + + set_memory_rw(dst_start, dst_len / PAGE_SIZE); + raw_spin_lock_irqsave(&patch_lock, flags); + + ret = copy_to_kernel_nofault(dst, src, len); + if (ret) + pr_err("%s: operation failed\n", __func__); + + raw_spin_unlock_irqrestore(&patch_lock, flags); + set_memory_rox(dst_start, dst_len / PAGE_SIZE); + + if (!ret) + flush_icache_range((unsigned long)dst, (unsigned long)dst + len); + + return ret; +} + u32 larch_insn_gen_nop(void) { return INSN_NOP; @@ -323,6 +350,34 @@ u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) return insn.word; } +u32 larch_insn_gen_beq(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) +{ + union loongarch_instruction insn; + + if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) { + pr_warn("The generated beq instruction is out of range.\n"); + return INSN_BREAK; + } + + emit_beq(&insn, rj, rd, imm >> 2); + + return insn.word; +} + +u32 larch_insn_gen_bne(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) +{ + union loongarch_instruction insn; + + if ((imm & 3) || imm < -SZ_128K || imm >= SZ_128K) { + pr_warn("The generated bne instruction is out of range.\n"); + return INSN_BREAK; + } + + emit_bne(&insn, rj, rd, imm >> 2); + + return insn.word; +} + u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) { union loongarch_instruction insn; diff --git a/arch/loongarch/kernel/relocate_kernel.S b/arch/loongarch/kernel/relocate_kernel.S index 84e6de2fd973..8b5140ac9ea1 100644 --- a/arch/loongarch/kernel/relocate_kernel.S +++ b/arch/loongarch/kernel/relocate_kernel.S @@ -109,4 +109,4 @@ SYM_CODE_END(kexec_smp_wait) relocate_new_kernel_end: .section ".data" -SYM_DATA(relocate_new_kernel_size, .long relocate_new_kernel_end - relocate_new_kernel) +SYM_DATA(relocate_new_kernel_size, .quad relocate_new_kernel_end - relocate_new_kernel) diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 22b27cd447a1..075b79b2c1d3 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -191,6 +191,16 @@ static int __init early_parse_mem(char *p) return -EINVAL; } + start = 0; + size = memparse(p, &p); + if (*p == '@') /* Every mem=... should contain '@' */ + start = memparse(p + 1, &p); + else { /* Only one mem=... is allowed if no '@' */ + usermem = 1; + memblock_enforce_memory_limit(size); + return 0; + } + /* * If a user specifies memory size, we * blow away any automatically generated @@ -201,14 +211,6 @@ static int __init early_parse_mem(char *p) memblock_remove(memblock_start_of_DRAM(), memblock_end_of_DRAM() - memblock_start_of_DRAM()); } - start = 0; - size = memparse(p, &p); - if (*p == '@') - start = memparse(p + 1, &p); - else { - pr_err("Invalid format!\n"); - return -EINVAL; - } if (!IS_ENABLED(CONFIG_NUMA)) memblock_add(start, size); diff --git a/arch/loongarch/kernel/unwind_orc.c b/arch/loongarch/kernel/unwind_orc.c index 0005be49b056..0d5fa64a2225 100644 --- a/arch/loongarch/kernel/unwind_orc.c +++ b/arch/loongarch/kernel/unwind_orc.c @@ -508,7 +508,7 @@ bool unwind_next_frame(struct unwind_state *state) state->pc = bt_address(pc); if (!state->pc) { - pr_err("cannot find unwind pc at %pK\n", (void *)pc); + pr_err("cannot find unwind pc at %p\n", (void *)pc); goto err; } diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index fa1500d4aa3e..1ecc2c59459c 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -4,13 +4,20 @@ * * Copyright (C) 2022 Loongson Technology Corporation Limited */ +#include <linux/memory.h> #include "bpf_jit.h" -#define REG_TCC LOONGARCH_GPR_A6 -#define TCC_SAVED LOONGARCH_GPR_S5 +#define LOONGARCH_MAX_REG_ARGS 8 + +#define LOONGARCH_LONG_JUMP_NINSNS 5 +#define LOONGARCH_LONG_JUMP_NBYTES (LOONGARCH_LONG_JUMP_NINSNS * 4) -#define SAVE_RA BIT(0) -#define SAVE_TCC BIT(1) +#define LOONGARCH_FENTRY_NINSNS 2 +#define LOONGARCH_FENTRY_NBYTES (LOONGARCH_FENTRY_NINSNS * 4) +#define LOONGARCH_BPF_FENTRY_NBYTES (LOONGARCH_LONG_JUMP_NINSNS * 4) + +#define REG_TCC LOONGARCH_GPR_A6 +#define BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack) (round_up(stack, 16) - 80) static const int regmap[] = { /* return value from in-kernel function, and exit value for eBPF program */ @@ -32,32 +39,57 @@ static const int regmap[] = { [BPF_REG_AX] = LOONGARCH_GPR_T0, }; -static void mark_call(struct jit_ctx *ctx) +static void prepare_bpf_tail_call_cnt(struct jit_ctx *ctx, int *store_offset) { - ctx->flags |= SAVE_RA; -} + const struct bpf_prog *prog = ctx->prog; + const bool is_main_prog = !bpf_is_subprog(prog); -static void mark_tail_call(struct jit_ctx *ctx) -{ - ctx->flags |= SAVE_TCC; -} + if (is_main_prog) { + /* + * LOONGARCH_GPR_T3 = MAX_TAIL_CALL_CNT + * if (REG_TCC > T3 ) + * std REG_TCC -> LOONGARCH_GPR_SP + store_offset + * else + * std REG_TCC -> LOONGARCH_GPR_SP + store_offset + * REG_TCC = LOONGARCH_GPR_SP + store_offset + * + * std REG_TCC -> LOONGARCH_GPR_SP + store_offset + * + * The purpose of this code is to first push the TCC into stack, + * and then push the address of TCC into stack. + * In cases where bpf2bpf and tailcall are used in combination, + * the value in REG_TCC may be a count or an address, + * these two cases need to be judged and handled separately. + */ + emit_insn(ctx, addid, LOONGARCH_GPR_T3, LOONGARCH_GPR_ZERO, MAX_TAIL_CALL_CNT); + *store_offset -= sizeof(long); -static bool seen_call(struct jit_ctx *ctx) -{ - return (ctx->flags & SAVE_RA); -} + emit_cond_jmp(ctx, BPF_JGT, REG_TCC, LOONGARCH_GPR_T3, 4); -static bool seen_tail_call(struct jit_ctx *ctx) -{ - return (ctx->flags & SAVE_TCC); -} + /* + * If REG_TCC < MAX_TAIL_CALL_CNT, the value in REG_TCC is a count, + * push tcc into stack + */ + emit_insn(ctx, std, REG_TCC, LOONGARCH_GPR_SP, *store_offset); -static u8 tail_call_reg(struct jit_ctx *ctx) -{ - if (seen_call(ctx)) - return TCC_SAVED; + /* Push the address of TCC into the REG_TCC */ + emit_insn(ctx, addid, REG_TCC, LOONGARCH_GPR_SP, *store_offset); + + emit_uncond_jmp(ctx, 2); + + /* + * If REG_TCC > MAX_TAIL_CALL_CNT, the value in REG_TCC is an address, + * push tcc_ptr into stack + */ + emit_insn(ctx, std, REG_TCC, LOONGARCH_GPR_SP, *store_offset); + } else { + *store_offset -= sizeof(long); + emit_insn(ctx, std, REG_TCC, LOONGARCH_GPR_SP, *store_offset); + } - return REG_TCC; + /* Push tcc_ptr into stack */ + *store_offset -= sizeof(long); + emit_insn(ctx, std, REG_TCC, LOONGARCH_GPR_SP, *store_offset); } /* @@ -80,6 +112,10 @@ static u8 tail_call_reg(struct jit_ctx *ctx) * | $s4 | * +-------------------------+ * | $s5 | + * +-------------------------+ + * | tcc | + * +-------------------------+ + * | tcc_ptr | * +-------------------------+ <--BPF_REG_FP * | prog->aux->stack_depth | * | (optional) | @@ -88,22 +124,32 @@ static u8 tail_call_reg(struct jit_ctx *ctx) */ static void build_prologue(struct jit_ctx *ctx) { - int stack_adjust = 0, store_offset, bpf_stack_adjust; + int i, stack_adjust = 0, store_offset, bpf_stack_adjust; + const struct bpf_prog *prog = ctx->prog; + const bool is_main_prog = !bpf_is_subprog(prog); bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16); - /* To store ra, fp, s0, s1, s2, s3, s4 and s5. */ + /* To store ra, fp, s0, s1, s2, s3, s4, s5 */ stack_adjust += sizeof(long) * 8; + /* To store tcc and tcc_ptr */ + stack_adjust += sizeof(long) * 2; + stack_adjust = round_up(stack_adjust, 16); stack_adjust += bpf_stack_adjust; + /* Reserve space for the move_imm + jirl instruction */ + for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++) + emit_insn(ctx, nop); + /* - * First instruction initializes the tail call count (TCC). - * On tail call we skip this instruction, and the TCC is - * passed in REG_TCC from the caller. + * First instruction initializes the tail call count (TCC) + * register to zero. On tail call we skip this instruction, + * and the TCC is passed in REG_TCC from the caller. */ - emit_insn(ctx, addid, REG_TCC, LOONGARCH_GPR_ZERO, MAX_TAIL_CALL_CNT); + if (is_main_prog) + emit_insn(ctx, addid, REG_TCC, LOONGARCH_GPR_ZERO, 0); emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_adjust); @@ -131,20 +177,13 @@ static void build_prologue(struct jit_ctx *ctx) store_offset -= sizeof(long); emit_insn(ctx, std, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, store_offset); + prepare_bpf_tail_call_cnt(ctx, &store_offset); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_adjust); if (bpf_stack_adjust) emit_insn(ctx, addid, regmap[BPF_REG_FP], LOONGARCH_GPR_SP, bpf_stack_adjust); - /* - * Program contains calls and tail calls, so REG_TCC need - * to be saved across calls. - */ - if (seen_tail_call(ctx) && seen_call(ctx)) - move_reg(ctx, TCC_SAVED, REG_TCC); - else - emit_insn(ctx, nop); - ctx->stack_size = stack_adjust; } @@ -177,6 +216,16 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) load_offset -= sizeof(long); emit_insn(ctx, ldd, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, load_offset); + /* + * When push into the stack, follow the order of tcc then tcc_ptr. + * When pop from the stack, first pop tcc_ptr then followed by tcc. + */ + load_offset -= 2 * sizeof(long); + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_SP, load_offset); + + load_offset += sizeof(long); + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_SP, load_offset); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_adjust); if (!is_tail_call) { @@ -189,7 +238,7 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) * Call the next bpf prog and skip the first instruction * of TCC initialization. */ - emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1); + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 6); } } @@ -208,12 +257,10 @@ bool bpf_jit_supports_far_kfunc_call(void) return true; } -/* initialized on the first pass of build_body() */ -static int out_offset = -1; -static int emit_bpf_tail_call(struct jit_ctx *ctx) +static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn) { - int off; - u8 tcc = tail_call_reg(ctx); + int off, tc_ninsn = 0; + int tcc_ptr_off = BPF_TAIL_CALL_CNT_PTR_STACK_OFF(ctx->stack_size); u8 a1 = LOONGARCH_GPR_A1; u8 a2 = LOONGARCH_GPR_A2; u8 t1 = LOONGARCH_GPR_T1; @@ -222,7 +269,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) const int idx0 = ctx->idx; #define cur_offset (ctx->idx - idx0) -#define jmp_offset (out_offset - (cur_offset)) +#define jmp_offset (tc_ninsn - (cur_offset)) /* * a0: &ctx @@ -232,6 +279,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) * if (index >= array->map.max_entries) * goto out; */ + tc_ninsn = insn ? ctx->offset[insn+1] - ctx->offset[insn] : ctx->offset[0]; off = offsetof(struct bpf_array, map.max_entries); emit_insn(ctx, ldwu, t1, a1, off); /* bgeu $a2, $t1, jmp_offset */ @@ -239,11 +287,15 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) goto toofar; /* - * if (--TCC < 0) - * goto out; + * if ((*tcc_ptr)++ >= MAX_TAIL_CALL_CNT) + * goto out; */ - emit_insn(ctx, addid, REG_TCC, tcc, -1); - if (emit_tailcall_jmp(ctx, BPF_JSLT, REG_TCC, LOONGARCH_GPR_ZERO, jmp_offset) < 0) + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_SP, tcc_ptr_off); + emit_insn(ctx, ldd, t3, REG_TCC, 0); + emit_insn(ctx, addid, t3, t3, 1); + emit_insn(ctx, std, t3, REG_TCC, 0); + emit_insn(ctx, addid, t2, LOONGARCH_GPR_ZERO, MAX_TAIL_CALL_CNT); + if (emit_tailcall_jmp(ctx, BPF_JSGT, t3, t2, jmp_offset) < 0) goto toofar; /* @@ -263,15 +315,6 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx) emit_insn(ctx, ldd, t3, t2, off); __build_epilogue(ctx, true); - /* out: */ - if (out_offset == -1) - out_offset = cur_offset; - if (cur_offset != out_offset) { - pr_err_once("tail_call out_offset = %d, expected %d!\n", - cur_offset, out_offset); - return -1; - } - return 0; toofar: @@ -463,7 +506,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext u64 func_addr; bool func_addr_fixed, sign_extend; int i = insn - ctx->prog->insnsi; - int ret, jmp_offset; + int ret, jmp_offset, tcc_ptr_off; const u8 code = insn->code; const u8 cond = BPF_OP(code); const u8 t1 = LOONGARCH_GPR_T1; @@ -899,12 +942,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext /* function call */ case BPF_JMP | BPF_CALL: - mark_call(ctx); ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &func_addr, &func_addr_fixed); if (ret < 0) return ret; + if (insn->src_reg == BPF_PSEUDO_CALL) { + tcc_ptr_off = BPF_TAIL_CALL_CNT_PTR_STACK_OFF(ctx->stack_size); + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_SP, tcc_ptr_off); + } + move_addr(ctx, t1, func_addr); emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0); @@ -915,8 +962,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext /* tail call */ case BPF_JMP | BPF_TAIL_CALL: - mark_tail_call(ctx); - if (emit_bpf_tail_call(ctx) < 0) + if (emit_bpf_tail_call(ctx, i) < 0) return -EINVAL; break; @@ -1180,12 +1226,526 @@ static int validate_code(struct jit_ctx *ctx) return -1; } + return 0; +} + +static int validate_ctx(struct jit_ctx *ctx) +{ + if (validate_code(ctx)) + return -1; + if (WARN_ON_ONCE(ctx->num_exentries != ctx->prog->aux->num_exentries)) return -1; return 0; } +static int emit_jump_and_link(struct jit_ctx *ctx, u8 rd, u64 target) +{ + if (!target) { + pr_err("bpf_jit: jump target address is error\n"); + return -EFAULT; + } + + move_imm(ctx, LOONGARCH_GPR_T1, target, false); + emit_insn(ctx, jirl, rd, LOONGARCH_GPR_T1, 0); + + return 0; +} + +static int emit_jump_or_nops(void *target, void *ip, u32 *insns, bool is_call) +{ + struct jit_ctx ctx; + + ctx.idx = 0; + ctx.image = (union loongarch_instruction *)insns; + + if (!target) { + emit_insn((&ctx), nop); + emit_insn((&ctx), nop); + return 0; + } + + return emit_jump_and_link(&ctx, is_call ? LOONGARCH_GPR_T0 : LOONGARCH_GPR_ZERO, (u64)target); +} + +static int emit_call(struct jit_ctx *ctx, u64 addr) +{ + return emit_jump_and_link(ctx, LOONGARCH_GPR_RA, addr); +} + +void *bpf_arch_text_copy(void *dst, void *src, size_t len) +{ + int ret; + + mutex_lock(&text_mutex); + ret = larch_insn_text_copy(dst, src, len); + mutex_unlock(&text_mutex); + + return ret ? ERR_PTR(-EINVAL) : dst; +} + +int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type, + void *old_addr, void *new_addr) +{ + int ret; + bool is_call = (poke_type == BPF_MOD_CALL); + u32 old_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP}; + u32 new_insns[LOONGARCH_LONG_JUMP_NINSNS] = {[0 ... 4] = INSN_NOP}; + + if (!is_kernel_text((unsigned long)ip) && + !is_bpf_text_address((unsigned long)ip)) + return -ENOTSUPP; + + ret = emit_jump_or_nops(old_addr, ip, old_insns, is_call); + if (ret) + return ret; + + if (memcmp(ip, old_insns, LOONGARCH_LONG_JUMP_NBYTES)) + return -EFAULT; + + ret = emit_jump_or_nops(new_addr, ip, new_insns, is_call); + if (ret) + return ret; + + mutex_lock(&text_mutex); + if (memcmp(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES)) + ret = larch_insn_text_copy(ip, new_insns, LOONGARCH_LONG_JUMP_NBYTES); + mutex_unlock(&text_mutex); + + return ret; +} + +int bpf_arch_text_invalidate(void *dst, size_t len) +{ + int i; + int ret = 0; + u32 *inst; + + inst = kvmalloc(len, GFP_KERNEL); + if (!inst) + return -ENOMEM; + + for (i = 0; i < (len / sizeof(u32)); i++) + inst[i] = INSN_BREAK; + + mutex_lock(&text_mutex); + if (larch_insn_text_copy(dst, inst, len)) + ret = -EINVAL; + mutex_unlock(&text_mutex); + + kvfree(inst); + + return ret; +} + +static void store_args(struct jit_ctx *ctx, int nargs, int args_off) +{ + int i; + + for (i = 0; i < nargs; i++) { + emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); + args_off -= 8; + } +} + +static void restore_args(struct jit_ctx *ctx, int nargs, int args_off) +{ + int i; + + for (i = 0; i < nargs; i++) { + emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off); + args_off -= 8; + } +} + +static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, + int args_off, int retval_off, int run_ctx_off, bool save_ret) +{ + int ret; + u32 *branch; + struct bpf_prog *p = l->link.prog; + int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); + + if (l->cookie) { + move_imm(ctx, LOONGARCH_GPR_T1, l->cookie, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off); + } else { + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off); + } + + /* arg1: prog */ + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false); + /* arg2: &run_ctx */ + emit_insn(ctx, addid, LOONGARCH_GPR_A1, LOONGARCH_GPR_FP, -run_ctx_off); + ret = emit_call(ctx, (const u64)bpf_trampoline_enter(p)); + if (ret) + return ret; + + /* store prog start time */ + move_reg(ctx, LOONGARCH_GPR_S1, LOONGARCH_GPR_A0); + + /* if (__bpf_prog_enter(prog) == 0) + * goto skip_exec_of_prog; + */ + branch = (u32 *)ctx->image + ctx->idx; + /* nop reserved for conditional jump */ + emit_insn(ctx, nop); + + /* arg1: &args_off */ + emit_insn(ctx, addid, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -args_off); + if (!p->jited) + move_imm(ctx, LOONGARCH_GPR_A1, (const s64)p->insnsi, false); + ret = emit_call(ctx, (const u64)p->bpf_func); + if (ret) + return ret; + + if (save_ret) { + emit_insn(ctx, std, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, std, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8)); + } + + /* update branch with beqz */ + if (ctx->image) { + int offset = (void *)(&ctx->image[ctx->idx]) - (void *)branch; + *branch = larch_insn_gen_beq(LOONGARCH_GPR_A0, LOONGARCH_GPR_ZERO, offset); + } + + /* arg1: prog */ + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false); + /* arg2: prog start time */ + move_reg(ctx, LOONGARCH_GPR_A1, LOONGARCH_GPR_S1); + /* arg3: &run_ctx */ + emit_insn(ctx, addid, LOONGARCH_GPR_A2, LOONGARCH_GPR_FP, -run_ctx_off); + ret = emit_call(ctx, (const u64)bpf_trampoline_exit(p)); + + return ret; +} + +static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl, + int args_off, int retval_off, int run_ctx_off, u32 **branches) +{ + int i; + + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off); + for (i = 0; i < tl->nr_links; i++) { + invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, true); + emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off); + branches[i] = (u32 *)ctx->image + ctx->idx; + emit_insn(ctx, nop); + } +} + +void *arch_alloc_bpf_trampoline(unsigned int size) +{ + return bpf_prog_pack_alloc(size, jit_fill_hole); +} + +void arch_free_bpf_trampoline(void *image, unsigned int size) +{ + bpf_prog_pack_free(image, size); +} + +static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, + const struct btf_func_model *m, struct bpf_tramp_links *tlinks, + void *func_addr, u32 flags) +{ + int i, ret, save_ret; + int stack_size = 0, nargs = 0; + int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off; + bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT; + void *orig_call = func_addr; + struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; + struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; + struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; + u32 **branches = NULL; + + if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) + return -ENOTSUPP; + + /* + * FP + 8 [ RA to parent func ] return address to parent + * function + * FP + 0 [ FP of parent func ] frame pointer of parent + * function + * FP - 8 [ T0 to traced func ] return address of traced + * function + * FP - 16 [ FP of traced func ] frame pointer of traced + * function + * + * FP - retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or + * BPF_TRAMP_F_RET_FENTRY_RET + * [ argN ] + * [ ... ] + * FP - args_off [ arg1 ] + * + * FP - nargs_off [ regs count ] + * + * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG + * + * FP - run_ctx_off [ bpf_tramp_run_ctx ] + * + * FP - sreg_off [ callee saved reg ] + * + * FP - tcc_ptr_off [ tail_call_cnt_ptr ] + */ + + if (m->nr_args > LOONGARCH_MAX_REG_ARGS) + return -ENOTSUPP; + + if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY)) + return -ENOTSUPP; + + stack_size = 0; + + /* Room of trampoline frame to store return address and frame pointer */ + stack_size += 16; + + save_ret = flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET); + if (save_ret) { + /* Save BPF R0 and A0 */ + stack_size += 16; + retval_off = stack_size; + } + + /* Room of trampoline frame to store args */ + nargs = m->nr_args; + stack_size += nargs * 8; + args_off = stack_size; + + /* Room of trampoline frame to store args number */ + stack_size += 8; + nargs_off = stack_size; + + /* Room of trampoline frame to store ip address */ + if (flags & BPF_TRAMP_F_IP_ARG) { + stack_size += 8; + ip_off = stack_size; + } + + /* Room of trampoline frame to store struct bpf_tramp_run_ctx */ + stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8); + run_ctx_off = stack_size; + + stack_size += 8; + sreg_off = stack_size; + + /* Room of trampoline frame to store tail_call_cnt_ptr */ + if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) { + stack_size += 8; + tcc_ptr_off = stack_size; + } + + stack_size = round_up(stack_size, 16); + + if (is_struct_ops) { + /* + * For the trampoline called directly, just handle + * the frame of trampoline. + */ + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size); + emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size); + } else { + /* + * For the trampoline called from function entry, + * the frame of traced function and the frame of + * trampoline need to be considered. + */ + /* RA and FP for parent function */ + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -16); + emit_insn(ctx, std, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8); + emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 16); + + /* RA and FP for traced function */ + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, -stack_size); + emit_insn(ctx, std, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, std, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size); + } + + if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) + emit_insn(ctx, std, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off); + + /* callee saved register S1 to pass start time */ + emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off); + + /* store ip address of the traced function */ + if (flags & BPF_TRAMP_F_IP_ARG) { + move_imm(ctx, LOONGARCH_GPR_T1, (const s64)func_addr, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -ip_off); + } + + /* store nargs number */ + move_imm(ctx, LOONGARCH_GPR_T1, nargs, false); + emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nargs_off); + + store_args(ctx, nargs, args_off); + + /* To traced function */ + /* Ftrace jump skips 2 NOP instructions */ + if (is_kernel_text((unsigned long)orig_call)) + orig_call += LOONGARCH_FENTRY_NBYTES; + /* Direct jump skips 5 NOP instructions */ + else if (is_bpf_text_address((unsigned long)orig_call)) + orig_call += LOONGARCH_BPF_FENTRY_NBYTES; + + if (flags & BPF_TRAMP_F_CALL_ORIG) { + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)im, false); + ret = emit_call(ctx, (const u64)__bpf_tramp_enter); + if (ret) + return ret; + } + + for (i = 0; i < fentry->nr_links; i++) { + ret = invoke_bpf_prog(ctx, fentry->links[i], args_off, retval_off, + run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET); + if (ret) + return ret; + } + if (fmod_ret->nr_links) { + branches = kcalloc(fmod_ret->nr_links, sizeof(u32 *), GFP_KERNEL); + if (!branches) + return -ENOMEM; + + invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off, run_ctx_off, branches); + } + + if (flags & BPF_TRAMP_F_CALL_ORIG) { + restore_args(ctx, m->nr_args, args_off); + + if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off); + + ret = emit_call(ctx, (const u64)orig_call); + if (ret) + goto out; + emit_insn(ctx, std, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, std, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8)); + im->ip_after_call = ctx->ro_image + ctx->idx; + /* Reserve space for the move_imm + jirl instruction */ + for (i = 0; i < LOONGARCH_LONG_JUMP_NINSNS; i++) + emit_insn(ctx, nop); + } + + for (i = 0; ctx->image && i < fmod_ret->nr_links; i++) { + int offset = (void *)(&ctx->image[ctx->idx]) - (void *)branches[i]; + *branches[i] = larch_insn_gen_bne(LOONGARCH_GPR_T1, LOONGARCH_GPR_ZERO, offset); + } + + for (i = 0; i < fexit->nr_links; i++) { + ret = invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off, run_ctx_off, false); + if (ret) + goto out; + } + + if (flags & BPF_TRAMP_F_CALL_ORIG) { + im->ip_epilogue = ctx->ro_image + ctx->idx; + move_imm(ctx, LOONGARCH_GPR_A0, (const s64)im, false); + ret = emit_call(ctx, (const u64)__bpf_tramp_exit); + if (ret) + goto out; + } + + if (flags & BPF_TRAMP_F_RESTORE_REGS) + restore_args(ctx, m->nr_args, args_off); + + if (save_ret) { + emit_insn(ctx, ldd, LOONGARCH_GPR_A0, LOONGARCH_GPR_FP, -retval_off); + emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8)); + } + + emit_insn(ctx, ldd, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off); + + if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) + emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off); + + if (is_struct_ops) { + /* trampoline called directly */ + emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size); + + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0); + } else { + /* trampoline called from function entry */ + emit_insn(ctx, ldd, LOONGARCH_GPR_T0, LOONGARCH_GPR_SP, stack_size - 8); + emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_size - 16); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, stack_size); + + emit_insn(ctx, ldd, LOONGARCH_GPR_RA, LOONGARCH_GPR_SP, 8); + emit_insn(ctx, ldd, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, 0); + emit_insn(ctx, addid, LOONGARCH_GPR_SP, LOONGARCH_GPR_SP, 16); + + if (flags & BPF_TRAMP_F_SKIP_FRAME) + /* return to parent function */ + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0); + else + /* return to traced function */ + emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T0, 0); + } + + ret = ctx->idx; +out: + kfree(branches); + + return ret; +} + +int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image, + void *ro_image_end, const struct btf_func_model *m, + u32 flags, struct bpf_tramp_links *tlinks, void *func_addr) +{ + int ret, size; + void *image, *tmp; + struct jit_ctx ctx; + + size = ro_image_end - ro_image; + image = kvmalloc(size, GFP_KERNEL); + if (!image) + return -ENOMEM; + + ctx.image = (union loongarch_instruction *)image; + ctx.ro_image = (union loongarch_instruction *)ro_image; + ctx.idx = 0; + + jit_fill_hole(image, (unsigned int)(ro_image_end - ro_image)); + ret = __arch_prepare_bpf_trampoline(&ctx, im, m, tlinks, func_addr, flags); + if (ret > 0 && validate_code(&ctx) < 0) { + ret = -EINVAL; + goto out; + } + + tmp = bpf_arch_text_copy(ro_image, image, size); + if (IS_ERR(tmp)) { + ret = PTR_ERR(tmp); + goto out; + } + + bpf_flush_icache(ro_image, ro_image_end); +out: + kvfree(image); + return ret < 0 ? ret : size; +} + +int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, + struct bpf_tramp_links *tlinks, void *func_addr) +{ + int ret; + struct jit_ctx ctx; + struct bpf_tramp_image im; + + ctx.image = NULL; + ctx.idx = 0; + + ret = __arch_prepare_bpf_trampoline(&ctx, &im, m, tlinks, func_addr, flags); + + /* Page align */ + return ret < 0 ? ret : round_up(ret * LOONGARCH_INSN_SIZE, PAGE_SIZE); +} + struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) { bool tmp_blinded = false, extra_pass = false; @@ -1288,7 +1848,7 @@ skip_init_ctx: build_epilogue(&ctx); /* 3. Extra pass to validate JITed code */ - if (validate_code(&ctx)) { + if (validate_ctx(&ctx)) { bpf_jit_binary_free(header); prog = orig_prog; goto out_offset; @@ -1342,7 +1902,6 @@ out: if (tmp_blinded) bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog); - out_offset = -1; return prog; @@ -1354,6 +1913,16 @@ out_free: goto out_offset; } +bool bpf_jit_bypass_spec_v1(void) +{ + return true; +} + +bool bpf_jit_bypass_spec_v4(void) +{ + return true; +} + /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ bool bpf_jit_supports_subprog_tailcalls(void) { diff --git a/arch/loongarch/net/bpf_jit.h b/arch/loongarch/net/bpf_jit.h index f9c569f53949..5697158fd164 100644 --- a/arch/loongarch/net/bpf_jit.h +++ b/arch/loongarch/net/bpf_jit.h @@ -18,6 +18,7 @@ struct jit_ctx { u32 *offset; int num_exentries; union loongarch_instruction *image; + union loongarch_instruction *ro_image; u32 stack_size; }; @@ -308,3 +309,8 @@ static inline int emit_tailcall_jmp(struct jit_ctx *ctx, u8 cond, enum loongarch return -EINVAL; } + +static inline void bpf_flush_icache(void *start, void *end) +{ + flush_icache_range((unsigned long)start, (unsigned long)end); +} diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile index ccd2c5e135c6..d8316f993482 100644 --- a/arch/loongarch/vdso/Makefile +++ b/arch/loongarch/vdso/Makefile @@ -36,7 +36,7 @@ endif # VDSO linker flags. ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \ - $(filter -E%,$(KBUILD_CFLAGS)) -nostdlib -shared --build-id -T + $(filter -E%,$(KBUILD_CFLAGS)) -shared --build-id -T # # Shared build commands. diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 162ebd73a698..99f7bf95ca16 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -26,7 +26,7 @@ #include <asm/irq.h> #include <asm/sections.h> -#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +#ifdef CONFIG_X86_LOCAL_APIC struct irq_data; struct pci_dev; struct msi_desc; @@ -103,10 +103,10 @@ static inline void irq_complete_move(struct irq_cfg *c) { } #endif extern void apic_ack_edge(struct irq_data *data); -#else /* CONFIG_IRQ_DOMAIN_HIERARCHY */ +#else /* CONFIG_X86_LOCAL_APIC */ static inline void lock_vector_lock(void) {} static inline void unlock_vector_lock(void) {} -#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */ +#endif /* !CONFIG_X86_LOCAL_APIC */ /* Statistics */ extern atomic_t irq_err_count; diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index be10c188614f..e345dbdf933e 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -150,6 +150,11 @@ #define INTEL_PANTHERLAKE_L IFM(6, 0xCC) /* Cougar Cove / Crestmont */ +#define INTEL_WILDCATLAKE_L IFM(6, 0xD5) + +#define INTEL_NOVALAKE IFM(18, 0x01) +#define INTEL_NOVALAKE_L IFM(18, 0x03) + /* "Small Core" Processors (Atom/E-Core) */ #define INTEL_ATOM_BONNELL IFM(6, 0x1C) /* Diamondville, Pineview */ diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 9ed29ff10e59..10721a125226 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -256,26 +256,59 @@ static __always_inline void handle_irq(struct irq_desc *desc, __handle_irq(desc, regs); } -static __always_inline int call_irq_handler(int vector, struct pt_regs *regs) +static struct irq_desc *reevaluate_vector(int vector) { - struct irq_desc *desc; - int ret = 0; + struct irq_desc *desc = __this_cpu_read(vector_irq[vector]); + + if (!IS_ERR_OR_NULL(desc)) + return desc; + + if (desc == VECTOR_UNUSED) + pr_emerg_ratelimited("No irq handler for %d.%u\n", smp_processor_id(), vector); + else + __this_cpu_write(vector_irq[vector], VECTOR_UNUSED); + return NULL; +} + +static __always_inline bool call_irq_handler(int vector, struct pt_regs *regs) +{ + struct irq_desc *desc = __this_cpu_read(vector_irq[vector]); - desc = __this_cpu_read(vector_irq[vector]); if (likely(!IS_ERR_OR_NULL(desc))) { handle_irq(desc, regs); - } else { - ret = -EINVAL; - if (desc == VECTOR_UNUSED) { - pr_emerg_ratelimited("%s: %d.%u No irq handler for vector\n", - __func__, smp_processor_id(), - vector); - } else { - __this_cpu_write(vector_irq[vector], VECTOR_UNUSED); - } + return true; } - return ret; + /* + * Reevaluate with vector_lock held to prevent a race against + * request_irq() setting up the vector: + * + * CPU0 CPU1 + * interrupt is raised in APIC IRR + * but not handled + * free_irq() + * per_cpu(vector_irq, CPU1)[vector] = VECTOR_SHUTDOWN; + * + * request_irq() common_interrupt() + * d = this_cpu_read(vector_irq[vector]); + * + * per_cpu(vector_irq, CPU1)[vector] = desc; + * + * if (d == VECTOR_SHUTDOWN) + * this_cpu_write(vector_irq[vector], VECTOR_UNUSED); + * + * This requires that the same vector on the same target CPU is + * handed out or that a spurious interrupt hits that CPU/vector. + */ + lock_vector_lock(); + desc = reevaluate_vector(vector); + unlock_vector_lock(); + + if (!desc) + return false; + + handle_irq(desc, regs); + return true; } /* @@ -289,7 +322,7 @@ DEFINE_IDTENTRY_IRQ(common_interrupt) /* entry code tells RCU that we're not quiescent. Check it. */ RCU_LOCKDEP_WARN(!rcu_is_watching(), "IRQ failed to wake up RCU"); - if (unlikely(call_irq_handler(vector, regs))) + if (unlikely(!call_irq_handler(vector, regs))) apic_eoi(); set_irq_regs(old_regs); diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h index 687a3a7ba784..0b4704932d72 100644 --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -427,9 +427,6 @@ struct bfq_iocq_bfqq_data { */ bool saved_IO_bound; - u64 saved_io_start_time; - u64 saved_tot_idle_time; - /* * Same purpose as the previous fields for the values of the * field keeping the queue's belonging to a large burst @@ -450,6 +447,9 @@ struct bfq_iocq_bfqq_data { */ unsigned int saved_weight; + u64 saved_io_start_time; + u64 saved_tot_idle_time; + /* * Similar to previous fields: save wr information. */ @@ -457,13 +457,13 @@ struct bfq_iocq_bfqq_data { unsigned long saved_last_wr_start_finish; unsigned long saved_service_from_wr; unsigned long saved_wr_start_at_switch_to_srt; - unsigned int saved_wr_cur_max_time; struct bfq_ttime saved_ttime; + unsigned int saved_wr_cur_max_time; /* Save also injection state */ - u64 saved_last_serv_time_ns; unsigned int saved_inject_limit; unsigned long saved_decrease_time_jif; + u64 saved_last_serv_time_ns; /* candidate queue for a stable merge (due to close creation time) */ struct bfq_queue *stable_merge_bfqq; diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index d1585f073776..6112d942499b 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -21,6 +21,7 @@ struct regmap_irq_chip_data { struct mutex lock; + struct lock_class_key lock_key; struct irq_chip irq_chip; struct regmap *map; @@ -801,7 +802,13 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, goto err_alloc; } - mutex_init(&d->lock); + /* + * If one regmap-irq is the parent of another then we'll try + * to lock the child with the parent locked, use an explicit + * lock_key so lockdep can figure out what's going on. + */ + lockdep_register_key(&d->lock_key); + mutex_init_with_key(&d->lock, &d->lock_key); for (i = 0; i < chip->num_irqs; i++) d->mask_buf_def[chip->irqs[i].reg_offset / map->reg_stride] @@ -816,7 +823,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, d->mask_buf[i], chip->irq_drv_data); if (ret) - goto err_alloc; + goto err_mutex; } if (chip->mask_base && !chip->handle_mask_sync) { @@ -827,7 +834,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (ret) { dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", reg, ret); - goto err_alloc; + goto err_mutex; } } @@ -838,7 +845,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (ret) { dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", reg, ret); - goto err_alloc; + goto err_mutex; } } @@ -855,7 +862,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (ret != 0) { dev_err(map->dev, "Failed to read IRQ status: %d\n", ret); - goto err_alloc; + goto err_mutex; } } @@ -879,7 +886,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (ret != 0) { dev_err(map->dev, "Failed to ack 0x%x: %d\n", reg, ret); - goto err_alloc; + goto err_mutex; } } } @@ -901,7 +908,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (ret != 0) { dev_err(map->dev, "Failed to set masks in 0x%x: %d\n", reg, ret); - goto err_alloc; + goto err_mutex; } } } @@ -910,7 +917,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, if (chip->status_is_level) { ret = read_irq_data(d); if (ret < 0) - goto err_alloc; + goto err_mutex; memcpy(d->prev_status_buf, d->status_buf, array_size(d->chip->num_regs, sizeof(d->prev_status_buf[0]))); @@ -918,7 +925,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, ret = regmap_irq_create_domain(fwnode, irq_base, chip, d); if (ret) - goto err_alloc; + goto err_mutex; ret = request_threaded_irq(irq, NULL, regmap_irq_thread, irq_flags | IRQF_ONESHOT, @@ -935,6 +942,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, err_domain: /* Should really dispose of the domain but... */ +err_mutex: + mutex_destroy(&d->lock); + lockdep_unregister_key(&d->lock_key); err_alloc: kfree(d->type_buf); kfree(d->type_buf_def); @@ -1027,6 +1037,8 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d) kfree(d->config_buf[i]); kfree(d->config_buf); } + mutex_destroy(&d->lock); + lockdep_unregister_key(&d->lock_key); kfree(d); } EXPORT_SYMBOL_GPL(regmap_del_irq_chip); diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index ce17c5ea67e8..22a2953adbd6 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -2416,6 +2416,13 @@ static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code) btintel_pcie_reset(hdev); } +static bool btintel_pcie_wakeup(struct hci_dev *hdev) +{ + struct btintel_pcie_data *data = hci_get_drvdata(hdev); + + return device_may_wakeup(&data->pdev->dev); +} + static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) { int err; @@ -2441,6 +2448,7 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) hdev->set_diag = btintel_set_diag; hdev->set_bdaddr = btintel_set_bdaddr; hdev->reset = btintel_pcie_reset; + hdev->wakeup = btintel_pcie_wakeup; err = hci_register_dev(hdev); if (err < 0) { diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 4390fd571dbd..a8c520dc09e1 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -642,12 +642,7 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev, * WMT command. */ err = wait_on_bit_timeout(&data->flags, BTMTK_TX_WAIT_VND_EVT, - TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT); - if (err == -EINTR) { - bt_dev_err(hdev, "Execution of wmt command interrupted"); - clear_bit(BTMTK_TX_WAIT_VND_EVT, &data->flags); - goto err_free_wc; - } + TASK_UNINTERRUPTIBLE, HCI_INIT_TIMEOUT); if (err) { bt_dev_err(hdev, "Execution of wmt command timed out"); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 8085fabadde8..3595a8bad6bd 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -522,6 +522,8 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8851BU Bluetooth devices */ { USB_DEVICE(0x3625, 0x010b), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2001, 0x332a), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek 8852AE Bluetooth devices */ { USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK | diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 064944ae9fdc..8e9050f99e9e 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4607,10 +4607,10 @@ return_unspecified: * The NetFN and Command in the response is not even * marginally correct. */ - dev_warn(intf->si_dev, - "BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n", - (msg->data[0] >> 2) | 1, msg->data[1], - msg->rsp[0] >> 2, msg->rsp[1]); + dev_warn_ratelimited(intf->si_dev, + "BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n", + (msg->data[0] >> 2) | 1, msg->data[1], + msg->rsp[0] >> 2, msg->rsp[1]); goto return_unspecified; } diff --git a/drivers/dpll/zl3073x/Kconfig b/drivers/dpll/zl3073x/Kconfig index 7db262ab8458..9915f7423dea 100644 --- a/drivers/dpll/zl3073x/Kconfig +++ b/drivers/dpll/zl3073x/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config ZL3073X - tristate "Microchip Azurite DPLL/PTP/SyncE devices" + tristate "Microchip Azurite DPLL/PTP/SyncE devices" if COMPILE_TEST depends on NET select DPLL select NET_DEVLINK @@ -16,9 +16,9 @@ config ZL3073X config ZL3073X_I2C tristate "I2C bus implementation for Microchip Azurite devices" - depends on I2C && ZL3073X + depends on I2C select REGMAP_I2C - default m + select ZL3073X help This is I2C bus implementation for Microchip Azurite DPLL/PTP/SyncE devices. @@ -28,9 +28,9 @@ config ZL3073X_I2C config ZL3073X_SPI tristate "SPI bus implementation for Microchip Azurite devices" - depends on SPI && ZL3073X + depends on SPI select REGMAP_SPI - default m + select ZL3073X help This is SPI bus implementation for Microchip Azurite DPLL/PTP/SyncE devices. diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c index 6f3dda6b635f..390f2e74a9d8 100644 --- a/drivers/gpio/gpio-mlxbf2.c +++ b/drivers/gpio/gpio-mlxbf2.c @@ -397,7 +397,7 @@ mlxbf2_gpio_probe(struct platform_device *pdev) gc->ngpio = npins; gc->owner = THIS_MODULE; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq >= 0) { girq = &gs->gc.irq; gpio_irq_chip_set_chip(girq, &mlxbf2_gpio_irq_chip); diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 13f7da2a9486..cbcdd416f8b9 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -499,8 +499,6 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) gfer = readl_relaxed(base + GFER_OFFSET) & ~GPIO_bit(gpio); writel_relaxed(grer, base + GRER_OFFSET); writel_relaxed(gfer, base + GFER_OFFSET); - - gpiochip_disable_irq(&pchip->chip, gpio); } static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) @@ -520,21 +518,17 @@ static void pxa_unmask_muxed_gpio(struct irq_data *d) unsigned int gpio = irqd_to_hwirq(d); struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio); - gpiochip_enable_irq(&pchip->chip, gpio); - c->irq_mask |= GPIO_bit(gpio); update_edge_detect(c); } -static const struct irq_chip pxa_muxed_gpio_chip = { +static struct irq_chip pxa_muxed_gpio_chip = { .name = "GPIO", .irq_ack = pxa_ack_muxed_gpio, .irq_mask = pxa_mask_muxed_gpio, .irq_unmask = pxa_unmask_muxed_gpio, .irq_set_type = pxa_gpio_irq_type, .irq_set_wake = pxa_gpio_set_wake, - .flags = IRQCHIP_IMMUTABLE, - GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static int pxa_gpio_nums(struct platform_device *pdev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c index cbc40cad581b..d1e431818212 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c @@ -130,6 +130,27 @@ static void aca_smu_bank_dump(struct amdgpu_device *adev, int idx, int total, st RAS_EVENT_LOG(adev, event_id, HW_ERR "hardware error logged by the scrubber\n"); } +static bool aca_bank_hwip_is_matched(struct aca_bank *bank, enum aca_hwip_type type) +{ + + struct aca_hwip *hwip; + int hwid, mcatype; + u64 ipid; + + if (!bank || type == ACA_HWIP_TYPE_UNKNOW) + return false; + + hwip = &aca_hwid_mcatypes[type]; + if (!hwip->hwid) + return false; + + ipid = bank->regs[ACA_REG_IDX_IPID]; + hwid = ACA_REG__IPID__HARDWAREID(ipid); + mcatype = ACA_REG__IPID__MCATYPE(ipid); + + return hwip->hwid == hwid && hwip->mcatype == mcatype; +} + static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_type type, int start, int count, struct aca_banks *banks, struct ras_query_context *qctx) @@ -168,6 +189,15 @@ static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_ bank.smu_err_type = type; + /* + * Poison being consumed when injecting a UE while running background workloads, + * which are unexpected. + */ + if (type == ACA_SMU_TYPE_UE && + ACA_REG__STATUS__POISON(bank.regs[ACA_REG_IDX_STATUS]) && + !aca_bank_hwip_is_matched(&bank, ACA_HWIP_TYPE_UMC)) + continue; + aca_smu_bank_dump(adev, i, count, &bank, qctx); ret = aca_banks_add_bank(banks, &bank); @@ -178,27 +208,6 @@ static int aca_smu_get_valid_aca_banks(struct amdgpu_device *adev, enum aca_smu_ return 0; } -static bool aca_bank_hwip_is_matched(struct aca_bank *bank, enum aca_hwip_type type) -{ - - struct aca_hwip *hwip; - int hwid, mcatype; - u64 ipid; - - if (!bank || type == ACA_HWIP_TYPE_UNKNOW) - return false; - - hwip = &aca_hwid_mcatypes[type]; - if (!hwip->hwid) - return false; - - ipid = bank->regs[ACA_REG_IDX_IPID]; - hwid = ACA_REG__IPID__HARDWAREID(ipid); - mcatype = ACA_REG__IPID__MCATYPE(ipid); - - return hwip->hwid == hwid && hwip->mcatype == mcatype; -} - static bool aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, enum aca_smu_type type) { const struct aca_bank_ops *bank_ops = handle->bank_ops; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 260165bbe373..37d8a7034a7e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -494,7 +494,8 @@ static int vm_update_pds(struct amdgpu_vm *vm, struct amdgpu_sync *sync) return amdgpu_sync_fence(sync, vm->last_update, GFP_KERNEL); } -static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem) +static uint64_t get_pte_flags(struct amdgpu_device *adev, struct amdgpu_vm *vm, + struct kgd_mem *mem) { uint32_t mapping_flags = AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_DEFAULT; @@ -504,7 +505,7 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem) if (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE) mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE; - return amdgpu_gem_va_map_flags(adev, mapping_flags); + return mapping_flags; } /** @@ -961,7 +962,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, goto unwind; } attachment[i]->va = va; - attachment[i]->pte_flags = get_pte_flags(adev, mem); + attachment[i]->pte_flags = get_pte_flags(adev, vm, mem); attachment[i]->adev = adev; list_add(&attachment[i]->list, &mem->attachments); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c index 25252231a68a..6c266f18c598 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c @@ -206,6 +206,7 @@ int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev { struct cper_sec_desc *section_desc; struct cper_sec_nonstd_err *section; + uint32_t socket_id; section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx)); section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr + @@ -224,6 +225,9 @@ int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump); /* Hardcoded Reg dump for bad page threshold CPER */ + socket_id = (adev->smuio.funcs && adev->smuio.funcs->get_socket_id) ? + adev->smuio.funcs->get_socket_id(adev) : + 0; section->ctx.reg_dump[CPER_ACA_REG_CTL_LO] = 0x1; section->ctx.reg_dump[CPER_ACA_REG_CTL_HI] = 0x0; section->ctx.reg_dump[CPER_ACA_REG_STATUS_LO] = 0x137; @@ -234,8 +238,8 @@ int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev section->ctx.reg_dump[CPER_ACA_REG_MISC0_HI] = 0x0; section->ctx.reg_dump[CPER_ACA_REG_CONFIG_LO] = 0x2; section->ctx.reg_dump[CPER_ACA_REG_CONFIG_HI] = 0x1ff; - section->ctx.reg_dump[CPER_ACA_REG_IPID_LO] = 0x0; - section->ctx.reg_dump[CPER_ACA_REG_IPID_HI] = 0x96; + section->ctx.reg_dump[CPER_ACA_REG_IPID_LO] = (socket_id / 4) & 0x01; + section->ctx.reg_dump[CPER_ACA_REG_IPID_HI] = 0x096 | (((socket_id % 4) & 0x3) << 12); section->ctx.reg_dump[CPER_ACA_REG_SYND_LO] = 0x0; section->ctx.reg_dump[CPER_ACA_REG_SYND_HI] = 0x0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index a2adaacf6adb..27f8f316f6c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -396,7 +396,7 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p, chunk_ib->ib_bytes : 0, AMDGPU_IB_POOL_DELAYED, ib); if (r) { - DRM_ERROR("Failed to get ib !\n"); + drm_err(adev_to_drm(p->adev), "Failed to get ib !\n"); return r; } @@ -468,7 +468,7 @@ static int amdgpu_syncobj_lookup_and_add(struct amdgpu_cs_parser *p, r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence); if (r) { - DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n", + drm_err(adev_to_drm(p->adev), "syncobj %u failed to find fence @ %llu (%d)!\n", handle, point, r); return r; } @@ -902,7 +902,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, sizeof(struct page *), GFP_KERNEL); if (!e->user_pages) { - DRM_ERROR("kvmalloc_array failure\n"); + drm_err(adev_to_drm(p->adev), "kvmalloc_array failure\n"); r = -ENOMEM; goto out_free_user_pages; } @@ -983,7 +983,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, r = amdgpu_vm_validate(p->adev, &fpriv->vm, NULL, amdgpu_cs_bo_validate, p); if (r) { - DRM_ERROR("amdgpu_vm_validate() failed.\n"); + drm_err(adev_to_drm(p->adev), "amdgpu_vm_validate() failed.\n"); goto out_free_user_pages; } @@ -1061,13 +1061,13 @@ static int amdgpu_cs_patch_ibs(struct amdgpu_cs_parser *p, va_start = ib->gpu_addr & AMDGPU_GMC_HOLE_MASK; r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m); if (r) { - DRM_ERROR("IB va_start is invalid\n"); + drm_err(adev_to_drm(p->adev), "IB va_start is invalid\n"); return r; } if ((va_start + ib->length_dw * 4) > (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) { - DRM_ERROR("IB va_start+ib_bytes is invalid\n"); + drm_err(adev_to_drm(p->adev), "IB va_start+ib_bytes is invalid\n"); return -EINVAL; } @@ -1235,7 +1235,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]); if (r) { if (r != -ERESTARTSYS) - DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n"); + drm_err(adev_to_drm(p->adev), "amdgpu_ctx_wait_prev_fence failed.\n"); return r; } @@ -1448,7 +1448,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = amdgpu_cs_parser_init(&parser, adev, filp, data); if (r) { - DRM_ERROR_RATELIMITED("Failed to initialize parser %d!\n", r); + drm_err_ratelimited(dev, "Failed to initialize parser %d!\n", r); return r; } @@ -1463,9 +1463,9 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = amdgpu_cs_parser_bos(&parser, data); if (r) { if (r == -ENOMEM) - DRM_ERROR("Not enough memory for command submission!\n"); + drm_err(dev, "Not enough memory for command submission!\n"); else if (r != -ERESTARTSYS && r != -EAGAIN) - DRM_DEBUG("Failed to process the buffer list %d!\n", r); + drm_dbg(dev, "Failed to process the buffer list %d!\n", r); goto error_fini; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6f93473436be..3843e30fb3f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3389,7 +3389,7 @@ static int amdgpu_device_enable_mgpu_fan_boost(void) for (i = 0; i < mgpu_info.num_dgpu; i++) { gpu_ins = &(mgpu_info.gpu_ins[i]); adev = gpu_ins->adev; - if (!(adev->flags & AMD_IS_APU) && + if (!(adev->flags & AMD_IS_APU || amdgpu_sriov_multi_vf_mode(adev)) && !gpu_ins->mgpu_fan_enabled) { ret = amdgpu_dpm_enable_mgpu_fan_boost(adev); if (ret) @@ -5701,7 +5701,7 @@ int amdgpu_device_link_reset(struct amdgpu_device *adev) dev_info(adev->dev, "GPU link reset\n"); - if (!adev->pcie_reset_ctx.occurs_dpc) + if (!amdgpu_reset_in_dpc(adev)) ret = amdgpu_dpm_link_reset(adev); if (ret) @@ -6136,12 +6136,11 @@ static int amdgpu_device_health_check(struct list_head *device_list_handle) return ret; } -static int amdgpu_device_recovery_prepare(struct amdgpu_device *adev, +static void amdgpu_device_recovery_prepare(struct amdgpu_device *adev, struct list_head *device_list, struct amdgpu_hive_info *hive) { struct amdgpu_device *tmp_adev = NULL; - int r; /* * Build list of devices to reset. @@ -6153,7 +6152,7 @@ static int amdgpu_device_recovery_prepare(struct amdgpu_device *adev, list_add_tail(&tmp_adev->reset_list, device_list); if (adev->shutdown) tmp_adev->shutdown = true; - if (adev->pcie_reset_ctx.occurs_dpc) + if (amdgpu_reset_in_dpc(adev)) tmp_adev->pcie_reset_ctx.in_link_reset = true; } if (!list_is_first(&adev->reset_list, device_list)) @@ -6161,14 +6160,6 @@ static int amdgpu_device_recovery_prepare(struct amdgpu_device *adev, } else { list_add_tail(&adev->reset_list, device_list); } - - if (!amdgpu_sriov_vf(adev) && (!adev->pcie_reset_ctx.occurs_dpc)) { - r = amdgpu_device_health_check(device_list); - if (r) - return r; - } - - return 0; } static void amdgpu_device_recovery_get_reset_lock(struct amdgpu_device *adev, @@ -6237,9 +6228,8 @@ static void amdgpu_device_halt_activities(struct amdgpu_device *adev, drm_client_dev_suspend(adev_to_drm(tmp_adev), false); /* disable ras on ALL IPs */ - if (!need_emergency_restart && - (!adev->pcie_reset_ctx.occurs_dpc) && - amdgpu_device_ip_need_full_reset(tmp_adev)) + if (!need_emergency_restart && !amdgpu_reset_in_dpc(adev) && + amdgpu_device_ip_need_full_reset(tmp_adev)) amdgpu_ras_suspend(tmp_adev); for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { @@ -6267,10 +6257,10 @@ static int amdgpu_device_asic_reset(struct amdgpu_device *adev, retry: /* Rest of adevs pre asic reset from XGMI hive. */ list_for_each_entry(tmp_adev, device_list, reset_list) { - if (adev->pcie_reset_ctx.occurs_dpc) + if (amdgpu_reset_in_dpc(adev)) tmp_adev->no_hw_access = true; r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context); - if (adev->pcie_reset_ctx.occurs_dpc) + if (amdgpu_reset_in_dpc(adev)) tmp_adev->no_hw_access = false; /*TODO Should we stop ?*/ if (r) { @@ -6461,8 +6451,13 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, reset_context->hive = hive; INIT_LIST_HEAD(&device_list); - if (amdgpu_device_recovery_prepare(adev, &device_list, hive)) - goto end_reset; + amdgpu_device_recovery_prepare(adev, &device_list, hive); + + if (!amdgpu_sriov_vf(adev)) { + r = amdgpu_device_health_check(&device_list); + if (r) + goto end_reset; + } /* We need to lock reset domain only once both for XGMI and single device */ amdgpu_device_recovery_get_reset_lock(adev, &device_list); @@ -6907,7 +6902,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta if (hive) mutex_lock(&hive->hive_lock); - adev->pcie_reset_ctx.occurs_dpc = true; + amdgpu_reset_set_dpc_status(adev, true); memset(&reset_context, 0, sizeof(reset_context)); INIT_LIST_HEAD(&device_list); @@ -6969,12 +6964,6 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev) int r = 0, i; u32 memsize; - /* PCI error slot reset should be skipped During RAS recovery */ - if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) || - amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4)) && - amdgpu_ras_in_recovery(adev)) - return PCI_ERS_RESULT_RECOVERED; - dev_info(adev->dev, "PCI error: slot reset callback!!\n"); memset(&reset_context, 0, sizeof(reset_context)); @@ -7076,7 +7065,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev) amdgpu_device_sched_resume(&device_list, NULL, NULL); amdgpu_device_gpu_resume(adev, &device_list, false); amdgpu_device_recovery_put_reset_lock(adev, &device_list); - adev->pcie_reset_ctx.occurs_dpc = false; + amdgpu_reset_set_dpc_status(adev, false); if (hive) { mutex_unlock(&hive->hive_lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index efb54c23ba17..141ba1f100d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2597,6 +2597,7 @@ static int amdgpu_pmops_suspend(struct device *dev) else if (amdgpu_acpi_is_s3_active(adev)) adev->in_s3 = true; if (!adev->in_s0ix && !adev->in_s3) { +#if IS_ENABLED(CONFIG_SUSPEND) /* don't allow going deep first time followed by s2idle the next time */ if (adev->last_suspend_state != PM_SUSPEND_ON && adev->last_suspend_state != pm_suspend_target_state) { @@ -2604,11 +2605,14 @@ static int amdgpu_pmops_suspend(struct device *dev) pm_suspend_target_state); return -EINVAL; } +#endif return 0; } +#if IS_ENABLED(CONFIG_SUSPEND) /* cache the state last used for suspend */ adev->last_suspend_state = pm_suspend_target_state; +#endif return amdgpu_device_suspend(drm_dev, true); } @@ -2964,15 +2968,15 @@ out: } static const struct dev_pm_ops amdgpu_pm_ops = { - .prepare = amdgpu_pmops_prepare, - .complete = amdgpu_pmops_complete, - .suspend = amdgpu_pmops_suspend, - .suspend_noirq = amdgpu_pmops_suspend_noirq, - .resume = amdgpu_pmops_resume, - .freeze = amdgpu_pmops_freeze, - .thaw = amdgpu_pmops_thaw, - .poweroff = amdgpu_pmops_poweroff, - .restore = amdgpu_pmops_restore, + .prepare = pm_sleep_ptr(amdgpu_pmops_prepare), + .complete = pm_sleep_ptr(amdgpu_pmops_complete), + .suspend = pm_sleep_ptr(amdgpu_pmops_suspend), + .suspend_noirq = pm_sleep_ptr(amdgpu_pmops_suspend_noirq), + .resume = pm_sleep_ptr(amdgpu_pmops_resume), + .freeze = pm_sleep_ptr(amdgpu_pmops_freeze), + .thaw = pm_sleep_ptr(amdgpu_pmops_thaw), + .poweroff = pm_sleep_ptr(amdgpu_pmops_poweroff), + .restore = pm_sleep_ptr(amdgpu_pmops_restore), .runtime_suspend = amdgpu_pmops_runtime_suspend, .runtime_resume = amdgpu_pmops_runtime_resume, .runtime_idle = amdgpu_pmops_runtime_idle, @@ -3117,7 +3121,7 @@ static struct pci_driver amdgpu_kms_pci_driver = { .probe = amdgpu_pci_probe, .remove = amdgpu_pci_remove, .shutdown = amdgpu_pci_shutdown, - .driver.pm = &amdgpu_pm_ops, + .driver.pm = pm_ptr(&amdgpu_pm_ops), .err_handler = &amdgpu_pci_err_handler, .dev_groups = amdgpu_sysfs_groups, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 9e7506965cab..bcb74286a78a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -738,7 +738,7 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring) } -/** +/* * Kernel queue reset handling * * The driver can reset individual queues for most engines, but those queues diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 6626a6e64ff5..d5e685c5e28b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -790,36 +790,6 @@ error: return fence; } -/** - * amdgpu_gem_va_map_flags - map GEM UAPI flags into hardware flags - * - * @adev: amdgpu_device pointer - * @flags: GEM UAPI flags - * - * Returns the GEM UAPI flags mapped into hardware for the ASIC. - */ -uint64_t amdgpu_gem_va_map_flags(struct amdgpu_device *adev, uint32_t flags) -{ - uint64_t pte_flag = 0; - - if (flags & AMDGPU_VM_PAGE_EXECUTABLE) - pte_flag |= AMDGPU_PTE_EXECUTABLE; - if (flags & AMDGPU_VM_PAGE_READABLE) - pte_flag |= AMDGPU_PTE_READABLE; - if (flags & AMDGPU_VM_PAGE_WRITEABLE) - pte_flag |= AMDGPU_PTE_WRITEABLE; - if (flags & AMDGPU_VM_PAGE_PRT) - pte_flag |= AMDGPU_PTE_PRT_FLAG(adev); - if (flags & AMDGPU_VM_PAGE_NOALLOC) - pte_flag |= AMDGPU_PTE_NOALLOC; - - if (adev->gmc.gmc_funcs->map_mtype) - pte_flag |= amdgpu_gmc_map_mtype(adev, - flags & AMDGPU_VM_MTYPE_MASK); - - return pte_flag; -} - int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -840,7 +810,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, struct dma_fence_chain *timeline_chain = NULL; struct dma_fence *fence; struct drm_exec exec; - uint64_t va_flags; uint64_t vm_size; int r = 0; @@ -944,10 +913,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, switch (args->operation) { case AMDGPU_VA_OP_MAP: - va_flags = amdgpu_gem_va_map_flags(adev, args->flags); r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, args->offset_in_bo, args->map_size, - va_flags); + args->flags); break; case AMDGPU_VA_OP_UNMAP: r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); @@ -959,10 +927,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, args->map_size); break; case AMDGPU_VA_OP_REPLACE: - va_flags = amdgpu_gem_va_map_flags(adev, args->flags); r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address, args->offset_in_bo, args->map_size, - va_flags); + args->flags); break; default: break; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h index 3a8f57900a3a..b51e8f95ee86 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h @@ -63,7 +63,6 @@ int amdgpu_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); -uint64_t amdgpu_gem_va_map_flags(struct amdgpu_device *adev, uint32_t flags); int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index 397c6ccdb903..55097ca10738 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -154,15 +154,15 @@ struct amdgpu_gmc_funcs { unsigned pasid); /* enable/disable PRT support */ void (*set_prt)(struct amdgpu_device *adev, bool enable); - /* map mtype to hardware flags */ - uint64_t (*map_mtype)(struct amdgpu_device *adev, uint32_t flags); /* get the pde for a given mc addr */ void (*get_vm_pde)(struct amdgpu_device *adev, int level, u64 *dst, u64 *flags); - /* get the pte flags to use for a BO VA mapping */ + /* get the pte flags to use for PTEs */ void (*get_vm_pte)(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, - uint64_t *flags); + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, + uint64_t *pte_flags); /* override per-page pte flags */ void (*override_vm_pte_flags)(struct amdgpu_device *dev, struct amdgpu_vm *vm, @@ -356,9 +356,10 @@ struct amdgpu_gmc { #define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr)) #define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid)) -#define amdgpu_gmc_map_mtype(adev, flags) (adev)->gmc.gmc_funcs->map_mtype((adev),(flags)) #define amdgpu_gmc_get_vm_pde(adev, level, dst, flags) (adev)->gmc.gmc_funcs->get_vm_pde((adev), (level), (dst), (flags)) -#define amdgpu_gmc_get_vm_pte(adev, mapping, flags) (adev)->gmc.gmc_funcs->get_vm_pte((adev), (mapping), (flags)) +#define amdgpu_gmc_get_vm_pte(adev, vm, bo, vm_flags, pte_flags) \ + ((adev)->gmc.gmc_funcs->get_vm_pte((adev), (vm), (bo), (vm_flags), \ + (pte_flags))) #define amdgpu_gmc_override_vm_pte_flags(adev, vm, addr, pte_flags) \ (adev)->gmc.gmc_funcs->override_vm_pte_flags \ ((adev), (vm), (addr), (pte_flags)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index e6061d45f142..9b1c55115921 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -365,13 +365,6 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job, dev_err(ring->adev->dev, "Error getting VM ID (%d)\n", r); goto error; } - /* - * The VM structure might be released after the VMID is - * assigned, we had multiple problems with people trying to use - * the VM pointer so better set it to NULL. - */ - if (!fence) - job->vm = NULL; return fence; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c index e56ba93a8df6..a974265837f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.c @@ -55,7 +55,8 @@ u64 amdgpu_nbio_get_pcie_replay_count(struct amdgpu_device *adev) bool amdgpu_nbio_is_replay_cnt_supported(struct amdgpu_device *adev) { - if (amdgpu_sriov_vf(adev) || !adev->asic_funcs->get_pcie_replay_count || + if (amdgpu_sriov_vf(adev) || !adev->asic_funcs || + !adev->asic_funcs->get_pcie_replay_count || (!adev->nbio.funcs || !adev->nbio.funcs->get_pcie_replay_count)) return false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index c316920f3450..87523fcd4386 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -69,7 +69,7 @@ struct amdgpu_bo_va_mapping { uint64_t last; uint64_t __subtree_last; uint64_t offset; - uint64_t flags; + uint32_t flags; }; /* User space allocated BO in a VM */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index eb3c28669789..25bade9a5e95 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2622,7 +2622,7 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, goto out; } - *bps = kmalloc(sizeof(struct ras_badpage) * data->count, GFP_KERNEL); + *bps = kmalloc_array(data->count, sizeof(struct ras_badpage), GFP_KERNEL); if (!*bps) { ret = -ENOMEM; goto out; @@ -2786,7 +2786,7 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev, unsigned int old_space = data->count + data->space_left; unsigned int new_space = old_space + pages; unsigned int align_space = ALIGN(new_space, 512); - void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL); + void *bps = kmalloc_array(align_space, sizeof(*data->bps), GFP_KERNEL); if (!bps) { return -ENOMEM; @@ -3363,7 +3363,6 @@ static void amdgpu_ras_do_page_retirement(struct work_struct *work) page_retirement_dwork.work); struct amdgpu_device *adev = con->adev; struct ras_err_data err_data; - unsigned long err_cnt; /* If gpu reset is ongoing, delay retiring the bad pages */ if (amdgpu_in_reset(adev) || amdgpu_ras_in_recovery(adev)) { @@ -3375,13 +3374,9 @@ static void amdgpu_ras_do_page_retirement(struct work_struct *work) amdgpu_ras_error_data_init(&err_data); amdgpu_umc_handle_bad_pages(adev, &err_data); - err_cnt = err_data.err_addr_cnt; amdgpu_ras_error_data_fini(&err_data); - if (err_cnt && amdgpu_ras_is_rma(adev)) - amdgpu_ras_reset_gpu(adev); - amdgpu_ras_schedule_retirement_dwork(con, AMDGPU_RAS_RETIRE_PAGE_INTERVAL); } @@ -3435,6 +3430,9 @@ static int amdgpu_ras_poison_creation_handler(struct amdgpu_device *adev, if (total_detect_count) schedule_delayed_work(&ras->page_retirement_dwork, 0); + if (amdgpu_ras_is_rma(adev) && atomic_cmpxchg(&ras->rma_in_recovery, 0, 1) == 0) + amdgpu_ras_reset_gpu(adev); + return 0; } @@ -3470,6 +3468,12 @@ static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev, reset_flags |= msg.reset; } + /* + * Try to ensure poison creation handler is completed first + * to set rma if bad page exceed threshold. + */ + flush_delayed_work(&con->page_retirement_dwork); + /* for RMA, amdgpu_ras_poison_creation_handler will trigger gpu reset */ if (reset_flags && !amdgpu_ras_is_rma(adev)) { if (reset_flags & AMDGPU_RAS_GPU_RESET_MODE1_RESET) @@ -3479,8 +3483,6 @@ static int amdgpu_ras_poison_consumption_handler(struct amdgpu_device *adev, else reset = reset_flags; - flush_delayed_work(&con->page_retirement_dwork); - con->gpu_reset_flags |= reset; amdgpu_ras_reset_gpu(adev); @@ -3648,6 +3650,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info) mutex_init(&con->recovery_lock); INIT_WORK(&con->recovery_work, amdgpu_ras_do_recovery); atomic_set(&con->in_recovery, 0); + atomic_set(&con->rma_in_recovery, 0); con->eeprom_control.bad_channel_bitmap = 0; max_eeprom_records_count = amdgpu_ras_eeprom_max_record_count(&con->eeprom_control); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index 434e23c84962..ff63020f9c6c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -522,6 +522,7 @@ struct amdgpu_ras { /* gpu recovery */ struct work_struct recovery_work; atomic_t in_recovery; + atomic_t rma_in_recovery; struct amdgpu_device *adev; /* error handler data */ struct ras_err_handler_data *eh_data; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h index 4d9b9701139b..3a806953338f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h @@ -160,4 +160,15 @@ int amdgpu_reset_do_xgmi_reset_on_init( bool amdgpu_reset_in_recovery(struct amdgpu_device *adev); +static inline void amdgpu_reset_set_dpc_status(struct amdgpu_device *adev, + bool status) +{ + adev->pcie_reset_ctx.occurs_dpc = status; +} + +static inline bool amdgpu_reset_in_dpc(struct amdgpu_device *adev) +{ + return adev->pcie_reset_ctx.occurs_dpc; +} + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c index d45ebfb642ca..a0b479d5fff1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c @@ -67,9 +67,9 @@ static inline u64 amdgpu_seq64_get_va_base(struct amdgpu_device *adev) int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo_va **bo_va) { - u64 seq64_addr, va_flags; struct amdgpu_bo *bo; struct drm_exec exec; + u64 seq64_addr; int r; bo = adev->seq64.sbo; @@ -94,9 +94,9 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, seq64_addr = amdgpu_seq64_get_va_base(adev) & AMDGPU_GMC_HOLE_MASK; - va_flags = amdgpu_gem_va_map_flags(adev, AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC); - r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE, - va_flags); + r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, + AMDGPU_VA_RESERVED_SEQ64_SIZE, + AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_MTYPE_UC); if (r) { DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r); amdgpu_vm_bo_del(adev, *bo_va); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index f1f67521c29c..b497a6714138 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -92,6 +92,7 @@ MODULE_FIRMWARE(FIRMWARE_VCN5_0_0); MODULE_FIRMWARE(FIRMWARE_VCN5_0_1); static void amdgpu_vcn_idle_work_handler(struct work_struct *work); +static void amdgpu_vcn_reg_dump_fini(struct amdgpu_device *adev); int amdgpu_vcn_early_init(struct amdgpu_device *adev, int i) { @@ -285,6 +286,10 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev, int i) amdgpu_ucode_release(&adev->vcn.inst[0].fw); adev->vcn.inst[i].fw = NULL; } + + if (adev->vcn.reg_list) + amdgpu_vcn_reg_dump_fini(adev); + mutex_destroy(&adev->vcn.inst[i].vcn_pg_lock); mutex_destroy(&adev->vcn.inst[i].vcn1_jpeg1_workaround); @@ -1527,3 +1532,85 @@ int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring, return amdgpu_vcn_reset_engine(adev, ring->me); } + +int amdgpu_vcn_reg_dump_init(struct amdgpu_device *adev, + const struct amdgpu_hwip_reg_entry *reg, u32 count) +{ + adev->vcn.ip_dump = kcalloc(adev->vcn.num_vcn_inst * count, + sizeof(uint32_t), GFP_KERNEL); + if (!adev->vcn.ip_dump) + return -ENOMEM; + adev->vcn.reg_list = reg; + adev->vcn.reg_count = count; + + return 0; +} + +static void amdgpu_vcn_reg_dump_fini(struct amdgpu_device *adev) +{ + kfree(adev->vcn.ip_dump); + adev->vcn.reg_list = NULL; + adev->vcn.reg_count = 0; +} + +void amdgpu_vcn_dump_ip_state(struct amdgpu_ip_block *ip_block) +{ + struct amdgpu_device *adev = ip_block->adev; + int i, j; + bool is_powered; + u32 inst_off; + + if (!adev->vcn.ip_dump) + return; + + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + + inst_off = i * adev->vcn.reg_count; + /* mmUVD_POWER_STATUS is always readable and is the first in reg_list */ + adev->vcn.ip_dump[inst_off] = + RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->vcn.reg_list[0], i)); + is_powered = (adev->vcn.ip_dump[inst_off] & + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF) != + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; + + if (is_powered) + for (j = 1; j < adev->vcn.reg_count; j++) + adev->vcn.ip_dump[inst_off + j] = + RREG32(SOC15_REG_ENTRY_OFFSET_INST(adev->vcn.reg_list[j], i)); + } +} + +void amdgpu_vcn_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) +{ + struct amdgpu_device *adev = ip_block->adev; + int i, j; + bool is_powered; + u32 inst_off; + + if (!adev->vcn.ip_dump) + return; + + drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) { + drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); + continue; + } + + inst_off = i * adev->vcn.reg_count; + is_powered = (adev->vcn.ip_dump[inst_off] & + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF) != + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF; + + if (is_powered) { + drm_printf(p, "\nActive Instance:VCN%d\n", i); + for (j = 0; j < adev->vcn.reg_count; j++) + drm_printf(p, "%-50s \t 0x%08x\n", adev->vcn.reg_list[j].reg_name, + adev->vcn.ip_dump[inst_off + j]); + } else { + drm_printf(p, "\nInactive Instance:VCN%d\n", i); + } + } +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 0bc0a94d7cf0..b3fb1d0e43fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -237,6 +237,8 @@ #define AMDGPU_DRM_KEY_INJECT_WORKAROUND_VCNFW_ASD_HANDSHAKING 2 +struct amdgpu_hwip_reg_entry; + enum amdgpu_vcn_caps { AMDGPU_VCN_RRMT_ENABLED, }; @@ -362,6 +364,8 @@ struct amdgpu_vcn { bool workload_profile_active; struct mutex workload_profile_mutex; + u32 reg_count; + const struct amdgpu_hwip_reg_entry *reg_list; }; struct amdgpu_fw_shared_rb_ptrs_struct { @@ -557,4 +561,8 @@ int vcn_set_powergating_state(struct amdgpu_ip_block *ip_block, int amdgpu_vcn_ring_reset(struct amdgpu_ring *ring, unsigned int vmid, struct amdgpu_fence *guilty_fence); +int amdgpu_vcn_reg_dump_init(struct amdgpu_device *adev, + const struct amdgpu_hwip_reg_entry *reg, u32 count); +void amdgpu_vcn_dump_ip_state(struct amdgpu_ip_block *ip_block); +void amdgpu_vcn_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 5cacf5717016..39b4250ede0f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1332,13 +1332,14 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here * but in case of something, we filter the flags in first place */ - if (!(mapping->flags & AMDGPU_PTE_READABLE)) + if (!(mapping->flags & AMDGPU_VM_PAGE_READABLE)) update_flags &= ~AMDGPU_PTE_READABLE; - if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) + if (!(mapping->flags & AMDGPU_VM_PAGE_WRITEABLE)) update_flags &= ~AMDGPU_PTE_WRITEABLE; /* Apply ASIC specific mapping flags */ - amdgpu_gmc_get_vm_pte(adev, mapping, &update_flags); + amdgpu_gmc_get_vm_pte(adev, vm, bo, mapping->flags, + &update_flags); trace_amdgpu_vm_bo_update(mapping); @@ -1479,7 +1480,7 @@ static void amdgpu_vm_free_mapping(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping, struct dma_fence *fence) { - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev)) + if (mapping->flags & AMDGPU_VM_PAGE_PRT) amdgpu_vm_add_prt_cb(adev, fence); kfree(mapping); } @@ -1758,7 +1759,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev, list_add(&mapping->list, &bo_va->invalids); amdgpu_vm_it_insert(mapping, &vm->va); - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev)) + if (mapping->flags & AMDGPU_VM_PAGE_PRT) amdgpu_vm_prt_get(adev); if (amdgpu_vm_is_bo_always_valid(vm, bo) && !bo_va->base.moved) @@ -1818,7 +1819,7 @@ static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev, int amdgpu_vm_bo_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t saddr, uint64_t offset, - uint64_t size, uint64_t flags) + uint64_t size, uint32_t flags) { struct amdgpu_bo_va_mapping *mapping, *tmp; struct amdgpu_bo *bo = bo_va->base.bo; @@ -1877,7 +1878,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t saddr, uint64_t offset, - uint64_t size, uint64_t flags) + uint64_t size, uint32_t flags) { struct amdgpu_bo_va_mapping *mapping; struct amdgpu_bo *bo = bo_va->base.bo; @@ -2734,7 +2735,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) dma_fence_put(vm->last_tlb_flush); list_for_each_entry_safe(mapping, tmp, &vm->freed, list) { - if (mapping->flags & AMDGPU_PTE_PRT_FLAG(adev) && prt_fini_needed) { + if (mapping->flags & AMDGPU_VM_PAGE_PRT && prt_fini_needed) { amdgpu_vm_prt_fini(adev, vm); prt_fini_needed = false; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index fd086efd8457..3b4fa3246675 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -538,11 +538,11 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, int amdgpu_vm_bo_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t addr, uint64_t offset, - uint64_t size, uint64_t flags); + uint64_t size, uint32_t flags); int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t addr, uint64_t offset, - uint64_t size, uint64_t flags); + uint64_t size, uint32_t flags); int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, uint64_t addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index c417f8689220..699acc1b46b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -406,6 +406,7 @@ void amdgpu_xcp_dev_unplug(struct amdgpu_device *adev) p_ddev->primary->dev = adev->xcp_mgr->xcp[i].pdev; p_ddev->driver = adev->xcp_mgr->xcp[i].driver; p_ddev->vma_offset_manager = adev->xcp_mgr->xcp[i].vma_offset_manager; + amdgpu_xcp_drm_dev_free(p_ddev); } } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 7923f491cf73..7031dd8c3c5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -466,24 +466,6 @@ static void gmc_v10_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned int * 0 valid */ -static uint64_t gmc_v10_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) -{ - switch (flags) { - case AMDGPU_VM_MTYPE_DEFAULT: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_NC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_WC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_WC); - case AMDGPU_VM_MTYPE_CC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_CC); - case AMDGPU_VM_MTYPE_UC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_UC); - default: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - } -} - static void gmc_v10_0_get_vm_pde(struct amdgpu_device *adev, int level, uint64_t *addr, uint64_t *flags) { @@ -508,21 +490,39 @@ static void gmc_v10_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v10_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { - struct amdgpu_bo *bo = mapping->bo_va->base.bo; - - *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) + *flags |= AMDGPU_PTE_EXECUTABLE; + else + *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK; - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK); + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { + case AMDGPU_VM_MTYPE_DEFAULT: + case AMDGPU_VM_MTYPE_NC: + default: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_NC); + break; + case AMDGPU_VM_MTYPE_WC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_WC); + break; + case AMDGPU_VM_MTYPE_CC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_CC); + break; + case AMDGPU_VM_MTYPE_UC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_UC); + break; + } - *flags &= ~AMDGPU_PTE_NOALLOC; - *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC); + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) + *flags |= AMDGPU_PTE_NOALLOC; + else + *flags &= ~AMDGPU_PTE_NOALLOC; - if (mapping->flags & AMDGPU_PTE_PRT) { + if (vm_flags & AMDGPU_VM_PAGE_PRT) { *flags |= AMDGPU_PTE_PRT; *flags |= AMDGPU_PTE_SNOOPED; *flags |= AMDGPU_PTE_LOG; @@ -563,7 +563,6 @@ static const struct amdgpu_gmc_funcs gmc_v10_0_gmc_funcs = { .flush_gpu_tlb_pasid = gmc_v10_0_flush_gpu_tlb_pasid, .emit_flush_gpu_tlb = gmc_v10_0_emit_flush_gpu_tlb, .emit_pasid_mapping = gmc_v10_0_emit_pasid_mapping, - .map_mtype = gmc_v10_0_map_mtype, .get_vm_pde = gmc_v10_0_get_vm_pde, .get_vm_pte = gmc_v10_0_get_vm_pte, .get_vbios_fb_size = gmc_v10_0_get_vbios_fb_size, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index f15d691e9a20..93d2b0bbe641 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -430,24 +430,6 @@ static void gmc_v11_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned int * 0 valid */ -static uint64_t gmc_v11_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) -{ - switch (flags) { - case AMDGPU_VM_MTYPE_DEFAULT: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_NC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_WC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_WC); - case AMDGPU_VM_MTYPE_CC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_CC); - case AMDGPU_VM_MTYPE_UC: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_UC); - default: - return AMDGPU_PTE_MTYPE_NV10(0ULL, MTYPE_NC); - } -} - static void gmc_v11_0_get_vm_pde(struct amdgpu_device *adev, int level, uint64_t *addr, uint64_t *flags) { @@ -472,21 +454,39 @@ static void gmc_v11_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v11_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { - struct amdgpu_bo *bo = mapping->bo_va->base.bo; - - *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) + *flags |= AMDGPU_PTE_EXECUTABLE; + else + *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags &= ~AMDGPU_PTE_MTYPE_NV10_MASK; - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_NV10_MASK); + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { + case AMDGPU_VM_MTYPE_DEFAULT: + case AMDGPU_VM_MTYPE_NC: + default: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_NC); + break; + case AMDGPU_VM_MTYPE_WC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_WC); + break; + case AMDGPU_VM_MTYPE_CC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_CC); + break; + case AMDGPU_VM_MTYPE_UC: + *flags = AMDGPU_PTE_MTYPE_NV10(*flags, MTYPE_UC); + break; + } - *flags &= ~AMDGPU_PTE_NOALLOC; - *flags |= (mapping->flags & AMDGPU_PTE_NOALLOC); + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) + *flags |= AMDGPU_PTE_NOALLOC; + else + *flags &= ~AMDGPU_PTE_NOALLOC; - if (mapping->flags & AMDGPU_PTE_PRT) { + if (vm_flags & AMDGPU_VM_PAGE_PRT) { *flags |= AMDGPU_PTE_PRT; *flags |= AMDGPU_PTE_SNOOPED; *flags |= AMDGPU_PTE_LOG; @@ -527,7 +527,6 @@ static const struct amdgpu_gmc_funcs gmc_v11_0_gmc_funcs = { .flush_gpu_tlb_pasid = gmc_v11_0_flush_gpu_tlb_pasid, .emit_flush_gpu_tlb = gmc_v11_0_emit_flush_gpu_tlb, .emit_pasid_mapping = gmc_v11_0_emit_pasid_mapping, - .map_mtype = gmc_v11_0_map_mtype, .get_vm_pde = gmc_v11_0_get_vm_pde, .get_vm_pte = gmc_v11_0_get_vm_pte, .get_vbios_fb_size = gmc_v11_0_get_vbios_fb_size, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index de763105fdfd..a0a5367f9dc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -453,20 +453,6 @@ static void gmc_v12_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned vmid * 0 valid */ -static uint64_t gmc_v12_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) -{ - switch (flags) { - case AMDGPU_VM_MTYPE_DEFAULT: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_NC: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_UC: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_UC); - default: - return AMDGPU_PTE_MTYPE_GFX12(0ULL, MTYPE_NC); - } -} - static void gmc_v12_0_get_vm_pde(struct amdgpu_device *adev, int level, uint64_t *addr, uint64_t *flags) { @@ -490,19 +476,35 @@ static void gmc_v12_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v12_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { - struct amdgpu_bo *bo = mapping->bo_va->base.bo; + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) + *flags |= AMDGPU_PTE_EXECUTABLE; + else + *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { + case AMDGPU_VM_MTYPE_DEFAULT: + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_NC); + break; + case AMDGPU_VM_MTYPE_NC: + default: + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_NC); + break; + case AMDGPU_VM_MTYPE_UC: + *flags = AMDGPU_PTE_MTYPE_GFX12(*flags, MTYPE_UC); + break; + } - *flags &= ~AMDGPU_PTE_MTYPE_GFX12_MASK; - *flags |= (mapping->flags & AMDGPU_PTE_MTYPE_GFX12_MASK); + if (vm_flags & AMDGPU_VM_PAGE_NOALLOC) + *flags |= AMDGPU_PTE_NOALLOC; + else + *flags &= ~AMDGPU_PTE_NOALLOC; - if (mapping->flags & AMDGPU_PTE_PRT_GFX12) { - *flags |= AMDGPU_PTE_PRT_GFX12; + if (vm_flags & AMDGPU_VM_PAGE_PRT) { *flags |= AMDGPU_PTE_SNOOPED; *flags |= AMDGPU_PTE_SYSTEM; *flags |= AMDGPU_PTE_IS_PTE; @@ -543,7 +545,6 @@ static const struct amdgpu_gmc_funcs gmc_v12_0_gmc_funcs = { .flush_gpu_tlb_pasid = gmc_v12_0_flush_gpu_tlb_pasid, .emit_flush_gpu_tlb = gmc_v12_0_emit_flush_gpu_tlb, .emit_pasid_mapping = gmc_v12_0_emit_pasid_mapping, - .map_mtype = gmc_v12_0_map_mtype, .get_vm_pde = gmc_v12_0_get_vm_pde, .get_vm_pte = gmc_v12_0_get_vm_pte, .get_vbios_fb_size = gmc_v12_0_get_vbios_fb_size, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 8030fcd64210..f6ad7911f1e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -382,7 +382,9 @@ static void gmc_v6_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v6_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { *flags &= ~AMDGPU_PTE_EXECUTABLE; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index a8d5795084fc..93d7ccb7d013 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -504,7 +504,9 @@ static void gmc_v7_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v7_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { *flags &= ~AMDGPU_PTE_EXECUTABLE; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index b45fa0cea9d2..c5e2a2c41e06 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -716,11 +716,15 @@ static void gmc_v8_0_get_vm_pde(struct amdgpu_device *adev, int level, } static void gmc_v8_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { - *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) + *flags |= AMDGPU_PTE_EXECUTABLE; + else + *flags &= ~AMDGPU_PTE_EXECUTABLE; *flags &= ~AMDGPU_PTE_PRT; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index c4d69cf4e06c..8404695eb13f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1073,27 +1073,6 @@ static void gmc_v9_0_emit_pasid_mapping(struct amdgpu_ring *ring, unsigned int v * 0 valid */ -static uint64_t gmc_v9_0_map_mtype(struct amdgpu_device *adev, uint32_t flags) - -{ - switch (flags) { - case AMDGPU_VM_MTYPE_DEFAULT: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_NC: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); - case AMDGPU_VM_MTYPE_WC: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_WC); - case AMDGPU_VM_MTYPE_RW: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_RW); - case AMDGPU_VM_MTYPE_CC: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_CC); - case AMDGPU_VM_MTYPE_UC: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_UC); - default: - return AMDGPU_PTE_MTYPE_VG10(0ULL, MTYPE_NC); - } -} - static void gmc_v9_0_get_vm_pde(struct amdgpu_device *adev, int level, uint64_t *addr, uint64_t *flags) { @@ -1123,6 +1102,7 @@ static void gmc_v9_0_get_vm_pde(struct amdgpu_device *adev, int level, static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { struct amdgpu_device *bo_adev = amdgpu_ttm_adev(bo->tbo.bdev); @@ -1236,25 +1216,43 @@ static void gmc_v9_0_get_coherence_flags(struct amdgpu_device *adev, } static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev, - struct amdgpu_bo_va_mapping *mapping, + struct amdgpu_vm *vm, + struct amdgpu_bo *bo, + uint32_t vm_flags, uint64_t *flags) { - struct amdgpu_bo *bo = mapping->bo_va->base.bo; - - *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags |= mapping->flags & AMDGPU_PTE_EXECUTABLE; + if (vm_flags & AMDGPU_VM_PAGE_EXECUTABLE) + *flags |= AMDGPU_PTE_EXECUTABLE; + else + *flags &= ~AMDGPU_PTE_EXECUTABLE; - *flags &= ~AMDGPU_PTE_MTYPE_VG10_MASK; - *flags |= mapping->flags & AMDGPU_PTE_MTYPE_VG10_MASK; + switch (vm_flags & AMDGPU_VM_MTYPE_MASK) { + case AMDGPU_VM_MTYPE_DEFAULT: + case AMDGPU_VM_MTYPE_NC: + default: + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_NC); + break; + case AMDGPU_VM_MTYPE_WC: + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC); + break; + case AMDGPU_VM_MTYPE_RW: + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW); + break; + case AMDGPU_VM_MTYPE_CC: + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC); + break; + case AMDGPU_VM_MTYPE_UC: + *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC); + break; + } - if (mapping->flags & AMDGPU_PTE_PRT) { + if (vm_flags & AMDGPU_VM_PAGE_PRT) { *flags |= AMDGPU_PTE_PRT; *flags &= ~AMDGPU_PTE_VALID; } if ((*flags & AMDGPU_PTE_VALID) && bo) - gmc_v9_0_get_coherence_flags(adev, mapping->bo_va->base.vm, bo, - flags); + gmc_v9_0_get_coherence_flags(adev, vm, bo, vm_flags, flags); } static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev, @@ -1391,7 +1389,6 @@ static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = { .flush_gpu_tlb_pasid = gmc_v9_0_flush_gpu_tlb_pasid, .emit_flush_gpu_tlb = gmc_v9_0_emit_flush_gpu_tlb, .emit_pasid_mapping = gmc_v9_0_emit_pasid_mapping, - .map_mtype = gmc_v9_0_map_mtype, .get_vm_pde = gmc_v9_0_get_vm_pde, .get_vm_pte = gmc_v9_0_get_vm_pte, .override_vm_pte_flags = gmc_v9_0_override_vm_pte_flags, diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c index b86288a69e7b..a78144773fab 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c @@ -444,7 +444,7 @@ static int jpeg_v4_0_3_hw_fini(struct amdgpu_ip_block *ip_block) ret = jpeg_v4_0_3_set_powergating_state(ip_block, AMD_PG_STATE_GATE); } - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG)) + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG) && !amdgpu_sriov_vf(adev)) amdgpu_irq_put(adev, &adev->jpeg.inst->ras_poison_irq, 0); return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c index 54523dc1f702..a2d781898767 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c @@ -196,6 +196,14 @@ static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) } } + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG)) { + r = amdgpu_jpeg_ras_sw_init(adev); + if (r) { + dev_err(adev->dev, "Failed to initialize jpeg ras block!\n"); + return r; + } + } + r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_1, ARRAY_SIZE(jpeg_reg_list_5_0_1)); if (r) return r; @@ -1016,8 +1024,9 @@ static int jpeg_v5_0_1_aca_bank_parser(struct aca_handle *handle, struct aca_ban /* reference to smu driver if header file */ static int jpeg_v5_0_1_err_codes[] = { - 16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-7][S|D] */ - 24, 25, 26, 27, 28, 29, 30, 31 + 16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-9][S|D] */ + 24, 25, 26, 27, 28, 29, 30, 31, + 48, 49, 50, 51, }; static bool jpeg_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, @@ -1058,6 +1067,11 @@ static int jpeg_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_comm if (r) return r; + r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__JPEG, + &jpeg_v5_0_1_aca_info, NULL); + if (r) + goto late_fini; + if (amdgpu_ras_is_supported(adev, ras_block->block) && adev->jpeg.inst->ras_poison_irq.funcs) { r = amdgpu_irq_get(adev, &adev->jpeg.inst->ras_poison_irq, 0); @@ -1065,11 +1079,6 @@ static int jpeg_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_comm goto late_fini; } - r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__JPEG, - &jpeg_v5_0_1_aca_info, NULL); - if (r) - goto late_fini; - return 0; late_fini: diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c index 134c4ec10887..910337dc28d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c @@ -36,40 +36,47 @@ static const char *mmhub_client_ids_v3_0_1[][2] = { [0][0] = "VMC", + [1][0] = "ISPXT", + [2][0] = "ISPIXT", [4][0] = "DCEDMC", [5][0] = "DCEVGA", [6][0] = "MP0", [7][0] = "MP1", - [8][0] = "MPIO", - [16][0] = "HDP", - [17][0] = "LSDMA", - [18][0] = "JPEG", - [19][0] = "VCNU0", - [21][0] = "VSCH", - [22][0] = "VCNU1", - [23][0] = "VCN1", - [32+20][0] = "VCN0", - [2][1] = "DBGUNBIO", + [8][0] = "MPM", + [12][0] = "ISPTNR", + [14][0] = "ISPCRD0", + [15][0] = "ISPCRD1", + [16][0] = "ISPCRD2", + [22][0] = "HDP", + [23][0] = "LSDMA", + [24][0] = "JPEG", + [27][0] = "VSCH", + [28][0] = "VCNU", + [29][0] = "VCN", + [1][1] = "ISPXT", + [2][1] = "ISPIXT", [3][1] = "DCEDWB", [4][1] = "DCEDMC", [5][1] = "DCEVGA", [6][1] = "MP0", [7][1] = "MP1", - [8][1] = "MPIO", - [10][1] = "DBGU0", - [11][1] = "DBGU1", - [12][1] = "DBGU2", - [13][1] = "DBGU3", - [14][1] = "XDP", - [15][1] = "OSSSYS", - [16][1] = "HDP", - [17][1] = "LSDMA", - [18][1] = "JPEG", - [19][1] = "VCNU0", - [20][1] = "VCN0", - [21][1] = "VSCH", - [22][1] = "VCNU1", - [23][1] = "VCN1", + [8][1] = "MPM", + [10][1] = "ISPMWR0", + [11][1] = "ISPMWR1", + [12][1] = "ISPTNR", + [13][1] = "ISPSWR", + [14][1] = "ISPCWR0", + [15][1] = "ISPCWR1", + [16][1] = "ISPCWR2", + [17][1] = "ISPCWR3", + [18][1] = "XDP", + [21][1] = "OSSSYS", + [22][1] = "HDP", + [23][1] = "LSDMA", + [24][1] = "JPEG", + [27][1] = "VSCH", + [28][1] = "VCNU", + [29][1] = "VCN", }; static uint32_t mmhub_v3_0_1_get_invalidate_req(unsigned int vmid, diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c index bc3d6c2fc87a..f6fc9778bc30 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c @@ -40,30 +40,129 @@ static const char *mmhub_client_ids_v3_3[][2] = { [0][0] = "VMC", + [1][0] = "ISPXT", + [2][0] = "ISPIXT", [4][0] = "DCEDMC", [6][0] = "MP0", [7][0] = "MP1", [8][0] = "MPM", + [9][0] = "ISPPDPRD", + [10][0] = "ISPCSTATRD", + [11][0] = "ISPBYRPRD", + [12][0] = "ISPRGBPRD", + [13][0] = "ISPMCFPRD", + [14][0] = "ISPMCFPRD1", + [15][0] = "ISPYUVPRD", + [16][0] = "ISPMCSCRD", + [17][0] = "ISPGDCRD", + [18][0] = "ISPLMERD", + [22][0] = "ISPXT1", + [23][0] = "ISPIXT1", [24][0] = "HDP", [25][0] = "LSDMA", [26][0] = "JPEG", [27][0] = "VPE", + [28][0] = "VSCH", [29][0] = "VCNU", [30][0] = "VCN", + [1][1] = "ISPXT", + [2][1] = "ISPIXT", [3][1] = "DCEDWB", [4][1] = "DCEDMC", + [5][1] = "ISPCSISWR", [6][1] = "MP0", [7][1] = "MP1", [8][1] = "MPM", + [9][1] = "ISPPDPWR", + [10][1] = "ISPCSTATWR", + [11][1] = "ISPBYRPWR", + [12][1] = "ISPRGBPWR", + [13][1] = "ISPMCFPWR", + [14][1] = "ISPMWR0", + [15][1] = "ISPYUVPWR", + [16][1] = "ISPMCSCWR", + [17][1] = "ISPGDCWR", + [18][1] = "ISPLMEWR", + [20][1] = "ISPMWR2", [21][1] = "OSSSYS", + [22][1] = "ISPXT1", + [23][1] = "ISPIXT1", [24][1] = "HDP", [25][1] = "LSDMA", [26][1] = "JPEG", [27][1] = "VPE", + [28][1] = "VSCH", [29][1] = "VCNU", [30][1] = "VCN", }; +static const char *mmhub_client_ids_v3_3_1[][2] = { + [0][0] = "VMC", + [4][0] = "DCEDMC", + [6][0] = "MP0", + [7][0] = "MP1", + [8][0] = "MPM", + [24][0] = "HDP", + [25][0] = "LSDMA", + [26][0] = "JPEG0", + [27][0] = "VPE0", + [28][0] = "VSCH", + [29][0] = "VCNU0", + [30][0] = "VCN0", + [32+1][0] = "ISPXT", + [32+2][0] = "ISPIXT", + [32+9][0] = "ISPPDPRD", + [32+10][0] = "ISPCSTATRD", + [32+11][0] = "ISPBYRPRD", + [32+12][0] = "ISPRGBPRD", + [32+13][0] = "ISPMCFPRD", + [32+14][0] = "ISPMCFPRD1", + [32+15][0] = "ISPYUVPRD", + [32+16][0] = "ISPMCSCRD", + [32+17][0] = "ISPGDCRD", + [32+18][0] = "ISPLMERD", + [32+22][0] = "ISPXT1", + [32+23][0] = "ISPIXT1", + [32+26][0] = "JPEG1", + [32+27][0] = "VPE1", + [32+29][0] = "VCNU1", + [32+30][0] = "VCN1", + [3][1] = "DCEDWB", + [4][1] = "DCEDMC", + [6][1] = "MP0", + [7][1] = "MP1", + [8][1] = "MPM", + [21][1] = "OSSSYS", + [24][1] = "HDP", + [25][1] = "LSDMA", + [26][1] = "JPEG0", + [27][1] = "VPE0", + [28][1] = "VSCH", + [29][1] = "VCNU0", + [30][1] = "VCN0", + [32+1][1] = "ISPXT", + [32+2][1] = "ISPIXT", + [32+5][1] = "ISPCSISWR", + [32+9][1] = "ISPPDPWR", + [32+10][1] = "ISPCSTATWR", + [32+11][1] = "ISPBYRPWR", + [32+12][1] = "ISPRGBPWR", + [32+13][1] = "ISPMCFPWR", + [32+14][1] = "ISPMWR0", + [32+15][1] = "ISPYUVPWR", + [32+16][1] = "ISPMCSCWR", + [32+17][1] = "ISPGDCWR", + [32+18][1] = "ISPLMEWR", + [32+19][1] = "ISPMWR1", + [32+20][1] = "ISPMWR2", + [32+22][1] = "ISPXT1", + [32+23][1] = "ISPIXT1", + [32+26][1] = "JPEG1", + [32+27][1] = "VPE1", + [32+29][1] = "VCNU1", + [32+30][1] = "VCN1", +}; + static uint32_t mmhub_v3_3_get_invalidate_req(unsigned int vmid, uint32_t flush_type) { @@ -102,12 +201,16 @@ mmhub_v3_3_print_l2_protection_fault_status(struct amdgpu_device *adev, switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) { case IP_VERSION(3, 3, 0): - case IP_VERSION(3, 3, 1): case IP_VERSION(3, 3, 2): mmhub_cid = cid < ARRAY_SIZE(mmhub_client_ids_v3_3) ? mmhub_client_ids_v3_3[cid][rw] : cid == 0x140 ? "UMSCH" : NULL; break; + case IP_VERSION(3, 3, 1): + mmhub_cid = cid < ARRAY_SIZE(mmhub_client_ids_v3_3_1) ? + mmhub_client_ids_v3_3_1[cid][rw] : + cid == 0x140 ? "UMSCH" : NULL; + break; default: mmhub_cid = NULL; break; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c index b8b06d4c5882..326ecc8d37d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c @@ -1353,7 +1353,7 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block) switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { case IP_VERSION(7, 0, 0): case IP_VERSION(7, 0, 1): - if ((adev->sdma.instance[0].fw_version >= 7836028) && !adev->sdma.disable_uq) + if ((adev->sdma.instance[0].fw_version >= 7966358) && !adev->sdma.disable_uq) adev->userq_funcs[AMDGPU_HW_IP_DMA] = &userq_mes_funcs; break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c index d1481e6d57ec..b115137ab2d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c @@ -136,8 +136,6 @@ static int vcn_v2_0_sw_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_ring *ring; int i, r; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); - uint32_t *ptr; struct amdgpu_device *adev = ip_block->adev; volatile struct amdgpu_fw_shared *fw_shared; @@ -232,14 +230,9 @@ static int vcn_v2_0_sw_init(struct amdgpu_ip_block *ip_block) if (amdgpu_vcnfw_log) amdgpu_vcn_fwlog_init(adev->vcn.inst); - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_2_0, ARRAY_SIZE(vcn_reg_list_2_0)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -276,8 +269,6 @@ static int vcn_v2_0_sw_fini(struct amdgpu_ip_block *ip_block) r = amdgpu_vcn_sw_fini(adev, 0); - kfree(adev->vcn.ip_dump); - return r; } @@ -2101,66 +2092,6 @@ static int vcn_v2_0_start_sriov(struct amdgpu_device *adev) return vcn_v2_0_start_mmsch(adev, &adev->virt.mm_table); } -static void vcn_v2_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_0[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v2_0_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_0); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_0[j], i)); - } -} - static const struct amd_ip_funcs vcn_v2_0_ip_funcs = { .name = "vcn_v2_0", .early_init = vcn_v2_0_early_init, @@ -2174,8 +2105,8 @@ static const struct amd_ip_funcs vcn_v2_0_ip_funcs = { .wait_for_idle = vcn_v2_0_wait_for_idle, .set_clockgating_state = vcn_v2_0_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v2_0_dump_ip_state, - .print_ip_state = vcn_v2_0_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index d7b2668ab0d9..3a7c137a83ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -297,8 +297,6 @@ static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_ring *ring; int i, j, r; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); - uint32_t *ptr; struct amdgpu_device *adev = ip_block->adev; for (j = 0; j < adev->vcn.num_vcn_inst; j++) { @@ -423,14 +421,9 @@ static int vcn_v2_5_sw_init(struct amdgpu_ip_block *ip_block) if (r) return r; - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_2_5, ARRAY_SIZE(vcn_reg_list_2_5)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -477,8 +470,6 @@ static int vcn_v2_5_sw_fini(struct amdgpu_ip_block *ip_block) return r; } - kfree(adev->vcn.ip_dump); - return 0; } @@ -2133,66 +2124,6 @@ static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev) } } -static void vcn_v2_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_2_5[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v2_5_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_2_5); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_2_5[j], i)); - } -} - static const struct amd_ip_funcs vcn_v2_5_ip_funcs = { .name = "vcn_v2_5", .early_init = vcn_v2_5_early_init, @@ -2206,8 +2137,8 @@ static const struct amd_ip_funcs vcn_v2_5_ip_funcs = { .wait_for_idle = vcn_v2_5_wait_for_idle, .set_clockgating_state = vcn_v2_5_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v2_5_dump_ip_state, - .print_ip_state = vcn_v2_5_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; static const struct amd_ip_funcs vcn_v2_6_ip_funcs = { @@ -2223,8 +2154,8 @@ static const struct amd_ip_funcs vcn_v2_6_ip_funcs = { .wait_for_idle = vcn_v2_5_wait_for_idle, .set_clockgating_state = vcn_v2_5_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v2_5_dump_ip_state, - .print_ip_state = vcn_v2_5_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v2_5_ip_block = diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index a89662c97c9e..ff2a85619f23 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -175,8 +175,6 @@ static int vcn_v3_0_sw_init(struct amdgpu_ip_block *ip_block) struct amdgpu_ring *ring; int i, j, r; int vcn_doorbell_index = 0; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); - uint32_t *ptr; struct amdgpu_device *adev = ip_block->adev; /* @@ -304,14 +302,9 @@ static int vcn_v3_0_sw_init(struct amdgpu_ip_block *ip_block) return r; } - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (ptr == NULL) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_3_0, ARRAY_SIZE(vcn_reg_list_3_0)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -2348,67 +2341,6 @@ static void vcn_v3_0_set_irq_funcs(struct amdgpu_device *adev) } } -static void vcn_v3_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); - uint32_t inst_off; - bool is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_3_0[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v3_0_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_3_0); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, mmUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_3_0[j], i)); - } -} - static const struct amd_ip_funcs vcn_v3_0_ip_funcs = { .name = "vcn_v3_0", .early_init = vcn_v3_0_early_init, @@ -2422,8 +2354,8 @@ static const struct amd_ip_funcs vcn_v3_0_ip_funcs = { .wait_for_idle = vcn_v3_0_wait_for_idle, .set_clockgating_state = vcn_v3_0_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v3_0_dump_ip_state, - .print_ip_state = vcn_v3_0_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v3_0_ip_block = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c index e9f9cb169034..1785786a72f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c @@ -183,8 +183,6 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block) struct amdgpu_ring *ring; struct amdgpu_device *adev = ip_block->adev; int i, r; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); - uint32_t *ptr; for (i = 0; i < adev->vcn.num_vcn_inst; i++) { if (adev->vcn.harvest_config & (1 << i)) @@ -255,14 +253,9 @@ static int vcn_v4_0_sw_init(struct amdgpu_ip_block *ip_block) if (r) return r; - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0, ARRAY_SIZE(vcn_reg_list_4_0)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -315,8 +308,6 @@ static int vcn_v4_0_sw_fini(struct amdgpu_ip_block *ip_block) return r; } - kfree(adev->vcn.ip_dump); - return 0; } @@ -2252,67 +2243,6 @@ static void vcn_v4_0_set_irq_funcs(struct amdgpu_device *adev) } } -static void vcn_v4_0_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v4_0_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0[j], - i)); - } -} - static const struct amd_ip_funcs vcn_v4_0_ip_funcs = { .name = "vcn_v4_0", .early_init = vcn_v4_0_early_init, @@ -2326,8 +2256,8 @@ static const struct amd_ip_funcs vcn_v4_0_ip_funcs = { .wait_for_idle = vcn_v4_0_wait_for_idle, .set_clockgating_state = vcn_v4_0_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v4_0_dump_ip_state, - .print_ip_state = vcn_v4_0_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v4_0_ip_block = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c index b904afc358ae..c6450ed65c12 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c @@ -160,8 +160,6 @@ static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) struct amdgpu_device *adev = ip_block->adev; struct amdgpu_ring *ring; int i, r, vcn_inst; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); - uint32_t *ptr; /* VCN DEC TRAP */ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, @@ -231,14 +229,9 @@ static int vcn_v4_0_3_sw_init(struct amdgpu_ip_block *ip_block) } } - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0_3, ARRAY_SIZE(vcn_reg_list_4_0_3)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -391,7 +384,7 @@ static int vcn_v4_0_3_hw_fini(struct amdgpu_ip_block *ip_block) vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); } - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN) && !amdgpu_sriov_vf(adev)) amdgpu_irq_put(adev, &adev->vcn.inst->ras_poison_irq, 0); return 0; @@ -1877,68 +1870,6 @@ static void vcn_v4_0_3_set_irq_funcs(struct amdgpu_device *adev) adev->vcn.inst->ras_poison_irq.funcs = &vcn_v4_0_3_ras_irq_funcs; } -static void vcn_v4_0_3_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_3[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v4_0_3_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off, inst_id; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_3); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_id = GET_INST(VCN, i); - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, inst_id, regUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_3[j], - inst_id)); - } -} - static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = { .name = "vcn_v4_0_3", .early_init = vcn_v4_0_3_early_init, @@ -1952,8 +1883,8 @@ static const struct amd_ip_funcs vcn_v4_0_3_ip_funcs = { .wait_for_idle = vcn_v4_0_3_wait_for_idle, .set_clockgating_state = vcn_v4_0_3_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v4_0_3_dump_ip_state, - .print_ip_state = vcn_v4_0_3_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v4_0_3_ip_block = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c index ed57e6431d4b..f785467370d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c @@ -147,9 +147,6 @@ static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block) struct amdgpu_ring *ring; struct amdgpu_device *adev = ip_block->adev; int i, r; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); - uint32_t *ptr; - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { volatile struct amdgpu_vcn4_fw_shared *fw_shared; @@ -233,15 +230,9 @@ static int vcn_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block) return r; } - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } - return 0; + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_4_0_5, ARRAY_SIZE(vcn_reg_list_4_0_5)); + + return r; } /** @@ -1710,67 +1701,6 @@ static void vcn_v4_0_5_set_irq_funcs(struct amdgpu_device *adev) } } -static void vcn_v4_0_5_print_ip_state(struct amdgpu_ip_block *ip_block, struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_4_0_5[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -static void vcn_v4_0_5_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_4_0_5); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_4_0_5[j], - i)); - } -} - static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = { .name = "vcn_v4_0_5", .early_init = vcn_v4_0_5_early_init, @@ -1784,8 +1714,8 @@ static const struct amd_ip_funcs vcn_v4_0_5_ip_funcs = { .wait_for_idle = vcn_v4_0_5_wait_for_idle, .set_clockgating_state = vcn_v4_0_5_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v4_0_5_dump_ip_state, - .print_ip_state = vcn_v4_0_5_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v4_0_5_ip_block = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c index f8bb90fe764b..455f829b8bb9 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c @@ -115,21 +115,6 @@ static int vcn_v5_0_0_early_init(struct amdgpu_ip_block *ip_block) return 0; } -void vcn_v5_0_0_alloc_ip_dump(struct amdgpu_device *adev) -{ - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); - uint32_t *ptr; - - /* Allocate memory for VCN IP Dump buffer */ - ptr = kcalloc(adev->vcn.num_vcn_inst * reg_count, sizeof(uint32_t), GFP_KERNEL); - if (!ptr) { - DRM_ERROR("Failed to allocate memory for VCN IP Dump\n"); - adev->vcn.ip_dump = NULL; - } else { - adev->vcn.ip_dump = ptr; - } -} - /** * vcn_v5_0_0_sw_init - sw init for VCN block * @@ -201,7 +186,9 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block) if (!amdgpu_sriov_vf(adev)) adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; - vcn_v5_0_0_alloc_ip_dump(adev); + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0, ARRAY_SIZE(vcn_reg_list_5_0)); + if (r) + return r; r = amdgpu_vcn_sysfs_reset_mask_init(adev); if (r) @@ -251,8 +238,6 @@ static int vcn_v5_0_0_sw_fini(struct amdgpu_ip_block *ip_block) return r; } - kfree(adev->vcn.ip_dump); - return 0; } @@ -769,9 +754,10 @@ static int vcn_v5_0_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst, if (indirect) { ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, 0); - dev_err(adev->dev, "%s: vcn sram load failed %d\n", __func__, ret); - if (ret) + if (ret) { + dev_err(adev->dev, "%s: vcn sram load failed %d\n", __func__, ret); return ret; + } } ring = &adev->vcn.inst[inst_idx].ring_enc[0]; @@ -1433,67 +1419,6 @@ static void vcn_v5_0_0_set_irq_funcs(struct amdgpu_device *adev) } } -void vcn_v5_0_0_print_ip_state(struct amdgpu_ip_block *ip_block, - struct drm_printer *p) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); - uint32_t inst_off, is_powered; - - if (!adev->vcn.ip_dump) - return; - - drm_printf(p, "num_instances:%d\n", adev->vcn.num_vcn_inst); - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) { - drm_printf(p, "\nHarvested Instance:VCN%d Skipping dump\n", i); - continue; - } - - inst_off = i * reg_count; - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) { - drm_printf(p, "\nActive Instance:VCN%d\n", i); - for (j = 0; j < reg_count; j++) - drm_printf(p, "%-50s \t 0x%08x\n", vcn_reg_list_5_0[j].reg_name, - adev->vcn.ip_dump[inst_off + j]); - } else { - drm_printf(p, "\nInactive Instance:VCN%d\n", i); - } - } -} - -void vcn_v5_0_0_dump_ip_state(struct amdgpu_ip_block *ip_block) -{ - struct amdgpu_device *adev = ip_block->adev; - int i, j; - bool is_powered; - uint32_t inst_off; - uint32_t reg_count = ARRAY_SIZE(vcn_reg_list_5_0); - - if (!adev->vcn.ip_dump) - return; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - - inst_off = i * reg_count; - /* mmUVD_POWER_STATUS is always readable and is first element of the array */ - adev->vcn.ip_dump[inst_off] = RREG32_SOC15(VCN, i, regUVD_POWER_STATUS); - is_powered = (adev->vcn.ip_dump[inst_off] & - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK) != 1; - - if (is_powered) - for (j = 1; j < reg_count; j++) - adev->vcn.ip_dump[inst_off + j] = - RREG32(SOC15_REG_ENTRY_OFFSET_INST(vcn_reg_list_5_0[j], i)); - } -} - static const struct amd_ip_funcs vcn_v5_0_0_ip_funcs = { .name = "vcn_v5_0_0", .early_init = vcn_v5_0_0_early_init, @@ -1507,8 +1432,8 @@ static const struct amd_ip_funcs vcn_v5_0_0_ip_funcs = { .wait_for_idle = vcn_v5_0_0_wait_for_idle, .set_clockgating_state = vcn_v5_0_0_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v5_0_0_dump_ip_state, - .print_ip_state = vcn_v5_0_0_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v5_0_0_ip_block = { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h index b8927652bc50..51bbccd4360f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.h @@ -32,11 +32,6 @@ #define VCN_VID_IP_ADDRESS 0x0 #define VCN_AON_IP_ADDRESS 0x30000 -void vcn_v5_0_0_alloc_ip_dump(struct amdgpu_device *adev); -void vcn_v5_0_0_print_ip_state(struct amdgpu_ip_block *ip_block, - struct drm_printer *p); -void vcn_v5_0_0_dump_ip_state(struct amdgpu_ip_block *ip_block); - extern const struct amdgpu_ip_block_version vcn_v5_0_0_ip_block; #endif /* __VCN_V5_0_0_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c index d8bbb9376731..7cb21e2b4eb0 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -40,6 +40,40 @@ #include <drm/drm_drv.h> +static const struct amdgpu_hwip_reg_entry vcn_reg_list_5_0_1[] = { + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK), + SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE) +}; + static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev); static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev); static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev); @@ -163,7 +197,17 @@ static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block) return r; } - vcn_v5_0_0_alloc_ip_dump(adev); + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) { + r = amdgpu_vcn_ras_sw_init(adev); + if (r) { + dev_err(adev->dev, "Failed to initialize vcn ras block!\n"); + return r; + } + } + + r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0_1, ARRAY_SIZE(vcn_reg_list_5_0_1)); + if (r) + return r; return amdgpu_vcn_sysfs_reset_mask_init(adev); } @@ -209,8 +253,6 @@ static int vcn_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block) amdgpu_vcn_sysfs_reset_mask_fini(adev); - kfree(adev->vcn.ip_dump); - return 0; } @@ -1480,8 +1522,8 @@ static const struct amd_ip_funcs vcn_v5_0_1_ip_funcs = { .post_soft_reset = NULL, .set_clockgating_state = vcn_v5_0_1_set_clockgating_state, .set_powergating_state = vcn_set_powergating_state, - .dump_ip_state = vcn_v5_0_0_dump_ip_state, - .print_ip_state = vcn_v5_0_0_print_ip_state, + .dump_ip_state = amdgpu_vcn_dump_ip_state, + .print_ip_state = amdgpu_vcn_print_ip_state, }; const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = { @@ -1562,7 +1604,7 @@ static int vcn_v5_0_1_aca_bank_parser(struct aca_handle *handle, struct aca_bank /* reference to smu driver if header file */ static int vcn_v5_0_1_err_codes[] = { - 14, 15, /* VCN */ + 14, 15, 47, /* VCN [D|V|S] */ }; static bool vcn_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank, @@ -1608,6 +1650,13 @@ static int vcn_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_commo if (r) goto late_fini; + if (amdgpu_ras_is_supported(adev, ras_block->block) && + adev->vcn.inst->ras_poison_irq.funcs) { + r = amdgpu_irq_get(adev, &adev->vcn.inst->ras_poison_irq, 0); + if (r) + goto late_fini; + } + return 0; late_fini: diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 2d91027e2a74..6c5c7c1bf5ed 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -2725,7 +2725,7 @@ static void get_queue_checkpoint_info(struct device_queue_manager *dqm, dqm_lock(dqm); mqd_mgr = dqm->mqd_mgrs[mqd_type]; - *mqd_size = mqd_mgr->mqd_size; + *mqd_size = mqd_mgr->mqd_size * NUM_XCC(mqd_mgr->dev->xcc_mask); *ctl_stack_size = 0; if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE && mqd_mgr->get_checkpoint_info) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 97933d2a3803..f2dee320fada 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -373,7 +373,7 @@ static void get_checkpoint_info(struct mqd_manager *mm, void *mqd, u32 *ctl_stac { struct v9_mqd *m = get_mqd(mqd); - *ctl_stack_size = m->cp_hqd_cntl_stack_size; + *ctl_stack_size = m->cp_hqd_cntl_stack_size * NUM_XCC(mm->dev->xcc_mask); } static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst) @@ -388,6 +388,24 @@ static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, voi memcpy(ctl_stack_dst, ctl_stack, m->cp_hqd_cntl_stack_size); } +static void checkpoint_mqd_v9_4_3(struct mqd_manager *mm, + void *mqd, + void *mqd_dst, + void *ctl_stack_dst) +{ + struct v9_mqd *m; + int xcc; + uint64_t size = get_mqd(mqd)->cp_mqd_stride_size; + + for (xcc = 0; xcc < NUM_XCC(mm->dev->xcc_mask); xcc++) { + m = get_mqd(mqd + size * xcc); + + checkpoint_mqd(mm, m, + (uint8_t *)mqd_dst + sizeof(*m) * xcc, + (uint8_t *)ctl_stack_dst + m->cp_hqd_cntl_stack_size * xcc); + } +} + static void restore_mqd(struct mqd_manager *mm, void **mqd, struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr, struct queue_properties *qp, @@ -764,13 +782,35 @@ static void restore_mqd_v9_4_3(struct mqd_manager *mm, void **mqd, const void *mqd_src, const void *ctl_stack_src, u32 ctl_stack_size) { - restore_mqd(mm, mqd, mqd_mem_obj, gart_addr, qp, mqd_src, ctl_stack_src, ctl_stack_size); - if (amdgpu_sriov_multi_vf_mode(mm->dev->adev)) { - struct v9_mqd *m; + struct kfd_mem_obj xcc_mqd_mem_obj; + u32 mqd_ctl_stack_size; + struct v9_mqd *m; + u32 num_xcc; + int xcc; - m = (struct v9_mqd *) mqd_mem_obj->cpu_ptr; - m->cp_hqd_pq_doorbell_control |= 1 << - CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_MODE__SHIFT; + uint64_t offset = mm->mqd_stride(mm, qp); + + mm->dev->dqm->current_logical_xcc_start++; + + num_xcc = NUM_XCC(mm->dev->xcc_mask); + mqd_ctl_stack_size = ctl_stack_size / num_xcc; + + memset(&xcc_mqd_mem_obj, 0x0, sizeof(struct kfd_mem_obj)); + + /* Set the MQD pointer and gart address to XCC0 MQD */ + *mqd = mqd_mem_obj->cpu_ptr; + if (gart_addr) + *gart_addr = mqd_mem_obj->gpu_addr; + + for (xcc = 0; xcc < num_xcc; xcc++) { + get_xcc_mqd(mqd_mem_obj, &xcc_mqd_mem_obj, offset * xcc); + restore_mqd(mm, (void **)&m, + &xcc_mqd_mem_obj, + NULL, + qp, + (uint8_t *)mqd_src + xcc * sizeof(*m), + (uint8_t *)ctl_stack_src + xcc * mqd_ctl_stack_size, + mqd_ctl_stack_size); } } static int destroy_mqd_v9_4_3(struct mqd_manager *mm, void *mqd, @@ -906,7 +946,6 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type, mqd->free_mqd = kfd_free_mqd_cp; mqd->is_occupied = kfd_is_occupied_cp; mqd->get_checkpoint_info = get_checkpoint_info; - mqd->checkpoint_mqd = checkpoint_mqd; mqd->mqd_size = sizeof(struct v9_mqd); mqd->mqd_stride = mqd_stride_v9; #if defined(CONFIG_DEBUG_FS) @@ -918,16 +957,18 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type, mqd->init_mqd = init_mqd_v9_4_3; mqd->load_mqd = load_mqd_v9_4_3; mqd->update_mqd = update_mqd_v9_4_3; - mqd->restore_mqd = restore_mqd_v9_4_3; mqd->destroy_mqd = destroy_mqd_v9_4_3; mqd->get_wave_state = get_wave_state_v9_4_3; + mqd->checkpoint_mqd = checkpoint_mqd_v9_4_3; + mqd->restore_mqd = restore_mqd_v9_4_3; } else { mqd->init_mqd = init_mqd; mqd->load_mqd = load_mqd; mqd->update_mqd = update_mqd; - mqd->restore_mqd = restore_mqd; mqd->destroy_mqd = kfd_destroy_mqd_cp; mqd->get_wave_state = get_wave_state; + mqd->checkpoint_mqd = checkpoint_mqd; + mqd->restore_mqd = restore_mqd; } break; case KFD_MQD_TYPE_HIQ: diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index c643e0ccec52..7fbb5c274ccc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -914,7 +914,10 @@ static int criu_checkpoint_queues_device(struct kfd_process_device *pdd, q_data = (struct kfd_criu_queue_priv_data *)q_private_data; - /* data stored in this order: priv_data, mqd, ctl_stack */ + /* + * data stored in this order: + * priv_data, mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]... + */ q_data->mqd_size = mqd_size; q_data->ctl_stack_size = ctl_stack_size; @@ -963,7 +966,7 @@ int kfd_criu_checkpoint_queues(struct kfd_process *p, } static void set_queue_properties_from_criu(struct queue_properties *qp, - struct kfd_criu_queue_priv_data *q_data) + struct kfd_criu_queue_priv_data *q_data, uint32_t num_xcc) { qp->is_interop = false; qp->queue_percent = q_data->q_percent; @@ -976,7 +979,11 @@ static void set_queue_properties_from_criu(struct queue_properties *qp, qp->eop_ring_buffer_size = q_data->eop_ring_buffer_size; qp->ctx_save_restore_area_address = q_data->ctx_save_restore_area_address; qp->ctx_save_restore_area_size = q_data->ctx_save_restore_area_size; - qp->ctl_stack_size = q_data->ctl_stack_size; + if (q_data->type == KFD_QUEUE_TYPE_COMPUTE) + qp->ctl_stack_size = q_data->ctl_stack_size / num_xcc; + else + qp->ctl_stack_size = q_data->ctl_stack_size; + qp->type = q_data->type; qp->format = q_data->format; } @@ -1036,12 +1043,15 @@ int kfd_criu_restore_queue(struct kfd_process *p, goto exit; } - /* data stored in this order: mqd, ctl_stack */ + /* + * data stored in this order: + * mqd[xcc0], mqd[xcc1],..., ctl_stack[xcc0], ctl_stack[xcc1]... + */ mqd = q_extra_data; ctl_stack = mqd + q_data->mqd_size; memset(&qp, 0, sizeof(qp)); - set_queue_properties_from_criu(&qp, q_data); + set_queue_properties_from_criu(&qp, q_data, NUM_XCC(pdd->dev->adev->gfx.xcc_mask)); print_queue_properties(&qp); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index a0f22ea6d15a..e23b5a0f31f2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1189,7 +1189,7 @@ svm_nodes_in_same_hive(struct kfd_node *node_a, struct kfd_node *node_b) } static uint64_t -svm_range_get_pte_flags(struct kfd_node *node, +svm_range_get_pte_flags(struct kfd_node *node, struct amdgpu_vm *vm, struct svm_range *prange, int domain) { struct kfd_node *bo_node; @@ -1292,10 +1292,6 @@ svm_range_get_pte_flags(struct kfd_node *node, AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC; } - mapping_flags |= AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE; - - if (flags & KFD_IOCTL_SVM_FLAG_GPU_RO) - mapping_flags &= ~AMDGPU_VM_PAGE_WRITEABLE; if (flags & KFD_IOCTL_SVM_FLAG_GPU_EXEC) mapping_flags |= AMDGPU_VM_PAGE_EXECUTABLE; @@ -1305,7 +1301,10 @@ svm_range_get_pte_flags(struct kfd_node *node, if (gc_ip_version >= IP_VERSION(12, 0, 0)) pte_flags |= AMDGPU_PTE_IS_PTE; - pte_flags |= amdgpu_gem_va_map_flags(node->adev, mapping_flags); + amdgpu_gmc_get_vm_pte(node->adev, vm, NULL, mapping_flags, &pte_flags); + pte_flags |= AMDGPU_PTE_READABLE; + if (!(flags & KFD_IOCTL_SVM_FLAG_GPU_RO)) + pte_flags |= AMDGPU_PTE_WRITEABLE; return pte_flags; } @@ -1412,7 +1411,7 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange, pr_debug("Mapping range [0x%lx 0x%llx] on domain: %s\n", last_start, prange->start + i, last_domain ? "GPU" : "CPU"); - pte_flags = svm_range_get_pte_flags(pdd->dev, prange, last_domain); + pte_flags = svm_range_get_pte_flags(pdd->dev, vm, prange, last_domain); if (readonly) pte_flags &= ~AMDGPU_PTE_WRITEABLE; diff --git a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c index 8bc36f04b1b7..44009aa8216e 100644 --- a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c +++ b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c @@ -46,18 +46,29 @@ static const struct drm_driver amdgpu_xcp_driver = { static int8_t pdev_num; static struct xcp_device *xcp_dev[MAX_XCP_PLATFORM_DEVICE]; +static DEFINE_MUTEX(xcp_mutex); int amdgpu_xcp_drm_dev_alloc(struct drm_device **ddev) { struct platform_device *pdev; struct xcp_device *pxcp_dev; char dev_name[20]; - int ret; + int ret, i; + + guard(mutex)(&xcp_mutex); if (pdev_num >= MAX_XCP_PLATFORM_DEVICE) return -ENODEV; - snprintf(dev_name, sizeof(dev_name), "amdgpu_xcp_%d", pdev_num); + for (i = 0; i < MAX_XCP_PLATFORM_DEVICE; i++) { + if (!xcp_dev[i]) + break; + } + + if (i >= MAX_XCP_PLATFORM_DEVICE) + return -ENODEV; + + snprintf(dev_name, sizeof(dev_name), "amdgpu_xcp_%d", i); pdev = platform_device_register_simple(dev_name, -1, NULL, 0); if (IS_ERR(pdev)) return PTR_ERR(pdev); @@ -73,8 +84,8 @@ int amdgpu_xcp_drm_dev_alloc(struct drm_device **ddev) goto out_devres; } - xcp_dev[pdev_num] = pxcp_dev; - xcp_dev[pdev_num]->pdev = pdev; + xcp_dev[i] = pxcp_dev; + xcp_dev[i]->pdev = pdev; *ddev = &pxcp_dev->drm; pdev_num++; @@ -89,16 +100,43 @@ out_unregister: } EXPORT_SYMBOL(amdgpu_xcp_drm_dev_alloc); -void amdgpu_xcp_drv_release(void) +static void free_xcp_dev(int8_t index) { - for (--pdev_num; pdev_num >= 0; --pdev_num) { - struct platform_device *pdev = xcp_dev[pdev_num]->pdev; + if ((index < MAX_XCP_PLATFORM_DEVICE) && (xcp_dev[index])) { + struct platform_device *pdev = xcp_dev[index]->pdev; devres_release_group(&pdev->dev, NULL); platform_device_unregister(pdev); - xcp_dev[pdev_num] = NULL; + + xcp_dev[index] = NULL; + pdev_num--; + } +} + +void amdgpu_xcp_drm_dev_free(struct drm_device *ddev) +{ + int8_t i; + + guard(mutex)(&xcp_mutex); + + for (i = 0; i < MAX_XCP_PLATFORM_DEVICE; i++) { + if ((xcp_dev[i]) && (&xcp_dev[i]->drm == ddev)) { + free_xcp_dev(i); + break; + } + } +} +EXPORT_SYMBOL(amdgpu_xcp_drm_dev_free); + +void amdgpu_xcp_drv_release(void) +{ + int8_t i; + + guard(mutex)(&xcp_mutex); + + for (i = 0; pdev_num && i < MAX_XCP_PLATFORM_DEVICE; i++) { + free_xcp_dev(i); } - pdev_num = 0; } EXPORT_SYMBOL(amdgpu_xcp_drv_release); diff --git a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h index c1c4b679bf95..580a1602c8e3 100644 --- a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h +++ b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.h @@ -25,5 +25,6 @@ #define _AMDGPU_XCP_DRV_H_ int amdgpu_xcp_drm_dev_alloc(struct drm_device **ddev); +void amdgpu_xcp_drm_dev_free(struct drm_device *ddev); void amdgpu_xcp_drv_release(void); #endif /* _AMDGPU_XCP_DRV_H_ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c71167ffdb76..31ea57edeb45 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -530,6 +530,50 @@ static void dm_pflip_high_irq(void *interrupt_params) amdgpu_crtc->crtc_id, amdgpu_crtc, vrr_active, (int)!e); } +static void dm_handle_vmin_vmax_update(struct work_struct *offload_work) +{ + struct vupdate_offload_work *work = container_of(offload_work, struct vupdate_offload_work, work); + struct amdgpu_device *adev = work->adev; + struct dc_stream_state *stream = work->stream; + struct dc_crtc_timing_adjust *adjust = work->adjust; + + mutex_lock(&adev->dm.dc_lock); + dc_stream_adjust_vmin_vmax(adev->dm.dc, stream, adjust); + mutex_unlock(&adev->dm.dc_lock); + + dc_stream_release(stream); + kfree(work->adjust); + kfree(work); +} + +static void schedule_dc_vmin_vmax(struct amdgpu_device *adev, + struct dc_stream_state *stream, + struct dc_crtc_timing_adjust *adjust) +{ + struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL); + if (!offload_work) { + drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n"); + return; + } + + struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_KERNEL); + if (!adjust_copy) { + drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n"); + kfree(offload_work); + return; + } + + dc_stream_retain(stream); + memcpy(adjust_copy, adjust, sizeof(*adjust_copy)); + + INIT_WORK(&offload_work->work, dm_handle_vmin_vmax_update); + offload_work->adev = adev; + offload_work->stream = stream; + offload_work->adjust = adjust_copy; + + queue_work(system_wq, &offload_work->work); +} + static void dm_vupdate_high_irq(void *interrupt_params) { struct common_irq_params *irq_params = interrupt_params; @@ -568,6 +612,11 @@ static void dm_vupdate_high_irq(void *interrupt_params) * if a pageflip happened inside front-porch. */ if (vrr_active) { + bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; + bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; + bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state + == VRR_STATE_ACTIVE_VARIABLE; + amdgpu_dm_crtc_handle_vblank(acrtc); /* BTR processing for pre-DCE12 ASICs */ @@ -579,10 +628,11 @@ static void dm_vupdate_high_irq(void *interrupt_params) acrtc->dm_irq_params.stream, &acrtc->dm_irq_params.vrr_params); - dc_stream_adjust_vmin_vmax( - adev->dm.dc, - acrtc->dm_irq_params.stream, - &acrtc->dm_irq_params.vrr_params.adjust); + if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { + schedule_dc_vmin_vmax(adev, + acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); + } spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); } } @@ -665,15 +715,20 @@ static void dm_crtc_high_irq(void *interrupt_params) spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); if (acrtc->dm_irq_params.stream && - acrtc->dm_irq_params.vrr_params.supported && - acrtc->dm_irq_params.freesync_config.state == - VRR_STATE_ACTIVE_VARIABLE) { + acrtc->dm_irq_params.vrr_params.supported) { + bool replay_en = acrtc->dm_irq_params.stream->link->replay_settings.replay_feature_enabled; + bool psr_en = acrtc->dm_irq_params.stream->link->psr_settings.psr_feature_enabled; + bool fs_active_var_en = acrtc->dm_irq_params.freesync_config.state == VRR_STATE_ACTIVE_VARIABLE; + mod_freesync_handle_v_update(adev->dm.freesync_module, acrtc->dm_irq_params.stream, &acrtc->dm_irq_params.vrr_params); - dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc->dm_irq_params.stream, - &acrtc->dm_irq_params.vrr_params.adjust); + /* update vmin_vmax only if freesync is enabled, or only if PSR and REPLAY are disabled */ + if (fs_active_var_en || (!fs_active_var_en && !replay_en && !psr_en)) { + schedule_dc_vmin_vmax(adev, acrtc->dm_irq_params.stream, + &acrtc->dm_irq_params.vrr_params.adjust); + } } /* @@ -4745,16 +4800,16 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, return 1; } -/* Rescale from [min..max] to [0..MAX_BACKLIGHT_LEVEL] */ +/* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */ static inline u32 scale_input_to_fw(int min, int max, u64 input) { - return DIV_ROUND_CLOSEST_ULL(input * MAX_BACKLIGHT_LEVEL, max - min); + return DIV_ROUND_CLOSEST_ULL(input * AMDGPU_MAX_BL_LEVEL, max - min); } -/* Rescale from [0..MAX_BACKLIGHT_LEVEL] to [min..max] */ +/* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */ static inline u32 scale_fw_to_input(int min, int max, u64 input) { - return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), MAX_BACKLIGHT_LEVEL); + return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL); } static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 67c3a7a967f2..94f312bae9ac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -153,6 +153,20 @@ struct idle_workqueue { bool running; }; +/** + * struct dm_vupdate_work - Work data for periodic action in idle + * @work: Kernel work data for the work event + * @adev: amdgpu_device back pointer + * @stream: DC stream associated with the crtc + * @adjust: DC CRTC timing adjust to be applied to the crtc + */ +struct vupdate_offload_work { + struct work_struct work; + struct amdgpu_device *adev; + struct dc_stream_state *stream; + struct dc_crtc_timing_adjust *adjust; +}; + #define MAX_LUMINANCE_DATA_POINTS 99 /** diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 2551823382f8..010172f930ae 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -661,6 +661,15 @@ static int amdgpu_dm_crtc_helper_atomic_check(struct drm_crtc *crtc, return -EINVAL; } + if (!state->legacy_cursor_update && amdgpu_dm_crtc_vrr_active(dm_crtc_state)) { + struct drm_plane_state *primary_state; + + /* Pull in primary plane for correct VRR handling */ + primary_state = drm_atomic_get_plane_state(state, crtc->primary); + if (IS_ERR(primary_state)) + return PTR_ERR(primary_state); + } + /* In some use cases, like reset, no stream is attached */ if (!dm_crtc_state->stream) return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 137f18d41f1b..32281bf62f70 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -1763,14 +1763,17 @@ static bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_lin union lane_count_set lane_count; u8 dp_link_encoding; u8 link_bw_set = 0; + u8 data[16] = {0}; *cur_link_bw = 0; - if (drm_dp_dpcd_read(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, &dp_link_encoding, 1) != 1 || - drm_dp_dpcd_read(aux, DP_LANE_COUNT_SET, &lane_count.raw, 1) != 1 || - drm_dp_dpcd_read(aux, DP_LINK_BW_SET, &link_bw_set, 1) != 1) + if (drm_dp_dpcd_read(aux, DP_LINK_BW_SET, data, 16) != 16) return false; + dp_link_encoding = data[DP_MAIN_LINK_CHANNEL_CODING_SET - DP_LINK_BW_SET]; + link_bw_set = data[DP_LINK_BW_SET - DP_LINK_BW_SET]; + lane_count.raw = data[DP_LANE_COUNT_SET - DP_LINK_BW_SET]; + switch (dp_link_encoding) { case DP_8b_10b_ENCODING: link_rate = link_bw_set; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 33b9d36619ff..4071851f9e86 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -158,7 +158,6 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p return NULL; } dce60_clk_mgr_construct(ctx, clk_mgr); - dce_clk_mgr_construct(ctx, clk_mgr); return &clk_mgr->base; } #endif diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c index 26feefbb8990..f5ad0a177038 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c @@ -245,6 +245,11 @@ int dce_set_clock( pxl_clk_params.target_pixel_clock_100hz = requested_clk_khz * 10; pxl_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; + /* DCE 6.0, DCE 6.4: engine clock is the same as PLL0 */ + if (clk_mgr_base->ctx->dce_version == DCE_VERSION_6_0 || + clk_mgr_base->ctx->dce_version == DCE_VERSION_6_4) + pxl_clk_params.pll_id = CLOCK_SOURCE_ID_PLL0; + if (clk_mgr_dce->dfs_bypass_active) pxl_clk_params.flags.SET_DISPCLK_DFS_BYPASS = true; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index 9e2ef0e724fc..7aee02d56292 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -563,6 +563,7 @@ static void vg_clk_mgr_helper_populate_bw_params( { int i, j; struct clk_bw_params *bw_params = clk_mgr->base.bw_params; + uint32_t max_dispclk = 0, max_dppclk = 0; j = -1; @@ -584,6 +585,15 @@ static void vg_clk_mgr_helper_populate_bw_params( return; } + /* dispclk and dppclk can be max at any voltage, same number of levels for both */ + if (clock_table->NumDispClkLevelsEnabled <= VG_NUM_DISPCLK_DPM_LEVELS && + clock_table->NumDispClkLevelsEnabled <= VG_NUM_DPPCLK_DPM_LEVELS) { + max_dispclk = find_max_clk_value(clock_table->DispClocks, clock_table->NumDispClkLevelsEnabled); + max_dppclk = find_max_clk_value(clock_table->DppClocks, clock_table->NumDispClkLevelsEnabled); + } else { + ASSERT(0); + } + bw_params->clk_table.num_entries = j + 1; for (i = 0; i < bw_params->clk_table.num_entries - 1; i++, j--) { @@ -591,11 +601,17 @@ static void vg_clk_mgr_helper_populate_bw_params( bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->DfPstateTable[j].voltage); + + /* Now update clocks we do read */ + bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; + bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; } bw_params->clk_table.entries[i].fclk_mhz = clock_table->DfPstateTable[j].fclk; bw_params->clk_table.entries[i].memclk_mhz = clock_table->DfPstateTable[j].memclk; bw_params->clk_table.entries[i].voltage = clock_table->DfPstateTable[j].voltage; bw_params->clk_table.entries[i].dcfclk_mhz = find_max_clk_value(clock_table->DcfClocks, VG_NUM_DCFCLK_DPM_LEVELS); + bw_params->clk_table.entries[i].dispclk_mhz = find_max_clk_value(clock_table->DispClocks, VG_NUM_DISPCLK_DPM_LEVELS); + bw_params->clk_table.entries[i].dppclk_mhz = find_max_clk_value(clock_table->DppClocks, VG_NUM_DPPCLK_DPM_LEVELS); bw_params->vram_type = bios_info->memory_type; bw_params->num_channels = bios_info->ma_channel_number; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index cf3893a2f8ce..242bcb30dd34 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -940,17 +940,18 @@ static void dc_destruct(struct dc *dc) if (dc->link_srv) link_destroy_link_service(&dc->link_srv); - if (dc->ctx->gpio_service) - dal_gpio_service_destroy(&dc->ctx->gpio_service); + if (dc->ctx) { + if (dc->ctx->gpio_service) + dal_gpio_service_destroy(&dc->ctx->gpio_service); - if (dc->ctx->created_bios) - dal_bios_parser_destroy(&dc->ctx->dc_bios); + if (dc->ctx->created_bios) + dal_bios_parser_destroy(&dc->ctx->dc_bios); + kfree(dc->ctx->logger); + dc_perf_trace_destroy(&dc->ctx->perf_trace); - kfree(dc->ctx->logger); - dc_perf_trace_destroy(&dc->ctx->perf_trace); - - kfree(dc->ctx); - dc->ctx = NULL; + kfree(dc->ctx); + dc->ctx = NULL; + } kfree(dc->bw_vbios); dc->bw_vbios = NULL; @@ -6338,3 +6339,21 @@ bool dc_can_clear_cursor_limit(struct dc *dc) return false; } + +void dc_get_underflow_debug_data_for_otg(struct dc *dc, int primary_otg_inst, + struct dc_underflow_debug_data *out_data) +{ + struct timing_generator *tg = NULL; + + for (int i = 0; i < MAX_PIPES; i++) { + if (dc->res_pool->timing_generators[i] && + dc->res_pool->timing_generators[i]->inst == primary_otg_inst) { + tg = dc->res_pool->timing_generators[i]; + break; + } + } + + dc_exit_ips_for_hw_access(dc); + if (dc->hwss.get_underflow_debug_data) + dc->hwss.get_underflow_debug_data(dc, tg, out_data); +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 4d6181e7c612..d712548b1927 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -165,7 +165,13 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) case FAMILY_NV: dc_version = DCN_VERSION_2_0; - if (asic_id.chip_id == DEVICE_ID_NV_13FE || asic_id.chip_id == DEVICE_ID_NV_143F) { + if (asic_id.chip_id == DEVICE_ID_NV_13FE || + asic_id.chip_id == DEVICE_ID_NV_143F || + asic_id.chip_id == DEVICE_ID_NV_13F9 || + asic_id.chip_id == DEVICE_ID_NV_13FA || + asic_id.chip_id == DEVICE_ID_NV_13FB || + asic_id.chip_id == DEVICE_ID_NV_13FC || + asic_id.chip_id == DEVICE_ID_NV_13DB) { dc_version = DCN_VERSION_2_01; break; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5653c1673aec..18c68e531f71 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -55,7 +55,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.343" +#define DC_VER "3.2.344" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC @@ -1073,6 +1073,7 @@ struct dc_debug_options { unsigned int force_mall_ss_num_ways; bool alloc_extra_way_for_cursor; uint32_t subvp_extra_lines; + bool disable_force_pstate_allow_on_hw_release; bool force_usr_allow; /* uses value at boot and disables switch */ bool disable_dtb_ref_clk_switch; @@ -1311,6 +1312,32 @@ union dc_3dlut_state { }; +#define MATRIX_9C__DIM_128_ALIGNED_LEN 16 // 9+8 : 9 * 8 + 7 * 8 = 72 + 56 = 128 % 128 = 0 +#define MATRIX_17C__DIM_128_ALIGNED_LEN 32 //17+15: 17 * 8 + 15 * 8 = 136 + 120 = 256 % 128 = 0 +#define MATRIX_33C__DIM_128_ALIGNED_LEN 64 //17+47: 17 * 8 + 47 * 8 = 136 + 376 = 512 % 128 = 0 + +struct lut_rgb { + uint16_t b; + uint16_t g; + uint16_t r; + uint16_t padding; +}; + +//this structure maps directly to how the lut will read it from memory +struct lut_mem_mapping { + union { + //NATIVE MODE 1, 2 + //RGB layout [b][g][r] //red is 128 byte aligned + //BGR layout [r][g][b] //blue is 128 byte aligned + struct lut_rgb rgb_17c[17][17][MATRIX_17C__DIM_128_ALIGNED_LEN]; + struct lut_rgb rgb_33c[33][33][MATRIX_33C__DIM_128_ALIGNED_LEN]; + + //TRANSFORMED + uint16_t linear_rgb[(33*33*33*4/128+1)*128]; + }; + uint16_t size; +}; + struct dc_rmcm_3dlut { bool isInUse; const struct dc_stream_state *stream; @@ -1792,6 +1819,23 @@ struct dc_surface_update { struct dc_bias_and_scale bias_and_scale; }; +struct dc_underflow_debug_data { + uint32_t otg_inst; + uint32_t otg_underflow; + uint32_t h_position; + uint32_t v_position; + uint32_t otg_frame_count; + struct dc_underflow_per_hubp_debug_data { + uint32_t hubp_underflow; + uint32_t hubp_in_blank; + uint32_t hubp_readline; + uint32_t det_config_error; + } hubps[MAX_PIPES]; + uint32_t curr_det_sizes[MAX_PIPES]; + uint32_t target_det_sizes[MAX_PIPES]; + uint32_t compbuf_config_error; +}; + /* * Create a new surface with default parameters; */ @@ -2686,4 +2730,17 @@ bool dc_is_timing_changed(struct dc_stream_state *cur_stream, bool dc_is_cursor_limit_pending(struct dc *dc); bool dc_can_clear_cursor_limit(struct dc *dc); +/** + * dc_get_underflow_debug_data_for_otg() - Retrieve underflow debug data. + * + * @dc: Pointer to the display core context. + * @primary_otg_inst: Instance index of the primary OTG that underflowed. + * @out_data: Pointer to a dc_underflow_debug_data struct to be filled with debug information. + * + * This function collects and logs underflow-related HW states when underflow happens, + * including OTG underflow status, current read positions, frame count, and per-HUBP debug data. + * The results are stored in the provided out_data structure for further analysis or logging. + */ +void dc_get_underflow_debug_data_for_otg(struct dc *dc, int primary_otg_inst, struct dc_underflow_debug_data *out_data); + #endif /* DC_INTERFACE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c index 0c0b2d67c9cd..2066a65c69bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn301/dcn301_fpu.c @@ -326,7 +326,7 @@ void dcn301_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); struct clk_limit_table *clk_table = &bw_params->clk_table; unsigned int i, closest_clk_lvl; - int j; + int j = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 0; dc_assert_fp_enabled(); @@ -338,6 +338,15 @@ void dcn301_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p dcn3_01_soc.num_chans = bw_params->num_channels; ASSERT(clk_table->num_entries); + + /* Prepass to find max clocks independent of voltage level. */ + for (i = 0; i < clk_table->num_entries; ++i) { + if (clk_table->entries[i].dispclk_mhz > max_dispclk_mhz) + max_dispclk_mhz = clk_table->entries[i].dispclk_mhz; + if (clk_table->entries[i].dppclk_mhz > max_dppclk_mhz) + max_dppclk_mhz = clk_table->entries[i].dppclk_mhz; + } + for (i = 0; i < clk_table->num_entries; i++) { /* loop backwards*/ for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) { @@ -353,8 +362,13 @@ void dcn301_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p s[i].socclk_mhz = clk_table->entries[i].socclk_mhz; s[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; - s[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; - s[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + /* Clocks independent of voltage level. */ + s[i].dispclk_mhz = max_dispclk_mhz ? max_dispclk_mhz : + dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; + + s[i].dppclk_mhz = max_dppclk_mhz ? max_dppclk_mhz : + dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + s[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; s[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c index d347bb06577a..e7e5f6d4778e 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.c @@ -440,6 +440,35 @@ void hubbub3_init_watermarks(struct hubbub *hubbub) REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, reg); } +void hubbub3_get_det_sizes(struct hubbub *hubbub, uint32_t *curr_det_sizes, uint32_t *target_det_sizes) +{ + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); + + REG_GET_2(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, &curr_det_sizes[0], + DET0_SIZE, &target_det_sizes[0]); + + REG_GET_2(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, &curr_det_sizes[1], + DET1_SIZE, &target_det_sizes[1]); + + REG_GET_2(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, &curr_det_sizes[2], + DET2_SIZE, &target_det_sizes[2]); + + REG_GET_2(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, &curr_det_sizes[3], + DET3_SIZE, &target_det_sizes[3]); + +} + +uint32_t hubbub3_compbuf_config_error(struct hubbub *hubbub) +{ + struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); + uint32_t compbuf_config_error = 0; + + REG_GET(DCHUBBUB_COMPBUF_CTRL, CONFIG_ERROR, + &compbuf_config_error); + + return compbuf_config_error; +} + static const struct hubbub_funcs hubbub30_funcs = { .update_dchub = hubbub2_update_dchub, .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, @@ -457,6 +486,8 @@ static const struct hubbub_funcs hubbub30_funcs = { .force_pstate_change_control = hubbub3_force_pstate_change_control, .init_watermarks = hubbub3_init_watermarks, .hubbub_read_state = hubbub2_read_state, + .get_det_sizes = hubbub3_get_det_sizes, + .compbuf_config_error = hubbub3_compbuf_config_error, }; void hubbub3_construct(struct dcn20_hubbub *hubbub3, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h index ca6233e8f1f4..49a469969d36 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn30/dcn30_hubbub.h @@ -133,4 +133,10 @@ void hubbub3_force_pstate_change_control(struct hubbub *hubbub, void hubbub3_init_watermarks(struct hubbub *hubbub); +void hubbub3_get_det_sizes(struct hubbub *hubbub, + uint32_t *curr_det_sizes, + uint32_t *target_det_sizes); + +uint32_t hubbub3_compbuf_config_error(struct hubbub *hubbub); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c index b98505b240a7..cdb20251a154 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn31/dcn31_hubbub.c @@ -1071,6 +1071,8 @@ static const struct hubbub_funcs hubbub31_funcs = { .program_compbuf_size = dcn31_program_compbuf_size, .init_crb = dcn31_init_crb, .hubbub_read_state = hubbub2_read_state, + .get_det_sizes = hubbub3_get_det_sizes, + .compbuf_config_error = hubbub3_compbuf_config_error, }; void hubbub31_construct(struct dcn20_hubbub *hubbub31, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c index 32a6be543105..92957398ac0a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn32/dcn32_hubbub.c @@ -1009,6 +1009,8 @@ static const struct hubbub_funcs hubbub32_funcs = { .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow, .set_request_limit = hubbub32_set_request_limit, .get_mall_en = hubbub32_get_mall_en, + .get_det_sizes = hubbub3_get_det_sizes, + .compbuf_config_error = hubbub3_compbuf_config_error, }; void hubbub32_construct(struct dcn20_hubbub *hubbub2, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c index 6d41953011f5..a443722a8632 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn35/dcn35_hubbub.c @@ -589,6 +589,8 @@ static const struct hubbub_funcs hubbub35_funcs = { .hubbub_read_state = hubbub2_read_state, .force_usr_retraining_allow = hubbub32_force_usr_retraining_allow, .dchubbub_init = hubbub35_init, + .get_det_sizes = hubbub3_get_det_sizes, + .compbuf_config_error = hubbub3_compbuf_config_error, }; void hubbub35_construct(struct dcn20_hubbub *hubbub2, diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c index 92fab471b183..a36273a52880 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c @@ -1247,6 +1247,8 @@ static const struct hubbub_funcs hubbub4_01_funcs = { .program_compbuf_segments = dcn401_program_compbuf_segments, .wait_for_det_update = dcn401_wait_for_det_update, .program_arbiter = dcn401_program_arbiter, + .get_det_sizes = hubbub3_get_det_sizes, + .compbuf_config_error = hubbub3_compbuf_config_error, }; void hubbub401_construct(struct dcn20_hubbub *hubbub2, diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h index f8f991785d4f..cf2eb9793008 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn10/dcn10_hubp.h @@ -104,7 +104,8 @@ SRI(DCN_SURF1_TTU_CNTL1, HUBPREQ, id),\ SRI(DCN_CUR0_TTU_CNTL0, HUBPREQ, id),\ SRI(DCN_CUR0_TTU_CNTL1, HUBPREQ, id),\ - SRI(HUBP_CLK_CNTL, HUBP, id) + SRI(HUBP_CLK_CNTL, HUBP, id),\ + SRI(HUBPRET_READ_LINE_VALUE, HUBPRET, id) /* Register address initialization macro for ASICs with VM */ #define HUBP_REG_LIST_DCN_VM(id)\ @@ -249,7 +250,8 @@ uint32_t CURSOR_POSITION; \ uint32_t CURSOR_HOT_SPOT; \ uint32_t CURSOR_DST_OFFSET; \ - uint32_t HUBP_CLK_CNTL + uint32_t HUBP_CLK_CNTL; \ + uint32_t HUBPRET_READ_LINE_VALUE #define HUBP_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -622,6 +624,8 @@ type DCN_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM;\ type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB;\ type DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB;\ + type PIPE_READ_LINE;\ + type HUBP_SEG_ALLOC_ERR_STATUS;\ /* todo: get these from GVM instead of reading registers ourselves */\ type PAGE_DIRECTORY_ENTRY_HI32;\ type PAGE_DIRECTORY_ENTRY_LO32;\ @@ -671,6 +675,7 @@ struct dcn_fl_regs_st { uint32_t lut_done; uint32_t lut_addr_mode; uint32_t lut_width; + uint32_t lut_mpc_width; uint32_t lut_tmz; uint32_t lut_crossbar_sel_r; uint32_t lut_crossbar_sel_g; diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h index 62369be070ea..f325db555102 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.h @@ -264,6 +264,7 @@ type HUBP_3DLUT_DONE;\ type HUBP_3DLUT_ADDRESSING_MODE;\ type HUBP_3DLUT_WIDTH;\ + type HUBP_3DLUT_MPC_WIDTH;\ type HUBP_3DLUT_TMZ;\ type HUBP_3DLUT_CROSSBAR_SELECT_Y_G;\ type HUBP_3DLUT_CROSSBAR_SELECT_CB_B;\ diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c index 0da70b50e86d..556214b2227d 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.c @@ -505,6 +505,30 @@ void hubp3_init(struct hubp *hubp) hubp_reset(hubp); } +uint32_t hubp3_get_current_read_line(struct hubp *hubp) +{ + uint32_t read_line = 0; + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + + REG_GET(HUBPRET_READ_LINE_VALUE, + PIPE_READ_LINE, + &read_line); + + return read_line; +} + +unsigned int hubp3_get_underflow_status(struct hubp *hubp) +{ + uint32_t hubp_underflow = 0; + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + + REG_GET(DCHUBP_CNTL, + HUBP_UNDERFLOW_STATUS, + &hubp_underflow); + + return hubp_underflow; +} + static struct hubp_funcs dcn30_hubp_funcs = { .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, @@ -534,6 +558,8 @@ static struct hubp_funcs dcn30_hubp_funcs = { .hubp_soft_reset = hubp1_soft_reset, .hubp_set_flip_int = hubp1_set_flip_int, .hubp_clear_tiling = hubp3_clear_tiling, + .hubp_get_underflow_status = hubp3_get_underflow_status, + .hubp_get_current_read_line = hubp3_get_current_read_line, }; bool hubp3_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h index b7d7adf0b58c..842f4eb72cc8 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn30/dcn30_hubp.h @@ -243,7 +243,8 @@ HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_6, REFCYC_PER_META_CHUNK_FLIP_C, mask_sh),\ HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, mask_sh),\ HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_6, REFCYC_PER_VM_REQ_VBLANK, mask_sh),\ - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh) + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh),\ + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh) bool hubp3_construct( struct dcn20_hubp *hubp2, @@ -299,6 +300,11 @@ void hubp3_init(struct hubp *hubp); void hubp3_clear_tiling(struct hubp *hubp); +uint32_t hubp3_get_current_read_line(struct hubp *hubp); + +uint32_t hubp3_get_underflow_status(struct hubp *hubp); + + #endif /* __DC_HUBP_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c index 7fd582a8a4ba..47101847c2b7 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.c @@ -68,6 +68,18 @@ void hubp31_program_extended_blank_value( hubp31_program_extended_blank(hubp, min_dst_y_next_start_optimized); } +uint32_t hubp31_get_det_config_error(struct hubp *hubp) +{ + uint32_t config_error = 0; + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + + REG_GET(DCHUBP_CNTL, + HUBP_SEG_ALLOC_ERR_STATUS, + &config_error); + + return config_error; +} + static struct hubp_funcs dcn31_hubp_funcs = { .hubp_enable_tripleBuffer = hubp2_enable_triplebuffer, .hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled, @@ -98,6 +110,9 @@ static struct hubp_funcs dcn31_hubp_funcs = { .hubp_in_blank = hubp1_in_blank, .program_extended_blank = hubp31_program_extended_blank, .hubp_clear_tiling = hubp3_clear_tiling, + .hubp_get_underflow_status = hubp3_get_underflow_status, + .hubp_get_current_read_line = hubp3_get_current_read_line, + .hubp_get_det_config_error = hubp31_get_det_config_error, }; bool hubp31_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h index d688db79b750..5952c4671507 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn31/dcn31_hubp.h @@ -228,7 +228,9 @@ HUBP_SF(HUBPREQ0_FLIP_PARAMETERS_6, REFCYC_PER_META_CHUNK_FLIP_C, mask_sh),\ HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, mask_sh),\ HUBP_SF(HUBPREQ0_VBLANK_PARAMETERS_6, REFCYC_PER_VM_REQ_VBLANK, mask_sh),\ - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh) + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, VM_GROUP_SIZE, mask_sh),\ + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh),\ + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_SEG_ALLOC_ERR_STATUS, mask_sh) bool hubp31_construct( @@ -246,4 +248,6 @@ void hubp31_set_unbounded_requesting(struct hubp *hubp, bool enable); void hubp31_program_extended_blank_value( struct hubp *hubp, unsigned int min_dst_y_next_start_optimized); +uint32_t hubp31_get_det_config_error(struct hubp *hubp); + #endif /* __DC_HUBP_DCN31_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c index f3a21c623f44..a5f23bb2a76a 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn32/dcn32_hubp.c @@ -206,6 +206,9 @@ static struct hubp_funcs dcn32_hubp_funcs = { .hubp_update_mall_sel = hubp32_update_mall_sel, .hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering, .hubp_clear_tiling = hubp3_clear_tiling, + .hubp_get_underflow_status = hubp3_get_underflow_status, + .hubp_get_current_read_line = hubp3_get_current_read_line, + .hubp_get_det_config_error = hubp31_get_det_config_error, }; bool hubp32_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c index 6d060ba12da8..b140808f21af 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn35/dcn35_hubp.c @@ -218,6 +218,9 @@ static struct hubp_funcs dcn35_hubp_funcs = { .hubp_in_blank = hubp1_in_blank, .program_extended_blank = hubp31_program_extended_blank_value, .hubp_clear_tiling = hubp3_clear_tiling, + .hubp_get_underflow_status = hubp3_get_underflow_status, + .hubp_get_current_read_line = hubp3_get_current_read_line, + .hubp_get_det_config_error = hubp31_get_det_config_error, }; bool hubp35_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c index 705b98b1b6cc..0fcbc6a35be6 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c @@ -127,6 +127,43 @@ void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_forma REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format); } +void hubp401_program_3dlut_fl_config( + struct hubp *hubp, + struct hubp_fl_3dlut_config *cfg) +{ + struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + + uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1}; + uint32_t width = {cfg->width}; + + if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR) + width = (cfg->width == 17) ? 4916 : 35940; + + REG_UPDATE_2(_3DLUT_FL_CONFIG, + HUBP0_3DLUT_FL_MODE, cfg->mode, + HUBP0_3DLUT_FL_FORMAT, cfg->format); + + REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, + HUBP0_3DLUT_FL_BIAS, cfg->bias, + HUBP0_3DLUT_FL_SCALE, cfg->scale); + + REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, + HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part); + REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW, + HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part); + + //cross bar + REG_UPDATE_8(HUBP_3DLUT_CONTROL, + HUBP_3DLUT_MPC_WIDTH, mpc_width, + HUBP_3DLUT_WIDTH, width, + HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r, + HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g, + HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b, + HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode, + HUBP_3DLUT_TMZ, cfg->protection_bits, + HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0); +} + void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor) { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); @@ -1033,6 +1070,10 @@ static struct hubp_funcs dcn401_hubp_funcs = { .hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar, .hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done, .hubp_clear_tiling = hubp401_clear_tiling, + .hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config, + .hubp_get_underflow_status = hubp3_get_underflow_status, + .hubp_get_current_read_line = hubp3_get_current_read_line, + .hubp_get_det_config_error = hubp31_get_det_config_error, }; bool hubp401_construct( diff --git a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h index 608e6153fa68..fdabbeec8ffa 100644 --- a/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.h @@ -252,7 +252,9 @@ HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_1H_P0, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P0, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_1H_P1, mask_sh),\ - HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P1, mask_sh) + HUBP_SF(HUBP0_DCHUBP_MCACHEID_CONFIG, MCACHEID_MALL_PREF_2H_P1, mask_sh),\ + HUBP_SF(HUBPRET0_HUBPRET_READ_LINE_VALUE, PIPE_READ_LINE, mask_sh),\ + HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_SEG_ALLOC_ERR_STATUS, mask_sh) void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor); @@ -349,6 +351,10 @@ void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_forma void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode); +void hubp401_program_3dlut_fl_config( + struct hubp *hubp, + struct hubp_fl_3dlut_config *cfg); + void hubp401_clear_tiling(struct hubp *hubp); void hubp401_vready_at_or_After_vsync(struct hubp *hubp, diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index 39910f73ecd0..79c9bea78c47 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -328,19 +328,25 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx) } DTN_INFO("\n=======HUBP FL======\n"); - DTN_INFO( - "HUBP FL: Enabled Done adr_mode width tmz xbar_sel_R xbar_sel_G xbar_sel_B adr_hi adr_low REFCYC Bias Scale Mode Format\n"); + char pLabels[18][50] = { + "inst", "Enabled ", "Done ", "adr_mode ", "width ", "mpc_width ", + "tmz", "xbar_sel_R", "xbar_sel_G", "xbar_sel_B", "adr_hi ", + "adr_low", "REFCYC", "Bias", "Scale", "Mode", + "Format", "prefetch"}; + for (i = 0; i < pool->pipe_count; i++) { struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); struct dcn_fl_regs_st *fl_regs = &s->fl_regs; + struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr; if (!s->blank_en) { - DTN_INFO("[%2d]: %5xh %6xh %5d %6d %8xh %2xh %6xh %6d %8d %8d %7d %8xh %5x %5x %5x", + uint32_t values[] = { pool->hubps[i]->inst, fl_regs->lut_enable, fl_regs->lut_done, fl_regs->lut_addr_mode, fl_regs->lut_width, + fl_regs->lut_mpc_width, fl_regs->lut_tmz, fl_regs->lut_crossbar_sel_r, fl_regs->lut_crossbar_sel_g, @@ -351,8 +357,13 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx) fl_regs->lut_fl_bias, fl_regs->lut_fl_scale, fl_regs->lut_fl_mode, - fl_regs->lut_fl_format); - DTN_INFO("\n"); + fl_regs->lut_fl_format, + dlg_regs->dst_y_prefetch}; + + int num_elements = 18; + + for (int j = 0; j < num_elements; j++) + DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]); } } @@ -541,19 +552,43 @@ static void dcn10_log_color_state(struct dc *dc, dc->caps.color.mpc.ogam_ram, dc->caps.color.mpc.ocsc); DTN_INFO("===== MPC RMCM 3DLUT =====\n"); - DTN_INFO("MPCC: SIZE MODE MODE_CUR RD_SEL 30BIT_EN WR_EN_MASK RAM_SEL OUT_NORM_FACTOR FL_SEL OUT_OFFSET OUT_SCALE FL_DONE SOFT_UNDERFLOW HARD_UNDERFLOW MEM_PWR_ST FORCE DIS MODE\n"); + char pLabels[19][50] = { + "MPCC", "SIZE", "MODE", "MODE_CUR", "RD_SEL", + "30BIT_EN", "WR_EN_MASK", "RAM_SEL", "OUT_NORM_FACTOR", "FL_SEL", + "OUT_OFFSET", "OUT_SCALE", "FL_DONE", "SOFT_UNDERFLOW", "HARD_UNDERFLOW", + "MEM_PWR_ST", "FORCE", "DIS", "MODE"}; + for (i = 0; i < pool->mpcc_count; i++) { struct mpcc_state s = {0}; pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s); - if (s.opp_id != 0xf) - DTN_INFO("[%2d]: %4xh %4xh %6xh %4x %4x %4x %4x %4x %4xh %4xh %6xh %4x %4x %4x %4x %4x %4x %4x\n", - i, s.rmcm_regs.rmcm_3dlut_size, s.rmcm_regs.rmcm_3dlut_mode, s.rmcm_regs.rmcm_3dlut_mode_cur, - s.rmcm_regs.rmcm_3dlut_read_sel, s.rmcm_regs.rmcm_3dlut_30bit_en, s.rmcm_regs.rmcm_3dlut_wr_en_mask, - s.rmcm_regs.rmcm_3dlut_ram_sel, s.rmcm_regs.rmcm_3dlut_out_norm_factor, s.rmcm_regs.rmcm_3dlut_fl_sel, - s.rmcm_regs.rmcm_3dlut_out_offset_r, s.rmcm_regs.rmcm_3dlut_out_scale_r, s.rmcm_regs.rmcm_3dlut_fl_done, - s.rmcm_regs.rmcm_3dlut_fl_soft_underflow, s.rmcm_regs.rmcm_3dlut_fl_hard_underflow, s.rmcm_regs.rmcm_3dlut_mem_pwr_state, - s.rmcm_regs.rmcm_3dlut_mem_pwr_force, s.rmcm_regs.rmcm_3dlut_mem_pwr_dis, s.rmcm_regs.rmcm_3dlut_mem_pwr_mode); + if (s.opp_id != 0xf) { + uint32_t values[] = { + i, + s.rmcm_regs.rmcm_3dlut_size, + s.rmcm_regs.rmcm_3dlut_mode, + s.rmcm_regs.rmcm_3dlut_mode_cur, + s.rmcm_regs.rmcm_3dlut_read_sel, + s.rmcm_regs.rmcm_3dlut_30bit_en, + s.rmcm_regs.rmcm_3dlut_wr_en_mask, + s.rmcm_regs.rmcm_3dlut_ram_sel, + s.rmcm_regs.rmcm_3dlut_out_norm_factor, + s.rmcm_regs.rmcm_3dlut_fl_sel, + s.rmcm_regs.rmcm_3dlut_out_offset_r, + s.rmcm_regs.rmcm_3dlut_out_scale_r, + s.rmcm_regs.rmcm_3dlut_fl_done, + s.rmcm_regs.rmcm_3dlut_fl_soft_underflow, + s.rmcm_regs.rmcm_3dlut_fl_hard_underflow, + s.rmcm_regs.rmcm_3dlut_mem_pwr_state, + s.rmcm_regs.rmcm_3dlut_mem_pwr_force, + s.rmcm_regs.rmcm_3dlut_mem_pwr_dis, + s.rmcm_regs.rmcm_3dlut_mem_pwr_mode}; + + int num_elements = 19; + + for (int j = 0; j < num_elements; j++) + DTN_INFO("%s \t %8xh\n", pLabels[j], values[j]); + } } DTN_INFO("\n"); DTN_INFO("===== MPC RMCM Shaper =====\n"); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c index 37a239219dfe..139a63101488 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c @@ -1228,3 +1228,51 @@ void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx) } } } + +void dcn30_get_underflow_debug_data(const struct dc *dc, + struct timing_generator *tg, + struct dc_underflow_debug_data *out_data) +{ + struct hubbub *hubbub = dc->res_pool->hubbub; + + if (tg) { + uint32_t v_blank_start = 0, v_blank_end = 0; + + out_data->otg_inst = tg->inst; + + tg->funcs->get_scanoutpos(tg, + &v_blank_start, + &v_blank_end, + &out_data->h_position, + &out_data->v_position); + + out_data->otg_frame_count = tg->funcs->get_frame_count(tg); + + out_data->otg_underflow = tg->funcs->is_optc_underflow_occurred(tg); + } + + for (int i = 0; i < MAX_PIPES; i++) { + struct hubp *hubp = dc->res_pool->hubps[i]; + + if (hubp) { + if (hubp->funcs->hubp_get_underflow_status) + out_data->hubps[i].hubp_underflow = hubp->funcs->hubp_get_underflow_status(hubp); + + if (hubp->funcs->hubp_in_blank) + out_data->hubps[i].hubp_in_blank = hubp->funcs->hubp_in_blank(hubp); + + if (hubp->funcs->hubp_get_current_read_line) + out_data->hubps[i].hubp_readline = hubp->funcs->hubp_get_current_read_line(hubp); + + if (hubp->funcs->hubp_get_det_config_error) + out_data->hubps[i].det_config_error = hubp->funcs->hubp_get_det_config_error(hubp); + } + } + + if (hubbub->funcs->get_det_sizes) + hubbub->funcs->get_det_sizes(hubbub, out_data->curr_det_sizes, out_data->target_det_sizes); + + if (hubbub->funcs->compbuf_config_error) + out_data->compbuf_config_error = hubbub->funcs->compbuf_config_error(hubbub); + +} diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h index 4b90b781c4f2..40afbbfb5b9c 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.h @@ -29,6 +29,7 @@ #include "hw_sequencer_private.h" struct dc; +struct dc_underflow_debug_data; void dcn30_init_hw(struct dc *dc); void dcn30_program_all_writeback_pipes_in_tree( @@ -98,4 +99,8 @@ void dcn30_prepare_bandwidth(struct dc *dc, void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx); +void dcn30_get_underflow_debug_data(const struct dc *dc, + struct timing_generator *tg, + struct dc_underflow_debug_data *out_data); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c index 2ac5d54d1626..d7ff55669bac 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_init.c @@ -110,6 +110,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .update_visual_confirm_color = dcn10_update_visual_confirm_color, .is_abm_supported = dcn21_is_abm_supported, .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c index 556f4fe57eda..5a6a459da224 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_init.c @@ -112,6 +112,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = { .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, .update_visual_confirm_color = dcn10_update_visual_confirm_color, .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn31_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c index f5112742edf9..a99145a30230 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_init.c @@ -115,6 +115,7 @@ static const struct hw_sequencer_funcs dcn314_funcs = { .update_visual_confirm_color = dcn10_update_visual_confirm_color, .calculate_pix_rate_divider = dcn314_calculate_pix_rate_divider, .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn314_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c index b971356d30b1..c19ef075c882 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c @@ -121,6 +121,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = { .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider, .program_outstanding_updates = dcn32_program_outstanding_updates, .wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn32_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c index a3ccf805bd16..52cc488416ac 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c @@ -128,6 +128,7 @@ static const struct hw_sequencer_funcs dcn35_funcs = { .enable_plane = dcn20_enable_plane, .update_dchubp_dpp = dcn20_update_dchubp_dpp, .post_unlock_reset_opp = dcn20_post_unlock_reset_opp, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn35_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c index 58f2be2a326b..e34efcb7bde5 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn351/dcn351_init.c @@ -123,6 +123,7 @@ static const struct hw_sequencer_funcs dcn351_funcs = { .set_long_vtotal = dcn35_set_long_vblank, .calculate_pix_rate_divider = dcn32_calculate_pix_rate_divider, .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn351_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index fb949aeb1244..d5b5e2ce6ff6 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -1621,20 +1621,28 @@ void dcn401_unblank_stream(struct pipe_ctx *pipe_ctx, void dcn401_hardware_release(struct dc *dc) { - dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); - - /* If pstate unsupported, or still supported - * by firmware, force it supported by dcn - */ - if (dc->current_state) { - if ((!dc->clk_mgr->clks.p_state_change_support || - dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) && - dc->res_pool->hubbub->funcs->force_pstate_change_control) - dc->res_pool->hubbub->funcs->force_pstate_change_control( - dc->res_pool->hubbub, true, true); - - dc->current_state->bw_ctx.bw.dcn.clk.p_state_change_support = true; - dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); + if (!dc->debug.disable_force_pstate_allow_on_hw_release) { + dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); + + /* If pstate unsupported, or still supported + * by firmware, force it supported by dcn + */ + if (dc->current_state) { + if ((!dc->clk_mgr->clks.p_state_change_support || + dc->current_state->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable) && + dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, true, true); + + dc->current_state->bw_ctx.bw.dcn.clk.p_state_change_support = true; + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); + } + } else { + if (dc->current_state) { + dc->clk_mgr->clks.p_state_change_support = false; + dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, dc->current_state, true); + } + dc_dmub_srv_fams2_update_config(dc, dc->current_state, false); } } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c index fe7aceb2f510..d6e11b7e4fce 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_init.c @@ -104,6 +104,7 @@ static const struct hw_sequencer_funcs dcn401_funcs = { .enable_plane = dcn20_enable_plane, .update_dchubp_dpp = dcn20_update_dchubp_dpp, .post_unlock_reset_opp = dcn20_post_unlock_reset_opp, + .get_underflow_debug_data = dcn30_get_underflow_debug_data, }; static const struct hwseq_private_funcs dcn401_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index 9df8030e37f7..1723bbcf2c46 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -47,6 +47,7 @@ struct link_resource; struct dc_dmub_cmd; struct pg_block_update; struct drr_params; +struct dc_underflow_debug_data; struct subvp_pipe_control_lock_fast_params { struct dc *dc; @@ -475,6 +476,9 @@ struct hw_sequencer_funcs { struct dc_state *context); void (*post_unlock_reset_opp)(struct dc *dc, struct pipe_ctx *opp_head); + void (*get_underflow_debug_data)(const struct dc *dc, + struct timing_generator *tg, + struct dc_underflow_debug_data *out_data); }; void color_space_to_black_color( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index 52b745667ef7..9bee45b36629 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -229,6 +229,8 @@ struct hubbub_funcs { void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst); bool (*program_arbiter)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower); + void (*get_det_sizes)(struct hubbub *hubbub, uint32_t *curr_det_sizes, uint32_t *target_det_sizes); + uint32_t (*compbuf_config_error)(struct hubbub *hubbub); }; struct hubbub { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index cee29e89ec5c..2b874d2cc61c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -89,7 +89,7 @@ enum hubp_3dlut_fl_addressing_mode { enum hubp_3dlut_fl_width { hubp_3dlut_fl_width_17 = 17, hubp_3dlut_fl_width_33 = 33, - hubp_3dlut_fl_width_transformed = 4916 + hubp_3dlut_fl_width_transformed = 4916, //mpc default }; enum hubp_3dlut_fl_crossbar_bit_slice { @@ -99,6 +99,22 @@ enum hubp_3dlut_fl_crossbar_bit_slice { hubp_3dlut_fl_crossbar_bit_slice_48_63 = 3 }; +struct hubp_fl_3dlut_config { + bool enabled; + enum hubp_3dlut_fl_width width; + enum hubp_3dlut_fl_mode mode; + enum hubp_3dlut_fl_format format; + uint16_t bias; + uint16_t scale; + struct dc_plane_address address; + enum hubp_3dlut_fl_addressing_mode addr_mode; + enum dc_cm2_gpu_mem_layout layout; + uint8_t protection_bits; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_y_g; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cb_b; + enum hubp_3dlut_fl_crossbar_bit_slice crossbar_bit_slice_cr_r; +}; + struct hubp { const struct hubp_funcs *funcs; struct dc_context *ctx; @@ -288,7 +304,10 @@ struct hubp_funcs { enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b, enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r); int (*hubp_get_3dlut_fl_done)(struct hubp *hubp); + void (*hubp_program_3dlut_fl_config)(struct hubp *hubp, struct hubp_fl_3dlut_config *cfg); void (*hubp_clear_tiling)(struct hubp *hubp); + uint32_t (*hubp_get_current_read_line)(struct hubp *hubp); + uint32_t (*hubp_get_det_config_error)(struct hubp *hubp); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index 7641439f6ca0..14f0304e3eb9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -115,6 +115,16 @@ enum MCM_LUT_ID { MCM_LUT_SHAPER }; +struct mpc_fl_3dlut_config { + bool enabled; + uint16_t width; + bool select_lut_bank_a; + uint16_t bit_depth; + int hubp_index; + uint16_t bias; + uint16_t scale; +}; + union mcm_lut_params { const struct pwl_params *pwl; const struct tetrahedral_params *lut3d; @@ -1098,6 +1108,7 @@ struct mpc_funcs { * MPC RMCM new HW sequential programming functions */ struct { + void (*fl_3dlut_configure)(struct mpc *mpc, struct mpc_fl_3dlut_config *cfg, int mpcc_id); void (*enable_3dlut_fl)(struct mpc *mpc, bool enable, int mpcc_id); void (*update_3dlut_fast_load_select)(struct mpc *mpc, int mpcc_id, int hubp_idx); void (*program_lut_read_write_control)(struct mpc *mpc, const enum MCM_LUT_ID id, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index be714cbf6615..2c3e2945124a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -1046,7 +1046,7 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) { alpm_config.bits.ALPM_MODE_SEL = 1; - alpm_config.bits.ACDS_PERIOD_DURATION = 1; + alpm_config.bits.ACDS_PERIOD_DURATION = 0; } dm_helpers_dp_write_dpcd( diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index 58b59d52dc9d..53b60044653f 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -373,7 +373,7 @@ static const struct resource_caps res_cap = { .num_timing_generator = 6, .num_audio = 6, .num_stream_encoder = 6, - .num_pll = 2, + .num_pll = 3, .num_ddc = 6, }; @@ -389,7 +389,7 @@ static const struct resource_caps res_cap_64 = { .num_timing_generator = 2, .num_audio = 2, .num_stream_encoder = 2, - .num_pll = 2, + .num_pll = 3, .num_ddc = 2, }; @@ -973,21 +973,24 @@ static bool dce60_construct( if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); + /* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */ pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 2; } else { pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); - pool->base.clk_src_count = 1; + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); + pool->base.clock_sources[1] = + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); + pool->base.clk_src_count = 2; } if (pool->base.dp_clock_source == NULL) { @@ -1365,21 +1368,24 @@ static bool dce64_construct( if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) { pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true); + /* DCE 6.0 and 6.4: PLL0 can only be used with DP. Don't initialize it here. */ pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], false); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); pool->base.clock_sources[1] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); pool->base.clk_src_count = 2; } else { pool->base.dp_clock_source = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[0], true); + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true); pool->base.clock_sources[0] = - dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[1], false); - pool->base.clk_src_count = 1; + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false); + pool->base.clock_sources[1] = + dce60_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false); + pool->base.clk_src_count = 2; } if (pool->base.dp_clock_source == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h index 82f966cf4ed2..20d714596021 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h @@ -1141,7 +1141,8 @@ unsigned int dcn32_get_max_hw_cursor_size(const struct dc *dc, SRI_ARR(DCN_SURF1_TTU_CNTL1, HUBPREQ, id), \ SRI_ARR(DCN_CUR0_TTU_CNTL0, HUBPREQ, id), \ SRI_ARR(DCN_CUR0_TTU_CNTL1, HUBPREQ, id), \ - SRI_ARR(HUBP_CLK_CNTL, HUBP, id) + SRI_ARR(HUBP_CLK_CNTL, HUBP, id), \ + SRI_ARR(HUBPRET_READ_LINE_VALUE, HUBPRET, id) #define HUBP_REG_LIST_DCN2_COMMON_RI(id) \ HUBP_REG_LIST_DCN_RI(id), HUBP_REG_LIST_DCN_VM_RI(id), \ SRI_ARR(PREFETCH_SETTINGS, HUBPREQ, id), \ diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c index b3988e38d0a6..068c123ea8a8 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c @@ -708,6 +708,7 @@ static const struct dc_debug_options debug_defaults_drv = { }, .use_max_lb = true, .force_disable_subvp = false, + .disable_force_pstate_allow_on_hw_release = false, .exit_idle_opt_for_cursor_updates = true, .using_dml2 = true, .using_dml21 = true, diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h index 2ae6831c31ef..0fc66487d800 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h @@ -140,7 +140,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context); SRI_ARR(UCLK_PSTATE_FORCE, HUBPREQ, id), \ HUBP_3DLUT_FL_REG_LIST_DCN401(id), \ SRI_ARR(DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE, HUBP, id), \ - SRI_ARR(DCHUBP_MCACHEID_CONFIG, HUBP, id) + SRI_ARR(DCHUBP_MCACHEID_CONFIG, HUBP, id), \ + SRI_ARR(HUBPRET_READ_LINE_VALUE, HUBPRET, id) /* ABM */ #define ABM_DCN401_REG_LIST_RI(id) \ diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index 0bafb6710761..87b761ac3135 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -316,6 +316,7 @@ struct dmub_srv_hw_params { bool disable_sldo_opt; bool enable_non_transparent_setconfig; bool lower_hbr3_phy_ssc; + bool override_hbr3_pll_vco; }; /** diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index dcae768c2cf4..79b5b1bb9b93 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -843,7 +843,8 @@ union dmub_fw_boot_options { uint32_t ips_sequential_ono: 1; /**< 1 to enable sequential ONO IPS sequence */ uint32_t disable_sldo_opt: 1; /**< 1 to disable SLDO optimizations */ uint32_t lower_hbr3_phy_ssc: 1; /**< 1 to lower hbr3 phy ssc to 0.125 percent */ - uint32_t reserved : 6; /**< reserved */ + uint32_t override_hbr3_pll_vco: 1; /**< 1 to override the hbr3 pll vco to 0 */ + uint32_t reserved : 5; /**< reserved */ } bits; /**< boot bits */ uint32_t all; /**< 32-bit access to bits */ }; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 3f38db752b84..4777c7203b2c 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -377,6 +377,7 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu boot_options.bits.dpia_hpd_int_enable_supported = params->dpia_hpd_int_enable_supported; boot_options.bits.power_optimization = params->power_optimization; boot_options.bits.lower_hbr3_phy_ssc = params->lower_hbr3_phy_ssc; + boot_options.bits.override_hbr3_pll_vco = params->override_hbr3_pll_vco; boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 5fc29164e4b4..8aea50aa9533 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -213,6 +213,11 @@ enum { #endif #define DEVICE_ID_NV_13FE 0x13FE // CYAN_SKILLFISH #define DEVICE_ID_NV_143F 0x143F +#define DEVICE_ID_NV_13F9 0x13F9 +#define DEVICE_ID_NV_13FA 0x13FA +#define DEVICE_ID_NV_13FB 0x13FB +#define DEVICE_ID_NV_13FC 0x13FC +#define DEVICE_ID_NV_13DB 0x13DB #define FAMILY_VGH 144 #define DEVICE_ID_VGH_163F 0x163F #define DEVICE_ID_VGH_1435 0x1435 diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 756afe78a6e5..b47cb4a5f488 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -77,6 +77,9 @@ static void smu_power_profile_mode_get(struct smu_context *smu, static void smu_power_profile_mode_put(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile_mode); static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type); +static int smu_od_edit_dpm_table(void *handle, + enum PP_OD_DPM_TABLE_COMMAND type, + long *input, uint32_t size); static int smu_sys_get_pp_feature_mask(void *handle, char *buf) @@ -2195,6 +2198,7 @@ static int smu_resume(struct amdgpu_ip_block *ip_block) int ret; struct amdgpu_device *adev = ip_block->adev; struct smu_context *smu = adev->powerplay.pp_handle; + struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); if (amdgpu_sriov_multi_vf_mode(adev)) return 0; @@ -2226,6 +2230,18 @@ static int smu_resume(struct amdgpu_ip_block *ip_block) adev->pm.dpm_enabled = true; + if (smu->current_power_limit) { + ret = smu_set_power_limit(smu, smu->current_power_limit); + if (ret && ret != -EOPNOTSUPP) + return ret; + } + + if (smu_dpm_ctx->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) { + ret = smu_od_edit_dpm_table(smu, PP_OD_COMMIT_DPM_TABLE, NULL, 0); + if (ret) + return ret; + } + dev_info(adev->dev, "SMU is resumed successfully!\n"); return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 9ad46f545d15..599eddb5a67d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1897,7 +1897,7 @@ static ssize_t arcturus_get_gpu_metrics(struct smu_context *smu, ret = smu_cmn_get_metrics_table(smu, &metrics, - true); + false); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index c63d2e28954d..b067147b7c41 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1781,7 +1781,7 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, ret = smu_cmn_get_metrics_table(smu, &metrics, - true); + false); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 9cc294f4708b..a0ce108aab44 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -177,7 +177,7 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU MSG_MAP(SetThrottlingPolicy, PPSMC_MSG_SetThrottlingPolicy, 0), MSG_MAP(ResetSDMA, PPSMC_MSG_ResetSDMA, 0), MSG_MAP(ResetVCN, PPSMC_MSG_ResetVCN, 0), - MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 0), + MSG_MAP(GetStaticMetricsTable, PPSMC_MSG_GetStaticMetricsTable, 1), }; // clang-format on @@ -402,14 +402,28 @@ static void smu_v13_0_6_init_caps(struct smu_context *smu) if ((pgm == 7 && fw_ver >= 0x7550E00) || (pgm == 0 && fw_ver >= 0x00557E00)) smu_v13_0_6_cap_set(smu, SMU_CAP(HST_LIMIT_METRICS)); - if ((pgm == 0 && fw_ver >= 0x00557F01) || - (pgm == 7 && fw_ver >= 0x7551000)) { - smu_v13_0_6_cap_set(smu, SMU_CAP(STATIC_METRICS)); - smu_v13_0_6_cap_set(smu, SMU_CAP(BOARD_VOLTAGE)); + + if (amdgpu_sriov_vf(adev)) { + if ((pgm == 0 && fw_ver >= 0x00558000) || + (pgm == 7 && fw_ver >= 0x7551000)) { + smu_v13_0_6_cap_set(smu, + SMU_CAP(STATIC_METRICS)); + smu_v13_0_6_cap_set(smu, + SMU_CAP(BOARD_VOLTAGE)); + smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); + } + } else { + if ((pgm == 0 && fw_ver >= 0x00557F01) || + (pgm == 7 && fw_ver >= 0x7551000)) { + smu_v13_0_6_cap_set(smu, + SMU_CAP(STATIC_METRICS)); + smu_v13_0_6_cap_set(smu, + SMU_CAP(BOARD_VOLTAGE)); + } + if ((pgm == 0 && fw_ver >= 0x00558000) || + (pgm == 7 && fw_ver >= 0x7551000)) + smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); } - if ((pgm == 0 && fw_ver >= 0x00558000) || - (pgm == 7 && fw_ver >= 0x7551000)) - smu_v13_0_6_cap_set(smu, SMU_CAP(PLDM_VERSION)); } if (((pgm == 7) && (fw_ver >= 0x7550700)) || ((pgm == 0) && (fw_ver >= 0x00557900)) || diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c index b63304d3a80f..b3e4cdff61d6 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -18,6 +18,7 @@ static void drm_aux_bridge_release(struct device *dev) { struct auxiliary_device *adev = to_auxiliary_dev(dev); + of_node_put(dev->of_node); ida_free(&drm_aux_bridge_ida, adev->id); kfree(adev); @@ -65,6 +66,7 @@ int drm_aux_bridge_register(struct device *parent) ret = auxiliary_device_init(adev); if (ret) { + of_node_put(adev->dev.of_node); ida_free(&drm_aux_bridge_ida, adev->id); kfree(adev); return ret; diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index dd45d9b504d8..4bde00083047 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -1227,6 +1227,7 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_check); /** * drm_bridge_detect - check if anything is attached to the bridge output * @bridge: bridge control structure + * @connector: attached connector * * If the bridge supports output detection, as reported by the * DRM_BRIDGE_OP_DETECT bridge ops flag, call &drm_bridge_funcs.detect for the diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index a15ce72920ac..6a44351e58b7 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -646,7 +646,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) i = 0; while (i < npages) { long nr; - folio = shmem_read_folio_gfp(mapping, i, 0, + folio = shmem_read_folio_gfp(mapping, i, mapping_gfp_mask(mapping)); if (IS_ERR(folio)) goto fail; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 28bccf3d71ef..e3d188455f67 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -70,7 +70,6 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, struct scatterlist *sg; unsigned long next_pfn = 0; /* suppress gcc warning */ gfp_t noreclaim; - size_t chunk; int ret; if (overflows_type(size / PAGE_SIZE, page_count)) @@ -96,7 +95,6 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, mapping_set_unevictable(mapping); noreclaim = mapping_gfp_constraint(mapping, ~__GFP_RECLAIM); noreclaim |= __GFP_NORETRY | __GFP_NOWARN; - chunk = mapping_max_folio_size(mapping); sg = st->sgl; st->nents = 0; @@ -108,13 +106,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, 0, }, *s = shrink; gfp_t gfp = noreclaim; - loff_t bytes = (page_count - i) << PAGE_SHIFT; - loff_t pos = i << PAGE_SHIFT; - bytes = min_t(loff_t, chunk, bytes); do { cond_resched(); - folio = shmem_read_folio_gfp(mapping, i, pos + bytes, gfp); + folio = shmem_read_folio_gfp(mapping, i, gfp); if (!IS_ERR(folio)) break; diff --git a/drivers/gpu/drm/ttm/ttm_backup.c b/drivers/gpu/drm/ttm/ttm_backup.c index b04b5860b068..32530c75f038 100644 --- a/drivers/gpu/drm/ttm/ttm_backup.c +++ b/drivers/gpu/drm/ttm/ttm_backup.c @@ -102,7 +102,7 @@ ttm_backup_backup_page(struct file *backup, struct page *page, struct folio *to_folio; int ret; - to_folio = shmem_read_folio_gfp(mapping, idx, 0, alloc_gfp); + to_folio = shmem_read_folio_gfp(mapping, idx, alloc_gfp); if (IS_ERR(to_folio)) return PTR_ERR(to_folio); diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig index 2bb2bc052120..714d5702dfd7 100644 --- a/drivers/gpu/drm/xe/Kconfig +++ b/drivers/gpu/drm/xe/Kconfig @@ -5,6 +5,7 @@ config DRM_XE depends on KUNIT || !KUNIT depends on INTEL_VSEC || !INTEL_VSEC depends on X86_PLATFORM_DEVICES || !(X86 && ACPI) + depends on PAGE_SIZE_4KB || COMPILE_TEST || BROKEN select INTERVAL_TREE # we need shmfs for the swappable backing store, and in particular # the shmem_readpage() which depends upon tmpfs diff --git a/drivers/gpu/drm/xe/abi/guc_actions_abi.h b/drivers/gpu/drm/xe/abi/guc_actions_abi.h index 81eb046aeebf..d8cf68a0516d 100644 --- a/drivers/gpu/drm/xe/abi/guc_actions_abi.h +++ b/drivers/gpu/drm/xe/abi/guc_actions_abi.h @@ -193,6 +193,14 @@ enum xe_guc_register_context_multi_lrc_param_offsets { XE_GUC_REGISTER_CONTEXT_MULTI_LRC_MSG_MIN_LEN = 11, }; +enum xe_guc_context_wq_item_offsets { + XE_GUC_CONTEXT_WQ_HEADER_DATA_0_TYPE_LEN = 0, + XE_GUC_CONTEXT_WQ_EL_INFO_DATA_1_CTX_DESC_LOW, + XE_GUC_CONTEXT_WQ_EL_INFO_DATA_2_GUCCTX_RINGTAIL_FREEZEPOCS, + XE_GUC_CONTEXT_WQ_EL_INFO_DATA_3_WI_FENCE_ID, + XE_GUC_CONTEXT_WQ_EL_CHILD_LIST_DATA_4_RINGTAIL, +}; + enum xe_guc_report_status { XE_GUC_REPORT_STATUS_UNKNOWN = 0x0, XE_GUC_REPORT_STATUS_ACKED = 0x1, diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index c754374f1a8d..57edbc63da6f 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -822,10 +822,6 @@ int xe_device_probe(struct xe_device *xe) return err; } - err = xe_devcoredump_init(xe); - if (err) - return err; - /* * From here on, if a step fails, make sure a Driver-FLR is triggereed */ @@ -890,6 +886,10 @@ int xe_device_probe(struct xe_device *xe) XE_WA(xe->tiles->media_gt, 15015404425_disable)) XE_DEVICE_WA_DISABLE(xe, 15015404425); + err = xe_devcoredump_init(xe); + if (err) + return err; + xe_nvm_init(xe); err = xe_heci_gsc_init(xe); diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index d5958518ef00..6c176183ed58 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -1076,3 +1076,51 @@ int xe_exec_queue_last_fence_test_dep(struct xe_exec_queue *q, struct xe_vm *vm) return err; } + +/** + * xe_exec_queue_contexts_hwsp_rebase - Re-compute GGTT references + * within all LRCs of a queue. + * @q: the &xe_exec_queue struct instance containing target LRCs + * @scratch: scratch buffer to be used as temporary storage + * + * Returns: zero on success, negative error code on failure + */ +int xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q, void *scratch) +{ + int i; + int err = 0; + + for (i = 0; i < q->width; ++i) { + xe_lrc_update_memirq_regs_with_address(q->lrc[i], q->hwe, scratch); + xe_lrc_update_hwctx_regs_with_address(q->lrc[i]); + err = xe_lrc_setup_wa_bb_with_scratch(q->lrc[i], q->hwe, scratch); + if (err) + break; + } + + return err; +} + +/** + * xe_exec_queue_jobs_ring_restore - Re-emit ring commands of requests pending on given queue. + * @q: the &xe_exec_queue struct instance + */ +void xe_exec_queue_jobs_ring_restore(struct xe_exec_queue *q) +{ + struct xe_gpu_scheduler *sched = &q->guc->sched; + struct xe_sched_job *job; + + /* + * This routine is used within VF migration recovery. This means + * using the lock here introduces a restriction: we cannot wait + * for any GFX HW response while the lock is taken. + */ + spin_lock(&sched->base.job_list_lock); + list_for_each_entry(job, &sched->base.pending_list, drm.list) { + if (xe_sched_job_is_error(job)) + continue; + + q->ring_ops->emit_job(job); + } + spin_unlock(&sched->base.job_list_lock); +} diff --git a/drivers/gpu/drm/xe/xe_exec_queue.h b/drivers/gpu/drm/xe/xe_exec_queue.h index 17bc50a7f05a..4d416f23001c 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.h +++ b/drivers/gpu/drm/xe/xe_exec_queue.h @@ -90,4 +90,8 @@ int xe_exec_queue_last_fence_test_dep(struct xe_exec_queue *q, struct xe_vm *vm); void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q); +int xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q, void *scratch); + +void xe_exec_queue_jobs_ring_restore(struct xe_exec_queue *q); + #endif diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.c b/drivers/gpu/drm/xe/xe_gpu_scheduler.c index 869b43a4151d..455ccaf17314 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.c +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.c @@ -101,6 +101,19 @@ void xe_sched_submission_stop(struct xe_gpu_scheduler *sched) cancel_work_sync(&sched->work_process_msg); } +/** + * xe_sched_submission_stop_async - Stop further runs of submission tasks on a scheduler. + * @sched: the &xe_gpu_scheduler struct instance + * + * This call disables further runs of scheduling work queue. It does not wait + * for any in-progress runs to finish, only makes sure no further runs happen + * afterwards. + */ +void xe_sched_submission_stop_async(struct xe_gpu_scheduler *sched) +{ + drm_sched_wqueue_stop(&sched->base); +} + void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched) { drm_sched_resume_timeout(&sched->base, sched->base.timeout); diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.h b/drivers/gpu/drm/xe/xe_gpu_scheduler.h index 308061f0cf37..e548b2aed95a 100644 --- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h @@ -21,6 +21,7 @@ void xe_sched_fini(struct xe_gpu_scheduler *sched); void xe_sched_submission_start(struct xe_gpu_scheduler *sched); void xe_sched_submission_stop(struct xe_gpu_scheduler *sched); +void xe_sched_submission_stop_async(struct xe_gpu_scheduler *sched); void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched); diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 5a79c6e3208b..390394bbaadc 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -41,6 +41,7 @@ #include "xe_gt_topology.h" #include "xe_guc_exec_queue_types.h" #include "xe_guc_pc.h" +#include "xe_guc_submit.h" #include "xe_hw_fence.h" #include "xe_hw_engine_class_sysfs.h" #include "xe_irq.h" @@ -802,6 +803,11 @@ static int do_gt_restart(struct xe_gt *gt) return 0; } +static int gt_wait_reset_unblock(struct xe_gt *gt) +{ + return xe_guc_wait_reset_unblock(>->uc.guc); +} + static int gt_reset(struct xe_gt *gt) { unsigned int fw_ref; @@ -816,6 +822,10 @@ static int gt_reset(struct xe_gt *gt) xe_gt_info(gt, "reset started\n"); + err = gt_wait_reset_unblock(gt); + if (!err) + xe_gt_warn(gt, "reset block failed to get lifted"); + xe_pm_runtime_get(gt_to_xe(gt)); if (xe_fault_inject_gt_reset()) { diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c index 8d4b66ca38b7..bf3a67b5951c 100644 --- a/drivers/gpu/drm/xe/xe_gt_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c @@ -29,6 +29,7 @@ #include "xe_pm.h" #include "xe_reg_sr.h" #include "xe_reg_whitelist.h" +#include "xe_sa.h" #include "xe_sriov.h" #include "xe_tuning.h" #include "xe_uc_debugfs.h" @@ -128,7 +129,7 @@ static int sa_info(struct xe_gt *gt, struct drm_printer *p) xe_pm_runtime_get(gt_to_xe(gt)); drm_suballoc_dump_debug_info(&tile->mem.kernel_bb_pool->base, p, - tile->mem.kernel_bb_pool->gpu_addr); + xe_sa_manager_gpu_addr(tile->mem.kernel_bb_pool)); xe_pm_runtime_put(gt_to_xe(gt)); return 0; @@ -152,7 +153,7 @@ static int sa_info_vf_ccs(struct xe_gt *gt, struct drm_printer *p) drm_printf(p, "ccs %s bb suballoc info\n", ctx_id ? "write" : "read"); drm_printf(p, "-------------------------\n"); - drm_suballoc_dump_debug_info(&bb_pool->base, p, bb_pool->gpu_addr); + drm_suballoc_dump_debug_info(&bb_pool->base, p, xe_sa_manager_gpu_addr(bb_pool)); drm_puts(p, "\n"); } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c index 35489fa81825..c4dda87b47cc 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.c @@ -16,6 +16,7 @@ #include "xe_gt_sriov_pf_migration.h" #include "xe_gt_sriov_pf_service.h" #include "xe_gt_sriov_printk.h" +#include "xe_guc_submit.h" #include "xe_mmio.h" #include "xe_pm.h" @@ -47,9 +48,21 @@ static int pf_alloc_metadata(struct xe_gt *gt) static void pf_init_workers(struct xe_gt *gt) { + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); INIT_WORK(>->sriov.pf.workers.restart, pf_worker_restart_func); } +static void pf_fini_workers(struct xe_gt *gt) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + + if (disable_work_sync(>->sriov.pf.workers.restart)) { + xe_gt_sriov_dbg_verbose(gt, "pending restart disabled!\n"); + /* release an rpm reference taken on the worker's behalf */ + xe_pm_runtime_put(gt_to_xe(gt)); + } +} + /** * xe_gt_sriov_pf_init_early - Prepare SR-IOV PF data structures on PF. * @gt: the &xe_gt to initialize @@ -79,6 +92,21 @@ int xe_gt_sriov_pf_init_early(struct xe_gt *gt) return 0; } +static void pf_fini_action(void *arg) +{ + struct xe_gt *gt = arg; + + pf_fini_workers(gt); +} + +static int pf_init_late(struct xe_gt *gt) +{ + struct xe_device *xe = gt_to_xe(gt); + + xe_gt_assert(gt, IS_SRIOV_PF(xe)); + return devm_add_action_or_reset(xe->drm.dev, pf_fini_action, gt); +} + /** * xe_gt_sriov_pf_init - Prepare SR-IOV PF data structures on PF. * @gt: the &xe_gt to initialize @@ -95,7 +123,15 @@ int xe_gt_sriov_pf_init(struct xe_gt *gt) if (err) return err; - return xe_gt_sriov_pf_migration_init(gt); + err = xe_gt_sriov_pf_migration_init(gt); + if (err) + return err; + + err = pf_init_late(gt); + if (err) + return err; + + return 0; } static bool pf_needs_enable_ggtt_guest_update(struct xe_device *xe) @@ -176,8 +212,11 @@ static void pf_cancel_restart(struct xe_gt *gt) { xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); - if (cancel_work_sync(>->sriov.pf.workers.restart)) + if (cancel_work_sync(>->sriov.pf.workers.restart)) { xe_gt_sriov_dbg_verbose(gt, "pending restart canceled!\n"); + /* release an rpm reference taken on the worker's behalf */ + xe_pm_runtime_put(gt_to_xe(gt)); + } } /** @@ -195,9 +234,12 @@ static void pf_restart(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); - xe_pm_runtime_get(xe); + xe_gt_assert(gt, !xe_pm_runtime_suspended(xe)); + xe_gt_sriov_pf_config_restart(gt); xe_gt_sriov_pf_control_restart(gt); + + /* release an rpm reference taken on our behalf */ xe_pm_runtime_put(xe); xe_gt_sriov_dbg(gt, "restart completed\n"); @@ -216,8 +258,13 @@ static void pf_queue_restart(struct xe_gt *gt) xe_gt_assert(gt, IS_SRIOV_PF(xe)); - if (!queue_work(xe->sriov.wq, >->sriov.pf.workers.restart)) + /* take an rpm reference on behalf of the worker */ + xe_pm_runtime_get_noresume(xe); + + if (!queue_work(xe->sriov.wq, >->sriov.pf.workers.restart)) { xe_gt_sriov_dbg(gt, "restart already in queue!\n"); + xe_pm_runtime_put(xe); + } } /** @@ -230,3 +277,27 @@ void xe_gt_sriov_pf_restart(struct xe_gt *gt) { pf_queue_restart(gt); } + +static void pf_flush_restart(struct xe_gt *gt) +{ + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt))); + flush_work(>->sriov.pf.workers.restart); +} + +/** + * xe_gt_sriov_pf_wait_ready() - Wait until per-GT PF SR-IOV support is ready. + * @gt: the &xe_gt + * + * This function can only be called on PF. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_gt_sriov_pf_wait_ready(struct xe_gt *gt) +{ + /* don't wait if there is another ongoing reset */ + if (xe_guc_read_stopped(>->uc.guc)) + return -EBUSY; + + pf_flush_restart(gt); + return 0; +} diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h index e2b2ff8132dc..e7fde3f9937a 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf.h @@ -11,6 +11,7 @@ struct xe_gt; #ifdef CONFIG_PCI_IOV int xe_gt_sriov_pf_init_early(struct xe_gt *gt); int xe_gt_sriov_pf_init(struct xe_gt *gt); +int xe_gt_sriov_pf_wait_ready(struct xe_gt *gt); void xe_gt_sriov_pf_init_hw(struct xe_gt *gt); void xe_gt_sriov_pf_sanitize_hw(struct xe_gt *gt, unsigned int vfid); void xe_gt_sriov_pf_stop_prepare(struct xe_gt *gt); diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c index f00cce81f1ff..c8f0320d032f 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c @@ -1434,7 +1434,8 @@ fail: return err; } -static void pf_release_vf_config_lmem(struct xe_gt *gt, struct xe_gt_sriov_config *config) +/* Return: %true if there was an LMEM provisioned, %false otherwise */ +static bool pf_release_vf_config_lmem(struct xe_gt *gt, struct xe_gt_sriov_config *config) { xe_gt_assert(gt, IS_DGFX(gt_to_xe(gt))); xe_gt_assert(gt, xe_gt_is_main_type(gt)); @@ -1443,7 +1444,9 @@ static void pf_release_vf_config_lmem(struct xe_gt *gt, struct xe_gt_sriov_confi if (config->lmem_obj) { xe_bo_unpin_map_no_vm(config->lmem_obj); config->lmem_obj = NULL; + return true; } + return false; } static int pf_provision_vf_lmem(struct xe_gt *gt, unsigned int vfid, u64 size) @@ -2021,12 +2024,13 @@ static void pf_release_vf_config(struct xe_gt *gt, unsigned int vfid) { struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid); struct xe_device *xe = gt_to_xe(gt); + bool released; if (xe_gt_is_main_type(gt)) { pf_release_vf_config_ggtt(gt, config); if (IS_DGFX(xe)) { - pf_release_vf_config_lmem(gt, config); - if (xe_device_has_lmtt(xe)) + released = pf_release_vf_config_lmem(gt, config); + if (released && xe_device_has_lmtt(xe)) pf_update_vf_lmtt(xe, vfid); } } diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c index bf679b21f485..3ed245e04d0c 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c @@ -22,6 +22,7 @@ #include "xe_gt_sriov_pf_policy.h" #include "xe_gt_sriov_pf_service.h" #include "xe_pm.h" +#include "xe_sriov_pf.h" /* * /sys/kernel/debug/dri/0/ @@ -205,7 +206,8 @@ static int CONFIG##_set(void *data, u64 val) \ return -EOVERFLOW; \ \ xe_pm_runtime_get(xe); \ - err = xe_gt_sriov_pf_config_set_##CONFIG(gt, vfid, val); \ + err = xe_sriov_pf_wait_ready(xe) ?: \ + xe_gt_sriov_pf_config_set_##CONFIG(gt, vfid, val); \ xe_pm_runtime_put(xe); \ \ return err; \ diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c index b282838d59e6..0461d5513487 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c @@ -25,6 +25,7 @@ #include "xe_guc.h" #include "xe_guc_hxg_helpers.h" #include "xe_guc_relay.h" +#include "xe_lrc.h" #include "xe_mmio.h" #include "xe_sriov.h" #include "xe_sriov_vf.h" @@ -751,6 +752,19 @@ failed: } /** + * xe_gt_sriov_vf_default_lrcs_hwsp_rebase - Update GGTT references in HWSP of default LRCs. + * @gt: the &xe_gt struct instance + */ +void xe_gt_sriov_vf_default_lrcs_hwsp_rebase(struct xe_gt *gt) +{ + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + + for_each_hw_engine(hwe, gt, id) + xe_default_lrc_update_memirq_regs_with_address(hwe); +} + +/** * xe_gt_sriov_vf_migrated_event_handler - Start a VF migration recovery, * or just mark that a GuC is ready for it. * @gt: the &xe_gt struct instance linked to target GuC diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.h b/drivers/gpu/drm/xe/xe_gt_sriov_vf.h index e0357f341a2d..0af1dc769fe0 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.h +++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.h @@ -21,6 +21,7 @@ void xe_gt_sriov_vf_guc_versions(struct xe_gt *gt, int xe_gt_sriov_vf_query_config(struct xe_gt *gt); int xe_gt_sriov_vf_connect(struct xe_gt *gt); int xe_gt_sriov_vf_query_runtime(struct xe_gt *gt); +void xe_gt_sriov_vf_default_lrcs_hwsp_rebase(struct xe_gt *gt); int xe_gt_sriov_vf_notify_resfix_done(struct xe_gt *gt); void xe_gt_sriov_vf_migrated_event_handler(struct xe_gt *gt); diff --git a/drivers/gpu/drm/xe/xe_guc_buf.c b/drivers/gpu/drm/xe/xe_guc_buf.c index 14a07dca48e7..502ca3a4ee60 100644 --- a/drivers/gpu/drm/xe/xe_guc_buf.c +++ b/drivers/gpu/drm/xe/xe_guc_buf.c @@ -164,7 +164,7 @@ u64 xe_guc_cache_gpu_addr_from_ptr(struct xe_guc_buf_cache *cache, const void *p if (offset < 0 || offset + size > cache->sam->base.size) return 0; - return cache->sam->gpu_addr + offset; + return xe_sa_manager_gpu_addr(cache->sam) + offset; } #if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST) diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c index 859a3ba91be5..243dad3e2418 100644 --- a/drivers/gpu/drm/xe/xe_guc_capture.c +++ b/drivers/gpu/drm/xe/xe_guc_capture.c @@ -1817,6 +1817,12 @@ void xe_engine_snapshot_print(struct xe_hw_engine_snapshot *snapshot, struct drm str_yes_no(snapshot->kernel_reserved)); for (type = GUC_STATE_CAPTURE_TYPE_GLOBAL; type < GUC_STATE_CAPTURE_TYPE_MAX; type++) { + /* + * FIXME: During devcoredump print we should avoid accessing the + * driver pointers for gt or engine. Printing should be done only + * using the snapshot captured. Here we are accessing the gt + * pointer. It should be fixed. + */ list = xe_guc_capture_get_reg_desc_list(gt, GUC_CAPTURE_LIST_INDEX_PF, type, capture_class, false); snapshot_print_by_list_order(snapshot, p, type, list); diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 751da5cd1d44..1185b23b1384 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -671,12 +671,18 @@ static void wq_item_append(struct xe_exec_queue *q) if (wq_wait_for_space(q, wqi_size)) return; + xe_gt_assert(guc_to_gt(guc), i == XE_GUC_CONTEXT_WQ_HEADER_DATA_0_TYPE_LEN); wqi[i++] = FIELD_PREP(WQ_TYPE_MASK, WQ_TYPE_MULTI_LRC) | FIELD_PREP(WQ_LEN_MASK, len_dw); + xe_gt_assert(guc_to_gt(guc), i == XE_GUC_CONTEXT_WQ_EL_INFO_DATA_1_CTX_DESC_LOW); wqi[i++] = xe_lrc_descriptor(q->lrc[0]); + xe_gt_assert(guc_to_gt(guc), i == + XE_GUC_CONTEXT_WQ_EL_INFO_DATA_2_GUCCTX_RINGTAIL_FREEZEPOCS); wqi[i++] = FIELD_PREP(WQ_GUC_ID_MASK, q->guc->id) | FIELD_PREP(WQ_RING_TAIL_MASK, q->lrc[0]->ring.tail / sizeof(u64)); + xe_gt_assert(guc_to_gt(guc), i == XE_GUC_CONTEXT_WQ_EL_INFO_DATA_3_WI_FENCE_ID); wqi[i++] = 0; + xe_gt_assert(guc_to_gt(guc), i == XE_GUC_CONTEXT_WQ_EL_CHILD_LIST_DATA_4_RINGTAIL); for (j = 1; j < q->width; ++j) { struct xe_lrc *lrc = q->lrc[j]; @@ -697,6 +703,50 @@ static void wq_item_append(struct xe_exec_queue *q) parallel_write(xe, map, wq_desc.tail, q->guc->wqi_tail); } +static int wq_items_rebase(struct xe_exec_queue *q) +{ + struct xe_guc *guc = exec_queue_to_guc(q); + struct xe_device *xe = guc_to_xe(guc); + struct iosys_map map = xe_lrc_parallel_map(q->lrc[0]); + int i = q->guc->wqi_head; + + /* the ring starts after a header struct */ + iosys_map_incr(&map, offsetof(struct guc_submit_parallel_scratch, wq[0])); + + while ((i % WQ_SIZE) != (q->guc->wqi_tail % WQ_SIZE)) { + u32 len_dw, type, val; + + if (drm_WARN_ON_ONCE(&xe->drm, i < 0 || i > 2 * WQ_SIZE)) + break; + + val = xe_map_rd_ring_u32(xe, &map, i / sizeof(u32) + + XE_GUC_CONTEXT_WQ_HEADER_DATA_0_TYPE_LEN, + WQ_SIZE / sizeof(u32)); + len_dw = FIELD_GET(WQ_LEN_MASK, val); + type = FIELD_GET(WQ_TYPE_MASK, val); + + if (drm_WARN_ON_ONCE(&xe->drm, len_dw >= WQ_SIZE / sizeof(u32))) + break; + + if (type == WQ_TYPE_MULTI_LRC) { + val = xe_lrc_descriptor(q->lrc[0]); + xe_map_wr_ring_u32(xe, &map, i / sizeof(u32) + + XE_GUC_CONTEXT_WQ_EL_INFO_DATA_1_CTX_DESC_LOW, + WQ_SIZE / sizeof(u32), val); + } else if (drm_WARN_ON_ONCE(&xe->drm, type != WQ_TYPE_NOOP)) { + break; + } + + i += (len_dw + 1) * sizeof(u32); + } + + if ((i % WQ_SIZE) != (q->guc->wqi_tail % WQ_SIZE)) { + xe_gt_err(q->gt, "Exec queue fixups incomplete - wqi parse failed\n"); + return -EBADMSG; + } + return 0; +} + #define RESUME_PENDING ~0x0ull static void submit_exec_queue(struct xe_exec_queue *q) { @@ -781,6 +831,30 @@ guc_exec_queue_run_job(struct drm_sched_job *drm_job) return fence; } +/** + * xe_guc_jobs_ring_rebase - Re-emit ring commands of requests pending + * on all queues under a guc. + * @guc: the &xe_guc struct instance + */ +void xe_guc_jobs_ring_rebase(struct xe_guc *guc) +{ + struct xe_exec_queue *q; + unsigned long index; + + /* + * This routine is used within VF migration recovery. This means + * using the lock here introduces a restriction: we cannot wait + * for any GFX HW response while the lock is taken. + */ + mutex_lock(&guc->submission_state.lock); + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { + if (exec_queue_killed_or_banned_or_wedged(q)) + continue; + xe_exec_queue_jobs_ring_restore(q); + } + mutex_unlock(&guc->submission_state.lock); +} + static void guc_exec_queue_free_job(struct drm_sched_job *drm_job) { struct xe_sched_job *job = to_xe_sched_job(drm_job); @@ -1777,6 +1851,43 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q) } } +/** + * xe_guc_submit_reset_block - Disallow reset calls on given GuC. + * @guc: the &xe_guc struct instance + */ +int xe_guc_submit_reset_block(struct xe_guc *guc) +{ + return atomic_fetch_or(1, &guc->submission_state.reset_blocked); +} + +/** + * xe_guc_submit_reset_unblock - Allow back reset calls on given GuC. + * @guc: the &xe_guc struct instance + */ +void xe_guc_submit_reset_unblock(struct xe_guc *guc) +{ + atomic_set_release(&guc->submission_state.reset_blocked, 0); + wake_up_all(&guc->ct.wq); +} + +static int guc_submit_reset_is_blocked(struct xe_guc *guc) +{ + return atomic_read_acquire(&guc->submission_state.reset_blocked); +} + +/* Maximum time of blocking reset */ +#define RESET_BLOCK_PERIOD_MAX (HZ * 5) + +/** + * xe_guc_wait_reset_unblock - Wait until reset blocking flag is lifted, or timeout. + * @guc: the &xe_guc struct instance + */ +int xe_guc_wait_reset_unblock(struct xe_guc *guc) +{ + return wait_event_timeout(guc->ct.wq, + !guc_submit_reset_is_blocked(guc), RESET_BLOCK_PERIOD_MAX); +} + int xe_guc_submit_reset_prepare(struct xe_guc *guc) { int ret; @@ -1830,6 +1941,19 @@ void xe_guc_submit_stop(struct xe_guc *guc) } +/** + * xe_guc_submit_pause - Stop further runs of submission tasks on given GuC. + * @guc: the &xe_guc struct instance whose scheduler is to be disabled + */ +void xe_guc_submit_pause(struct xe_guc *guc) +{ + struct xe_exec_queue *q; + unsigned long index; + + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) + xe_sched_submission_stop_async(&q->guc->sched); +} + static void guc_exec_queue_start(struct xe_exec_queue *q) { struct xe_gpu_scheduler *sched = &q->guc->sched; @@ -1870,6 +1994,28 @@ int xe_guc_submit_start(struct xe_guc *guc) return 0; } +static void guc_exec_queue_unpause(struct xe_exec_queue *q) +{ + struct xe_gpu_scheduler *sched = &q->guc->sched; + + xe_sched_submission_start(sched); +} + +/** + * xe_guc_submit_unpause - Allow further runs of submission tasks on given GuC. + * @guc: the &xe_guc struct instance whose scheduler is to be enabled + */ +void xe_guc_submit_unpause(struct xe_guc *guc) +{ + struct xe_exec_queue *q; + unsigned long index; + + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) + guc_exec_queue_unpause(q); + + wake_up_all(&guc->ct.wq); +} + static struct xe_exec_queue * g2h_exec_queue_lookup(struct xe_guc *guc, u32 guc_id) { @@ -2427,3 +2573,32 @@ void xe_guc_submit_print(struct xe_guc *guc, struct drm_printer *p) guc_exec_queue_print(q, p); mutex_unlock(&guc->submission_state.lock); } + +/** + * xe_guc_contexts_hwsp_rebase - Re-compute GGTT references within all + * exec queues registered to given GuC. + * @guc: the &xe_guc struct instance + * @scratch: scratch buffer to be used as temporary storage + * + * Returns: zero on success, negative error code on failure. + */ +int xe_guc_contexts_hwsp_rebase(struct xe_guc *guc, void *scratch) +{ + struct xe_exec_queue *q; + unsigned long index; + int err = 0; + + mutex_lock(&guc->submission_state.lock); + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { + err = xe_exec_queue_contexts_hwsp_rebase(q, scratch); + if (err) + break; + if (xe_exec_queue_is_parallel(q)) + err = wq_items_rebase(q); + if (err) + break; + } + mutex_unlock(&guc->submission_state.lock); + + return err; +} diff --git a/drivers/gpu/drm/xe/xe_guc_submit.h b/drivers/gpu/drm/xe/xe_guc_submit.h index 8f64e799283b..6b5df5d0956b 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.h +++ b/drivers/gpu/drm/xe/xe_guc_submit.h @@ -18,6 +18,11 @@ int xe_guc_submit_reset_prepare(struct xe_guc *guc); void xe_guc_submit_reset_wait(struct xe_guc *guc); void xe_guc_submit_stop(struct xe_guc *guc); int xe_guc_submit_start(struct xe_guc *guc); +void xe_guc_submit_pause(struct xe_guc *guc); +void xe_guc_submit_unpause(struct xe_guc *guc); +int xe_guc_submit_reset_block(struct xe_guc *guc); +void xe_guc_submit_reset_unblock(struct xe_guc *guc); +int xe_guc_wait_reset_unblock(struct xe_guc *guc); void xe_guc_submit_wedge(struct xe_guc *guc); int xe_guc_read_stopped(struct xe_guc *guc); @@ -29,6 +34,8 @@ int xe_guc_exec_queue_memory_cat_error_handler(struct xe_guc *guc, u32 *msg, int xe_guc_exec_queue_reset_failure_handler(struct xe_guc *guc, u32 *msg, u32 len); int xe_guc_error_capture_handler(struct xe_guc *guc, u32 *msg, u32 len); +void xe_guc_jobs_ring_rebase(struct xe_guc *guc); + struct xe_guc_submit_exec_queue_snapshot * xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q); void @@ -41,4 +48,6 @@ xe_guc_exec_queue_snapshot_free(struct xe_guc_submit_exec_queue_snapshot *snapsh void xe_guc_submit_print(struct xe_guc *guc, struct drm_printer *p); void xe_guc_register_exec_queue(struct xe_exec_queue *q, int ctx_type); +int xe_guc_contexts_hwsp_rebase(struct xe_guc *guc, void *scratch); + #endif diff --git a/drivers/gpu/drm/xe/xe_guc_types.h b/drivers/gpu/drm/xe/xe_guc_types.h index 1fde7614fcc5..c7b9642b41ba 100644 --- a/drivers/gpu/drm/xe/xe_guc_types.h +++ b/drivers/gpu/drm/xe/xe_guc_types.h @@ -85,6 +85,12 @@ struct xe_guc { struct xarray exec_queue_lookup; /** @submission_state.stopped: submissions are stopped */ atomic_t stopped; + /** + * @submission_state.reset_blocked: reset attempts are blocked; + * blocking reset in order to delay it may be required if running + * an operation which is sensitive to resets. + */ + atomic_t reset_blocked; /** @submission_state.lock: protects submission state */ struct mutex lock; /** @submission_state.enabled: submission is enabled */ diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index 540f044bf425..8760c4c2ca38 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -41,7 +41,6 @@ #define LRC_PPHWSP_SIZE SZ_4K #define LRC_INDIRECT_CTX_BO_SIZE SZ_4K #define LRC_INDIRECT_RING_STATE_SIZE SZ_4K -#define LRC_WA_BB_SIZE SZ_4K /* * Layout of the LRC and associated data allocated as @@ -697,7 +696,13 @@ u32 xe_lrc_regs_offset(struct xe_lrc *lrc) return xe_lrc_pphwsp_offset(lrc) + LRC_PPHWSP_SIZE; } -static size_t lrc_reg_size(struct xe_device *xe) +/** + * xe_lrc_reg_size() - Get size of the LRC registers area within queues + * @xe: the &xe_device struct instance + * + * Returns: Size of the LRC registers area for current platform + */ +size_t xe_lrc_reg_size(struct xe_device *xe) { if (GRAPHICS_VERx100(xe) >= 1250) return 96 * sizeof(u32); @@ -707,7 +712,7 @@ static size_t lrc_reg_size(struct xe_device *xe) size_t xe_lrc_skip_size(struct xe_device *xe) { - return LRC_PPHWSP_SIZE + lrc_reg_size(xe); + return LRC_PPHWSP_SIZE + xe_lrc_reg_size(xe); } static inline u32 __xe_lrc_seqno_offset(struct xe_lrc *lrc) @@ -948,6 +953,47 @@ static void *empty_lrc_data(struct xe_hw_engine *hwe) return data; } +/** + * xe_default_lrc_update_memirq_regs_with_address - Re-compute GGTT references in default LRC + * of given engine. + * @hwe: the &xe_hw_engine struct instance + */ +void xe_default_lrc_update_memirq_regs_with_address(struct xe_hw_engine *hwe) +{ + struct xe_gt *gt = hwe->gt; + u32 *regs; + + if (!gt->default_lrc[hwe->class]) + return; + + regs = gt->default_lrc[hwe->class] + LRC_PPHWSP_SIZE; + set_memory_based_intr(regs, hwe); +} + +/** + * xe_lrc_update_memirq_regs_with_address - Re-compute GGTT references in mem interrupt data + * for given LRC. + * @lrc: the &xe_lrc struct instance + * @hwe: the &xe_hw_engine struct instance + * @regs: scratch buffer to be used as temporary storage + */ +void xe_lrc_update_memirq_regs_with_address(struct xe_lrc *lrc, struct xe_hw_engine *hwe, + u32 *regs) +{ + struct xe_gt *gt = hwe->gt; + struct iosys_map map; + size_t regs_len; + + if (!xe_device_uses_memirq(gt_to_xe(gt))) + return; + + map = __xe_lrc_regs_map(lrc); + regs_len = xe_lrc_reg_size(gt_to_xe(gt)); + xe_map_memcpy_from(gt_to_xe(gt), regs, &map, 0, regs_len); + set_memory_based_intr(regs, hwe); + xe_map_memcpy_to(gt_to_xe(gt), &map, 0, regs, regs_len); +} + static void xe_lrc_set_ppgtt(struct xe_lrc *lrc, struct xe_vm *vm) { u64 desc = xe_vm_pdp4_descriptor(vm, gt_to_tile(lrc->gt)); @@ -1102,13 +1148,11 @@ static int setup_bo(struct bo_setup_state *state) ssize_t remain; if (state->lrc->bo->vmap.is_iomem) { - state->buffer = kmalloc(state->max_size, GFP_KERNEL); if (!state->buffer) return -ENOMEM; state->ptr = state->buffer; } else { state->ptr = state->lrc->bo->vmap.vaddr + state->offset; - state->buffer = NULL; } remain = state->max_size / sizeof(u32); @@ -1133,7 +1177,6 @@ static int setup_bo(struct bo_setup_state *state) return 0; fail: - kfree(state->buffer); return -ENOSPC; } @@ -1145,10 +1188,16 @@ static void finish_bo(struct bo_setup_state *state) xe_map_memcpy_to(gt_to_xe(state->lrc->gt), &state->lrc->bo->vmap, state->offset, state->buffer, state->written * sizeof(u32)); - kfree(state->buffer); } -static int setup_wa_bb(struct xe_lrc *lrc, struct xe_hw_engine *hwe) +/** + * xe_lrc_setup_wa_bb_with_scratch - Execute all wa bb setup callbacks. + * @lrc: the &xe_lrc struct instance + * @hwe: the &xe_hw_engine struct instance + * @scratch: preallocated scratch buffer for temporary storage + * Return: 0 on success, negative error code on failure + */ +int xe_lrc_setup_wa_bb_with_scratch(struct xe_lrc *lrc, struct xe_hw_engine *hwe, u32 *scratch) { static const struct bo_setup funcs[] = { { .setup = setup_timestamp_wa }, @@ -1159,6 +1208,7 @@ static int setup_wa_bb(struct xe_lrc *lrc, struct xe_hw_engine *hwe) .lrc = lrc, .hwe = hwe, .max_size = LRC_WA_BB_SIZE, + .buffer = scratch, .reserve_dw = 1, .offset = __xe_lrc_wa_bb_offset(lrc), .funcs = funcs, @@ -1181,6 +1231,21 @@ static int setup_wa_bb(struct xe_lrc *lrc, struct xe_hw_engine *hwe) return 0; } +static int setup_wa_bb(struct xe_lrc *lrc, struct xe_hw_engine *hwe) +{ + u32 *buf = NULL; + int ret; + + if (lrc->bo->vmap.is_iomem) + buf = kmalloc(LRC_WA_BB_SIZE, GFP_KERNEL); + + ret = xe_lrc_setup_wa_bb_with_scratch(lrc, hwe, buf); + + kfree(buf); + + return ret; +} + static int setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe) { @@ -1191,6 +1256,7 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe) .lrc = lrc, .hwe = hwe, .max_size = (63 * 64) /* max 63 cachelines */, + .buffer = NULL, .offset = __xe_lrc_indirect_ctx_offset(lrc), }; int ret; @@ -1207,9 +1273,14 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe) if (xe_gt_WARN_ON(lrc->gt, !state.funcs)) return 0; + if (lrc->bo->vmap.is_iomem) + state.buffer = kmalloc(state.max_size, GFP_KERNEL); + ret = setup_bo(&state); - if (ret) + if (ret) { + kfree(state.buffer); return ret; + } /* * Align to 64B cacheline so there's no garbage at the end for CS to @@ -1221,6 +1292,7 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe) } finish_bo(&state); + kfree(state.buffer); xe_lrc_write_ctx_reg(lrc, CTX_CS_INDIRECT_CTX, @@ -1439,6 +1511,23 @@ void xe_lrc_destroy(struct kref *ref) kfree(lrc); } +/** + * xe_lrc_update_hwctx_regs_with_address - Re-compute GGTT references within given LRC. + * @lrc: the &xe_lrc struct instance + */ +void xe_lrc_update_hwctx_regs_with_address(struct xe_lrc *lrc) +{ + if (xe_lrc_has_indirect_ring_state(lrc)) { + xe_lrc_write_ctx_reg(lrc, CTX_INDIRECT_RING_STATE, + __xe_lrc_indirect_ring_ggtt_addr(lrc)); + + xe_lrc_write_indirect_ctx_reg(lrc, INDIRECT_CTX_RING_START, + __xe_lrc_ring_ggtt_addr(lrc)); + } else { + xe_lrc_write_ctx_reg(lrc, CTX_RING_START, __xe_lrc_ring_ggtt_addr(lrc)); + } +} + void xe_lrc_set_ring_tail(struct xe_lrc *lrc, u32 tail) { if (xe_lrc_has_indirect_ring_state(lrc)) diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h index b6c8053c581b..188565465779 100644 --- a/drivers/gpu/drm/xe/xe_lrc.h +++ b/drivers/gpu/drm/xe/xe_lrc.h @@ -42,6 +42,8 @@ struct xe_lrc_snapshot { #define LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR (0x34 * 4) #define LRC_PPHWSP_PXP_INVAL_SCRATCH_ADDR (0x40 * 4) +#define LRC_WA_BB_SIZE SZ_4K + #define XE_LRC_CREATE_RUNALONE 0x1 #define XE_LRC_CREATE_PXP 0x2 struct xe_lrc *xe_lrc_create(struct xe_hw_engine *hwe, struct xe_vm *vm, @@ -88,6 +90,10 @@ bool xe_lrc_ring_is_idle(struct xe_lrc *lrc); u32 xe_lrc_indirect_ring_ggtt_addr(struct xe_lrc *lrc); u32 xe_lrc_ggtt_addr(struct xe_lrc *lrc); u32 *xe_lrc_regs(struct xe_lrc *lrc); +void xe_lrc_update_hwctx_regs_with_address(struct xe_lrc *lrc); +void xe_default_lrc_update_memirq_regs_with_address(struct xe_hw_engine *hwe); +void xe_lrc_update_memirq_regs_with_address(struct xe_lrc *lrc, struct xe_hw_engine *hwe, + u32 *regs); u32 xe_lrc_read_ctx_reg(struct xe_lrc *lrc, int reg_nr); void xe_lrc_write_ctx_reg(struct xe_lrc *lrc, int reg_nr, u32 val); @@ -106,6 +112,7 @@ s32 xe_lrc_start_seqno(struct xe_lrc *lrc); u32 xe_lrc_parallel_ggtt_addr(struct xe_lrc *lrc); struct iosys_map xe_lrc_parallel_map(struct xe_lrc *lrc); +size_t xe_lrc_reg_size(struct xe_device *xe); size_t xe_lrc_skip_size(struct xe_device *xe); void xe_lrc_dump_default(struct drm_printer *p, @@ -124,6 +131,8 @@ u32 xe_lrc_ctx_timestamp_udw_ggtt_addr(struct xe_lrc *lrc); u64 xe_lrc_ctx_timestamp(struct xe_lrc *lrc); u32 xe_lrc_ctx_job_timestamp_ggtt_addr(struct xe_lrc *lrc); u32 xe_lrc_ctx_job_timestamp(struct xe_lrc *lrc); +int xe_lrc_setup_wa_bb_with_scratch(struct xe_lrc *lrc, struct xe_hw_engine *hwe, + u32 *scratch); /** * xe_lrc_update_timestamp - readout LRC timestamp and update cached value diff --git a/drivers/gpu/drm/xe/xe_pci_sriov.c b/drivers/gpu/drm/xe/xe_pci_sriov.c index 8813efdcafbb..447a7867eecb 100644 --- a/drivers/gpu/drm/xe/xe_pci_sriov.c +++ b/drivers/gpu/drm/xe/xe_pci_sriov.c @@ -12,6 +12,7 @@ #include "xe_pci_sriov.h" #include "xe_pm.h" #include "xe_sriov.h" +#include "xe_sriov_pf.h" #include "xe_sriov_pf_helpers.h" #include "xe_sriov_printk.h" @@ -138,6 +139,10 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs) xe_assert(xe, num_vfs <= total_vfs); xe_sriov_dbg(xe, "enabling %u VF%s\n", num_vfs, str_plural(num_vfs)); + err = xe_sriov_pf_wait_ready(xe); + if (err) + goto out; + /* * We must hold additional reference to the runtime PM to keep PF in D0 * during VFs lifetime, as our VFs do not implement the PM capability. @@ -169,7 +174,7 @@ static int pf_enable_vfs(struct xe_device *xe, int num_vfs) failed: pf_unprovision_vfs(xe, num_vfs); xe_pm_runtime_put(xe); - +out: xe_sriov_notice(xe, "Failed to enable %u VF%s (%pe)\n", num_vfs, str_plural(num_vfs), ERR_PTR(err)); return err; diff --git a/drivers/gpu/drm/xe/xe_sa.c b/drivers/gpu/drm/xe/xe_sa.c index 1d43e183ca21..fedd017d6dd3 100644 --- a/drivers/gpu/drm/xe/xe_sa.c +++ b/drivers/gpu/drm/xe/xe_sa.c @@ -69,7 +69,6 @@ struct xe_sa_manager *__xe_sa_bo_manager_init(struct xe_tile *tile, u32 size, u3 } sa_manager->bo = bo; sa_manager->is_iomem = bo->vmap.is_iomem; - sa_manager->gpu_addr = xe_bo_ggtt_addr(bo); if (bo->vmap.is_iomem) { sa_manager->cpu_ptr = kvzalloc(managed_size, GFP_KERNEL); diff --git a/drivers/gpu/drm/xe/xe_sa.h b/drivers/gpu/drm/xe/xe_sa.h index 1170ee5a81a8..99dbf0eea540 100644 --- a/drivers/gpu/drm/xe/xe_sa.h +++ b/drivers/gpu/drm/xe/xe_sa.h @@ -7,6 +7,8 @@ #include <linux/sizes.h> #include <linux/types.h> + +#include "xe_bo.h" #include "xe_sa_types.h" struct dma_fence; @@ -43,9 +45,20 @@ to_xe_sa_manager(struct drm_suballoc_manager *mng) return container_of(mng, struct xe_sa_manager, base); } +/** + * xe_sa_manager_gpu_addr - Retrieve GPU address of a back storage BO + * within suballocator. + * @sa_manager: the &xe_sa_manager struct instance + * Return: GGTT address of the back storage BO. + */ +static inline u64 xe_sa_manager_gpu_addr(struct xe_sa_manager *sa_manager) +{ + return xe_bo_ggtt_addr(sa_manager->bo); +} + static inline u64 xe_sa_bo_gpu_addr(struct drm_suballoc *sa) { - return to_xe_sa_manager(sa->manager)->gpu_addr + + return xe_sa_manager_gpu_addr(to_xe_sa_manager(sa->manager)) + drm_suballoc_soffset(sa); } diff --git a/drivers/gpu/drm/xe/xe_sa_types.h b/drivers/gpu/drm/xe/xe_sa_types.h index 2b070ff1292e..cb7238799dcb 100644 --- a/drivers/gpu/drm/xe/xe_sa_types.h +++ b/drivers/gpu/drm/xe/xe_sa_types.h @@ -12,7 +12,6 @@ struct xe_bo; struct xe_sa_manager { struct drm_suballoc_manager base; struct xe_bo *bo; - u64 gpu_addr; void *cpu_ptr; bool is_iomem; }; diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.c b/drivers/gpu/drm/xe/xe_sriov_pf.c index afbdd894bd6e..27ddf3cc80e9 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf.c @@ -9,6 +9,7 @@ #include "xe_assert.h" #include "xe_device.h" +#include "xe_gt_sriov_pf.h" #include "xe_module.h" #include "xe_sriov.h" #include "xe_sriov_pf.h" @@ -103,6 +104,32 @@ int xe_sriov_pf_init_early(struct xe_device *xe) } /** + * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate. + * @xe: the &xe_device to test + * + * This function can only be called on PF. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_sriov_pf_wait_ready(struct xe_device *xe) +{ + struct xe_gt *gt; + unsigned int id; + int err; + + if (xe_device_wedged(xe)) + return -ECANCELED; + + for_each_gt(gt, xe, id) { + err = xe_gt_sriov_pf_wait_ready(gt); + if (err) + return err; + } + + return 0; +} + +/** * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information. * @xe: the &xe_device to print info from * @p: the &drm_printer diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.h b/drivers/gpu/drm/xe/xe_sriov_pf.h index c392c3fcf085..e3b34f8f5e04 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf.h +++ b/drivers/gpu/drm/xe/xe_sriov_pf.h @@ -15,6 +15,7 @@ struct xe_device; #ifdef CONFIG_PCI_IOV bool xe_sriov_pf_readiness(struct xe_device *xe); int xe_sriov_pf_init_early(struct xe_device *xe); +int xe_sriov_pf_wait_ready(struct xe_device *xe); void xe_sriov_pf_debugfs_register(struct xe_device *xe, struct dentry *root); void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p); #else diff --git a/drivers/gpu/drm/xe/xe_sriov_vf.c b/drivers/gpu/drm/xe/xe_sriov_vf.c index 26e243c28994..5de81f213d83 100644 --- a/drivers/gpu/drm/xe/xe_sriov_vf.c +++ b/drivers/gpu/drm/xe/xe_sriov_vf.c @@ -11,6 +11,9 @@ #include "xe_gt_sriov_printk.h" #include "xe_gt_sriov_vf.h" #include "xe_guc_ct.h" +#include "xe_guc_submit.h" +#include "xe_irq.h" +#include "xe_lrc.h" #include "xe_pm.h" #include "xe_sriov.h" #include "xe_sriov_printk.h" @@ -147,6 +150,56 @@ void xe_sriov_vf_init_early(struct xe_device *xe) xe_sriov_info(xe, "migration not supported by this module version\n"); } +/** + * vf_post_migration_shutdown - Stop the driver activities after VF migration. + * @xe: the &xe_device struct instance + * + * After this VM is migrated and assigned to a new VF, it is running on a new + * hardware, and therefore many hardware-dependent states and related structures + * require fixups. Without fixups, the hardware cannot do any work, and therefore + * all GPU pipelines are stalled. + * Stop some of kernel activities to make the fixup process faster. + */ +static void vf_post_migration_shutdown(struct xe_device *xe) +{ + struct xe_gt *gt; + unsigned int id; + int ret = 0; + + for_each_gt(gt, xe, id) { + xe_guc_submit_pause(>->uc.guc); + ret |= xe_guc_submit_reset_block(>->uc.guc); + } + + if (ret) + drm_info(&xe->drm, "migration recovery encountered ongoing reset\n"); +} + +/** + * vf_post_migration_kickstart - Re-start the driver activities under new hardware. + * @xe: the &xe_device struct instance + * + * After we have finished with all post-migration fixups, restart the driver + * activities to continue feeding the GPU with workloads. + */ +static void vf_post_migration_kickstart(struct xe_device *xe) +{ + struct xe_gt *gt; + unsigned int id; + + /* + * Make sure interrupts on the new HW are properly set. The GuC IRQ + * must be working at this point, since the recovery did started, + * but the rest was not enabled using the procedure from spec. + */ + xe_irq_resume(xe); + + for_each_gt(gt, xe, id) { + xe_guc_submit_reset_unblock(>->uc.guc); + xe_guc_submit_unpause(>->uc.guc); + } +} + static bool gt_vf_post_migration_needed(struct xe_gt *gt) { return test_bit(gt->info.id, >_to_xe(gt)->sriov.vf.migration.gt_flags); @@ -192,6 +245,11 @@ static int vf_get_next_migrated_gt_id(struct xe_device *xe) return -1; } +static size_t post_migration_scratch_size(struct xe_device *xe) +{ + return max(xe_lrc_reg_size(xe), LRC_WA_BB_SIZE); +} + /** * Perform post-migration fixups on a single GT. * @@ -208,19 +266,31 @@ static int vf_get_next_migrated_gt_id(struct xe_device *xe) static int gt_vf_post_migration_fixups(struct xe_gt *gt) { s64 shift; + void *buf; int err; + buf = kmalloc(post_migration_scratch_size(gt_to_xe(gt)), GFP_KERNEL); + if (!buf) + return -ENOMEM; + err = xe_gt_sriov_vf_query_config(gt); if (err) - return err; + goto out; shift = xe_gt_sriov_vf_ggtt_shift(gt); if (shift) { xe_tile_sriov_vf_fixup_ggtt_nodes(gt_to_tile(gt), shift); - /* FIXME: add the recovery steps */ + xe_gt_sriov_vf_default_lrcs_hwsp_rebase(gt); + err = xe_guc_contexts_hwsp_rebase(>->uc.guc, buf); + if (err) + goto out; + xe_guc_jobs_ring_rebase(>->uc.guc); xe_guc_ct_fixup_messages_with_ggtt(>->uc.guc.ct, shift); } - return 0; + +out: + kfree(buf); + return err; } static void vf_post_migration_recovery(struct xe_device *xe) @@ -230,6 +300,7 @@ static void vf_post_migration_recovery(struct xe_device *xe) drm_dbg(&xe->drm, "migration recovery in progress\n"); xe_pm_runtime_get(xe); + vf_post_migration_shutdown(xe); if (!vf_migration_supported(xe)) { xe_sriov_err(xe, "migration not supported by this module version\n"); @@ -247,6 +318,7 @@ static void vf_post_migration_recovery(struct xe_device *xe) set_bit(id, &fixed_gts); } + vf_post_migration_kickstart(xe); err = vf_post_migration_notify_resfix_done(xe, fixed_gts); if (err) goto fail; diff --git a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c index bf9fa1238462..f0ca2a9b2bb7 100644 --- a/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c +++ b/drivers/gpu/drm/xe/xe_sriov_vf_ccs.c @@ -169,7 +169,7 @@ static int alloc_bb_pool(struct xe_tile *tile, struct xe_tile_vf_ccs *ctx) static void ccs_rw_update_ring(struct xe_tile_vf_ccs *ctx) { struct xe_lrc *lrc = xe_migrate_lrc(ctx->migrate); - u64 addr = ctx->mem.ccs_bb_pool->gpu_addr; + u64 addr = xe_sa_manager_gpu_addr(ctx->mem.ccs_bb_pool); u32 dw[10], i = 0; dw[i++] = MI_ARB_ON_OFF | MI_ARB_ENABLE; @@ -271,8 +271,8 @@ int xe_sriov_vf_ccs_init(struct xe_device *xe) ctx->ctx_id = ctx_id; migrate = xe_migrate_alloc(tile); - if (IS_ERR(migrate)) { - err = PTR_ERR(migrate); + if (!migrate) { + err = -ENOMEM; goto err_ret; } diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 22a98600fd8f..535067e7fb0c 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -538,6 +538,11 @@ static const struct xe_rtp_entry_sr engine_was[] = { XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)), XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE)) }, + { XE_RTP_NAME("13012615864"), + XE_RTP_RULES(GRAPHICS_VERSION(2004), + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS)) + }, /* Xe2_HPG */ @@ -602,6 +607,11 @@ static const struct xe_rtp_entry_sr engine_was[] = { FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, STK_ID_RESTRICT)) }, + { XE_RTP_NAME("13012615864"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS)) + }, /* Xe2_LPM */ @@ -647,7 +657,8 @@ static const struct xe_rtp_entry_sr engine_was[] = { XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE)) }, { XE_RTP_NAME("13012615864"), - XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), OR, + GRAPHICS_VERSION(3003), FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS)) }, diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c8d115b58e44..070d014fdc5d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -992,7 +992,6 @@ config I2C_APPLE tristate "Apple SMBus platform driver" depends on !I2C_PASEMI depends on ARCH_APPLE || COMPILE_TEST - default ARCH_APPLE help Say Y here if you want to use the I2C controller present on Apple Silicon chips such as the M1. diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 3445cc3b476b..ed90858a27b7 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -370,6 +370,7 @@ static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { * the device works without issues on Windows at what is expected to be * a 400KHz frequency. The root cause of the issue is not known. */ + { "DLL0945", 0 }, { "ELAN06FA", 0 }, {} }; diff --git a/drivers/i2c/muxes/i2c-mux-mule.c b/drivers/i2c/muxes/i2c-mux-mule.c index 284ff4afeeac..d3b32b794172 100644 --- a/drivers/i2c/muxes/i2c-mux-mule.c +++ b/drivers/i2c/muxes/i2c-mux-mule.c @@ -47,7 +47,6 @@ static int mule_i2c_mux_probe(struct platform_device *pdev) struct mule_i2c_reg_mux *priv; struct i2c_client *client; struct i2c_mux_core *muxc; - struct device_node *dev; unsigned int readback; int ndev, ret; bool old_fw; @@ -95,7 +94,7 @@ static int mule_i2c_mux_probe(struct platform_device *pdev) "Failed to register mux remove\n"); /* Create device adapters */ - for_each_child_of_node(mux_dev->of_node, dev) { + for_each_child_of_node_scoped(mux_dev->of_node, dev) { u32 reg; ret = of_property_read_u32(dev, "reg", ®); diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c index bda370c0f660..8380b237831c 100644 --- a/drivers/iio/accel/sca3300.c +++ b/drivers/iio/accel/sca3300.c @@ -477,7 +477,7 @@ static irqreturn_t sca3300_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct sca3300_data *data = iio_priv(indio_dev); int bit, ret, val, i = 0; - IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX); + IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { }; iio_for_each_active_channel(indio_dev, bit) { ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val); diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 9808df2e9242..4d8c6bafd1c3 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -849,7 +849,7 @@ enum { static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan) { struct device *dev = &st->sd.spi->dev; - struct ad7124_channel *ch = &st->channels[chan->channel]; + struct ad7124_channel *ch = &st->channels[chan->address]; int ret; if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) { @@ -865,8 +865,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan if (ret < 0) return ret; - dev_dbg(dev, "offset for channel %d after zero-scale calibration: 0x%x\n", - chan->channel, ch->cfg.calibration_offset); + dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n", + chan->address, ch->cfg.calibration_offset); } else { ch->cfg.calibration_gain = st->gain_default; @@ -880,8 +880,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan if (ret < 0) return ret; - dev_dbg(dev, "gain for channel %d after full-scale calibration: 0x%x\n", - chan->channel, ch->cfg.calibration_gain); + dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n", + chan->address, ch->cfg.calibration_gain); } return 0; @@ -924,7 +924,7 @@ static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev, { struct ad7124_state *st = iio_priv(indio_dev); - st->channels[chan->channel].syscalib_mode = mode; + st->channels[chan->address].syscalib_mode = mode; return 0; } @@ -934,7 +934,7 @@ static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev, { struct ad7124_state *st = iio_priv(indio_dev); - return st->channels[chan->channel].syscalib_mode; + return st->channels[chan->address].syscalib_mode; } static const struct iio_enum ad7124_syscalib_mode_enum = { diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 4413207be28f..683146e83ab2 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -200,7 +200,7 @@ struct ad7173_channel_config { /* * Following fields are used to compare equality. If you * make adaptations in it, you most likely also have to adapt - * ad7173_find_live_config(), too. + * ad7173_is_setup_equal(), too. */ struct_group(config_props, bool bipolar; @@ -561,12 +561,19 @@ static void ad7173_reset_usage_cnts(struct ad7173_state *st) st->config_usage_counter = 0; } -static struct ad7173_channel_config * -ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg) +/** + * ad7173_is_setup_equal - Compare two channel setups + * @cfg1: First channel configuration + * @cfg2: Second channel configuration + * + * Compares all configuration options that affect the registers connected to + * SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx. + * + * Returns: true if the setups are identical, false otherwise + */ +static bool ad7173_is_setup_equal(const struct ad7173_channel_config *cfg1, + const struct ad7173_channel_config *cfg2) { - struct ad7173_channel_config *cfg_aux; - int i; - /* * This is just to make sure that the comparison is adapted after * struct ad7173_channel_config was changed. @@ -579,14 +586,22 @@ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *c u8 ref_sel; })); + return cfg1->bipolar == cfg2->bipolar && + cfg1->input_buf == cfg2->input_buf && + cfg1->odr == cfg2->odr && + cfg1->ref_sel == cfg2->ref_sel; +} + +static struct ad7173_channel_config * +ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg) +{ + struct ad7173_channel_config *cfg_aux; + int i; + for (i = 0; i < st->num_channels; i++) { cfg_aux = &st->channels[i].cfg; - if (cfg_aux->live && - cfg->bipolar == cfg_aux->bipolar && - cfg->input_buf == cfg_aux->input_buf && - cfg->odr == cfg_aux->odr && - cfg->ref_sel == cfg_aux->ref_sel) + if (cfg_aux->live && ad7173_is_setup_equal(cfg, cfg_aux)) return cfg_aux; } return NULL; @@ -1228,7 +1243,7 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct ad7173_state *st = iio_priv(indio_dev); - int i, ret; + int i, j, k, ret; for (i = 0; i < indio_dev->num_channels; i++) { if (test_bit(i, scan_mask)) @@ -1239,6 +1254,54 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev, return ret; } + /* + * On some chips, there are more channels that setups, so if there were + * more unique setups requested than the number of available slots, + * ad7173_set_channel() will have written over some of the slots. We + * can detect this by making sure each assigned cfg_slot matches the + * requested configuration. If it doesn't, we know that the slot was + * overwritten by a different channel. + */ + for_each_set_bit(i, scan_mask, indio_dev->num_channels) { + const struct ad7173_channel_config *cfg1, *cfg2; + + cfg1 = &st->channels[i].cfg; + + for_each_set_bit(j, scan_mask, indio_dev->num_channels) { + cfg2 = &st->channels[j].cfg; + + /* + * Only compare configs that are assigned to the same + * SETUP_SEL slot and don't compare channel to itself. + */ + if (i == j || cfg1->cfg_slot != cfg2->cfg_slot) + continue; + + /* + * If we find two different configs trying to use the + * same SETUP_SEL slot, then we know that the that we + * have too many unique configurations requested for + * the available slots and at least one was overwritten. + */ + if (!ad7173_is_setup_equal(cfg1, cfg2)) { + /* + * At this point, there isn't a way to tell + * which setups are actually programmed in the + * ADC anymore, so we could read them back to + * see, but it is simpler to just turn off all + * of the live flags so that everything gets + * reprogramed on the next attempt read a sample. + */ + for (k = 0; k < st->num_channels; k++) + st->channels[k].cfg.live = false; + + dev_err(&st->sd.spi->dev, + "Too many unique channel configurations requested for scan\n"); + return -EINVAL; + } + } + } + return 0; } diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index d1510fe24050..f69db6f2f380 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct isl29501_private *isl29501 = iio_priv(indio_dev); const unsigned long *active_mask = indio_dev->active_scan_mask; - u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ - - if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) - isl29501_register_read(isl29501, REG_DISTANCE, buffer); + u32 value; + struct { + u16 data; + aligned_s64 ts; + } scan = { }; + + if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) { + isl29501_register_read(isl29501, REG_DISTANCE, &value); + scan.data = value; + } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c index cae8e84821d7..205939680fd4 100644 --- a/drivers/iio/temperature/maxim_thermocouple.c +++ b/drivers/iio/temperature/maxim_thermocouple.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/err.h> #include <linux/spi/spi.h> +#include <linux/types.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h> @@ -121,8 +122,15 @@ struct maxim_thermocouple_data { struct spi_device *spi; const struct maxim_thermocouple_chip *chip; char tc_type; - - u8 buffer[16] __aligned(IIO_DMA_MINALIGN); + /* Buffer for reading up to 2 hardware channels. */ + struct { + union { + __be16 raw16; + __be32 raw32; + __be16 raw[2]; + }; + aligned_s64 timestamp; + } buffer __aligned(IIO_DMA_MINALIGN); }; static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, @@ -130,18 +138,16 @@ static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, { unsigned int storage_bytes = data->chip->read_size; unsigned int shift = chan->scan_type.shift + (chan->address * 8); - __be16 buf16; - __be32 buf32; int ret; switch (storage_bytes) { case 2: - ret = spi_read(data->spi, (void *)&buf16, storage_bytes); - *val = be16_to_cpu(buf16); + ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes); + *val = be16_to_cpu(data->buffer.raw16); break; case 4: - ret = spi_read(data->spi, (void *)&buf32, storage_bytes); - *val = be32_to_cpu(buf32); + ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes); + *val = be32_to_cpu(data->buffer.raw32); break; default: ret = -EINVAL; @@ -166,9 +172,9 @@ static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private) struct maxim_thermocouple_data *data = iio_priv(indio_dev); int ret; - ret = spi_read(data->spi, data->buffer, data->chip->read_size); + ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size); if (!ret) { - iio_push_to_buffers_with_ts(indio_dev, data->buffer, + iio_push_to_buffers_with_ts(indio_dev, &data->buffer, sizeof(data->buffer), iio_get_time_ns(indio_dev)); } diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 1dfd7b95a4ce..5d45680d74a4 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -68,15 +68,16 @@ struct max77693_haptic { static int max77693_haptic_set_duty_cycle(struct max77693_haptic *haptic) { - struct pwm_args pargs; - int delta; + struct pwm_state state; int error; - pwm_get_args(haptic->pwm_dev, &pargs); - delta = (pargs.period + haptic->pwm_duty) / 2; - error = pwm_config(haptic->pwm_dev, delta, pargs.period); + pwm_init_state(haptic->pwm_dev, &state); + state.duty_cycle = (state.period + haptic->pwm_duty) / 2; + + error = pwm_apply_might_sleep(haptic->pwm_dev, &state); if (error) { - dev_err(haptic->dev, "failed to configure pwm: %d\n", error); + dev_err(haptic->dev, + "failed to set pwm duty cycle: %d\n", error); return error; } @@ -166,12 +167,17 @@ static int max77693_haptic_lowsys(struct max77693_haptic *haptic, bool enable) static void max77693_haptic_enable(struct max77693_haptic *haptic) { + struct pwm_state state; int error; if (haptic->enabled) return; - error = pwm_enable(haptic->pwm_dev); + pwm_init_state(haptic->pwm_dev, &state); + state.duty_cycle = (state.period + haptic->pwm_duty) / 2; + state.enabled = true; + + error = pwm_apply_might_sleep(haptic->pwm_dev, &state); if (error) { dev_err(haptic->dev, "failed to enable haptic pwm device: %d\n", error); @@ -224,18 +230,13 @@ static void max77693_haptic_play_work(struct work_struct *work) { struct max77693_haptic *haptic = container_of(work, struct max77693_haptic, work); - int error; - - error = max77693_haptic_set_duty_cycle(haptic); - if (error) { - dev_err(haptic->dev, "failed to set duty cycle: %d\n", error); - return; - } - if (haptic->magnitude) - max77693_haptic_enable(haptic); - else + if (!haptic->magnitude) max77693_haptic_disable(haptic); + else if (haptic->enabled) + max77693_haptic_set_duty_cycle(haptic); + else + max77693_haptic_enable(haptic); } static int max77693_haptic_play_effect(struct input_dev *dev, void *data, @@ -340,12 +341,6 @@ static int max77693_haptic_probe(struct platform_device *pdev) return PTR_ERR(haptic->pwm_dev); } - /* - * FIXME: pwm_apply_args() should be removed when switching to the - * atomic PWM API. - */ - pwm_apply_args(haptic->pwm_dev); - haptic->motor_reg = devm_regulator_get(&pdev->dev, "haptic"); if (IS_ERR(haptic->motor_reg)) { dev_err(&pdev->dev, "failed to get regulator\n"); diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c index 74a2a28f9403..643c8e459611 100644 --- a/drivers/irqchip/irq-riscv-imsic-platform.c +++ b/drivers/irqchip/irq-riscv-imsic-platform.c @@ -308,7 +308,6 @@ static const struct msi_parent_ops imsic_msi_parent_ops = { int imsic_irqdomain_init(void) { struct irq_domain_info info = { - .fwnode = imsic->fwnode, .ops = &imsic_base_domain_ops, .host_data = imsic, }; @@ -325,6 +324,7 @@ int imsic_irqdomain_init(void) } /* Create Base IRQ domain */ + info.fwnode = imsic->fwnode, imsic->base_domain = msi_create_parent_irq_domain(&info, &imsic_msi_parent_ops); if (!imsic->base_domain) { pr_err("%pfwP: failed to create IMSIC base domain\n", imsic->fwnode); diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 15c538ee9537..79ea85d18e24 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -438,7 +438,7 @@ static bool rs_is_reshapable(struct raid_set *rs) /* Return true, if raid set in @rs is recovering */ static bool rs_is_recovering(struct raid_set *rs) { - return rs->md.recovery_cp < rs->md.dev_sectors; + return rs->md.resync_offset < rs->md.dev_sectors; } /* Return true, if raid set in @rs is reshaping */ @@ -768,7 +768,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r rs->md.layout = raid_type->algorithm; rs->md.new_layout = rs->md.layout; rs->md.delta_disks = 0; - rs->md.recovery_cp = MaxSector; + rs->md.resync_offset = MaxSector; for (i = 0; i < raid_devs; i++) md_rdev_init(&rs->dev[i].rdev); @@ -912,7 +912,7 @@ static int parse_dev_params(struct raid_set *rs, struct dm_arg_set *as) rs->md.external = 0; rs->md.persistent = 1; rs->md.major_version = 2; - } else if (rebuild && !rs->md.recovery_cp) { + } else if (rebuild && !rs->md.resync_offset) { /* * Without metadata, we will not be able to tell if the array * is in-sync or not - we must assume it is not. Therefore, @@ -1695,20 +1695,20 @@ static void rs_setup_recovery(struct raid_set *rs, sector_t dev_sectors) { /* raid0 does not recover */ if (rs_is_raid0(rs)) - rs->md.recovery_cp = MaxSector; + rs->md.resync_offset = MaxSector; /* * A raid6 set has to be recovered either * completely or for the grown part to * ensure proper parity and Q-Syndrome */ else if (rs_is_raid6(rs)) - rs->md.recovery_cp = dev_sectors; + rs->md.resync_offset = dev_sectors; /* * Other raid set types may skip recovery * depending on the 'nosync' flag. */ else - rs->md.recovery_cp = test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) + rs->md.resync_offset = test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags) ? MaxSector : dev_sectors; } @@ -2143,7 +2143,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev) sb->events = cpu_to_le64(mddev->events); sb->disk_recovery_offset = cpu_to_le64(rdev->recovery_offset); - sb->array_resync_offset = cpu_to_le64(mddev->recovery_cp); + sb->array_resync_offset = cpu_to_le64(mddev->resync_offset); sb->level = cpu_to_le32(mddev->level); sb->layout = cpu_to_le32(mddev->layout); @@ -2334,18 +2334,18 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) } if (!test_bit(__CTR_FLAG_NOSYNC, &rs->ctr_flags)) - mddev->recovery_cp = le64_to_cpu(sb->array_resync_offset); + mddev->resync_offset = le64_to_cpu(sb->array_resync_offset); /* * During load, we set FirstUse if a new superblock was written. * There are two reasons we might not have a superblock: * 1) The raid set is brand new - in which case, all of the * devices must have their In_sync bit set. Also, - * recovery_cp must be 0, unless forced. + * resync_offset must be 0, unless forced. * 2) This is a new device being added to an old raid set * and the new device needs to be rebuilt - in which * case the In_sync bit will /not/ be set and - * recovery_cp must be MaxSector. + * resync_offset must be MaxSector. * 3) This is/are a new device(s) being added to an old * raid set during takeover to a higher raid level * to provide capacity for redundancy or during reshape @@ -2390,8 +2390,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) new_devs > 1 ? "s" : ""); return -EINVAL; } else if (!test_bit(__CTR_FLAG_REBUILD, &rs->ctr_flags) && rs_is_recovering(rs)) { - DMERR("'rebuild' specified while raid set is not in-sync (recovery_cp=%llu)", - (unsigned long long) mddev->recovery_cp); + DMERR("'rebuild' specified while raid set is not in-sync (resync_offset=%llu)", + (unsigned long long) mddev->resync_offset); return -EINVAL; } else if (rs_is_reshaping(rs)) { DMERR("'rebuild' specified while raid set is being reshaped (reshape_position=%llu)", @@ -2700,11 +2700,11 @@ static int rs_adjust_data_offsets(struct raid_set *rs) } out: /* - * Raise recovery_cp in case data_offset != 0 to + * Raise resync_offset in case data_offset != 0 to * avoid false recovery positives in the constructor. */ - if (rs->md.recovery_cp < rs->md.dev_sectors) - rs->md.recovery_cp += rs->dev[0].rdev.data_offset; + if (rs->md.resync_offset < rs->md.dev_sectors) + rs->md.resync_offset += rs->dev[0].rdev.data_offset; /* Adjust data offsets on all rdevs but on any raid4/5/6 journal device */ rdev_for_each(rdev, &rs->md) { @@ -2759,7 +2759,7 @@ static int rs_setup_takeover(struct raid_set *rs) } clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags); - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; while (d--) { rdev = &rs->dev[d].rdev; @@ -2767,7 +2767,7 @@ static int rs_setup_takeover(struct raid_set *rs) if (test_bit(d, (void *) rs->rebuild_disks)) { clear_bit(In_sync, &rdev->flags); clear_bit(Faulty, &rdev->flags); - mddev->recovery_cp = rdev->recovery_offset = 0; + mddev->resync_offset = rdev->recovery_offset = 0; /* Bitmap has to be created when we do an "up" takeover */ set_bit(MD_ARRAY_FIRST_USE, &mddev->flags); } @@ -3225,7 +3225,7 @@ size_check: if (r) goto bad; - rs_setup_recovery(rs, rs->md.recovery_cp < rs->md.dev_sectors ? rs->md.recovery_cp : rs->md.dev_sectors); + rs_setup_recovery(rs, rs->md.resync_offset < rs->md.dev_sectors ? rs->md.resync_offset : rs->md.dev_sectors); } else { /* This is no size change or it is shrinking, update size and record in superblocks */ r = rs_set_dev_and_array_sectors(rs, rs->ti->len, false); @@ -3449,7 +3449,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery, } else { if (state == st_idle && !test_bit(MD_RECOVERY_INTR, &recovery)) - r = mddev->recovery_cp; + r = mddev->resync_offset; else r = mddev->curr_resync_completed; @@ -4077,9 +4077,9 @@ static int raid_preresume(struct dm_target *ti) } /* Check for any resize/reshape on @rs and adjust/initiate */ - if (mddev->recovery_cp && mddev->recovery_cp < MaxSector) { + if (mddev->resync_offset && mddev->resync_offset < MaxSector) { set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); - mddev->resync_min = mddev->recovery_cp; + mddev->resync_min = mddev->resync_offset; if (test_bit(RT_FLAG_RS_GROW, &rs->runtime_flags)) mddev->resync_max_sectors = mddev->dev_sectors; } diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 7f524a26cebc..334b71404930 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1987,12 +1987,12 @@ static void bitmap_dirty_bits(struct mddev *mddev, unsigned long s, md_bitmap_set_memory_bits(bitmap, sec, 1); md_bitmap_file_set_bit(bitmap, sec); - if (sec < bitmap->mddev->recovery_cp) + if (sec < bitmap->mddev->resync_offset) /* We are asserting that the array is dirty, - * so move the recovery_cp address back so + * so move the resync_offset address back so * that it is obvious that it is dirty */ - bitmap->mddev->recovery_cp = sec; + bitmap->mddev->resync_offset = sec; } } @@ -2258,7 +2258,7 @@ static int bitmap_load(struct mddev *mddev) || bitmap->events_cleared == mddev->events) /* no need to keep dirty bits to optimise a * re-add of a missing device */ - start = mddev->recovery_cp; + start = mddev->resync_offset; mutex_lock(&mddev->bitmap_info.mutex); err = md_bitmap_init_from_disk(bitmap, start); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 94221d964d4f..5497eaee96e7 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -337,11 +337,11 @@ static void recover_bitmaps(struct md_thread *thread) md_wakeup_thread(mddev->sync_thread); if (hi > 0) { - if (lo < mddev->recovery_cp) - mddev->recovery_cp = lo; + if (lo < mddev->resync_offset) + mddev->resync_offset = lo; /* wake up thread to continue resync in case resync * is not finished */ - if (mddev->recovery_cp != MaxSector) { + if (mddev->resync_offset != MaxSector) { /* * clear the REMOTE flag since we will launch * resync thread in current node. @@ -863,9 +863,9 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots) lockres_free(bm_lockres); continue; } - if ((hi > 0) && (lo < mddev->recovery_cp)) { + if ((hi > 0) && (lo < mddev->resync_offset)) { set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - mddev->recovery_cp = lo; + mddev->resync_offset = lo; md_check_recovery(mddev); } @@ -1027,7 +1027,7 @@ static int leave(struct mddev *mddev) * Also, we should send BITMAP_NEEDS_SYNC message in * case reshaping is interrupted. */ - if ((cinfo->slot_number > 0 && mddev->recovery_cp != MaxSector) || + if ((cinfo->slot_number > 0 && mddev->resync_offset != MaxSector) || (mddev->reshape_position != MaxSector && test_bit(MD_CLOSING, &mddev->flags))) resync_bitmap(mddev); @@ -1605,8 +1605,8 @@ static int gather_bitmaps(struct md_rdev *rdev) pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn); goto out; } - if ((hi > 0) && (lo < mddev->recovery_cp)) - mddev->recovery_cp = lo; + if ((hi > 0) && (lo < mddev->resync_offset)) + mddev->resync_offset = lo; } out: return err; diff --git a/drivers/md/md.c b/drivers/md/md.c index 046fe85c76fe..ac85ec73a409 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -637,6 +637,12 @@ static void __mddev_put(struct mddev *mddev) return; /* + * If array is freed by stopping array, MD_DELETED is set by + * do_md_stop(), MD_DELETED is still set here in case mddev is freed + * directly by closing a mddev that is created by create_on_open. + */ + set_bit(MD_DELETED, &mddev->flags); + /* * Call queue_work inside the spinlock so that flush_workqueue() after * mddev_find will succeed in waiting for the work to be done. */ @@ -1409,13 +1415,13 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru mddev->layout = -1; if (sb->state & (1<<MD_SB_CLEAN)) - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; else { if (sb->events_hi == sb->cp_events_hi && sb->events_lo == sb->cp_events_lo) { - mddev->recovery_cp = sb->recovery_cp; + mddev->resync_offset = sb->resync_offset; } else - mddev->recovery_cp = 0; + mddev->resync_offset = 0; } memcpy(mddev->uuid+0, &sb->set_uuid0, 4); @@ -1541,13 +1547,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev) mddev->minor_version = sb->minor_version; if (mddev->in_sync) { - sb->recovery_cp = mddev->recovery_cp; + sb->resync_offset = mddev->resync_offset; sb->cp_events_hi = (mddev->events>>32); sb->cp_events_lo = (u32)mddev->events; - if (mddev->recovery_cp == MaxSector) + if (mddev->resync_offset == MaxSector) sb->state = (1<< MD_SB_CLEAN); } else - sb->recovery_cp = 0; + sb->resync_offset = 0; sb->layout = mddev->layout; sb->chunk_size = mddev->chunk_sectors << 9; @@ -1895,7 +1901,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struc mddev->bitmap_info.default_space = (4096-1024) >> 9; mddev->reshape_backwards = 0; - mddev->recovery_cp = le64_to_cpu(sb->resync_offset); + mddev->resync_offset = le64_to_cpu(sb->resync_offset); memcpy(mddev->uuid, sb->set_uuid, 16); mddev->max_disks = (4096-256)/2; @@ -2081,7 +2087,7 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) sb->utime = cpu_to_le64((__u64)mddev->utime); sb->events = cpu_to_le64(mddev->events); if (mddev->in_sync) - sb->resync_offset = cpu_to_le64(mddev->recovery_cp); + sb->resync_offset = cpu_to_le64(mddev->resync_offset); else if (test_bit(MD_JOURNAL_CLEAN, &mddev->flags)) sb->resync_offset = cpu_to_le64(MaxSector); else @@ -2761,7 +2767,7 @@ repeat: /* If this is just a dirty<->clean transition, and the array is clean * and 'events' is odd, we can roll back to the previous clean state */ if (nospares - && (mddev->in_sync && mddev->recovery_cp == MaxSector) + && (mddev->in_sync && mddev->resync_offset == MaxSector) && mddev->can_decrease_events && mddev->events != 1) { mddev->events--; @@ -4297,9 +4303,9 @@ __ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store); static ssize_t resync_start_show(struct mddev *mddev, char *page) { - if (mddev->recovery_cp == MaxSector) + if (mddev->resync_offset == MaxSector) return sprintf(page, "none\n"); - return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp); + return sprintf(page, "%llu\n", (unsigned long long)mddev->resync_offset); } static ssize_t @@ -4325,7 +4331,7 @@ resync_start_store(struct mddev *mddev, const char *buf, size_t len) err = -EBUSY; if (!err) { - mddev->recovery_cp = n; + mddev->resync_offset = n; if (mddev->pers) set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags); } @@ -6417,7 +6423,7 @@ static void md_clean(struct mddev *mddev) mddev->external_size = 0; mddev->dev_sectors = 0; mddev->raid_disks = 0; - mddev->recovery_cp = 0; + mddev->resync_offset = 0; mddev->resync_min = 0; mddev->resync_max = MaxSector; mddev->reshape_position = MaxSector; @@ -7362,9 +7368,9 @@ int md_set_array_info(struct mddev *mddev, struct mdu_array_info_s *info) * openned */ if (info->state & (1<<MD_SB_CLEAN)) - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; else - mddev->recovery_cp = 0; + mddev->resync_offset = 0; mddev->persistent = ! info->not_persistent; mddev->external = 0; @@ -8303,7 +8309,7 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev) seq_printf(seq, "\tresync=REMOTE"); return 1; } - if (mddev->recovery_cp < MaxSector) { + if (mddev->resync_offset < MaxSector) { seq_printf(seq, "\tresync=PENDING"); return 1; } @@ -8946,7 +8952,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action) return mddev->resync_min; case ACTION_RESYNC: if (!mddev->bitmap) - return mddev->recovery_cp; + return mddev->resync_offset; return 0; case ACTION_RESHAPE: /* @@ -9184,8 +9190,8 @@ void md_do_sync(struct md_thread *thread) atomic_read(&mddev->recovery_active) == 0); mddev->curr_resync_completed = j; if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && - j > mddev->recovery_cp) - mddev->recovery_cp = j; + j > mddev->resync_offset) + mddev->resync_offset = j; update_time = jiffies; set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags); sysfs_notify_dirent_safe(mddev->sysfs_completed); @@ -9305,19 +9311,19 @@ void md_do_sync(struct md_thread *thread) mddev->curr_resync > MD_RESYNC_ACTIVE) { if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { - if (mddev->curr_resync >= mddev->recovery_cp) { + if (mddev->curr_resync >= mddev->resync_offset) { pr_debug("md: checkpointing %s of %s.\n", desc, mdname(mddev)); if (test_bit(MD_RECOVERY_ERROR, &mddev->recovery)) - mddev->recovery_cp = + mddev->resync_offset = mddev->curr_resync_completed; else - mddev->recovery_cp = + mddev->resync_offset = mddev->curr_resync; } } else - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; } else { if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) mddev->curr_resync = MaxSector; @@ -9421,6 +9427,12 @@ static bool rdev_is_spare(struct md_rdev *rdev) static bool rdev_addable(struct md_rdev *rdev) { + struct mddev *mddev; + + mddev = READ_ONCE(rdev->mddev); + if (!mddev) + return false; + /* rdev is already used, don't add it again. */ if (test_bit(Candidate, &rdev->flags) || rdev->raid_disk >= 0 || test_bit(Faulty, &rdev->flags)) @@ -9431,7 +9443,7 @@ static bool rdev_addable(struct md_rdev *rdev) return true; /* Allow to add if array is read-write. */ - if (md_is_rdwr(rdev->mddev)) + if (md_is_rdwr(mddev)) return true; /* @@ -9533,7 +9545,7 @@ static bool md_choose_sync_action(struct mddev *mddev, int *spares) } /* Check if resync is in progress. */ - if (mddev->recovery_cp < MaxSector) { + if (mddev->resync_offset < MaxSector) { remove_spares(mddev, NULL); set_bit(MD_RECOVERY_SYNC, &mddev->recovery); clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery); @@ -9714,7 +9726,7 @@ void md_check_recovery(struct mddev *mddev) test_bit(MD_RECOVERY_DONE, &mddev->recovery) || (mddev->external == 0 && mddev->safemode == 1) || (mddev->safemode == 2 - && !mddev->in_sync && mddev->recovery_cp == MaxSector) + && !mddev->in_sync && mddev->resync_offset == MaxSector) )) return; @@ -9771,8 +9783,8 @@ void md_check_recovery(struct mddev *mddev) * remove disk. */ rdev_for_each_safe(rdev, tmp, mddev) { - if (test_and_clear_bit(ClusterRemove, &rdev->flags) && - rdev->raid_disk < 0) + if (rdev->raid_disk < 0 && + test_and_clear_bit(ClusterRemove, &rdev->flags)) md_kick_rdev_from_array(rdev); } } @@ -10078,8 +10090,11 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) /* Check for change of roles in the active devices */ rdev_for_each_safe(rdev2, tmp, mddev) { - if (test_bit(Faulty, &rdev2->flags)) + if (test_bit(Faulty, &rdev2->flags)) { + if (test_bit(ClusterRemove, &rdev2->flags)) + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); continue; + } /* Check if the roles changed */ role = le16_to_cpu(sb->dev_roles[rdev2->desc_nr]); diff --git a/drivers/md/md.h b/drivers/md/md.h index 67b365621507..51af29a03079 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -523,7 +523,7 @@ struct mddev { unsigned long normal_io_events; /* IO event timestamp */ atomic_t recovery_active; /* blocks scheduled, but not written */ wait_queue_head_t recovery_wait; - sector_t recovery_cp; + sector_t resync_offset; sector_t resync_min; /* user requested sync * starts here */ sector_t resync_max; /* resync should pause diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index cbe2a9054cb9..f1d8811a542a 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -674,7 +674,7 @@ static void *raid0_takeover_raid45(struct mddev *mddev) mddev->raid_disks--; mddev->delta_disks = -1; /* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS); create_strip_zones(mddev, &priv_conf); @@ -717,7 +717,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) mddev->raid_disks += mddev->delta_disks; mddev->degraded = 0; /* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS); create_strip_zones(mddev, &priv_conf); @@ -760,7 +760,7 @@ static void *raid0_takeover_raid1(struct mddev *mddev) mddev->delta_disks = 1 - mddev->raid_disks; mddev->raid_disks = 1; /* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; mddev_clear_unsupported_flags(mddev, UNSUPPORTED_MDDEV_FLAGS); create_strip_zones(mddev, &priv_conf); diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c index b8b3a9069701..52881e6032da 100644 --- a/drivers/md/raid1-10.c +++ b/drivers/md/raid1-10.c @@ -283,7 +283,7 @@ static inline int raid1_check_read_range(struct md_rdev *rdev, static inline bool raid1_should_read_first(struct mddev *mddev, sector_t this_sector, int len) { - if ((mddev->recovery_cp < this_sector + len)) + if ((mddev->resync_offset < this_sector + len)) return true; if (mddev_is_clustered(mddev) && diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 64b8176907a9..408c26398321 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -127,10 +127,9 @@ static inline struct r1bio *get_resync_r1bio(struct bio *bio) return get_resync_pages(bio)->raid_bio; } -static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) +static void *r1bio_pool_alloc(gfp_t gfp_flags, struct r1conf *conf) { - struct pool_info *pi = data; - int size = offsetof(struct r1bio, bios[pi->raid_disks]); + int size = offsetof(struct r1bio, bios[conf->raid_disks * 2]); /* allocate a r1bio with room for raid_disks entries in the bios array */ return kzalloc(size, gfp_flags); @@ -145,18 +144,18 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) { - struct pool_info *pi = data; + struct r1conf *conf = data; struct r1bio *r1_bio; struct bio *bio; int need_pages; int j; struct resync_pages *rps; - r1_bio = r1bio_pool_alloc(gfp_flags, pi); + r1_bio = r1bio_pool_alloc(gfp_flags, conf); if (!r1_bio) return NULL; - rps = kmalloc_array(pi->raid_disks, sizeof(struct resync_pages), + rps = kmalloc_array(conf->raid_disks * 2, sizeof(struct resync_pages), gfp_flags); if (!rps) goto out_free_r1bio; @@ -164,7 +163,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) /* * Allocate bios : 1 for reading, n-1 for writing */ - for (j = pi->raid_disks ; j-- ; ) { + for (j = conf->raid_disks * 2; j-- ; ) { bio = bio_kmalloc(RESYNC_PAGES, gfp_flags); if (!bio) goto out_free_bio; @@ -177,11 +176,11 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) * If this is a user-requested check/repair, allocate * RESYNC_PAGES for each bio. */ - if (test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery)) - need_pages = pi->raid_disks; + if (test_bit(MD_RECOVERY_REQUESTED, &conf->mddev->recovery)) + need_pages = conf->raid_disks * 2; else need_pages = 1; - for (j = 0; j < pi->raid_disks; j++) { + for (j = 0; j < conf->raid_disks * 2; j++) { struct resync_pages *rp = &rps[j]; bio = r1_bio->bios[j]; @@ -207,7 +206,7 @@ out_free_pages: resync_free_pages(&rps[j]); out_free_bio: - while (++j < pi->raid_disks) { + while (++j < conf->raid_disks * 2) { bio_uninit(r1_bio->bios[j]); kfree(r1_bio->bios[j]); } @@ -220,12 +219,12 @@ out_free_r1bio: static void r1buf_pool_free(void *__r1_bio, void *data) { - struct pool_info *pi = data; + struct r1conf *conf = data; int i; struct r1bio *r1bio = __r1_bio; struct resync_pages *rp = NULL; - for (i = pi->raid_disks; i--; ) { + for (i = conf->raid_disks * 2; i--; ) { rp = get_resync_pages(r1bio->bios[i]); resync_free_pages(rp); bio_uninit(r1bio->bios[i]); @@ -255,7 +254,7 @@ static void free_r1bio(struct r1bio *r1_bio) struct r1conf *conf = r1_bio->mddev->private; put_all_bios(conf, r1_bio); - mempool_free(r1_bio, &conf->r1bio_pool); + mempool_free(r1_bio, conf->r1bio_pool); } static void put_buf(struct r1bio *r1_bio) @@ -1305,9 +1304,8 @@ alloc_r1bio(struct mddev *mddev, struct bio *bio) struct r1conf *conf = mddev->private; struct r1bio *r1_bio; - r1_bio = mempool_alloc(&conf->r1bio_pool, GFP_NOIO); - /* Ensure no bio records IO_BLOCKED */ - memset(r1_bio->bios, 0, conf->raid_disks * sizeof(r1_bio->bios[0])); + r1_bio = mempool_alloc(conf->r1bio_pool, GFP_NOIO); + memset(r1_bio, 0, offsetof(struct r1bio, bios[conf->raid_disks * 2])); init_r1bio(r1_bio, mddev, bio); return r1_bio; } @@ -2747,7 +2745,7 @@ static int init_resync(struct r1conf *conf) BUG_ON(mempool_initialized(&conf->r1buf_pool)); return mempool_init(&conf->r1buf_pool, buffs, r1buf_pool_alloc, - r1buf_pool_free, conf->poolinfo); + r1buf_pool_free, conf); } static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf) @@ -2757,7 +2755,7 @@ static struct r1bio *raid1_alloc_init_r1buf(struct r1conf *conf) struct bio *bio; int i; - for (i = conf->poolinfo->raid_disks; i--; ) { + for (i = conf->raid_disks * 2; i--; ) { bio = r1bio->bios[i]; rps = bio->bi_private; bio_reset(bio, NULL, 0); @@ -2822,7 +2820,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, } if (mddev->bitmap == NULL && - mddev->recovery_cp == MaxSector && + mddev->resync_offset == MaxSector && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && conf->fullsync == 0) { *skipped = 1; @@ -3085,6 +3083,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) int i; struct raid1_info *disk; struct md_rdev *rdev; + size_t r1bio_size; int err = -ENOMEM; conf = kzalloc(sizeof(struct r1conf), GFP_KERNEL); @@ -3121,21 +3120,15 @@ static struct r1conf *setup_conf(struct mddev *mddev) if (!conf->tmppage) goto abort; - conf->poolinfo = kzalloc(sizeof(*conf->poolinfo), GFP_KERNEL); - if (!conf->poolinfo) - goto abort; - conf->poolinfo->raid_disks = mddev->raid_disks * 2; - err = mempool_init(&conf->r1bio_pool, NR_RAID_BIOS, r1bio_pool_alloc, - rbio_pool_free, conf->poolinfo); - if (err) + r1bio_size = offsetof(struct r1bio, bios[mddev->raid_disks * 2]); + conf->r1bio_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS, r1bio_size); + if (!conf->r1bio_pool) goto abort; err = bioset_init(&conf->bio_split, BIO_POOL_SIZE, 0, 0); if (err) goto abort; - conf->poolinfo->mddev = mddev; - err = -EINVAL; spin_lock_init(&conf->device_lock); conf->raid_disks = mddev->raid_disks; @@ -3198,10 +3191,9 @@ static struct r1conf *setup_conf(struct mddev *mddev) abort: if (conf) { - mempool_exit(&conf->r1bio_pool); + mempool_destroy(conf->r1bio_pool); kfree(conf->mirrors); safe_put_page(conf->tmppage); - kfree(conf->poolinfo); kfree(conf->nr_pending); kfree(conf->nr_waiting); kfree(conf->nr_queued); @@ -3282,9 +3274,9 @@ static int raid1_run(struct mddev *mddev) } if (conf->raid_disks - mddev->degraded == 1) - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; - if (mddev->recovery_cp != MaxSector) + if (mddev->resync_offset != MaxSector) pr_info("md/raid1:%s: not clean -- starting background reconstruction\n", mdname(mddev)); pr_info("md/raid1:%s: active with %d out of %d mirrors\n", @@ -3311,10 +3303,9 @@ static void raid1_free(struct mddev *mddev, void *priv) { struct r1conf *conf = priv; - mempool_exit(&conf->r1bio_pool); + mempool_destroy(conf->r1bio_pool); kfree(conf->mirrors); safe_put_page(conf->tmppage); - kfree(conf->poolinfo); kfree(conf->nr_pending); kfree(conf->nr_waiting); kfree(conf->nr_queued); @@ -3345,8 +3336,8 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors) md_set_array_sectors(mddev, newsize); if (sectors > mddev->dev_sectors && - mddev->recovery_cp > mddev->dev_sectors) { - mddev->recovery_cp = mddev->dev_sectors; + mddev->resync_offset > mddev->dev_sectors) { + mddev->resync_offset = mddev->dev_sectors; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } mddev->dev_sectors = sectors; @@ -3367,17 +3358,13 @@ static int raid1_reshape(struct mddev *mddev) * At the same time, we "pack" the devices so that all the missing * devices have the higher raid_disk numbers. */ - mempool_t newpool, oldpool; - struct pool_info *newpoolinfo; + mempool_t *newpool, *oldpool; + size_t new_r1bio_size; struct raid1_info *newmirrors; struct r1conf *conf = mddev->private; int cnt, raid_disks; unsigned long flags; int d, d2; - int ret; - - memset(&newpool, 0, sizeof(newpool)); - memset(&oldpool, 0, sizeof(oldpool)); /* Cannot change chunk_size, layout, or level */ if (mddev->chunk_sectors != mddev->new_chunk_sectors || @@ -3403,24 +3390,16 @@ static int raid1_reshape(struct mddev *mddev) return -EBUSY; } - newpoolinfo = kmalloc(sizeof(*newpoolinfo), GFP_KERNEL); - if (!newpoolinfo) + new_r1bio_size = offsetof(struct r1bio, bios[raid_disks * 2]); + newpool = mempool_create_kmalloc_pool(NR_RAID_BIOS, new_r1bio_size); + if (!newpool) { return -ENOMEM; - newpoolinfo->mddev = mddev; - newpoolinfo->raid_disks = raid_disks * 2; - - ret = mempool_init(&newpool, NR_RAID_BIOS, r1bio_pool_alloc, - rbio_pool_free, newpoolinfo); - if (ret) { - kfree(newpoolinfo); - return ret; } newmirrors = kzalloc(array3_size(sizeof(struct raid1_info), raid_disks, 2), GFP_KERNEL); if (!newmirrors) { - kfree(newpoolinfo); - mempool_exit(&newpool); + mempool_destroy(newpool); return -ENOMEM; } @@ -3429,7 +3408,6 @@ static int raid1_reshape(struct mddev *mddev) /* ok, everything is stopped */ oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; - init_waitqueue_head(&conf->r1bio_pool.wait); for (d = d2 = 0; d < conf->raid_disks; d++) { struct md_rdev *rdev = conf->mirrors[d].rdev; @@ -3446,8 +3424,6 @@ static int raid1_reshape(struct mddev *mddev) } kfree(conf->mirrors); conf->mirrors = newmirrors; - kfree(conf->poolinfo); - conf->poolinfo = newpoolinfo; spin_lock_irqsave(&conf->device_lock, flags); mddev->degraded += (raid_disks - conf->raid_disks); @@ -3461,7 +3437,7 @@ static int raid1_reshape(struct mddev *mddev) set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); - mempool_exit(&oldpool); + mempool_destroy(oldpool); return 0; } diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h index 33f318fcc268..d236ef179cfb 100644 --- a/drivers/md/raid1.h +++ b/drivers/md/raid1.h @@ -49,22 +49,6 @@ struct raid1_info { sector_t seq_start; }; -/* - * memory pools need a pointer to the mddev, so they can force an unplug - * when memory is tight, and a count of the number of drives that the - * pool was allocated for, so they know how much to allocate and free. - * mddev->raid_disks cannot be used, as it can change while a pool is active - * These two datums are stored in a kmalloced struct. - * The 'raid_disks' here is twice the raid_disks in r1conf. - * This allows space for each 'real' device can have a replacement in the - * second half of the array. - */ - -struct pool_info { - struct mddev *mddev; - int raid_disks; -}; - struct r1conf { struct mddev *mddev; struct raid1_info *mirrors; /* twice 'raid_disks' to @@ -114,11 +98,7 @@ struct r1conf { */ int recovery_disabled; - /* poolinfo contains information about the content of the - * mempools - it changes when the array grows or shrinks - */ - struct pool_info *poolinfo; - mempool_t r1bio_pool; + mempool_t *r1bio_pool; mempool_t r1buf_pool; struct bio_set bio_split; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 95dc354a86a0..b60c30bfb6c7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2117,7 +2117,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) int last = conf->geo.raid_disks - 1; struct raid10_info *p; - if (mddev->recovery_cp < MaxSector) + if (mddev->resync_offset < MaxSector) /* only hot-add to in-sync arrays, as recovery is * very different from resync */ @@ -3185,7 +3185,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr, * of a clean array, like RAID1 does. */ if (mddev->bitmap == NULL && - mddev->recovery_cp == MaxSector && + mddev->resync_offset == MaxSector && mddev->reshape_position == MaxSector && !test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) && @@ -4145,7 +4145,7 @@ static int raid10_run(struct mddev *mddev) disk->recovery_disabled = mddev->recovery_disabled - 1; } - if (mddev->recovery_cp != MaxSector) + if (mddev->resync_offset != MaxSector) pr_notice("md/raid10:%s: not clean -- starting background reconstruction\n", mdname(mddev)); pr_info("md/raid10:%s: active with %d out of %d devices\n", @@ -4245,8 +4245,8 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) md_set_array_sectors(mddev, size); if (sectors > mddev->dev_sectors && - mddev->recovery_cp > oldsize) { - mddev->recovery_cp = oldsize; + mddev->resync_offset > oldsize) { + mddev->resync_offset = oldsize; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } calc_sectors(conf, sectors); @@ -4275,7 +4275,7 @@ static void *raid10_takeover_raid0(struct mddev *mddev, sector_t size, int devs) mddev->delta_disks = mddev->raid_disks; mddev->raid_disks *= 2; /* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; mddev->dev_sectors = size; conf = setup_conf(mddev); @@ -5087,8 +5087,8 @@ static void raid10_finish_reshape(struct mddev *mddev) return; if (mddev->delta_disks > 0) { - if (mddev->recovery_cp > mddev->resync_max_sectors) { - mddev->recovery_cp = mddev->resync_max_sectors; + if (mddev->resync_offset > mddev->resync_max_sectors) { + mddev->resync_offset = mddev->resync_max_sectors; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } mddev->resync_max_sectors = mddev->array_sectors; diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index c0fb335311aa..56b234683ee6 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c @@ -1163,7 +1163,7 @@ static int ppl_load_distributed(struct ppl_log *log) le64_to_cpu(pplhdr->generation)); /* attempt to recover from log if we are starting a dirty array */ - if (pplhdr && !mddev->pers && mddev->recovery_cp != MaxSector) + if (pplhdr && !mddev->pers && mddev->resync_offset != MaxSector) ret = ppl_recover(log, pplhdr, pplhdr_offset); /* write empty header if we are starting the array */ @@ -1422,14 +1422,14 @@ int ppl_init_log(struct r5conf *conf) if (ret) { goto err; - } else if (!mddev->pers && mddev->recovery_cp == 0 && + } else if (!mddev->pers && mddev->resync_offset == 0 && ppl_conf->recovered_entries > 0 && ppl_conf->mismatch_count == 0) { /* * If we are starting a dirty array and the recovery succeeds * without any issues, set the array as clean. */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags); } else if (mddev->pers && ppl_conf->mismatch_count > 0) { /* no mismatch allowed when enabling PPL for a running array */ diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7ec61ee7b218..023649fe2476 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3740,7 +3740,7 @@ static int want_replace(struct stripe_head *sh, int disk_idx) && !test_bit(Faulty, &rdev->flags) && !test_bit(In_sync, &rdev->flags) && (rdev->recovery_offset <= sh->sector - || rdev->mddev->recovery_cp <= sh->sector)) + || rdev->mddev->resync_offset <= sh->sector)) rv = 1; return rv; } @@ -3832,7 +3832,7 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s, * is missing/faulty, then we need to read everything we can. */ if (!force_rcw && - sh->sector < sh->raid_conf->mddev->recovery_cp) + sh->sector < sh->raid_conf->mddev->resync_offset) /* reconstruct-write isn't being forced */ return 0; for (i = 0; i < s->failed && i < 2; i++) { @@ -4097,7 +4097,7 @@ static int handle_stripe_dirtying(struct r5conf *conf, int disks) { int rmw = 0, rcw = 0, i; - sector_t recovery_cp = conf->mddev->recovery_cp; + sector_t resync_offset = conf->mddev->resync_offset; /* Check whether resync is now happening or should start. * If yes, then the array is dirty (after unclean shutdown or @@ -4107,14 +4107,14 @@ static int handle_stripe_dirtying(struct r5conf *conf, * generate correct data from the parity. */ if (conf->rmw_level == PARITY_DISABLE_RMW || - (recovery_cp < MaxSector && sh->sector >= recovery_cp && + (resync_offset < MaxSector && sh->sector >= resync_offset && s->failed == 0)) { /* Calculate the real rcw later - for now make it * look like rcw is cheaper */ rcw = 1; rmw = 2; - pr_debug("force RCW rmw_level=%u, recovery_cp=%llu sh->sector=%llu\n", - conf->rmw_level, (unsigned long long)recovery_cp, + pr_debug("force RCW rmw_level=%u, resync_offset=%llu sh->sector=%llu\n", + conf->rmw_level, (unsigned long long)resync_offset, (unsigned long long)sh->sector); } else for (i = disks; i--; ) { /* would I have to read this buffer for read_modify_write */ @@ -4770,14 +4770,14 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) if (test_bit(STRIPE_SYNCING, &sh->state)) { /* If there is a failed device being replaced, * we must be recovering. - * else if we are after recovery_cp, we must be syncing + * else if we are after resync_offset, we must be syncing * else if MD_RECOVERY_REQUESTED is set, we also are syncing. * else we can only be replacing * sync and recovery both need to read all devices, and so * use the same flag. */ if (do_recovery || - sh->sector >= conf->mddev->recovery_cp || + sh->sector >= conf->mddev->resync_offset || test_bit(MD_RECOVERY_REQUESTED, &(conf->mddev->recovery))) s->syncing = 1; else @@ -7780,7 +7780,7 @@ static int raid5_run(struct mddev *mddev) int first = 1; int ret = -EIO; - if (mddev->recovery_cp != MaxSector) + if (mddev->resync_offset != MaxSector) pr_notice("md/raid:%s: not clean -- starting background reconstruction\n", mdname(mddev)); @@ -7921,7 +7921,7 @@ static int raid5_run(struct mddev *mddev) mdname(mddev)); mddev->ro = 1; set_disk_ro(mddev->gendisk, 1); - } else if (mddev->recovery_cp == MaxSector) + } else if (mddev->resync_offset == MaxSector) set_bit(MD_JOURNAL_CLEAN, &mddev->flags); } @@ -7988,7 +7988,7 @@ static int raid5_run(struct mddev *mddev) mddev->resync_max_sectors = mddev->dev_sectors; if (mddev->degraded > dirty_parity_disks && - mddev->recovery_cp != MaxSector) { + mddev->resync_offset != MaxSector) { if (test_bit(MD_HAS_PPL, &mddev->flags)) pr_crit("md/raid:%s: starting dirty degraded array with PPL.\n", mdname(mddev)); @@ -8328,8 +8328,8 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors) md_set_array_sectors(mddev, newsize); if (sectors > mddev->dev_sectors && - mddev->recovery_cp > mddev->dev_sectors) { - mddev->recovery_cp = mddev->dev_sectors; + mddev->resync_offset > mddev->dev_sectors) { + mddev->resync_offset = mddev->dev_sectors; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); } mddev->dev_sectors = sectors; @@ -8423,7 +8423,7 @@ static int raid5_start_reshape(struct mddev *mddev) return -EINVAL; /* raid5 can't handle concurrent reshape and recovery */ - if (mddev->recovery_cp < MaxSector) + if (mddev->resync_offset < MaxSector) return -EBUSY; for (i = 0; i < conf->raid_disks; i++) if (conf->disks[i].replacement) @@ -8648,7 +8648,7 @@ static void *raid45_takeover_raid0(struct mddev *mddev, int level) mddev->raid_disks += 1; mddev->delta_disks = 1; /* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; return setup_conf(mddev); } diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 12bbb169c0b0..6abc9302cd84 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -230,19 +230,6 @@ source "drivers/media/platform/Kconfig" source "drivers/media/mmc/Kconfig" endif -config MEDIA_VIRTIO - tristate "Virtio-media Driver" - depends on VIRTIO && VIDEO_DEV && 64BIT && (X86 || (ARM && CPU_LITTLE_ENDIAN)) - select VIDEOBUF2_CORE - select VIDEOBUF2_MEMOPS - help - Enables the virtio-media driver. - - This driver is used to virtualize media devices such as cameras or - decoders from a host into a guest using the V4L2 protocol. - - If unsure, say N. - if MEDIA_TEST_SUPPORT source "drivers/media/test-drivers/Kconfig" endif diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 7a1377661919..20fac24e4f0f 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -25,8 +25,6 @@ obj-y += rc/ obj-$(CONFIG_CEC_CORE) += cec/ -obj-$(CONFIG_MEDIA_VIRTIO) += virtio/ - # # Finally, merge the drivers that require the core # diff --git a/drivers/media/virtio/Makefile b/drivers/media/virtio/Makefile deleted file mode 100644 index 16f91304420d..000000000000 --- a/drivers/media/virtio/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the virtio-media device driver. - -virtio-media-objs := scatterlist_builder.o virtio_media_ioctls.o \ - virtio_media_driver.o - -obj-$(CONFIG_MEDIA_VIRTIO) += virtio-media.o - diff --git a/drivers/media/virtio/protocol.h b/drivers/media/virtio/protocol.h deleted file mode 100644 index a22758cda5aa..000000000000 --- a/drivers/media/virtio/protocol.h +++ /dev/null @@ -1,288 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ */ - -/* - * Definitions of virtio-media protocol structures. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#ifndef __VIRTIO_MEDIA_PROTOCOL_H -#define __VIRTIO_MEDIA_PROTOCOL_H - -#include <linux/videodev2.h> - -/* - * Virtio protocol definition. - */ - -/** - * struct virtio_media_cmd_header - Header for all virtio-media commands. - * @cmd: one of VIRTIO_MEDIA_CMD_*. - * @__reserved: must be set to zero by the driver. - * - * This header starts all commands from the driver to the device on the - * commandq. - */ -struct virtio_media_cmd_header { - u32 cmd; - u32 __reserved; -}; - -/** - * struct virtio_media_resp_header - Header for all virtio-media responses. - * @status: 0 if the command was successful, or one of the standard Linux error - * codes. - * @__reserved: must be set to zero by the device. - * - * This header starts all responses from the device to the driver on the - * commandq. - */ -struct virtio_media_resp_header { - u32 status; - u32 __reserved; -}; - -/** - * VIRTIO_MEDIA_CMD_OPEN - Command for creating a new session. - * - * This is the equivalent of calling `open` on a V4L2 device node. Upon - * success, a session id is returned which can be used to perform other - * commands on the session, notably ioctls. - */ -#define VIRTIO_MEDIA_CMD_OPEN 1 - -/** - * struct virtio_media_cmd_open - Driver command for VIRTIO_MEDIA_CMD_OPEN. - * @hdr: header with cmd member set to VIRTIO_MEDIA_CMD_OPEN. - */ -struct virtio_media_cmd_open { - struct virtio_media_cmd_header hdr; -}; - -/** - * struct virtio_media_resp_open - Device response for VIRTIO_MEDIA_CMD_OPEN. - * @hdr: header containing the status of the command. - * @session_id: if hdr.status == 0, contains the id of the newly created session. - * @__reserved: must be set to zero by the device. - */ -struct virtio_media_resp_open { - struct virtio_media_resp_header hdr; - u32 session_id; - u32 __reserved; -}; - -/** - * VIRTIO_MEDIA_CMD_CLOSE - Command for closing an active session. - * - * This is the equivalent of calling `close` on a previously opened V4L2 - * session. All resources associated with this session will be freed and the - * session ID shall not be used again after queueing this command. - * - * This command does not require a response from the device. - */ -#define VIRTIO_MEDIA_CMD_CLOSE 2 - -/** - * struct virtio_media_cmd_close - Driver command for VIRTIO_MEDIA_CMD_CLOSE. - * @hdr: header with cmd member set to VIRTIO_MEDIA_CMD_CLOSE. - * @session_id: id of the session to close. - * @__reserved: must be set to zero by the driver. - */ -struct virtio_media_cmd_close { - struct virtio_media_cmd_header hdr; - u32 session_id; - u32 __reserved; -}; - -/** - * VIRTIO_MEDIA_CMD_IOCTL - Driver command for executing an ioctl. - * - * This command asks the device to run one of the `VIDIOC_*` ioctls on the - * active session. - * - * The code of the ioctl is extracted from the VIDIOC_* definitions in - * `videodev2.h`, and consists of the second argument of the `_IO*` macro. - * - * Each ioctl has a payload, which is defined by the third argument of the - * `_IO*` macro defining it. It can be writable by the driver (`_IOW`), the - * device (`_IOR`), or both (`_IOWR`). - * - * If an ioctl is writable by the driver, it must be followed by a - * driver-writable descriptor containing the payload. - * - * If an ioctl is writable by the device, it must be followed by a - * device-writable descriptor of the size of the payload that the device will - * write into. - * - */ -#define VIRTIO_MEDIA_CMD_IOCTL 3 - -/** - * struct virtio_media_cmd_ioctl - Driver command for VIRTIO_MEDIA_CMD_IOCTL. - * @hdr: header with cmd member set to VIRTIO_MEDIA_CMD_IOCTL. - * @session_id: id of the session to run the ioctl on. - * @code: code of the ioctl to run. - */ -struct virtio_media_cmd_ioctl { - struct virtio_media_cmd_header hdr; - u32 session_id; - u32 code; -}; - -/** - * struct virtio_media_resp_ioctl - Device response for VIRTIO_MEDIA_CMD_IOCTL. - * @hdr: header containing the status of the ioctl. - */ -struct virtio_media_resp_ioctl { - struct virtio_media_resp_header hdr; -}; - -/** - * struct virtio_media_sg_entry - Description of part of a scattered guest memory. - * @start: start guest address of the memory segment. - * @len: length of this memory segment. - * @__reserved: must be set to zero by the driver. - */ -struct virtio_media_sg_entry { - u64 start; - u32 len; - u32 __reserved; -}; - -/** - * enum virtio_media_memory - Memory types supported by virtio-media. - * @VIRTIO_MEDIA_MMAP: memory allocated and managed by device. Can be mapped - * into the guest using VIRTIO_MEDIA_CMD_MMAP. - * @VIRTIO_MEDIA_SHARED_PAGES: memory allocated by the driver. Passed to the - * device using virtio_media_sg_entry. - * @VIRTIO_MEDIA_OBJECT: memory backed by a virtio object. - */ -enum virtio_media_memory { - VIRTIO_MEDIA_MMAP = V4L2_MEMORY_MMAP, - VIRTIO_MEDIA_SHARED_PAGES = V4L2_MEMORY_USERPTR, - VIRTIO_MEDIA_OBJECT = V4L2_MEMORY_DMABUF, -}; - -#define VIRTIO_MEDIA_MMAP_FLAG_RW (1 << 0) - -/** - * VIRTIO_MEDIA_CMD_MMAP - Command for mapping a MMAP buffer into the driver's - * address space. - * - */ -#define VIRTIO_MEDIA_CMD_MMAP 4 - -/** - * struct virtio_media_cmd_mmap - Driver command for VIRTIO_MEDIA_CMD_MMAP. - * @hdr: header with cmd member set to VIRTIO_MEDIA_CMD_MMAP. - * @session_id: ID of the session we are mapping for. - * @flags: combination of VIRTIO_MEDIA_MMAP_FLAG_*. - * @offset: mem_offset field of the plane to map, as returned by VIDIOC_QUERYBUF. - */ -struct virtio_media_cmd_mmap { - struct virtio_media_cmd_header hdr; - u32 session_id; - u32 flags; - u32 offset; -}; - -/** - * struct virtio_media_resp_mmap - Device response for VIRTIO_MEDIA_CMD_MMAP. - * @hdr: header containing the status of the command. - * @driver_addr: offset into SHM region 0 of the start of the mapping. - * @len: length of the mapping. - */ -struct virtio_media_resp_mmap { - struct virtio_media_resp_header hdr; - u64 driver_addr; - u64 len; -}; - -/** - * VIRTIO_MEDIA_CMD_MUNMAP - Unmap a MMAP buffer previously mapped using - * VIRTIO_MEDIA_CMD_MMAP. - */ -#define VIRTIO_MEDIA_CMD_MUNMAP 5 - -/** - * struct virtio_media_cmd_munmap - Driver command for VIRTIO_MEDIA_CMD_MUNMAP. - * @hdr: header with cmd member set to VIRTIO_MEDIA_CMD_MUNMAP. - * @driver_addr: offset into SHM region 0 at which the buffer has been previously - * mapped. - */ -struct virtio_media_cmd_munmap { - struct virtio_media_cmd_header hdr; - u64 driver_addr; -}; - -/** - * struct virtio_media_resp_munmap - Device response for VIRTIO_MEDIA_CMD_MUNMAP. - * @hdr: header containing the status of the command. - */ -struct virtio_media_resp_munmap { - struct virtio_media_resp_header hdr; -}; - -#define VIRTIO_MEDIA_EVT_ERROR 0 -#define VIRTIO_MEDIA_EVT_DQBUF 1 -#define VIRTIO_MEDIA_EVT_EVENT 2 - -/** - * struct virtio_media_event_header - Header for events on the eventq. - * @event: one of VIRTIO_MEDIA_EVT_* - * @session_id: ID of the session the event applies to. - */ -struct virtio_media_event_header { - u32 event; - u32 session_id; -}; - -/** - * struct virtio_media_event_error - Unrecoverable device-side error. - * @hdr: header for the event. - * @errno: error code describing the kind of error that occurred. - * @__reserved: must to set to zero by the device. - * - * Upon receiving this event, the session mentioned in the header is considered - * corrupted and closed. - * - */ -struct virtio_media_event_error { - struct virtio_media_event_header hdr; - u32 errno; - u32 __reserved; -}; - -#define VIRTIO_MEDIA_MAX_PLANES VIDEO_MAX_PLANES - -/** - * struct virtio_media_event_dqbuf - Dequeued buffer event. - * @hdr: header for the event. - * @buffer: struct v4l2_buffer describing the buffer that has been dequeued. - * @planes: plane information for the dequeued buffer. - * - * This event is used to signal that a buffer is not being used anymore by the - * device and is returned to the driver. - */ -struct virtio_media_event_dqbuf { - struct virtio_media_event_header hdr; - struct v4l2_buffer buffer; - struct v4l2_plane planes[VIRTIO_MEDIA_MAX_PLANES]; -}; - -/** - * struct virtio_media_event_event - V4L2 event. - * @hdr: header for the event. - * @event: description of the event that occurred. - * - * This event signals that a V4L2 event has been emitted for a session. - */ -struct virtio_media_event_event { - struct virtio_media_event_header hdr; - struct v4l2_event event; -}; - -/* Maximum size of an event. We will queue descriptors of this size on the eventq. */ -#define VIRTIO_MEDIA_EVENT_MAX_SIZE sizeof(struct virtio_media_event_dqbuf) - -#endif // __VIRTIO_MEDIA_PROTOCOL_H diff --git a/drivers/media/virtio/scatterlist_builder.c b/drivers/media/virtio/scatterlist_builder.c deleted file mode 100644 index 2837689f385e..000000000000 --- a/drivers/media/virtio/scatterlist_builder.c +++ /dev/null @@ -1,563 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ - -/* - * Scatterlist builder helpers for virtio-media. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#include <linux/moduleparam.h> -#include <linux/scatterlist.h> -#include <linux/videodev2.h> -#include <media/videobuf2-memops.h> - -#include "protocol.h" -#include "scatterlist_builder.h" -#include "session.h" - -/* - * If set to ``true``, then the driver will always copy the data passed to the - * host into the shadow buffer (instead of trying to map the source memory into - * the SG table directly when possible). - */ -static bool always_use_shadow_buffer; -module_param(always_use_shadow_buffer, bool, 0660); - -/* Convert a V4L2 IOCTL into the IOCTL code we can give to the host */ -#define VIRTIO_MEDIA_IOCTL_CODE(IOCTL) ((IOCTL >> _IOC_NRSHIFT) & _IOC_NRMASK) - -/** - * scatterlist_builder_add_descriptor() - Add a descriptor to the chain. - * @builder: builder to use. - * @desc_index: index of the descriptor to add. - * - * Returns ``-ENOSPC`` if ``sgs`` is already full. - */ -int scatterlist_builder_add_descriptor(struct scatterlist_builder *builder, - size_t desc_index) -{ - if (builder->cur_sg >= builder->num_sgs) - return -ENOSPC; - builder->sgs[builder->cur_sg++] = &builder->descs[desc_index]; - - return 0; -} - -/** - * scatterlist_builder_add_data() - Append arbitrary data to the descriptor chain. - * @builder: builder to use. - * @data: pointer to the data to add to the descriptor chain. - * @len: length of the data to add. - * - * @data will either be directly referenced, or copied into the shadow buffer - * to be referenced from there. - */ -int scatterlist_builder_add_data(struct scatterlist_builder *builder, - void *data, size_t len) -{ - const size_t cur_desc = builder->cur_desc; - - if (len == 0) - return 0; - - if (builder->cur_desc >= builder->num_descs) - return -ENOSPC; - - if (!always_use_shadow_buffer && virt_addr_valid(data + len)) { - /* - * If "data" is in the 1:1 physical memory mapping then we can - * use a single SG entry and avoid copying. - */ - struct page *page = virt_to_page(data); - size_t offset = (((size_t)data) & ~PAGE_MASK); - struct scatterlist *next_desc = - &builder->descs[builder->cur_desc]; - - memset(next_desc, 0, sizeof(*next_desc)); - sg_set_page(next_desc, page, len, offset); - builder->cur_desc++; - } else if (!always_use_shadow_buffer && is_vmalloc_addr(data)) { - int prev_pfn = -2; - - /* - * If "data" has been vmalloc'ed, we need at most one entry per - * memory page but can avoid copying. - */ - while (len > 0) { - struct page *page = vmalloc_to_page(data); - int cur_pfn = page_to_pfn(page); - /* All pages but the first will start at offset 0. */ - unsigned long offset = - (((unsigned long)data) & ~PAGE_MASK); - size_t len_in_page = min(PAGE_SIZE - offset, len); - struct scatterlist *next_desc = - &builder->descs[builder->cur_desc]; - - if (builder->cur_desc >= builder->num_descs) - return -ENOSPC; - - /* Optimize contiguous pages */ - if (cur_pfn == prev_pfn + 1) { - (next_desc - 1)->length += len_in_page; - } else { - memset(next_desc, 0, sizeof(*next_desc)); - sg_set_page(next_desc, page, len_in_page, - offset); - builder->cur_desc++; - } - data += len_in_page; - len -= len_in_page; - prev_pfn = cur_pfn; - } - } else { - /* - * As a last resort, copy into the shadow buffer and reference - * it with a single SG entry. Calling - * `scatterlist_builder_retrieve_data` will be necessary to copy - * the data written by the device back into @data. - */ - void *shadow_buffer = - builder->shadow_buffer + builder->shadow_buffer_pos; - struct page *page = virt_to_page(shadow_buffer); - unsigned long offset = - (((unsigned long)shadow_buffer) & ~PAGE_MASK); - struct scatterlist *next_desc = - &builder->descs[builder->cur_desc]; - - if (len > - builder->shadow_buffer_size - builder->shadow_buffer_pos) - return -ENOSPC; - - memcpy(shadow_buffer, data, len); - memset(next_desc, 0, sizeof(*next_desc)); - sg_set_page(next_desc, page, len, offset); - builder->cur_desc++; - builder->shadow_buffer_pos += len; - } - - sg_mark_end(&builder->descs[builder->cur_desc - 1]); - return scatterlist_builder_add_descriptor(builder, cur_desc); -} - -/** - * scatterlist_builder_retrieve_data() - Retrieve a response written by the - * device on the shadow buffer. - * @builder: builder to use. - * @sg_index: index of the descriptor to read from. - * @data: destination for the shadowed data. - * - * If the shadow buffer is pointed to by the descriptor at index @sg_index of - * the chain, then ``sg->length`` bytes are copied back from it into @data. - * Otherwise nothing is done since the device has written into @data directly. - * - * @data must have originally been added by ``scatterlist_builder_add_data`` as - * the same size as passed to ``scatterlist_builder_add_data`` will be copied - * back. - */ -int scatterlist_builder_retrieve_data(struct scatterlist_builder *builder, - size_t sg_index, void *data) -{ - void *shadow_buf = builder->shadow_buffer; - struct scatterlist *sg; - void *kaddr; - - /* We can only retrieve from the range of sgs currently set. */ - if (sg_index >= builder->cur_sg) - return -ERANGE; - - sg = builder->sgs[sg_index]; - kaddr = pfn_to_kaddr(page_to_pfn(sg_page(sg))) + sg->offset; - - if (kaddr >= shadow_buf && - kaddr < shadow_buf + VIRTIO_SHADOW_BUF_SIZE) { - if (kaddr + sg->length >= shadow_buf + VIRTIO_SHADOW_BUF_SIZE) - return -EINVAL; - - memcpy(data, kaddr, sg->length); - } - - return 0; -} - -/** - * scatterlist_builder_add_ioctl_cmd() - Add an ioctl command to the descriptor - * chain. - * @builder: builder to use. - * @session: session on behalf of which the ioctl command is added. - * @ioctl_code: code of the ioctl to add (i.e. ``VIDIOC_*``). - */ -int scatterlist_builder_add_ioctl_cmd(struct scatterlist_builder *builder, - struct virtio_media_session *session, - u32 ioctl_code) -{ - struct virtio_media_cmd_ioctl *cmd_ioctl = &session->cmd.ioctl; - - cmd_ioctl->hdr.cmd = VIRTIO_MEDIA_CMD_IOCTL; - cmd_ioctl->session_id = session->id; - cmd_ioctl->code = VIRTIO_MEDIA_IOCTL_CODE(ioctl_code); - - return scatterlist_builder_add_data(builder, cmd_ioctl, - sizeof(*cmd_ioctl)); -} - -/** - * scatterlist_builder_add_ioctl_resp() - Add storage to receive an ioctl - * response to the descriptor chain. - * @builder: builder to use. - * @session: session on behalf of which the ioctl response is added. - */ -int scatterlist_builder_add_ioctl_resp(struct scatterlist_builder *builder, - struct virtio_media_session *session) -{ - struct virtio_media_resp_ioctl *resp_ioctl = &session->resp.ioctl; - - return scatterlist_builder_add_data(builder, resp_ioctl, - sizeof(*resp_ioctl)); -} - -/** - * __scatterlist_builder_add_userptr() - Add user pages to @builder. - * @builder: builder to use. - * @userptr: pointer to userspace memory that we want to add. - * @length: length of the data to add. - * @sg_list: output parameter. Upon success, points to the area of the shadow - * buffer containing the array of SG entries to be added to the descriptor - * chain. - * @nents: output parameter. Upon success, contains the number of entries - * pointed to by @sg_list. - * - * Data referenced by userspace pointers can be potentially large and very - * scattered, which could overwhelm the descriptor chain if added as-is. For - * these, we instead build an array of ``struct virtio_media_sg_entry`` in the - * shadow buffer and reference it using a single descriptor. - * - * This function is a helper to perform that. Callers should then add the - * descriptor to the chain properly. - * - * Returns -EFAULT if @userptr is not a valid user address, which is a case the - * driver should consider as "normal" operation. All other failures signal a - * problem with the driver. - */ -static int -__scatterlist_builder_add_userptr(struct scatterlist_builder *builder, - unsigned long userptr, unsigned long length, - struct virtio_media_sg_entry **sg_list, - int *nents) -{ - struct sg_table sg_table = {}; - struct frame_vector *framevec; - struct scatterlist *sg_iter; - struct page **pages; - const unsigned int offset = userptr & ~PAGE_MASK; - unsigned int pages_count; - size_t entries_size; - int i; - int ret; - - framevec = vb2_create_framevec(userptr, length, true); - if (IS_ERR(framevec)) { - if (PTR_ERR(framevec) != -EFAULT) { - pr_warn("error %ld creating frame vector for userptr 0x%lx, length 0x%lx\n", - PTR_ERR(framevec), userptr, length); - } else { - /* -EINVAL is expected in case of invalid userptr. */ - framevec = ERR_PTR(-EINVAL); - } - return PTR_ERR(framevec); - } - - pages = frame_vector_pages(framevec); - if (IS_ERR(pages)) { - pr_warn("error getting vector pages\n"); - ret = PTR_ERR(pages); - goto done; - } - pages_count = frame_vector_count(framevec); - ret = sg_alloc_table_from_pages(&sg_table, pages, pages_count, offset, - length, 0); - if (ret) { - pr_warn("error creating sg table\n"); - goto done; - } - - /* Allocate our actual SG in the shadow buffer. */ - *nents = sg_nents(sg_table.sgl); - entries_size = sizeof(**sg_list) * *nents; - if (builder->shadow_buffer_pos + entries_size > - builder->shadow_buffer_size) { - ret = -ENOMEM; - goto free_sg; - } - - *sg_list = builder->shadow_buffer + builder->shadow_buffer_pos; - builder->shadow_buffer_pos += entries_size; - - for_each_sgtable_sg(&sg_table, sg_iter, i) { - struct virtio_media_sg_entry *sg_entry = &(*sg_list)[i]; - - sg_entry->start = sg_phys(sg_iter); - sg_entry->len = sg_iter->length; - } - -free_sg: - sg_free_table(&sg_table); - -done: - vb2_destroy_framevec(framevec); - return ret; -} - -/** - * scatterlist_builder_add_userptr() - Add a user-memory buffer using an array - * of ``struct virtio_media_sg_entry``. - * @builder: builder to use. - * @userptr: pointer to userspace memory that we want to add. - * @length: length of the data to add. - * - * Upon success, an array of ``struct virtio_media_sg_entry`` referencing - * @userptr has been built into the shadow buffer, and that array added to the - * descriptor chain. - */ -static int scatterlist_builder_add_userptr(struct scatterlist_builder *builder, - unsigned long userptr, - unsigned long length) -{ - int ret; - int nents; - struct virtio_media_sg_entry *sg_list; - - ret = __scatterlist_builder_add_userptr(builder, userptr, length, - &sg_list, &nents); - if (ret) - return ret; - - ret = scatterlist_builder_add_data(builder, sg_list, - sizeof(*sg_list) * nents); - if (ret) - return ret; - - return 0; -} - -/** - * scatterlist_builder_add_buffer() - Add a ``v4l2_buffer`` and its planes to - * the descriptor chain. - * @builder: builder to use. - * @b: ``v4l2_buffer`` to add. - */ -int scatterlist_builder_add_buffer(struct scatterlist_builder *builder, - struct v4l2_buffer *b) -{ - int i; - int ret; - - /* Fixup: plane length must be zero if userptr is NULL */ - if (!V4L2_TYPE_IS_MULTIPLANAR(b->type) && - b->memory == V4L2_MEMORY_USERPTR && b->m.userptr == 0) - b->length = 0; - - /* v4l2_buffer */ - ret = scatterlist_builder_add_data(builder, b, sizeof(*b)); - if (ret) - return ret; - - if (V4L2_TYPE_IS_MULTIPLANAR(b->type) && b->length > 0) { - /* Fixup: plane length must be zero if userptr is NULL */ - if (b->memory == V4L2_MEMORY_USERPTR) { - for (i = 0; i < b->length; i++) { - struct v4l2_plane *plane = &b->m.planes[i]; - - if (plane->m.userptr == 0) - plane->length = 0; - } - } - - /* Array of v4l2_planes */ - ret = scatterlist_builder_add_data(builder, b->m.planes, - sizeof(struct v4l2_plane) * - b->length); - if (ret) - return ret; - } - - return 0; -} - -/** - * scatterlist_builder_add_buffer_userptr() - Add the payload of a ``USERTPR`` - * v4l2_buffer to the descriptor chain. - * @builder: builder to use. - * @b: ``v4l2_buffer`` which ``USERPTR`` payload we want to add. - * - * Add an array of ``virtio_media_sg_entry`` pointing to a ``USERPTR`` buffer's - * contents. Does nothing if the buffer is not of type ``USERPTR``. This is - * split out of :ref:`scatterlist_builder_add_buffer` because we only want to - * add these to the device-readable part of the descriptor chain. - */ -int scatterlist_builder_add_buffer_userptr(struct scatterlist_builder *builder, - struct v4l2_buffer *b) -{ - int i; - int ret; - - if (b->memory != V4L2_MEMORY_USERPTR) - return 0; - - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { - for (i = 0; i < b->length; i++) { - struct v4l2_plane *plane = &b->m.planes[i]; - - if (b->memory == V4L2_MEMORY_USERPTR && - plane->length > 0) { - ret = scatterlist_builder_add_userptr( - builder, plane->m.userptr, - plane->length); - if (ret) - return ret; - } - } - } else if (b->length > 0) { - ret = scatterlist_builder_add_userptr(builder, b->m.userptr, - b->length); - if (ret) - return ret; - } - - return 0; -} - -/** - * scatterlist_builder_retrieve_buffer() - Retrieve a v4l2_buffer written by - * the device on the shadow buffer, if needed. - * @builder: builder to use. - * @sg_index: index of the first SG entry of the buffer in the builder's - * descriptor chain. - * @b: v4l2_buffer to copy shadow buffer data into. - * @orig_planes: the original ``planes`` pointer, to be restored if the buffer - * is multi-planar. - * - * If the v4l2_buffer pointed by @buffer_sgs was copied into the shadow buffer, - * then its updated content is copied back into @b. Otherwise nothing is done - * as the device has written into @b directly. - * - * @orig_planes is used to restore the original ``planes`` pointer in case it - * gets modified by the host. The specification stipulates that the host should - * not modify it, but we enforce this for additional safety. - */ -int scatterlist_builder_retrieve_buffer(struct scatterlist_builder *builder, - size_t sg_index, struct v4l2_buffer *b, - struct v4l2_plane *orig_planes) -{ - int ret; - - ret = scatterlist_builder_retrieve_data(builder, sg_index++, b); - if (ret) - return ret; - - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { - b->m.planes = orig_planes; - - if (orig_planes != NULL) { - ret = scatterlist_builder_retrieve_data( - builder, sg_index++, b->m.planes); - if (ret) - return ret; - } - } - - return 0; -} - -/** - * scatterlist_builder_add_ext_ctrls() - Add a v4l2_ext_controls and its - * controls to @builder. - * @builder: builder to use. - * @ctrls: ``struct v4l2_ext_controls`` to add. - * - * Add @ctrls and its array of `struct v4l2_ext_control` to the descriptor chain. - */ -int scatterlist_builder_add_ext_ctrls(struct scatterlist_builder *builder, - struct v4l2_ext_controls *ctrls) -{ - int ret; - - /* v4l2_ext_controls */ - ret = scatterlist_builder_add_data(builder, ctrls, sizeof(*ctrls)); - if (ret) - return ret; - - if (ctrls->count > 0) { - /* array of v4l2_controls */ - ret = scatterlist_builder_add_data(builder, ctrls->controls, - sizeof(ctrls->controls[0]) * - ctrls->count); - if (ret) - return ret; - } - - return 0; -} - -/** - * scatterlist_builder_add_ext_ctrls_userptrs() - Add the userspace payloads of - * a ``struct v4l2_ext_controls`` to the descriptor chain. - * @builder: builder to use. - * @ctrls: ``struct v4l2_ext_controls`` from which we want to add the userspace payload of. - * - * Add the userspace payloads of @ctrls to the descriptor chain. This is split - * out of :ref:`scatterlist_builder_add_ext_ctrls` because we only want to add - * these to the device-readable part of the descriptor chain. - */ -int scatterlist_builder_add_ext_ctrls_userptrs( - struct scatterlist_builder *builder, struct v4l2_ext_controls *ctrls) -{ - int i; - int ret; - - /* Pointers to user memory in individual controls */ - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = &ctrls->controls[i]; - - if (ctrl->size > 0) { - ret = scatterlist_builder_add_userptr( - builder, (unsigned long)ctrl->ptr, ctrl->size); - if (ret) - return ret; - } - } - - return 0; -} - -/** - * scatterlist_builder_retrieve_ext_ctrls() - Retrieve controls written by the - * device on the shadow buffer, if needed. - * @builder: builder to use. - * @sg_index: index of the first SG entry of the controls in the builder's - * descriptor chain. - * @ctrls: ``struct v4l2_ext_controls`` to copy shadow buffer data into. - * - * If the shadow buffer is pointed to by @sg, copy its content back into @ctrls. - */ -int scatterlist_builder_retrieve_ext_ctrls(struct scatterlist_builder *builder, - size_t sg_index, - struct v4l2_ext_controls *ctrls) -{ - struct v4l2_ext_control *controls_backup = ctrls->controls; - int ret; - - ret = scatterlist_builder_retrieve_data(builder, sg_index++, ctrls); - if (ret) - return ret; - - ctrls->controls = controls_backup; - - if (ctrls->count > 0 && ctrls->controls) { - ret = scatterlist_builder_retrieve_data(builder, sg_index++, - ctrls->controls); - if (ret) - return ret; - } - - return 0; -} diff --git a/drivers/media/virtio/scatterlist_builder.h b/drivers/media/virtio/scatterlist_builder.h deleted file mode 100644 index c8323c31ac21..000000000000 --- a/drivers/media/virtio/scatterlist_builder.h +++ /dev/null @@ -1,111 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ */ - -/* - * Scatterlist builder helpers for virtio-media. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#ifndef __VIRTIO_MEDIA_SCATTERLIST_BUILDER_H -#define __VIRTIO_MEDIA_SCATTERLIST_BUILDER_H - -#include <linux/scatterlist.h> - -#include "session.h" - -/** - * struct scatterlist_builder - helper to build a scatterlist from data. - * @descs: pool of descriptors to use. - * @num_descs: number of entries in descs. - * @cur_desc: next descriptor to be used in @descs. - * @shadow_buffer: pointer to a shadow buffer where elements that cannot be - * mapped directly into the scatterlist get copied. - * @shadow_buffer_size: size of @shadow_buffer. - * @shadow_buffer_pos: current position in @shadow_buffer. - * @sgs: descriptor chain to eventually pass to virtio functions. - * @num_sgs: total number of entries in @sgs. - * @cur_sg: next entry in @sgs to be used. - * - * Virtio passes data from the driver to the device (through e.g. - * ``virtqueue_add_sgs``) via a scatterlist that the device interprets as a - * linear view over scattered driver memory. - * - * In virtio-media, the payload of ioctls from user-space can for the most part - * be passed as-is, or after slight modification, which makes it tempting to - * just forward the ioctl payload received from user-space as-is instead of - * doing another copy into a dedicated buffer. This structure helps with this. - * - * virtio-media descriptor chains are typically made of the following parts: - * - * Device-readable: - * - A command structure, i.e. ``virtio_media_cmd_*``, - * - An ioctl payload (one of the regular ioctl parameters), - * - (optionally) arrays of ``virtio_media_sg_entry`` describing the content of - * buffers in guest memory. - * - * Device-writable: - * - A response structure, i.e. ``virtio_media_resp_*``, - * - An ioctl payload, that the device will write to. - * - * This structure helps laying out the descriptor chain into its @sgs member in - * an optimal way, by building a scatterlist adapted to the originating memory - * of the data we want to pass to the device while avoiding copies when - * possible. - * - * It is made of a pool of ``struct scatterlist`` (@descs) that is used to - * build the final descriptor chain @sgs, and a @shadow_buffer where data that - * cannot (or should not) be mapped directly by the host can be temporarily - * copied. - */ -struct scatterlist_builder { - struct scatterlist *descs; - size_t num_descs; - size_t cur_desc; - - void *shadow_buffer; - size_t shadow_buffer_size; - size_t shadow_buffer_pos; - - struct scatterlist **sgs; - size_t num_sgs; - size_t cur_sg; -}; - -int scatterlist_builder_add_descriptor(struct scatterlist_builder *builder, - size_t desc_index); - -int scatterlist_builder_add_data(struct scatterlist_builder *builder, - void *data, size_t len); - -int scatterlist_builder_retrieve_data(struct scatterlist_builder *builder, - size_t sg_index, void *data); - -int scatterlist_builder_add_ioctl_cmd(struct scatterlist_builder *builder, - struct virtio_media_session *session, - u32 ioctl_code); - -int scatterlist_builder_add_ioctl_resp(struct scatterlist_builder *builder, - struct virtio_media_session *session); - -int scatterlist_builder_add_buffer(struct scatterlist_builder *builder, - struct v4l2_buffer *buffer); - -int scatterlist_builder_add_buffer_userptr(struct scatterlist_builder *builder, - struct v4l2_buffer *b); - -int scatterlist_builder_retrieve_buffer(struct scatterlist_builder *builder, - size_t sg_index, - struct v4l2_buffer *buffer, - struct v4l2_plane *orig_planes); - -int scatterlist_builder_add_ext_ctrls(struct scatterlist_builder *builder, - struct v4l2_ext_controls *ctrls); - -int scatterlist_builder_add_ext_ctrls_userptrs( - struct scatterlist_builder *builder, struct v4l2_ext_controls *ctrls); - -int scatterlist_builder_retrieve_ext_ctrls(struct scatterlist_builder *builder, - size_t sg_index, - struct v4l2_ext_controls *ctrls); - -#endif // __VIRTIO_MEDIA_SCATTERLIST_BUILDER_H diff --git a/drivers/media/virtio/session.h b/drivers/media/virtio/session.h deleted file mode 100644 index b643d0d95047..000000000000 --- a/drivers/media/virtio/session.h +++ /dev/null @@ -1,109 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ */ - -/* - * Definitions of virtio-media session related structures. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#ifndef __VIRTIO_MEDIA_SESSION_H -#define __VIRTIO_MEDIA_SESSION_H - -#include <linux/scatterlist.h> -#include <media/v4l2-fh.h> - -#include "protocol.h" - -#define VIRTIO_MEDIA_LAST_QUEUE (V4L2_BUF_TYPE_META_OUTPUT) - -/* - * Size of the per-session virtio shadow and event buffers. 16K should be - * enough to contain everything we need. - */ -#define VIRTIO_SHADOW_BUF_SIZE 0x4000 - -/** - * struct virtio_media_buffer - Current state of a buffer. - * @buffer: ``struct v4l2_buffer`` with current information about the buffer. - * @planes: backing planes array for @buffer. - * @list: link into the list of buffers pending dequeue. - */ -struct virtio_media_buffer { - struct v4l2_buffer buffer; - struct v4l2_plane planes[VIDEO_MAX_PLANES]; - struct list_head list; -}; - -/** - * struct virtio_media_queue_state - Represents the state of a V4L2 queue. - * @streaming: Whether the queue is currently streaming. - * @allocated_bufs: How many buffers are currently allocated. - * @is_capture_last: set to true when the last buffer has been received on a - * capture queue, so we can return -EPIPE on subsequent DQBUF requests. - * @buffers: Buffer state array of size @allocated_bufs. - * @queued_bufs: How many buffers are currently queued on the device. - * @pending_dqbufs: Buffers that are available for being dequeued. - */ -struct virtio_media_queue_state { - bool streaming; - size_t allocated_bufs; - bool is_capture_last; - - struct virtio_media_buffer *buffers; - size_t queued_bufs; - struct list_head pending_dqbufs; -}; - -/** - * struct virtio_media_session - A session on a virtio_media device. - * @fh: file handler for the session. - * @id: session ID used to communicate with the device. - * @nonblocking_dequeue: whether dequeue should block or not (nonblocking if - * file opened with O_NONBLOCK). - * @uses_mplane: whether the queues for this session use the MPLANE API or not. - * @cmd: union of session-related commands. A session can have one command currently running. - * @resp: union of session-related responses. A session can wait on one command only. - * @shadow_buf: shadow buffer where data to be added to the descriptor chain can - * be staged before being sent to the device. - * @command_sgs: SG table gathering descriptors for a given command and its response. - * @queues: state of all the queues for this session. - * @queues_lock: protects all members fo the queues for this session. - * virtio_media_queue_state`. - * @dqbuf_wait: waitqueue for dequeued buffers, if ``VIDIOC_DQBUF`` needs to - * block or when polling. - * @list: link into the list of sessions for the device. - */ -struct virtio_media_session { - struct v4l2_fh fh; - u32 id; - bool nonblocking_dequeue; - bool uses_mplane; - - union { - struct virtio_media_cmd_close close; - struct virtio_media_cmd_ioctl ioctl; - struct virtio_media_cmd_mmap mmap; - } cmd; - - union { - struct virtio_media_resp_ioctl ioctl; - struct virtio_media_resp_mmap mmap; - } resp; - - void *shadow_buf; - - struct sg_table command_sgs; - - struct virtio_media_queue_state queues[VIRTIO_MEDIA_LAST_QUEUE + 1]; - struct mutex queues_lock; - wait_queue_head_t dqbuf_wait; - - struct list_head list; -}; - -static inline struct virtio_media_session *fh_to_session(struct v4l2_fh *fh) -{ - return container_of(fh, struct virtio_media_session, fh); -} - -#endif // __VIRTIO_MEDIA_SESSION_H diff --git a/drivers/media/virtio/virtio_media.h b/drivers/media/virtio/virtio_media.h deleted file mode 100644 index 0aa503defdd6..000000000000 --- a/drivers/media/virtio/virtio_media.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ */ - -/* - * Virtio-media structures & functions declarations. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#ifndef __VIRTIO_MEDIA_H -#define __VIRTIO_MEDIA_H - -#include <linux/virtio_config.h> -#include <media/v4l2-device.h> - -#include "protocol.h" - -#define DESC_CHAIN_MAX_LEN SG_MAX_SINGLE_ALLOC - -#define VIRTIO_MEDIA_DEFAULT_DRIVER_NAME "virtio-media" - -extern char *virtio_media_driver_name; -extern bool virtio_media_allow_userptr; - -/** - * struct virtio_media - Virtio-media device. - * @v4l2_dev: v4l2_device for the media device. - * @video_dev: video_device for the media device. - * @virtio_dev: virtio device for the media device. - * @commandq: virtio command queue. - * @eventq: virtio event queue. - * @eventq_work: work to run when events are received on @eventq. - * @mmap_region: region into which MMAP buffers are mapped by the host. - * @event_buffer: buffer for event descriptors. - * @sessions: list of active sessions on the device. - * @sessions_lock: protects @sessions and ``virtio_media_session::list``. - * @events_lock: prevents concurrent processing of events. - * @cmd: union of device-related commands. - * @resp: union of device-related responses. - * @vlock: serializes access to the command queue. - * @wq: waitqueue for host responses on the command queue. - */ -struct virtio_media { - struct v4l2_device v4l2_dev; - struct video_device video_dev; - - struct virtio_device *virtio_dev; - struct virtqueue *commandq; - struct virtqueue *eventq; - struct work_struct eventq_work; - - struct virtio_shm_region mmap_region; - - void *event_buffer; - - struct list_head sessions; - struct mutex sessions_lock; - - struct mutex events_lock; - - union { - struct virtio_media_cmd_open open; - struct virtio_media_cmd_munmap munmap; - } cmd; - - union { - struct virtio_media_resp_open open; - struct virtio_media_resp_munmap munmap; - } resp; - - struct mutex vlock; - wait_queue_head_t wq; -}; - -static inline struct virtio_media * -to_virtio_media(struct video_device *video_dev) -{ - return container_of(video_dev, struct virtio_media, video_dev); -} - -/* virtio_media_driver.c */ - -int virtio_media_send_command(struct virtio_media *vv, struct scatterlist **sgs, - const size_t out_sgs, const size_t in_sgs, - size_t minimum_resp_len, size_t *resp_len); -void virtio_media_process_events(struct virtio_media *vv); - -/* virtio_media_ioctls.c */ - -long virtio_media_device_ioctl(struct file *file, unsigned int cmd, - unsigned long arg); -extern const struct v4l2_ioctl_ops virtio_media_ioctl_ops; - -#endif // __VIRTIO_MEDIA_H diff --git a/drivers/media/virtio/virtio_media_driver.c b/drivers/media/virtio/virtio_media_driver.c deleted file mode 100644 index e8d6dc453f22..000000000000 --- a/drivers/media/virtio/virtio_media_driver.c +++ /dev/null @@ -1,959 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ - -/* - * Virtio-media driver. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/dev_printk.h> -#include <linux/mm.h> -#include <linux/mutex.h> -#include <linux/scatterlist.h> -#include <linux/types.h> -#include <linux/videodev2.h> -#include <linux/vmalloc.h> -#include <linux/wait.h> -#include <linux/workqueue.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/virtio.h> -#include <linux/virtio_config.h> -#include <linux/virtio_ids.h> - -#include <media/frame_vector.h> -#include <media/v4l2-dev.h> -#include <media/v4l2-event.h> -#include <media/videobuf2-memops.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ioctl.h> - -#include "protocol.h" -#include "session.h" -#include "virtio_media.h" - -#define VIRTIO_MEDIA_NUM_EVENT_BUFS 16 - -/* ID of the SHM region into which MMAP buffer will be mapped. */ -#define VIRTIO_MEDIA_SHM_MMAP 0 - -/* - * Name of the driver to expose to user-space. - * - * This is configurable because v4l2-compliance has workarounds specific to - * some drivers. When proxying these directly from the host, this allows it to - * apply them as needed. - */ -char *virtio_media_driver_name; -module_param_named(driver_name, virtio_media_driver_name, charp, 0660); - -/* - * Whether USERPTR buffers are allowed. - * - * This is disabled by default as USERPTR buffers are dangerous, but the option - * is left to enable them if desired. - */ -bool virtio_media_allow_userptr; -module_param_named(allow_userptr, virtio_media_allow_userptr, bool, 0660); - -/** - * virtio_media_session_alloc - Allocate a new session. - * @vv: virtio-media device the session belongs to. - * @id: ID of the session. - * @nonblocking_dequeue: whether dequeuing of buffers should be blocking or - * not. - * - * The ``id`` and ``list`` fields must still be set by the caller. - */ -static struct virtio_media_session * -virtio_media_session_alloc(struct virtio_media *vv, u32 id, - bool nonblocking_dequeue) -{ - struct virtio_media_session *session; - int i; - int ret; - - session = kzalloc(sizeof(*session), GFP_KERNEL); - if (!session) - goto err_session; - - session->shadow_buf = kzalloc(VIRTIO_SHADOW_BUF_SIZE, GFP_KERNEL); - if (!session->shadow_buf) - goto err_shadow_buf; - - ret = sg_alloc_table(&session->command_sgs, DESC_CHAIN_MAX_LEN, - GFP_KERNEL); - if (ret) - goto err_payload_sgs; - - session->id = id; - session->nonblocking_dequeue = nonblocking_dequeue; - - INIT_LIST_HEAD(&session->list); - v4l2_fh_init(&session->fh, &vv->video_dev); - v4l2_fh_add(&session->fh); - - for (i = 0; i <= VIRTIO_MEDIA_LAST_QUEUE; i++) - INIT_LIST_HEAD(&session->queues[i].pending_dqbufs); - mutex_init(&session->queues_lock); - - init_waitqueue_head(&session->dqbuf_wait); - - mutex_lock(&vv->sessions_lock); - list_add_tail(&session->list, &vv->sessions); - mutex_unlock(&vv->sessions_lock); - - return session; - -err_payload_sgs: - kfree(session->shadow_buf); -err_shadow_buf: - kfree(session); -err_session: - return ERR_PTR(-ENOMEM); -} - -/** - * virtio_media_session_free - Free all resources of a session. - * @vv: virtio-media device the session belongs to. - * @session: session to destroy. - * - * All the resources of @sesssion, as well as the backing memory of @session - * itself, are freed. - */ -static void virtio_media_session_free(struct virtio_media *vv, - struct virtio_media_session *session) -{ - int i; - - mutex_lock(&vv->sessions_lock); - list_del(&session->list); - mutex_unlock(&vv->sessions_lock); - - v4l2_fh_del(&session->fh); - v4l2_fh_exit(&session->fh); - - sg_free_table(&session->command_sgs); - - for (i = 0; i <= VIRTIO_MEDIA_LAST_QUEUE; i++) - vfree(session->queues[i].buffers); - - kfree(session->shadow_buf); - kfree(session); -} - -/** - * virtio_media_session_close - Close and free a session. - * @vv: virtio-media device the session belongs to. - * @session: session to close and destroy. - * - * This send the ``VIRTIO_MEDIA_CMD_CLOSE`` command to the device, and frees - * all resources used by @session. - */ -static int virtio_media_session_close(struct virtio_media *vv, - struct virtio_media_session *session) -{ - struct virtio_media_cmd_close *cmd_close = &session->cmd.close; - struct scatterlist cmd_sg = {}; - struct scatterlist *sgs[1] = { &cmd_sg }; - int ret; - - mutex_lock(&vv->vlock); - - cmd_close->hdr.cmd = VIRTIO_MEDIA_CMD_CLOSE; - cmd_close->session_id = session->id; - - sg_set_buf(&cmd_sg, cmd_close, sizeof(*cmd_close)); - sg_mark_end(&cmd_sg); - - ret = virtio_media_send_command(vv, sgs, 1, 0, 0, NULL); - mutex_unlock(&vv->vlock); - if (ret < 0) - return ret; - - virtio_media_session_free(vv, session); - - return 0; -} - -/** - * virtio_media_find_session - Lookup for the session with a given ID. - * @vv: virtio-media device to lookup the session from. - * @id: ID of the session to lookup. - */ -static struct virtio_media_session * -virtio_media_find_session(struct virtio_media *vv, u32 id) -{ - struct list_head *p; - struct virtio_media_session *session = NULL; - - mutex_lock(&vv->sessions_lock); - list_for_each(p, &vv->sessions) { - struct virtio_media_session *s = - list_entry(p, struct virtio_media_session, list); - if (s->id == id) { - session = s; - break; - } - } - mutex_unlock(&vv->sessions_lock); - - return session; -} - -/** - * struct virtio_media_cmd_callback_param - Callback parameters to the virtio command queue. - * @vv: virtio-media device in use. - * @done: flag to be switched once the command is completed. - * @resp_len: length of the received response from the command. Only valid - * after @done_flag has switched to ``true``. - */ -struct virtio_media_cmd_callback_param { - struct virtio_media *vv; - bool done; - size_t resp_len; -}; - -/** - * commandq_callback: Callback for the command queue. - * @queue: command virtqueue. - * - * This just wakes up the thread that was waiting on the command to complete. - */ -static void commandq_callback(struct virtqueue *queue) -{ - unsigned int len; - struct virtio_media_cmd_callback_param *param; - -process_bufs: - while ((param = virtqueue_get_buf(queue, &len))) { - param->done = true; - param->resp_len = len; - wake_up(¶m->vv->wq); - } - - if (!virtqueue_enable_cb(queue)) { - virtqueue_disable_cb(queue); - goto process_bufs; - } -} - -/** - * virtio_media_kick_command - send a command to the commandq. - * @vv: virtio-media device in use. - * @sgs: descriptor chain to send. - * @out_sgs: number of device-readable descriptors in @sgs. - * @in_sgs: number of device-writable descriptors in @sgs. - * @resp_len: output parameter. Upon success, contains the size of the response - * in bytes. - * - */ -static int virtio_media_kick_command(struct virtio_media *vv, - struct scatterlist **sgs, - const size_t out_sgs, const size_t in_sgs, - size_t *resp_len) -{ - struct virtio_media_cmd_callback_param cb_param = { - .vv = vv, - .done = false, - .resp_len = 0, - }; - struct virtio_media_resp_header *resp_header; - int ret; - - ret = virtqueue_add_sgs(vv->commandq, sgs, out_sgs, in_sgs, &cb_param, - GFP_ATOMIC); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to add sgs to command virtqueue\n"); - return ret; - } - - if (!virtqueue_kick(vv->commandq)) { - v4l2_err(&vv->v4l2_dev, "failed to kick command virtqueue\n"); - return -EINVAL; - } - - /* Wait for the response. */ - ret = wait_event_timeout(vv->wq, cb_param.done, 5 * HZ); - if (ret == 0) { - v4l2_err(&vv->v4l2_dev, - "timed out waiting for response to command\n"); - return -ETIMEDOUT; - } - - if (resp_len) - *resp_len = cb_param.resp_len; - - if (in_sgs > 0) { - /* - * If we expect a response, make sure we have at least a - * response header - anything shorter is invalid. - */ - if (cb_param.resp_len < sizeof(*resp_header)) { - v4l2_err(&vv->v4l2_dev, - "received response header is too short\n"); - return -EINVAL; - } - - resp_header = sg_virt(sgs[out_sgs]); - if (resp_header->status) - /* Host returns a positive error code. */ - return -resp_header->status; - } - - return 0; -} - -/** - * virtio_media_send_command - Send a command to the device and wait for its - * response. - * @vv: virtio-media device in use. - * @sgs: descriptor chain to send. - * @out_sgs: number of device-readable descriptors in @sgs. - * @in_sgs: number of device-writable descriptors in @sgs. - * @minimum_resp_len: minimum length of the response expected by the caller - * when the command is successful. Anything shorter than that will result in - * ``-EINVAL`` being returned. - * @resp_len: output parameter. Upon success, contains the size of the response - * in bytes. - */ -int virtio_media_send_command(struct virtio_media *vv, struct scatterlist **sgs, - const size_t out_sgs, const size_t in_sgs, - size_t minimum_resp_len, size_t *resp_len) -{ - size_t local_resp_len = resp_len ? *resp_len : 0; - int ret = virtio_media_kick_command(vv, sgs, out_sgs, in_sgs, - &local_resp_len); - if (resp_len) - *resp_len = local_resp_len; - - /* If the host could not process the command, there is no valid response */ - if (ret < 0) - return ret; - - /* Make sure the host wrote a complete reply. */ - if (local_resp_len < minimum_resp_len) { - v4l2_err( - &vv->v4l2_dev, - "received response is too short: received %zu, expected at least %zu\n", - local_resp_len, minimum_resp_len); - return -EINVAL; - } - - return 0; -} - -/** - * virtio_media_send_event_buffer() - Sends an event buffer to the host so it - * can return it with an event. - * @vv: virtio-media device in use. - * @event_buffer: pointer to the event buffer to send to the device. - */ -static int virtio_media_send_event_buffer(struct virtio_media *vv, - void *event_buffer) -{ - struct scatterlist *sgs[1], vresp; - int ret; - - sg_init_one(&vresp, event_buffer, VIRTIO_MEDIA_EVENT_MAX_SIZE); - sgs[0] = &vresp; - - ret = virtqueue_add_sgs(vv->eventq, sgs, 0, 1, event_buffer, - GFP_ATOMIC); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to add sgs to event virtqueue\n"); - return ret; - } - - if (!virtqueue_kick(vv->eventq)) { - v4l2_err(&vv->v4l2_dev, "failed to kick event virtqueue\n"); - return -EINVAL; - } - - return 0; -} - -/** - * eventq_callback() - Callback for the event queue. - * @queue: event virtqueue. - * - * This just schedules for event work to be run. - */ -static void eventq_callback(struct virtqueue *queue) -{ - struct virtio_media *vv = queue->vdev->priv; - - schedule_work(&vv->eventq_work); -} - -/** - * virtio_media_process_dqbuf_event() - Process a dequeued event for a session. - * @vv: virtio-media device in use. - * @session: session the event is addressed to. - * @dqbuf_evt: the dequeued event to process. - * - * Invalid events are ignored with an error log. - */ -static void -virtio_media_process_dqbuf_event(struct virtio_media *vv, - struct virtio_media_session *session, - struct virtio_media_event_dqbuf *dqbuf_evt) -{ - struct virtio_media_buffer *dqbuf; - const enum v4l2_buf_type queue_type = dqbuf_evt->buffer.type; - struct virtio_media_queue_state *queue; - typeof(dqbuf->buffer.m) buffer_m; - typeof(dqbuf->buffer.m.planes[0].m) plane_m; - int i; - - if (queue_type >= ARRAY_SIZE(session->queues)) { - v4l2_err(&vv->v4l2_dev, - "unmanaged queue %d passed to dqbuf event", - dqbuf_evt->buffer.type); - return; - } - queue = &session->queues[queue_type]; - - if (dqbuf_evt->buffer.index >= queue->allocated_bufs) { - v4l2_err(&vv->v4l2_dev, - "invalid buffer ID %d for queue %d in dqbuf event", - dqbuf_evt->buffer.index, dqbuf_evt->buffer.type); - return; - } - - dqbuf = &queue->buffers[dqbuf_evt->buffer.index]; - - /* - * Preserve the 'm' union that was passed to us during QBUF so userspace - * gets back the information it submitted. - */ - buffer_m = dqbuf->buffer.m; - memcpy(&dqbuf->buffer, &dqbuf_evt->buffer, sizeof(dqbuf->buffer)); - dqbuf->buffer.m = buffer_m; - if (V4L2_TYPE_IS_MULTIPLANAR(dqbuf->buffer.type)) { - if (dqbuf->buffer.length > VIDEO_MAX_PLANES) { - v4l2_err( - &vv->v4l2_dev, - "invalid number of planes received from host for a multiplanar buffer\n"); - return; - } - for (i = 0; i < dqbuf->buffer.length; i++) { - plane_m = dqbuf->planes[i].m; - memcpy(&dqbuf->planes[i], &dqbuf_evt->planes[i], - sizeof(struct v4l2_plane)); - dqbuf->planes[i].m = plane_m; - } - } - - /* Set the DONE flag as the buffer is waiting for being dequeued. */ - dqbuf->buffer.flags |= V4L2_BUF_FLAG_DONE; - - mutex_lock(&session->queues_lock); - list_add_tail(&dqbuf->list, &queue->pending_dqbufs); - queue->queued_bufs -= 1; - mutex_unlock(&session->queues_lock); - - wake_up(&session->dqbuf_wait); -} - -/** - * virtio_media_process_events() - Process all pending events on a device. - * @vv: device which pending events we want to process. - * - * Retrieves all pending events on @vv's event queue and dispatch them to their - * corresponding session. - * - * Invalid events are ignored with an error log. - */ -void virtio_media_process_events(struct virtio_media *vv) -{ - struct virtio_media_event_error *error_evt; - struct virtio_media_event_dqbuf *dqbuf_evt; - struct virtio_media_event_event *event_evt; - struct virtio_media_session *session; - struct virtio_media_event_header *evt; - unsigned int len; - - mutex_lock(&vv->events_lock); - -process_bufs: - while ((evt = virtqueue_get_buf(vv->eventq, &len))) { - /* Make sure we received enough data */ - if (len < sizeof(*evt)) { - v4l2_err( - &vv->v4l2_dev, - "event is too short: got %u, expected at least %zu\n", - len, sizeof(*evt)); - goto end_of_event; - } - - session = virtio_media_find_session(vv, evt->session_id); - if (!session) { - v4l2_err(&vv->v4l2_dev, "cannot find session %d\n", - evt->session_id); - goto end_of_event; - } - - switch (evt->event) { - case VIRTIO_MEDIA_EVT_ERROR: - if (len < sizeof(*error_evt)) { - v4l2_err( - &vv->v4l2_dev, - "error event is too short: got %u, expected %zu\n", - len, sizeof(*error_evt)); - break; - } - error_evt = (struct virtio_media_event_error *)evt; - v4l2_err(&vv->v4l2_dev, - "received error %d for session %d", - error_evt->errno, error_evt->hdr.session_id); - virtio_media_session_close(vv, session); - break; - - /* - * Dequeued buffer: put it into the right queue so user-space can dequeue - * it. - */ - case VIRTIO_MEDIA_EVT_DQBUF: - if (len < sizeof(*dqbuf_evt)) { - v4l2_err( - &vv->v4l2_dev, - "dqbuf event is too short: got %u, expected %zu\n", - len, sizeof(*dqbuf_evt)); - break; - } - dqbuf_evt = (struct virtio_media_event_dqbuf *)evt; - virtio_media_process_dqbuf_event(vv, session, - dqbuf_evt); - break; - - case VIRTIO_MEDIA_EVT_EVENT: - if (len < sizeof(*event_evt)) { - v4l2_err( - &vv->v4l2_dev, - "session event is too short: got %u expected %zu\n", - len, sizeof(*event_evt)); - break; - } - - event_evt = (struct virtio_media_event_event *)evt; - v4l2_event_queue_fh(&session->fh, &event_evt->event); - break; - - default: - v4l2_err(&vv->v4l2_dev, "unknown event type %d\n", - evt->event); - break; - } - -end_of_event: - virtio_media_send_event_buffer(vv, evt); - } - - if (!virtqueue_enable_cb(vv->eventq)) { - virtqueue_disable_cb(vv->eventq); - goto process_bufs; - } - - mutex_unlock(&vv->events_lock); -} - -static void virtio_media_event_work(struct work_struct *work) -{ - struct virtio_media *vv = - container_of(work, struct virtio_media, eventq_work); - - virtio_media_process_events(vv); -} - -/** - * virtio_media_device_open() - Create a new session from an opened file. - * @file: opened file for the session. - */ -static int virtio_media_device_open(struct file *file) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_cmd_open *cmd_open = &vv->cmd.open; - struct virtio_media_resp_open *resp_open = &vv->resp.open; - struct scatterlist cmd_sg = {}, resp_sg = {}; - struct scatterlist *sgs[2] = { &cmd_sg, &resp_sg }; - struct virtio_media_session *session; - u32 session_id; - int ret; - - mutex_lock(&vv->vlock); - - sg_set_buf(&cmd_sg, cmd_open, sizeof(*cmd_open)); - sg_mark_end(&cmd_sg); - - sg_set_buf(&resp_sg, resp_open, sizeof(*resp_open)); - sg_mark_end(&resp_sg); - - cmd_open->hdr.cmd = VIRTIO_MEDIA_CMD_OPEN; - ret = virtio_media_send_command(vv, sgs, 1, 1, sizeof(*resp_open), - NULL); - session_id = resp_open->session_id; - mutex_unlock(&vv->vlock); - if (ret < 0) - return ret; - - session = virtio_media_session_alloc(vv, session_id, - (file->f_flags & O_NONBLOCK)); - if (IS_ERR(session)) - return PTR_ERR(session); - - file->private_data = &session->fh; - - return 0; -} - -/** - * virtio_media_device_close() - Close a previously opened session. - * @file: file of the session to close. - * - * This sends to ``VIRTIO_MEDIA_CMD_CLOSE`` command to the device, and close - * the session on the driver side. - */ -static int virtio_media_device_close(struct file *file) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = - fh_to_session(file->private_data); - - return virtio_media_session_close(vv, session); -} - -/** - * virtio_media_device_poll() - Poll logic for a virtio-media device. - * @file: file of the session to poll. - * @wait: poll table to wait on. - */ -static __poll_t virtio_media_device_poll(struct file *file, poll_table *wait) -{ - struct virtio_media_session *session = - fh_to_session(file->private_data); - enum v4l2_buf_type capture_type = - session->uses_mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : - V4L2_BUF_TYPE_VIDEO_CAPTURE; - enum v4l2_buf_type output_type = - session->uses_mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : - V4L2_BUF_TYPE_VIDEO_OUTPUT; - struct virtio_media_queue_state *capture_queue = - &session->queues[capture_type]; - struct virtio_media_queue_state *output_queue = - &session->queues[output_type]; - __poll_t req_events = poll_requested_events(wait); - __poll_t rc = 0; - - poll_wait(file, &session->dqbuf_wait, wait); - poll_wait(file, &session->fh.wait, wait); - - mutex_lock(&session->queues_lock); - if (req_events & (EPOLLIN | EPOLLRDNORM)) { - if (!capture_queue->streaming || - (capture_queue->queued_bufs == 0 && - list_empty(&capture_queue->pending_dqbufs))) - rc |= EPOLLERR; - else if (!list_empty(&capture_queue->pending_dqbufs)) - rc |= EPOLLIN | EPOLLRDNORM; - } - if (req_events & (EPOLLOUT | EPOLLWRNORM)) { - if (!output_queue->streaming) - rc |= EPOLLERR; - else if (output_queue->queued_bufs < - output_queue->allocated_bufs) - rc |= EPOLLOUT | EPOLLWRNORM; - } - mutex_unlock(&session->queues_lock); - - if (v4l2_event_pending(&session->fh)) - rc |= EPOLLPRI; - - return rc; -} - -static void virtio_media_vma_close_locked(struct vm_area_struct *vma) -{ - struct virtio_media *vv = vma->vm_private_data; - struct virtio_media_cmd_munmap *cmd_munmap = &vv->cmd.munmap; - struct virtio_media_resp_munmap *resp_munmap = &vv->resp.munmap; - struct scatterlist cmd_sg = {}, resp_sg = {}; - struct scatterlist *sgs[2] = { &cmd_sg, &resp_sg }; - int ret; - - sg_set_buf(&cmd_sg, cmd_munmap, sizeof(*cmd_munmap)); - sg_mark_end(&cmd_sg); - - sg_set_buf(&resp_sg, resp_munmap, sizeof(*resp_munmap)); - sg_mark_end(&resp_sg); - - cmd_munmap->hdr.cmd = VIRTIO_MEDIA_CMD_MUNMAP; - cmd_munmap->driver_addr = - (vma->vm_pgoff << PAGE_SHIFT) - vv->mmap_region.addr; - ret = virtio_media_send_command(vv, sgs, 1, 1, sizeof(*resp_munmap), - NULL); - if (ret < 0) { - v4l2_err(&vv->v4l2_dev, "host failed to unmap buffer: %d\n", - ret); - } -} - -/** - * virtio_media_vma_close() - Close a MMAP buffer mapping. - * @vma: VMA of the mapping to close. - * - * Inform the host that a previously created MMAP mapping is no longer needed - * and can be removed. - */ -static void virtio_media_vma_close(struct vm_area_struct *vma) -{ - struct virtio_media *vv = vma->vm_private_data; - - mutex_lock(&vv->vlock); - virtio_media_vma_close_locked(vma); - mutex_unlock(&vv->vlock); -} - -static const struct vm_operations_struct virtio_media_vm_ops = { - .close = virtio_media_vma_close, -}; - -/** - * virtio_media_device_mmap - Perform a mmap request from userspace. - * @file: opened file of the session to map for. - * @vma: VM area struct describing the desired mapping. - * - * This requests the host to map a MMAP buffer for us, so we can then make that - * mapping visible into user-space address space. - */ -static int virtio_media_device_mmap(struct file *file, - struct vm_area_struct *vma) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = - fh_to_session(file->private_data); - struct virtio_media_cmd_mmap *cmd_mmap = &session->cmd.mmap; - struct virtio_media_resp_mmap *resp_mmap = &session->resp.mmap; - struct scatterlist cmd_sg = {}, resp_sg = {}; - struct scatterlist *sgs[2] = { &cmd_sg, &resp_sg }; - int ret; - - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - if (!(vma->vm_flags & (VM_READ | VM_WRITE))) - return -EINVAL; - - mutex_lock(&vv->vlock); - - cmd_mmap->hdr.cmd = VIRTIO_MEDIA_CMD_MMAP; - cmd_mmap->session_id = session->id; - cmd_mmap->flags = - (vma->vm_flags & VM_WRITE) ? VIRTIO_MEDIA_MMAP_FLAG_RW : 0; - cmd_mmap->offset = vma->vm_pgoff << PAGE_SHIFT; - - sg_set_buf(&cmd_sg, cmd_mmap, sizeof(*cmd_mmap)); - sg_mark_end(&cmd_sg); - - sg_set_buf(&resp_sg, resp_mmap, sizeof(*resp_mmap)); - sg_mark_end(&resp_sg); - - /* - * The host performs reference counting and is smart enough to return the - * same guest physical address if this is called several times on the same - * buffer. - */ - ret = virtio_media_send_command(vv, sgs, 1, 1, sizeof(*resp_mmap), - NULL); - if (ret < 0) - goto end; - - vma->vm_private_data = vv; - /* - * Keep the guest address at which the buffer is mapped since we will - * use that to unmap. - */ - vma->vm_pgoff = (resp_mmap->driver_addr + vv->mmap_region.addr) >> - PAGE_SHIFT; - - /* - * We cannot let the mapping be larger than the buffer. - */ - if (vma->vm_end - vma->vm_start > PAGE_ALIGN(resp_mmap->len)) { - dev_dbg(&video_dev->dev, - "invalid MMAP, as it would overflow buffer length\n"); - virtio_media_vma_close_locked(vma); - ret = -EINVAL; - goto end; - } - - ret = io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); - if (ret) - goto end; - - vma->vm_ops = &virtio_media_vm_ops; - -end: - mutex_unlock(&vv->vlock); - return ret; -} - -static const struct v4l2_file_operations virtio_media_fops = { - .owner = THIS_MODULE, - .open = virtio_media_device_open, - .release = virtio_media_device_close, - .poll = virtio_media_device_poll, - .unlocked_ioctl = virtio_media_device_ioctl, - .mmap = virtio_media_device_mmap, -}; - -static int virtio_media_probe(struct virtio_device *virtio_dev) -{ - struct device *dev = &virtio_dev->dev; - struct virtqueue *vqs[2]; - static struct virtqueue_info vq_info[2] = { - { - .name = "command", - .callback = commandq_callback, - }, - { - .name = "event", - .callback = eventq_callback, - }, - }; - struct virtio_media *vv; - struct video_device *vd; - int i; - int ret; - - vv = devm_kzalloc(dev, sizeof(*vv), GFP_KERNEL); - if (!vv) - return -ENOMEM; - - vv->event_buffer = devm_kzalloc( - dev, VIRTIO_MEDIA_EVENT_MAX_SIZE * VIRTIO_MEDIA_NUM_EVENT_BUFS, - GFP_KERNEL); - if (!vv->event_buffer) - return -ENOMEM; - - INIT_LIST_HEAD(&vv->sessions); - mutex_init(&vv->sessions_lock); - mutex_init(&vv->events_lock); - mutex_init(&vv->vlock); - - vv->virtio_dev = virtio_dev; - virtio_dev->priv = vv; - - init_waitqueue_head(&vv->wq); - - ret = v4l2_device_register(dev, &vv->v4l2_dev); - if (ret) - return ret; - - ret = virtio_find_vqs(virtio_dev, 2, vqs, vq_info, NULL); - if (ret) - goto err_find_vqs; - - vv->commandq = vqs[0]; - vv->eventq = vqs[1]; - INIT_WORK(&vv->eventq_work, virtio_media_event_work); - - /* Get MMAP buffer mapping SHM region */ - virtio_get_shm_region(virtio_dev, &vv->mmap_region, - VIRTIO_MEDIA_SHM_MMAP); - - vd = &vv->video_dev; - - vd->v4l2_dev = &vv->v4l2_dev; - vd->vfl_type = VFL_TYPE_VIDEO; - vd->ioctl_ops = &virtio_media_ioctl_ops; - vd->fops = &virtio_media_fops; - vd->device_caps = virtio_cread32(virtio_dev, 0); - if (vd->device_caps & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE)) - vd->vfl_dir = VFL_DIR_M2M; - else if (vd->device_caps & - (V4L2_CAP_VIDEO_OUTPUT | V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) - vd->vfl_dir = VFL_DIR_TX; - else - vd->vfl_dir = VFL_DIR_RX; - vd->release = video_device_release_empty; - strscpy(vd->name, "virtio-media", sizeof(vd->name)); - - video_set_drvdata(vd, vv); - - ret = video_register_device(vd, virtio_cread32(virtio_dev, 4), 0); - if (ret) - goto err_register_device; - - for (i = 0; i < VIRTIO_MEDIA_NUM_EVENT_BUFS; i++) { - ret = virtio_media_send_event_buffer( - vv, vv->event_buffer + VIRTIO_MEDIA_EVENT_MAX_SIZE * i); - if (ret) - goto err_send_event_buffer; - } - - virtio_device_ready(virtio_dev); - - return 0; - -err_send_event_buffer: - video_unregister_device(&vv->video_dev); -err_register_device: - virtio_dev->config->del_vqs(virtio_dev); -err_find_vqs: - v4l2_device_unregister(&vv->v4l2_dev); - - return ret; -} - -static void virtio_media_remove(struct virtio_device *virtio_dev) -{ - struct virtio_media *vv = virtio_dev->priv; - struct list_head *p, *n; - - cancel_work_sync(&vv->eventq_work); - virtio_reset_device(virtio_dev); - - v4l2_device_unregister(&vv->v4l2_dev); - virtio_dev->config->del_vqs(virtio_dev); - video_unregister_device(&vv->video_dev); - - list_for_each_safe(p, n, &vv->sessions) { - struct virtio_media_session *s = - list_entry(p, struct virtio_media_session, list); - - virtio_media_session_free(vv, s); - } -} - -static struct virtio_device_id id_table[] = { - { VIRTIO_ID_MEDIA, VIRTIO_DEV_ANY_ID }, - { 0 }, -}; - -static unsigned int features[] = {}; - -static struct virtio_driver virtio_media_driver = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), - .driver.name = VIRTIO_MEDIA_DEFAULT_DRIVER_NAME, - .driver.owner = THIS_MODULE, - .id_table = id_table, - .probe = virtio_media_probe, - .remove = virtio_media_remove, -}; - -module_virtio_driver(virtio_media_driver); - -MODULE_DEVICE_TABLE(virtio, id_table); -MODULE_DESCRIPTION("virtio media driver"); -MODULE_AUTHOR("Alexandre Courbot <gnurou@gmail.com>"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/media/virtio/virtio_media_ioctls.c b/drivers/media/virtio/virtio_media_ioctls.c deleted file mode 100644 index 863cdfbaaadc..000000000000 --- a/drivers/media/virtio/virtio_media_ioctls.c +++ /dev/null @@ -1,1297 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0+ - -/* - * Ioctls implementations for the virtio-media driver. - * - * Copyright (c) 2024-2025 Google LLC. - */ - -#include <linux/mutex.h> -#include <linux/videodev2.h> -#include <linux/virtio_config.h> -#include <linux/vmalloc.h> -#include <media/v4l2-event.h> -#include <media/v4l2-ioctl.h> - -#include "scatterlist_builder.h" -#include "virtio_media.h" - -/** - * virtio_media_send_r_ioctl() - Send a read-only ioctl to the device. - * @fh: file handler of the session doing the ioctl. - * @ioctl: ``VIDIOC_*`` ioctl code. - * @ioctl_data: pointer to the ioctl payload. - * @ioctl_data_len: length in bytes of the ioctl payload. - * - * Send an ioctl that has no driver payload, but expects a response from the - * host (i.e. an ioctl specified with ``_IOR``). - */ -static int virtio_media_send_r_ioctl(struct v4l2_fh *fh, u32 ioctl, - void *ioctl_data, size_t ioctl_data_len) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = fh_to_session(fh); - struct scatterlist *sgs[3]; - struct scatterlist_builder builder = { - .descs = session->command_sgs.sgl, - .num_descs = DESC_CHAIN_MAX_LEN, - .cur_desc = 0, - .shadow_buffer = session->shadow_buf, - .shadow_buffer_size = VIRTIO_SHADOW_BUF_SIZE, - .shadow_buffer_pos = 0, - .sgs = sgs, - .num_sgs = ARRAY_SIZE(sgs), - .cur_sg = 0, - }; - int ret; - - /* Command descriptor */ - ret = scatterlist_builder_add_ioctl_cmd(&builder, session, ioctl); - if (ret) - return ret; - - /* Response descriptor */ - ret = scatterlist_builder_add_ioctl_resp(&builder, session); - if (ret) - return ret; - - /* Response payload */ - ret = scatterlist_builder_add_data(&builder, ioctl_data, - ioctl_data_len); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to prepare command descriptor chain\n"); - return ret; - } - - ret = virtio_media_send_command( - vv, sgs, 1, 2, - sizeof(struct virtio_media_resp_ioctl) + ioctl_data_len, NULL); - if (ret < 0) - return ret; - - ret = scatterlist_builder_retrieve_data(&builder, 2, ioctl_data); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to retrieve response descriptor chain\n"); - return ret; - } - - return 0; -} - -/** - * virtio_media_send_w_ioctl() - Send a write-only ioctl to the device. - * @fh: file handler of the session doing the ioctl. - * @ioctl: ``VIDIOC_*`` ioctl code. - * @ioctl_data: pointer to the ioctl payload. - * @ioctl_data_len: length in bytes of the ioctl payload. - * - * Send an ioctl that does not expect a reply beyond an error status (i.e. an - * ioctl specified with ``_IOW``) to the host. - */ -static int virtio_media_send_w_ioctl(struct v4l2_fh *fh, u32 ioctl, - const void *ioctl_data, - size_t ioctl_data_len) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = fh_to_session(fh); - struct scatterlist *sgs[3]; - struct scatterlist_builder builder = { - .descs = session->command_sgs.sgl, - .num_descs = DESC_CHAIN_MAX_LEN, - .cur_desc = 0, - .shadow_buffer = session->shadow_buf, - .shadow_buffer_size = VIRTIO_SHADOW_BUF_SIZE, - .shadow_buffer_pos = 0, - .sgs = sgs, - .num_sgs = ARRAY_SIZE(sgs), - .cur_sg = 0, - }; - int ret; - - /* Command descriptor */ - ret = scatterlist_builder_add_ioctl_cmd(&builder, session, ioctl); - if (ret) - return ret; - - /* Command payload */ - ret = scatterlist_builder_add_data(&builder, (void *)ioctl_data, - ioctl_data_len); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to prepare command descriptor chain\n"); - return ret; - } - - /* Response descriptor */ - ret = scatterlist_builder_add_ioctl_resp(&builder, session); - if (ret) - return ret; - - ret = virtio_media_send_command( - vv, sgs, 2, 1, sizeof(struct virtio_media_resp_ioctl), NULL); - if (ret < 0) - return ret; - - return 0; -} - -/** - * virtio_media_send_wr_ioctl() - Send a read-write ioctl to the device. - * @fh: file handler of the session doing the ioctl. - * @ioctl: ``VIDIOC_*`` ioctl code. - * @ioctl_data: pointer to the ioctl payload. - * @ioctl_data_len: length in bytes of the ioctl payload. - * @minimum_resp_payload: minimum expected length of the response's payload. - * - * Sends an ioctl that expects a response of exactly the same size as the - * input (i.e. an ioctl specified with ``_IOWR``) to the host. - * - * This corresponds to what most V4L2 ioctls do. For instance - * ``VIDIOC_ENUM_FMT`` takes a partially-initialized ``struct v4l2_fmtdesc`` - * and returns its filled version. - */ -static int virtio_media_send_wr_ioctl(struct v4l2_fh *fh, u32 ioctl, - void *ioctl_data, size_t ioctl_data_len, - size_t minimum_resp_payload) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = fh_to_session(fh); - struct scatterlist *sgs[4]; - struct scatterlist_builder builder = { - .descs = session->command_sgs.sgl, - .num_descs = DESC_CHAIN_MAX_LEN, - .cur_desc = 0, - .shadow_buffer = session->shadow_buf, - .shadow_buffer_size = VIRTIO_SHADOW_BUF_SIZE, - .shadow_buffer_pos = 0, - .sgs = sgs, - .num_sgs = ARRAY_SIZE(sgs), - .cur_sg = 0, - }; - int ret; - - /* Command descriptor */ - ret = scatterlist_builder_add_ioctl_cmd(&builder, session, ioctl); - if (ret) - return ret; - - /* Command payload */ - ret = scatterlist_builder_add_data(&builder, ioctl_data, - ioctl_data_len); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to prepare command descriptor chain\n"); - return ret; - } - - /* Response descriptor */ - ret = scatterlist_builder_add_ioctl_resp(&builder, session); - if (ret) - return ret; - - /* Response payload, same as command */ - ret = scatterlist_builder_add_descriptor(&builder, 1); - if (ret) - return ret; - - ret = virtio_media_send_command(vv, sgs, 2, 2, - sizeof(struct virtio_media_resp_ioctl) + - minimum_resp_payload, - NULL); - if (ret < 0) - return ret; - - ret = scatterlist_builder_retrieve_data(&builder, 3, ioctl_data); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to retrieve response descriptor chain\n"); - return ret; - } - - return 0; -} - -/** - * virtio_media_send_buffer_ioctl() - Send an ioctl taking a buffer as - * parameter to the device. - * @fh: file handler of the session doing the ioctl. - * @ioctl: ``VIDIOC_*`` ioctl code. - * @b: ``v4l2_buffer`` to be sent as the ioctl payload. - * - * Buffers can require an additional descriptor to send their planes array, and - * can have pointers to userspace memory hence this dedicated function. - */ -static int virtio_media_send_buffer_ioctl(struct v4l2_fh *fh, u32 ioctl, - struct v4l2_buffer *b) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = fh_to_session(fh); - struct v4l2_plane *orig_planes = NULL; - struct scatterlist *sgs[64]; - /* End of the device-readable buffer SGs, to reuse in device-writable section. */ - size_t num_cmd_sgs; - size_t end_buf_sg; - struct scatterlist_builder builder = { - .descs = session->command_sgs.sgl, - .num_descs = DESC_CHAIN_MAX_LEN, - .cur_desc = 0, - .shadow_buffer = session->shadow_buf, - .shadow_buffer_size = VIRTIO_SHADOW_BUF_SIZE, - .shadow_buffer_pos = 0, - .sgs = sgs, - .num_sgs = ARRAY_SIZE(sgs), - .cur_sg = 0, - }; - size_t resp_len; - int ret; - int i; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) - orig_planes = b->m.planes; - - /* Command descriptor */ - ret = scatterlist_builder_add_ioctl_cmd(&builder, session, ioctl); - if (ret) - return ret; - - /* Command payload (struct v4l2_buffer) */ - ret = scatterlist_builder_add_buffer(&builder, b); - if (ret < 0) - return ret; - - end_buf_sg = builder.cur_sg; - - /* Payload of SHARED_PAGES buffers, if relevant */ - ret = scatterlist_builder_add_buffer_userptr(&builder, b); - if (ret < 0) - return ret; - - num_cmd_sgs = builder.cur_sg; - - /* Response descriptor */ - ret = scatterlist_builder_add_ioctl_resp(&builder, session); - if (ret) - return ret; - - /* Response payload (same as input, but no userptr mapping) */ - for (i = 1; i < end_buf_sg; i++) { - ret = scatterlist_builder_add_descriptor(&builder, i); - if (ret < 0) - return ret; - } - - ret = virtio_media_send_command( - vv, builder.sgs, num_cmd_sgs, builder.cur_sg - num_cmd_sgs, - sizeof(struct virtio_media_resp_ioctl) + sizeof(*b), &resp_len); - if (ret < 0) - return ret; - - resp_len -= sizeof(struct virtio_media_resp_ioctl); - - /* Make sure that the reply length covers our v4l2_buffer */ - if (resp_len < sizeof(*b)) - return -EINVAL; - - ret = scatterlist_builder_retrieve_buffer(&builder, num_cmd_sgs + 1, b, - orig_planes); - if (ret) { - v4l2_err(&vv->v4l2_dev, - "failed to retrieve response descriptor chain\n"); - return ret; - } - - return 0; -} - -/** - * virtio_media_send_ext_controls_ioctl() - Send an ioctl taking extended - * controls as parameters to the device. - * @fh: file handler of the session doing the ioctl. - * @ioctl: ``VIDIOC_*`` ioctl code. - * @ctrls: ``v4l2_ext_controls`` to be sent as the ioctl payload. - * - * Queues an ioctl that sends a ``v4l2_ext_controls`` to the host and receives - * an updated version. - * - * ``v4l2_ext_controls`` has a pointer to an array of ``v4l2_ext_control``, and - * also potentially pointers to user-space memory that we need to map properly, - * hence the dedicated function. - */ -static int virtio_media_send_ext_controls_ioctl(struct v4l2_fh *fh, u32 ioctl, - struct v4l2_ext_controls *ctrls) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = fh_to_session(fh); - size_t num_cmd_sgs; - size_t end_ctrls_sg; - struct v4l2_ext_control *controls_backup = ctrls->controls; - const u32 num_ctrls = ctrls->count; - struct scatterlist *sgs[64]; - struct scatterlist_builder builder = { - .descs = session->command_sgs.sgl, - .num_descs = DESC_CHAIN_MAX_LEN, - .cur_desc = 0, - .shadow_buffer = session->shadow_buf, - .shadow_buffer_size = VIRTIO_SHADOW_BUF_SIZE, - .shadow_buffer_pos = 0, - .sgs = sgs, - .num_sgs = ARRAY_SIZE(sgs), - .cur_sg = 0, - }; - size_t resp_len = 0; - int ret; - int i; - - /* Command descriptor */ - ret = scatterlist_builder_add_ioctl_cmd(&builder, session, ioctl); - if (ret) - return ret; - - /* v4l2_controls */ - ret = scatterlist_builder_add_ext_ctrls(&builder, ctrls); - if (ret) - return ret; - - end_ctrls_sg = builder.cur_sg; - - ret = scatterlist_builder_add_ext_ctrls_userptrs(&builder, ctrls); - if (ret) - return ret; - - num_cmd_sgs = builder.cur_sg; - - /* Response descriptor */ - ret = scatterlist_builder_add_ioctl_resp(&builder, session); - if (ret) - return ret; - - /* Response payload (same as input but without userptrs) */ - for (i = 1; i < end_ctrls_sg; i++) { - ret = scatterlist_builder_add_descriptor(&builder, i); - if (ret < 0) - return ret; - } - - ret = virtio_media_send_command( - vv, builder.sgs, num_cmd_sgs, builder.cur_sg - num_cmd_sgs, - sizeof(struct virtio_media_resp_ioctl) + sizeof(*ctrls), - &resp_len); - - /* Just in case the host touched these. */ - ctrls->controls = controls_backup; - if (ctrls->count != num_ctrls) { - v4l2_err( - &vv->v4l2_dev, - "device returned a number of controls different than the one submitted\n"); - } - if (ctrls->count > num_ctrls) - return -ENOSPC; - - /* Event if we have received an error, we may need to read our payload back */ - if (ret < 0 && resp_len >= sizeof(struct virtio_media_resp_ioctl) + - sizeof(*ctrls)) { - /* Deliberately ignore the error here as we want to return the previous one */ - scatterlist_builder_retrieve_ext_ctrls(&builder, - num_cmd_sgs + 1, ctrls); - return ret; - } - - resp_len -= sizeof(struct virtio_media_resp_ioctl); - - /* Make sure that the reply's length covers our v4l2_ext_controls */ - if (resp_len < sizeof(*ctrls)) - return -EINVAL; - - ret = scatterlist_builder_retrieve_ext_ctrls(&builder, num_cmd_sgs + 1, - ctrls); - if (ret) - return ret; - - return 0; -} - -/** - * virtio_media_clear_queue() - clear all pending buffers on a streamed-off queue. - * @session: session which the queue to clear belongs to. - * @queue: state of the queue to clear. - * - * Helper function to clear the list of buffers waiting to be dequeued on a - * queue that has just been streamed off. - */ -static void virtio_media_clear_queue(struct virtio_media_session *session, - struct virtio_media_queue_state *queue) -{ - struct list_head *p, *n; - int i; - - mutex_lock(&session->queues_lock); - - list_for_each_safe(p, n, &queue->pending_dqbufs) { - struct virtio_media_buffer *dqbuf = - list_entry(p, struct virtio_media_buffer, list); - - list_del(&dqbuf->list); - } - - /* All buffers are now dequeued. */ - for (i = 0; i < queue->allocated_bufs; i++) - queue->buffers[i].buffer.flags = 0; - - queue->queued_bufs = 0; - queue->streaming = false; - queue->is_capture_last = false; - - mutex_unlock(&session->queues_lock); -} - -/* - * Macros suitable for defining ioctls with a constant size payload. - */ - -#define SIMPLE_WR_IOCTL(name, ioctl, payload_t) \ - static int virtio_media_##name(struct file *file, void *fh, \ - payload_t *payload) \ - { \ - return virtio_media_send_wr_ioctl(fh, ioctl, payload, \ - sizeof(*payload), \ - sizeof(*payload)); \ - } -#define SIMPLE_R_IOCTL(name, ioctl, payload_t) \ - static int virtio_media_##name(struct file *file, void *fh, \ - payload_t *payload) \ - { \ - return virtio_media_send_r_ioctl(fh, ioctl, payload, \ - sizeof(*payload)); \ - } -#define SIMPLE_W_IOCTL(name, ioctl, payload_t) \ - static int virtio_media_##name(struct file *file, void *fh, \ - payload_t *payload) \ - { \ - return virtio_media_send_w_ioctl(fh, ioctl, payload, \ - sizeof(*payload)); \ - } - -/* - * V4L2 ioctl handlers. - * - * Most of these functions just forward the ioctl to the host, for these we can - * use one of the SIMPLE_*_IOCTL macros. Exceptions that have their own - * standalone function follow. - */ - -SIMPLE_WR_IOCTL(enum_fmt, VIDIOC_ENUM_FMT, struct v4l2_fmtdesc) -SIMPLE_WR_IOCTL(g_fmt, VIDIOC_G_FMT, struct v4l2_format) -SIMPLE_WR_IOCTL(s_fmt, VIDIOC_S_FMT, struct v4l2_format) -SIMPLE_WR_IOCTL(try_fmt, VIDIOC_TRY_FMT, struct v4l2_format) -SIMPLE_WR_IOCTL(enum_framesizes, VIDIOC_ENUM_FRAMESIZES, - struct v4l2_frmsizeenum) -SIMPLE_WR_IOCTL(enum_frameintervals, VIDIOC_ENUM_FRAMEINTERVALS, - struct v4l2_frmivalenum) -SIMPLE_WR_IOCTL(query_ext_ctrl, VIDIOC_QUERY_EXT_CTRL, - struct v4l2_query_ext_ctrl) -SIMPLE_WR_IOCTL(s_dv_timings, VIDIOC_S_DV_TIMINGS, struct v4l2_dv_timings) -SIMPLE_WR_IOCTL(g_dv_timings, VIDIOC_G_DV_TIMINGS, struct v4l2_dv_timings) -SIMPLE_R_IOCTL(query_dv_timings, VIDIOC_QUERY_DV_TIMINGS, - struct v4l2_dv_timings) -SIMPLE_WR_IOCTL(enum_dv_timings, VIDIOC_ENUM_DV_TIMINGS, - struct v4l2_enum_dv_timings) -SIMPLE_WR_IOCTL(dv_timings_cap, VIDIOC_DV_TIMINGS_CAP, - struct v4l2_dv_timings_cap) -SIMPLE_WR_IOCTL(enuminput, VIDIOC_ENUMINPUT, struct v4l2_input) -SIMPLE_WR_IOCTL(querymenu, VIDIOC_QUERYMENU, struct v4l2_querymenu) -SIMPLE_WR_IOCTL(enumoutput, VIDIOC_ENUMOUTPUT, struct v4l2_output) -SIMPLE_WR_IOCTL(enumaudio, VIDIOC_ENUMAUDIO, struct v4l2_audio) -SIMPLE_R_IOCTL(g_audio, VIDIOC_G_AUDIO, struct v4l2_audio) -SIMPLE_W_IOCTL(s_audio, VIDIOC_S_AUDIO, const struct v4l2_audio) -SIMPLE_WR_IOCTL(enumaudout, VIDIOC_ENUMAUDOUT, struct v4l2_audioout) -SIMPLE_R_IOCTL(g_audout, VIDIOC_G_AUDOUT, struct v4l2_audioout) -SIMPLE_W_IOCTL(s_audout, VIDIOC_S_AUDOUT, const struct v4l2_audioout) -SIMPLE_WR_IOCTL(g_modulator, VIDIOC_G_MODULATOR, struct v4l2_modulator) -SIMPLE_W_IOCTL(s_modulator, VIDIOC_S_MODULATOR, const struct v4l2_modulator) -SIMPLE_WR_IOCTL(g_selection, VIDIOC_G_SELECTION, struct v4l2_selection) -SIMPLE_WR_IOCTL(s_selection, VIDIOC_S_SELECTION, struct v4l2_selection) -SIMPLE_R_IOCTL(g_enc_index, VIDIOC_G_ENC_INDEX, struct v4l2_enc_idx) -SIMPLE_WR_IOCTL(encoder_cmd, VIDIOC_ENCODER_CMD, struct v4l2_encoder_cmd) -SIMPLE_WR_IOCTL(try_encoder_cmd, VIDIOC_TRY_ENCODER_CMD, - struct v4l2_encoder_cmd) -SIMPLE_WR_IOCTL(try_decoder_cmd, VIDIOC_TRY_DECODER_CMD, - struct v4l2_decoder_cmd) -SIMPLE_WR_IOCTL(g_parm, VIDIOC_G_PARM, struct v4l2_streamparm) -SIMPLE_WR_IOCTL(s_parm, VIDIOC_S_PARM, struct v4l2_streamparm) -SIMPLE_R_IOCTL(g_std, VIDIOC_G_STD, v4l2_std_id) -SIMPLE_R_IOCTL(querystd, VIDIOC_QUERYSTD, v4l2_std_id) -SIMPLE_WR_IOCTL(enumstd, VIDIOC_ENUMSTD, struct v4l2_standard) -SIMPLE_WR_IOCTL(g_tuner, VIDIOC_G_TUNER, struct v4l2_tuner) -SIMPLE_W_IOCTL(s_tuner, VIDIOC_S_TUNER, const struct v4l2_tuner) -SIMPLE_WR_IOCTL(g_frequency, VIDIOC_G_FREQUENCY, struct v4l2_frequency) -SIMPLE_W_IOCTL(s_frequency, VIDIOC_S_FREQUENCY, const struct v4l2_frequency) -SIMPLE_WR_IOCTL(enum_freq_bands, VIDIOC_ENUM_FREQ_BANDS, - struct v4l2_frequency_band) -SIMPLE_WR_IOCTL(g_sliced_vbi_cap, VIDIOC_G_SLICED_VBI_CAP, - struct v4l2_sliced_vbi_cap) -SIMPLE_W_IOCTL(s_hw_freq_seek, VIDIOC_S_HW_FREQ_SEEK, - const struct v4l2_hw_freq_seek) - -/* - * QUERYCAP is handled by reading the configuration area. - * - */ - -static int virtio_media_querycap(struct file *file, void *fh, - struct v4l2_capability *cap) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - - strscpy(cap->bus_info, "platform:virtio-media"); - - if (!virtio_media_driver_name) - strscpy(cap->driver, VIRTIO_MEDIA_DEFAULT_DRIVER_NAME); - else - strscpy(cap->driver, virtio_media_driver_name); - - virtio_cread_bytes(vv->virtio_dev, 8, cap->card, sizeof(cap->card)); - - cap->capabilities = video_dev->device_caps | V4L2_CAP_DEVICE_CAPS; - cap->device_caps = video_dev->device_caps; - - return 0; -} - -/* - * Extended control ioctls are handled mostly identically. - */ - -static int virtio_media_g_ext_ctrls(struct file *file, void *fh, - struct v4l2_ext_controls *ctrls) -{ - return virtio_media_send_ext_controls_ioctl(fh, VIDIOC_G_EXT_CTRLS, - ctrls); -} - -static int virtio_media_s_ext_ctrls(struct file *file, void *fh, - struct v4l2_ext_controls *ctrls) -{ - return virtio_media_send_ext_controls_ioctl(fh, VIDIOC_S_EXT_CTRLS, - ctrls); -} - -static int virtio_media_try_ext_ctrls(struct file *file, void *fh, - struct v4l2_ext_controls *ctrls) -{ - return virtio_media_send_ext_controls_ioctl(fh, VIDIOC_TRY_EXT_CTRLS, - ctrls); -} - -/* - * Subscribe/unsubscribe from an event. - */ - -static int -virtio_media_subscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) -{ - struct video_device *video_dev = fh->vdev; - struct virtio_media *vv = to_virtio_media(video_dev); - int ret; - - /* First subscribe to the event in the guest. */ - switch (sub->type) { - case V4L2_EVENT_SOURCE_CHANGE: - ret = v4l2_src_change_event_subscribe(fh, sub); - break; - default: - ret = v4l2_event_subscribe(fh, sub, 1, NULL); - break; - } - if (ret) - return ret; - - /* Then ask the host to signal us these events. */ - ret = virtio_media_send_w_ioctl(fh, VIDIOC_SUBSCRIBE_EVENT, sub, - sizeof(*sub)); - if (ret < 0) { - v4l2_event_unsubscribe(fh, sub); - return ret; - } - - /* - * Subscribing to an event may result in that event being signaled - * immediately. Process all pending events to make sure we don't miss it. - */ - if (sub->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL) - virtio_media_process_events(vv); - - return 0; -} - -static int -virtio_media_unsubscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) -{ - int ret; - - ret = virtio_media_send_w_ioctl(fh, VIDIOC_UNSUBSCRIBE_EVENT, sub, - sizeof(*sub)); - if (ret < 0) - return ret; - - ret = v4l2_event_unsubscribe(fh, sub); - if (ret) - return ret; - - return 0; -} - -/* - * Streamon/off affect the local queue state. - */ - -static int virtio_media_streamon(struct file *file, void *fh, - enum v4l2_buf_type i) -{ - struct virtio_media_session *session = fh_to_session(fh); - int ret; - - if (i > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - ret = virtio_media_send_w_ioctl(fh, VIDIOC_STREAMON, &i, sizeof(i)); - if (ret < 0) - return ret; - - session->queues[i].streaming = true; - - return 0; -} - -static int virtio_media_streamoff(struct file *file, void *fh, - enum v4l2_buf_type i) -{ - struct virtio_media_session *session = fh_to_session(fh); - int ret; - - if (i > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - ret = virtio_media_send_w_ioctl(fh, VIDIOC_STREAMOFF, &i, sizeof(i)); - if (ret < 0) - return ret; - - virtio_media_clear_queue(session, &session->queues[i]); - - return 0; -} - -/* - * Buffer creation/queuing functions deal with the local driver state. - */ - -static int virtio_media_reqbufs(struct file *file, void *fh, - struct v4l2_requestbuffers *b) -{ - struct virtio_media_session *session = fh_to_session(fh); - struct virtio_media_queue_state *queue; - int ret; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - if (b->memory == V4L2_MEMORY_USERPTR && !virtio_media_allow_userptr) - return -EINVAL; - - ret = virtio_media_send_wr_ioctl(fh, VIDIOC_REQBUFS, b, sizeof(*b), - sizeof(*b)); - if (ret) - return ret; - - queue = &session->queues[b->type]; - - /* REQBUFS(0) is an implicit STREAMOFF. */ - if (b->count == 0) - virtio_media_clear_queue(session, queue); - - vfree(queue->buffers); - queue->buffers = NULL; - - if (b->count > 0) { - queue->buffers = - vzalloc(sizeof(struct virtio_media_buffer) * b->count); - if (!queue->buffers) - return -ENOMEM; - } - - queue->allocated_bufs = b->count; - - /* - * If a multiplanar queue is successfully used here, this means - * we are using the multiplanar interface. - */ - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) - session->uses_mplane = true; - - if (!virtio_media_allow_userptr) - b->capabilities &= ~V4L2_BUF_CAP_SUPPORTS_USERPTR; - - /* We do not support DMABUF yet. */ - b->capabilities &= ~V4L2_BUF_CAP_SUPPORTS_DMABUF; - - return 0; -} - -static int virtio_media_querybuf(struct file *file, void *fh, - struct v4l2_buffer *b) -{ - struct virtio_media_session *session = fh_to_session(fh); - struct virtio_media_queue_state *queue; - struct virtio_media_buffer *buffer; - int ret; - - ret = virtio_media_send_buffer_ioctl(fh, VIDIOC_QUERYBUF, b); - if (ret) - return ret; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - queue = &session->queues[b->type]; - if (b->index >= queue->allocated_bufs) - return -EINVAL; - - buffer = &queue->buffers[b->index]; - /* Set the DONE flag if the buffer is waiting in our own dequeue queue. */ - b->flags |= (buffer->buffer.flags & V4L2_BUF_FLAG_DONE); - - return 0; -} - -static int virtio_media_create_bufs(struct file *file, void *fh, - struct v4l2_create_buffers *b) -{ - struct virtio_media_session *session = fh_to_session(fh); - struct virtio_media_queue_state *queue; - struct virtio_media_buffer *buffers; - u32 type = b->format.type; - int ret; - - if (type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - queue = &session->queues[type]; - - ret = virtio_media_send_wr_ioctl(fh, VIDIOC_CREATE_BUFS, b, sizeof(*b), - sizeof(*b)); - if (ret) - return ret; - - /* If count is zero, we were just checking for format. */ - if (b->count == 0) - return 0; - - buffers = queue->buffers; - - queue->buffers = - vzalloc(sizeof(*queue->buffers) * (b->index + b->count)); - if (!queue->buffers) { - queue->buffers = buffers; - return -ENOMEM; - } - - memcpy(queue->buffers, buffers, - sizeof(*buffers) * queue->allocated_bufs); - vfree(buffers); - - queue->allocated_bufs = b->index + b->count; - - return 0; -} - -static int virtio_media_prepare_buf(struct file *file, void *fh, - struct v4l2_buffer *b) -{ - struct virtio_media_session *session = fh_to_session(fh); - struct virtio_media_queue_state *queue; - struct virtio_media_buffer *buffer; - int i, ret; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - queue = &session->queues[b->type]; - if (b->index >= queue->allocated_bufs) - return -EINVAL; - buffer = &queue->buffers[b->index]; - - buffer->buffer.m = b->m; - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { - if (b->length > VIDEO_MAX_PLANES) - return -EINVAL; - for (i = 0; i < b->length; i++) - buffer->planes[i].m = b->m.planes[i].m; - } - - ret = virtio_media_send_buffer_ioctl(fh, VIDIOC_PREPARE_BUF, b); - if (ret) - return ret; - - buffer->buffer.flags = V4L2_BUF_FLAG_PREPARED; - - return 0; -} - -static int virtio_media_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) -{ - struct virtio_media_session *session = fh_to_session(fh); - struct virtio_media_queue_state *queue; - struct virtio_media_buffer *buffer; - bool prepared; - u32 old_flags; - int i, ret; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - queue = &session->queues[b->type]; - if (b->index >= queue->allocated_bufs) - return -EINVAL; - buffer = &queue->buffers[b->index]; - prepared = buffer->buffer.flags & V4L2_BUF_FLAG_PREPARED; - - /* - * Store the buffer and plane `m` information so we can retrieve it again - * when DQBUF occurs. - */ - if (!prepared) { - buffer->buffer.m = b->m; - if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { - if (b->length > VIDEO_MAX_PLANES) - return -EINVAL; - for (i = 0; i < b->length; i++) - buffer->planes[i].m = b->m.planes[i].m; - } - } - old_flags = buffer->buffer.flags; - buffer->buffer.flags = V4L2_BUF_FLAG_QUEUED; - - ret = virtio_media_send_buffer_ioctl(fh, VIDIOC_QBUF, b); - if (ret) { - /* Rollback the previous flags as the buffer is not queued. */ - buffer->buffer.flags = old_flags; - return ret; - } - - queue->queued_bufs += 1; - - return 0; -} - -static int virtio_media_dqbuf(struct file *file, void *fh, - struct v4l2_buffer *b) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - struct virtio_media_session *session = - fh_to_session(file->private_data); - struct virtio_media_buffer *dqbuf; - struct virtio_media_queue_state *queue; - struct list_head *buffer_queue; - struct v4l2_plane *planes_backup = NULL; - const bool is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(b->type); - int ret; - - if (b->type > VIRTIO_MEDIA_LAST_QUEUE) - return -EINVAL; - - queue = &session->queues[b->type]; - - /* - * If a buffer with the LAST flag has been returned, subsequent calls to DQBUF - * must return -EPIPE until the queue is cleared. - */ - if (queue->is_capture_last) - return -EPIPE; - - buffer_queue = &queue->pending_dqbufs; - - if (session->nonblocking_dequeue) { - if (list_empty(buffer_queue)) - return -EAGAIN; - } else if (queue->allocated_bufs == 0) { - return -EINVAL; - } else if (!queue->streaming) { - return -EINVAL; - } - - /* - * vv->lock has been acquired by virtio_media_device_ioctl. Release it - * while we want to other ioctls for this session can be processed and - * potentially trigger dqbuf_wait. - */ - mutex_unlock(&vv->vlock); - ret = wait_event_interruptible(session->dqbuf_wait, - !list_empty(buffer_queue)); - mutex_lock(&vv->vlock); - if (ret) - return -EINTR; - - mutex_lock(&session->queues_lock); - dqbuf = list_first_entry(buffer_queue, struct virtio_media_buffer, - list); - list_del(&dqbuf->list); - mutex_unlock(&session->queues_lock); - - /* Clear the DONE flag as the buffer is now being dequeued. */ - dqbuf->buffer.flags &= ~V4L2_BUF_FLAG_DONE; - - if (is_multiplanar) { - size_t nb_planes = min_t(u32, b->length, VIDEO_MAX_PLANES); - - memcpy(b->m.planes, dqbuf->planes, - nb_planes * sizeof(struct v4l2_plane)); - planes_backup = b->m.planes; - } - - memcpy(b, &dqbuf->buffer, sizeof(*b)); - - if (is_multiplanar) - b->m.planes = planes_backup; - - if (V4L2_TYPE_IS_CAPTURE(b->type) && b->flags & V4L2_BUF_FLAG_LAST) - queue->is_capture_last = true; - - return 0; -} - -/* - * s/g_input/output work with an unsigned int - recast this to a u32 so the - * size is unambiguous. - */ - -static int virtio_media_g_input(struct file *file, void *fh, unsigned int *i) -{ - u32 input; - int ret; - - ret = virtio_media_send_wr_ioctl(fh, VIDIOC_G_INPUT, &input, - sizeof(input), sizeof(input)); - if (ret) - return ret; - - *i = input; - - return 0; -} - -static int virtio_media_s_input(struct file *file, void *fh, unsigned int i) -{ - u32 input = i; - - return virtio_media_send_wr_ioctl(fh, VIDIOC_S_INPUT, &input, - sizeof(input), sizeof(input)); -} - -static int virtio_media_g_output(struct file *file, void *fh, unsigned int *o) -{ - u32 output; - int ret; - - ret = virtio_media_send_wr_ioctl(fh, VIDIOC_G_OUTPUT, &output, - sizeof(output), sizeof(output)); - if (ret) - return ret; - - *o = output; - - return 0; -} - -static int virtio_media_s_output(struct file *file, void *fh, unsigned int o) -{ - u32 output = o; - - return virtio_media_send_wr_ioctl(fh, VIDIOC_S_OUTPUT, &output, - sizeof(output), sizeof(output)); -} - -/* - * decoder_cmd can affect the state of the CAPTURE queue. - */ - -static int virtio_media_decoder_cmd(struct file *file, void *fh, - struct v4l2_decoder_cmd *cmd) -{ - struct virtio_media_session *session = fh_to_session(fh); - int ret; - - ret = virtio_media_send_wr_ioctl(fh, VIDIOC_DECODER_CMD, cmd, - sizeof(*cmd), sizeof(*cmd)); - if (ret) - return ret; - - /* A START command makes the CAPTURE queue able to dequeue again. */ - if (cmd->cmd == V4L2_DEC_CMD_START) { - session->queues[V4L2_BUF_TYPE_VIDEO_CAPTURE].is_capture_last = - false; - session->queues[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] - .is_capture_last = false; - } - - return 0; -} - -/* - * s_std doesn't work with a pointer, so we cannot use SIMPLE_W_IOCTL. - */ - -static int virtio_media_s_std(struct file *file, void *fh, v4l2_std_id s) -{ - int ret; - - ret = virtio_media_send_w_ioctl(fh, VIDIOC_S_STD, &s, sizeof(s)); - if (ret) - return ret; - - return 0; -} - -const struct v4l2_ioctl_ops virtio_media_ioctl_ops = { - /* VIDIOC_QUERYCAP handler */ - .vidioc_querycap = virtio_media_querycap, - - /* VIDIOC_ENUM_FMT handlers */ - .vidioc_enum_fmt_vid_cap = virtio_media_enum_fmt, - .vidioc_enum_fmt_vid_overlay = virtio_media_enum_fmt, - .vidioc_enum_fmt_vid_out = virtio_media_enum_fmt, - .vidioc_enum_fmt_sdr_cap = virtio_media_enum_fmt, - .vidioc_enum_fmt_sdr_out = virtio_media_enum_fmt, - .vidioc_enum_fmt_meta_cap = virtio_media_enum_fmt, - .vidioc_enum_fmt_meta_out = virtio_media_enum_fmt, - - /* VIDIOC_G_FMT handlers */ - .vidioc_g_fmt_vid_cap = virtio_media_g_fmt, - .vidioc_g_fmt_vid_overlay = virtio_media_g_fmt, - .vidioc_g_fmt_vid_out = virtio_media_g_fmt, - .vidioc_g_fmt_vid_out_overlay = virtio_media_g_fmt, - .vidioc_g_fmt_vbi_cap = virtio_media_g_fmt, - .vidioc_g_fmt_vbi_out = virtio_media_g_fmt, - .vidioc_g_fmt_sliced_vbi_cap = virtio_media_g_fmt, - .vidioc_g_fmt_sliced_vbi_out = virtio_media_g_fmt, - .vidioc_g_fmt_vid_cap_mplane = virtio_media_g_fmt, - .vidioc_g_fmt_vid_out_mplane = virtio_media_g_fmt, - .vidioc_g_fmt_sdr_cap = virtio_media_g_fmt, - .vidioc_g_fmt_sdr_out = virtio_media_g_fmt, - .vidioc_g_fmt_meta_cap = virtio_media_g_fmt, - .vidioc_g_fmt_meta_out = virtio_media_g_fmt, - - /* VIDIOC_S_FMT handlers */ - .vidioc_s_fmt_vid_cap = virtio_media_s_fmt, - .vidioc_s_fmt_vid_overlay = virtio_media_s_fmt, - .vidioc_s_fmt_vid_out = virtio_media_s_fmt, - .vidioc_s_fmt_vid_out_overlay = virtio_media_s_fmt, - .vidioc_s_fmt_vbi_cap = virtio_media_s_fmt, - .vidioc_s_fmt_vbi_out = virtio_media_s_fmt, - .vidioc_s_fmt_sliced_vbi_cap = virtio_media_s_fmt, - .vidioc_s_fmt_sliced_vbi_out = virtio_media_s_fmt, - .vidioc_s_fmt_vid_cap_mplane = virtio_media_s_fmt, - .vidioc_s_fmt_vid_out_mplane = virtio_media_s_fmt, - .vidioc_s_fmt_sdr_cap = virtio_media_s_fmt, - .vidioc_s_fmt_sdr_out = virtio_media_s_fmt, - .vidioc_s_fmt_meta_cap = virtio_media_s_fmt, - .vidioc_s_fmt_meta_out = virtio_media_s_fmt, - - /* VIDIOC_TRY_FMT handlers */ - .vidioc_try_fmt_vid_cap = virtio_media_try_fmt, - .vidioc_try_fmt_vid_overlay = virtio_media_try_fmt, - .vidioc_try_fmt_vid_out = virtio_media_try_fmt, - .vidioc_try_fmt_vid_out_overlay = virtio_media_try_fmt, - .vidioc_try_fmt_vbi_cap = virtio_media_try_fmt, - .vidioc_try_fmt_vbi_out = virtio_media_try_fmt, - .vidioc_try_fmt_sliced_vbi_cap = virtio_media_try_fmt, - .vidioc_try_fmt_sliced_vbi_out = virtio_media_try_fmt, - .vidioc_try_fmt_vid_cap_mplane = virtio_media_try_fmt, - .vidioc_try_fmt_vid_out_mplane = virtio_media_try_fmt, - .vidioc_try_fmt_sdr_cap = virtio_media_try_fmt, - .vidioc_try_fmt_sdr_out = virtio_media_try_fmt, - .vidioc_try_fmt_meta_cap = virtio_media_try_fmt, - .vidioc_try_fmt_meta_out = virtio_media_try_fmt, - - /* Buffer handlers */ - .vidioc_reqbufs = virtio_media_reqbufs, - .vidioc_querybuf = virtio_media_querybuf, - .vidioc_qbuf = virtio_media_qbuf, - .vidioc_expbuf = NULL, - .vidioc_dqbuf = virtio_media_dqbuf, - .vidioc_create_bufs = virtio_media_create_bufs, - .vidioc_prepare_buf = virtio_media_prepare_buf, - /* Overlay interface not supported yet */ - .vidioc_overlay = NULL, - /* Overlay interface not supported yet */ - .vidioc_g_fbuf = NULL, - /* Overlay interface not supported yet */ - .vidioc_s_fbuf = NULL, - - /* Stream on/off */ - .vidioc_streamon = virtio_media_streamon, - .vidioc_streamoff = virtio_media_streamoff, - - /* Standard handling */ - .vidioc_g_std = virtio_media_g_std, - .vidioc_s_std = virtio_media_s_std, - .vidioc_querystd = virtio_media_querystd, - - /* Input handling */ - .vidioc_enum_input = virtio_media_enuminput, - .vidioc_g_input = virtio_media_g_input, - .vidioc_s_input = virtio_media_s_input, - - /* Output handling */ - .vidioc_enum_output = virtio_media_enumoutput, - .vidioc_g_output = virtio_media_g_output, - .vidioc_s_output = virtio_media_s_output, - - /* Control handling */ - .vidioc_query_ext_ctrl = virtio_media_query_ext_ctrl, - .vidioc_g_ext_ctrls = virtio_media_g_ext_ctrls, - .vidioc_s_ext_ctrls = virtio_media_s_ext_ctrls, - .vidioc_try_ext_ctrls = virtio_media_try_ext_ctrls, - .vidioc_querymenu = virtio_media_querymenu, - - /* Audio ioctls */ - .vidioc_enumaudio = virtio_media_enumaudio, - .vidioc_g_audio = virtio_media_g_audio, - .vidioc_s_audio = virtio_media_s_audio, - - /* Audio out ioctls */ - .vidioc_enumaudout = virtio_media_enumaudout, - .vidioc_g_audout = virtio_media_g_audout, - .vidioc_s_audout = virtio_media_s_audout, - .vidioc_g_modulator = virtio_media_g_modulator, - .vidioc_s_modulator = virtio_media_s_modulator, - - /* Crop ioctls */ - /* Not directly an ioctl (part of VIDIOC_CROPCAP), so no need to implement */ - .vidioc_g_pixelaspect = NULL, - .vidioc_g_selection = virtio_media_g_selection, - .vidioc_s_selection = virtio_media_s_selection, - - /* Compression ioctls */ - /* Deprecated in V4L2. */ - .vidioc_g_jpegcomp = NULL, - /* Deprecated in V4L2. */ - .vidioc_s_jpegcomp = NULL, - .vidioc_g_enc_index = virtio_media_g_enc_index, - .vidioc_encoder_cmd = virtio_media_encoder_cmd, - .vidioc_try_encoder_cmd = virtio_media_try_encoder_cmd, - .vidioc_decoder_cmd = virtio_media_decoder_cmd, - .vidioc_try_decoder_cmd = virtio_media_try_decoder_cmd, - - /* Stream type-dependent parameter ioctls */ - .vidioc_g_parm = virtio_media_g_parm, - .vidioc_s_parm = virtio_media_s_parm, - - /* Tuner ioctls */ - .vidioc_g_tuner = virtio_media_g_tuner, - .vidioc_s_tuner = virtio_media_s_tuner, - .vidioc_g_frequency = virtio_media_g_frequency, - .vidioc_s_frequency = virtio_media_s_frequency, - .vidioc_enum_freq_bands = virtio_media_enum_freq_bands, - - /* Sliced VBI cap */ - .vidioc_g_sliced_vbi_cap = virtio_media_g_sliced_vbi_cap, - - /* Log status ioctl */ - /* Guest-only operation */ - .vidioc_log_status = NULL, - - .vidioc_s_hw_freq_seek = virtio_media_s_hw_freq_seek, - - .vidioc_enum_framesizes = virtio_media_enum_framesizes, - .vidioc_enum_frameintervals = virtio_media_enum_frameintervals, - - /* DV Timings IOCTLs */ - .vidioc_s_dv_timings = virtio_media_s_dv_timings, - .vidioc_g_dv_timings = virtio_media_g_dv_timings, - .vidioc_query_dv_timings = virtio_media_query_dv_timings, - .vidioc_enum_dv_timings = virtio_media_enum_dv_timings, - .vidioc_dv_timings_cap = virtio_media_dv_timings_cap, - .vidioc_g_edid = NULL, - .vidioc_s_edid = NULL, - - .vidioc_subscribe_event = virtio_media_subscribe_event, - .vidioc_unsubscribe_event = virtio_media_unsubscribe_event, - - /* For other private ioctls */ - .vidioc_default = NULL, -}; - -long virtio_media_device_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct video_device *video_dev = video_devdata(file); - struct virtio_media *vv = to_virtio_media(video_dev); - struct v4l2_fh *vfh = NULL; - struct v4l2_standard standard; - v4l2_std_id std_id = 0; - int ret; - - if (test_bit(V4L2_FL_USES_V4L2_FH, &video_dev->flags)) - vfh = file->private_data; - - mutex_lock(&vv->vlock); - - /* - * We need to handle a few ioctls manually because their result rely on - * vfd->tvnorms, which is normally updated by the driver as S_INPUT is - * called. Since we want to just pass these ioctls through, we have to hijack - * them from here. - */ - switch (cmd) { - case VIDIOC_S_STD: - ret = copy_from_user(&std_id, (void __user *)arg, - sizeof(std_id)); - if (ret) { - ret = -EINVAL; - break; - } - ret = virtio_media_s_std(file, vfh, std_id); - break; - case VIDIOC_ENUMSTD: - ret = copy_from_user(&standard, (void __user *)arg, - sizeof(standard)); - if (ret) { - ret = -EINVAL; - break; - } - ret = virtio_media_enumstd(file, vfh, &standard); - if (ret) - break; - ret = copy_to_user((void __user *)arg, &standard, - sizeof(standard)); - if (ret) - ret = -EINVAL; - break; - case VIDIOC_QUERYSTD: - ret = virtio_media_querystd(file, vfh, &std_id); - if (ret) - break; - ret = copy_to_user((void __user *)arg, &std_id, sizeof(std_id)); - if (ret) - ret = -EINVAL; - break; - default: - ret = video_ioctl2(file, cmd, arg); - break; - } - - mutex_unlock(&vv->vlock); - - return ret; -} diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c index c354d536bc66..47411d2cbd28 100644 --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c @@ -508,9 +508,11 @@ static void airoha_ppe_foe_flow_stats_update(struct airoha_ppe *ppe, FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); } -struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, - u32 hash) +static struct airoha_foe_entry * +airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) { + lockdep_assert_held(&ppe_lock); + if (hash < PPE_SRAM_NUM_ENTRIES) { u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); struct airoha_eth *eth = ppe->eth; @@ -537,6 +539,18 @@ struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, return ppe->foe + hash * sizeof(struct airoha_foe_entry); } +struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, + u32 hash) +{ + struct airoha_foe_entry *hwe; + + spin_lock_bh(&ppe_lock); + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); + spin_unlock_bh(&ppe_lock); + + return hwe; +} + static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, struct airoha_foe_entry *hwe) { @@ -651,7 +665,7 @@ airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, struct airoha_flow_table_entry *f; int type; - hwe_p = airoha_ppe_foe_get_entry(ppe, hash); + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, hash); if (!hwe_p) return -EINVAL; @@ -703,7 +717,7 @@ static void airoha_ppe_foe_insert_entry(struct airoha_ppe *ppe, spin_lock_bh(&ppe_lock); - hwe = airoha_ppe_foe_get_entry(ppe, hash); + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); if (!hwe) goto unlock; @@ -818,7 +832,7 @@ airoha_ppe_foe_flow_l2_entry_update(struct airoha_ppe *ppe, u32 ib1, state; int idle; - hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); + hwe = airoha_ppe_foe_get_entry_locked(ppe, iter->hash); if (!hwe) continue; @@ -855,7 +869,7 @@ static void airoha_ppe_foe_flow_entry_update(struct airoha_ppe *ppe, if (e->hash == 0xffff) goto unlock; - hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, e->hash); if (!hwe_p) goto unlock; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 218b1a09534c..b8c609d91d11 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1574,6 +1574,7 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe, unsigned int hdrlen = mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt); skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt - hdrlen, lro_num_seg); + skb_shinfo(skb)->gso_segs = lro_num_seg; /* Subtract one since we already counted this as one * "regular" packet in mlx5e_complete_rx_cqe() */ diff --git a/drivers/net/ethernet/sfc/tc_encap_actions.c b/drivers/net/ethernet/sfc/tc_encap_actions.c index 2258f854e5be..e872f926e438 100644 --- a/drivers/net/ethernet/sfc/tc_encap_actions.c +++ b/drivers/net/ethernet/sfc/tc_encap_actions.c @@ -442,7 +442,7 @@ static void efx_tc_update_encap(struct efx_nic *efx, rule = container_of(acts, struct efx_tc_flow_rule, acts); if (rule->fallback) fallback = rule->fallback; - else /* fallback: deliver to PF */ + else /* fallback of the fallback: deliver to PF */ fallback = &efx->tc->facts.pf; rc = efx_mae_update_rule(efx, fallback->fw_id, rule->fw_id); diff --git a/drivers/net/mdio/mdio-bcm-unimac.c b/drivers/net/mdio/mdio-bcm-unimac.c index b6e30bdf5325..7baab230008a 100644 --- a/drivers/net/mdio/mdio-bcm-unimac.c +++ b/drivers/net/mdio/mdio-bcm-unimac.c @@ -209,10 +209,9 @@ static int unimac_mdio_clk_set(struct unimac_mdio_priv *priv) if (ret) return ret; - if (!priv->clk) + rate = clk_get_rate(priv->clk); + if (!rate) rate = 250000000; - else - rate = clk_get_rate(priv->clk); div = (rate / (2 * priv->clk_freq)) - 1; if (div & ~MDIO_CLK_DIV_MASK) { diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index ce0994d9219a..7205c59ff729 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1467,16 +1467,21 @@ static unsigned long ds3231_clk_sqw_recalc_rate(struct clk_hw *hw, return ds3231_clk_sqw_rates[rate_sel]; } -static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int ds3231_clk_sqw_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = ARRAY_SIZE(ds3231_clk_sqw_rates) - 1; i >= 0; i--) { - if (ds3231_clk_sqw_rates[i] <= rate) - return ds3231_clk_sqw_rates[i]; + if (ds3231_clk_sqw_rates[i] <= req->rate) { + req->rate = ds3231_clk_sqw_rates[i]; + + return 0; + } } + req->rate = ds3231_clk_sqw_rates[ARRAY_SIZE(ds3231_clk_sqw_rates) - 1]; + return 0; } @@ -1536,7 +1541,7 @@ static const struct clk_ops ds3231_clk_sqw_ops = { .unprepare = ds3231_clk_sqw_unprepare, .is_prepared = ds3231_clk_sqw_is_prepared, .recalc_rate = ds3231_clk_sqw_recalc_rate, - .round_rate = ds3231_clk_sqw_round_rate, + .determine_rate = ds3231_clk_sqw_determine_rate, .set_rate = ds3231_clk_sqw_set_rate, }; diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 38e25f63597a..97423f1d0361 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -3,7 +3,7 @@ * An rtc driver for the Dallas/Maxim DS1685/DS1687 and related real-time * chips. * - * Copyright (C) 2011-2014 Joshua Kinard <kumba@gentoo.org>. + * Copyright (C) 2011-2014 Joshua Kinard <linux@kumba.dev>. * Copyright (C) 2009 Matthias Fuchs <matthias.fuchs@esd-electronics.com>. * * References: @@ -1436,7 +1436,7 @@ EXPORT_SYMBOL_GPL(ds1685_rtc_poweroff); /* ----------------------------------------------------------------------- */ -MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>"); +MODULE_AUTHOR("Joshua Kinard <linux@kumba.dev>"); MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd-electronics.com>"); MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 63f11ea3589d..7a170c0f9710 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -285,14 +285,19 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw, return clkout_rates[ret]; } -static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int hym8563_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) - if (clkout_rates[i] <= rate) - return clkout_rates[i]; + if (clkout_rates[i] <= req->rate) { + req->rate = clkout_rates[i]; + + return 0; + } + + req->rate = clkout_rates[0]; return 0; } @@ -363,7 +368,7 @@ static const struct clk_ops hym8563_clkout_ops = { .unprepare = hym8563_clkout_unprepare, .is_prepared = hym8563_clkout_is_prepared, .recalc_rate = hym8563_clkout_recalc_rate, - .round_rate = hym8563_clkout_round_rate, + .determine_rate = hym8563_clkout_determine_rate, .set_rate = hym8563_clkout_set_rate, }; diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 869358e9305b..740cab013f59 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -484,16 +484,17 @@ static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw, return sqw_to_m41t80_data(hw)->freq; } -static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int m41t80_sqw_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - if (rate >= M41T80_SQW_MAX_FREQ) - return M41T80_SQW_MAX_FREQ; - if (rate >= M41T80_SQW_MAX_FREQ / 4) - return M41T80_SQW_MAX_FREQ / 4; - if (!rate) - return 0; - return 1 << ilog2(rate); + if (req->rate >= M41T80_SQW_MAX_FREQ) + req->rate = M41T80_SQW_MAX_FREQ; + else if (req->rate >= M41T80_SQW_MAX_FREQ / 4) + req->rate = M41T80_SQW_MAX_FREQ / 4; + else if (req->rate) + req->rate = 1 << ilog2(req->rate); + + return 0; } static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate, @@ -564,7 +565,7 @@ static const struct clk_ops m41t80_sqw_ops = { .unprepare = m41t80_sqw_unprepare, .is_prepared = m41t80_sqw_is_prepared, .recalc_rate = m41t80_sqw_recalc_rate, - .round_rate = m41t80_sqw_round_rate, + .determine_rate = m41t80_sqw_determine_rate, .set_rate = m41t80_sqw_set_rate, }; diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c index a7bb37aaab9e..dfb5bad3a369 100644 --- a/drivers/rtc/rtc-max31335.c +++ b/drivers/rtc/rtc-max31335.c @@ -497,15 +497,17 @@ static unsigned long max31335_clkout_recalc_rate(struct clk_hw *hw, return max31335_clkout_freq[reg & freq_mask]; } -static long max31335_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int max31335_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int index; - index = find_closest(rate, max31335_clkout_freq, + index = find_closest(req->rate, max31335_clkout_freq, ARRAY_SIZE(max31335_clkout_freq)); - return max31335_clkout_freq[index]; + req->rate = max31335_clkout_freq[index]; + + return 0; } static int max31335_clkout_set_rate(struct clk_hw *hw, unsigned long rate, @@ -554,7 +556,7 @@ static int max31335_clkout_is_enabled(struct clk_hw *hw) static const struct clk_ops max31335_clkout_ops = { .recalc_rate = max31335_clkout_recalc_rate, - .round_rate = max31335_clkout_round_rate, + .determine_rate = max31335_clkout_determine_rate, .set_rate = max31335_clkout_set_rate, .enable = max31335_clkout_enable, .disable = max31335_clkout_disable, diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c index 76c5f464b2da..cd4b1db902e9 100644 --- a/drivers/rtc/rtc-nct3018y.c +++ b/drivers/rtc/rtc-nct3018y.c @@ -367,14 +367,19 @@ static unsigned long nct3018y_clkout_recalc_rate(struct clk_hw *hw, return clkout_rates[flags]; } -static long nct3018y_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int nct3018y_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) - if (clkout_rates[i] <= rate) - return clkout_rates[i]; + if (clkout_rates[i] <= req->rate) { + req->rate = clkout_rates[i]; + + return 0; + } + + req->rate = clkout_rates[0]; return 0; } @@ -446,7 +451,7 @@ static const struct clk_ops nct3018y_clkout_ops = { .unprepare = nct3018y_clkout_unprepare, .is_prepared = nct3018y_clkout_is_prepared, .recalc_rate = nct3018y_clkout_recalc_rate, - .round_rate = nct3018y_clkout_round_rate, + .determine_rate = nct3018y_clkout_determine_rate, .set_rate = nct3018y_clkout_set_rate, }; diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index e3b58cdb1eda..f643e0bd7351 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -405,14 +405,19 @@ static unsigned long pcf85063_clkout_recalc_rate(struct clk_hw *hw, return clkout_rates[buf]; } -static long pcf85063_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int pcf85063_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) - if (clkout_rates[i] <= rate) - return clkout_rates[i]; + if (clkout_rates[i] <= req->rate) { + req->rate = clkout_rates[i]; + + return 0; + } + + req->rate = clkout_rates[0]; return 0; } @@ -486,7 +491,7 @@ static const struct clk_ops pcf85063_clkout_ops = { .unprepare = pcf85063_clkout_unprepare, .is_prepared = pcf85063_clkout_is_prepared, .recalc_rate = pcf85063_clkout_recalc_rate, - .round_rate = pcf85063_clkout_round_rate, + .determine_rate = pcf85063_clkout_determine_rate, .set_rate = pcf85063_clkout_set_rate, }; diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index b2611697fa5e..4e61011fb7a9 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -330,14 +330,19 @@ static unsigned long pcf8563_clkout_recalc_rate(struct clk_hw *hw, return clkout_rates[buf]; } -static long pcf8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int pcf8563_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) - if (clkout_rates[i] <= rate) - return clkout_rates[i]; + if (clkout_rates[i] <= req->rate) { + req->rate = clkout_rates[i]; + + return 0; + } + + req->rate = clkout_rates[0]; return 0; } @@ -413,7 +418,7 @@ static const struct clk_ops pcf8563_clkout_ops = { .unprepare = pcf8563_clkout_unprepare, .is_prepared = pcf8563_clkout_is_prepared, .recalc_rate = pcf8563_clkout_recalc_rate, - .round_rate = pcf8563_clkout_round_rate, + .determine_rate = pcf8563_clkout_determine_rate, .set_rate = pcf8563_clkout_set_rate, }; diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index 868d1b1eb0f4..c2a531f0e125 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -731,14 +731,19 @@ static unsigned long rv3028_clkout_recalc_rate(struct clk_hw *hw, return clkout_rates[clkout]; } -static long rv3028_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int rv3028_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) - if (clkout_rates[i] <= rate) - return clkout_rates[i]; + if (clkout_rates[i] <= req->rate) { + req->rate = clkout_rates[i]; + + return 0; + } + + req->rate = clkout_rates[0]; return 0; } @@ -802,7 +807,7 @@ static const struct clk_ops rv3028_clkout_ops = { .unprepare = rv3028_clkout_unprepare, .is_prepared = rv3028_clkout_is_prepared, .recalc_rate = rv3028_clkout_recalc_rate, - .round_rate = rv3028_clkout_round_rate, + .determine_rate = rv3028_clkout_determine_rate, .set_rate = rv3028_clkout_set_rate, }; diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c index 2c6a8918acba..b8376bd1d905 100644 --- a/drivers/rtc/rtc-rv3032.c +++ b/drivers/rtc/rtc-rv3032.c @@ -646,19 +646,24 @@ static unsigned long rv3032_clkout_recalc_rate(struct clk_hw *hw, return clkout_xtal_rates[FIELD_GET(RV3032_CLKOUT2_FD_MSK, clkout)]; } -static long rv3032_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int rv3032_clkout_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i, hfd; - if (rate < RV3032_HFD_STEP) + if (req->rate < RV3032_HFD_STEP) for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) - if (clkout_xtal_rates[i] <= rate) - return clkout_xtal_rates[i]; + if (clkout_xtal_rates[i] <= req->rate) { + req->rate = clkout_xtal_rates[i]; - hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP); + return 0; + } + + hfd = DIV_ROUND_CLOSEST(req->rate, RV3032_HFD_STEP); - return RV3032_HFD_STEP * clamp(hfd, 0, 8192); + req->rate = RV3032_HFD_STEP * clamp(hfd, 0, 8192); + + return 0; } static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate, @@ -738,7 +743,7 @@ static const struct clk_ops rv3032_clkout_ops = { .unprepare = rv3032_clkout_unprepare, .is_prepared = rv3032_clkout_is_prepared, .recalc_rate = rv3032_clkout_recalc_rate, - .round_rate = rv3032_clkout_round_rate, + .determine_rate = rv3032_clkout_determine_rate, .set_rate = rv3032_clkout_set_rate, }; diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c75fddc83576..ce44e3498d37 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -72,7 +72,7 @@ static ssize_t rpmb_routing_model_show(struct device *dev, else s = "user"; - return scnprintf(buf, PAGE_SIZE, "%s\n", s); + return sysfs_emit(buf, "%s\n", s); } static DEVICE_ATTR_RO(rpmb_routing_model); diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index acc7998758ad..944f913f8592 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -977,7 +977,7 @@ static ssize_t implementation_id_show(struct device *dev, struct tee_ioctl_version_data vers; teedev->desc->ops->get_version(teedev, &vers); - return scnprintf(buf, PAGE_SIZE, "%d\n", vers.impl_id); + return sysfs_emit(buf, "%d\n", vers.impl_id); } static DEVICE_ATTR_RO(implementation_id); diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index daf6e5cfd59a..2a7d253d9c55 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -230,7 +230,7 @@ int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) { rc = -ENOMEM; - goto err; + goto err_pages; } for (i = 0; i < nr_pages; i++) @@ -243,11 +243,13 @@ int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, rc = shm_register(shm->ctx, shm, pages, nr_pages, (unsigned long)shm->kaddr); if (rc) - goto err; + goto err_kfree; } return 0; -err: +err_kfree: + kfree(pages); +err_pages: free_pages_exact(shm->kaddr, shm->size); shm->kaddr = NULL; return rc; @@ -560,9 +562,13 @@ EXPORT_SYMBOL_GPL(tee_shm_get_from_id); */ void tee_shm_put(struct tee_shm *shm) { - struct tee_device *teedev = shm->ctx->teedev; + struct tee_device *teedev; bool do_release = false; + if (!shm || !shm->ctx || !shm->ctx->teedev) + return; + + teedev = shm->ctx->teedev; mutex_lock(&teedev->mutex); if (refcount_dec_and_test(&shm->refcount)) { /* diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 23286e4d7b49..8570fdf2e14a 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -615,6 +615,7 @@ void vhost_dev_init(struct vhost_dev *dev, vq->log = NULL; vq->indirect = NULL; vq->heads = NULL; + vq->nheads = NULL; vq->dev = dev; mutex_init(&vq->mutex); vhost_vq_reset(dev, vq); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index f9cdbf8c53e3..37bd18730fe0 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1168,7 +1168,7 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, c->vc_screenbuf_size - delta); c->vc_origin = vga_vram_end - c->vc_screenbuf_size; vga_rolled_over = 0; - } else if (oldo - delta >= (unsigned long)c->vc_screenbuf) + } else c->vc_origin -= delta; c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char, diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index eabbc4bd7cf6..55f5731e94c3 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -837,7 +837,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, fg_vc->vc_rows); } - update_screen(vc_cons[fg_console].d); + if (fg_console != unit) + update_screen(vc_cons[fg_console].d); } /** @@ -1375,6 +1376,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, struct vc_data *svc; struct fbcon_ops *ops = info->fbcon_par; int rows, cols; + unsigned long ret = 0; p = &fb_display[unit]; @@ -1425,11 +1427,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); cols /= vc->vc_font.width; rows /= vc->vc_font.height; - vc_resize(vc, cols, rows); + ret = vc_resize(vc, cols, rows); - if (con_is_visible(vc)) { + if (con_is_visible(vc) && !ret) update_screen(vc); - } } static __inline__ void ywrap_up(struct vc_data *vc, int count) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 98e990ee2073..c147145a6593 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1005,7 +1005,7 @@ static void virtqueue_vring_init_split(struct vring_virtqueue_split *vring_split } } -static void virtqueue_reset_split(struct vring_virtqueue *vq) +static void virtqueue_reinit_split(struct vring_virtqueue *vq) { int num; @@ -1248,7 +1248,7 @@ static int virtqueue_resize_split(struct virtqueue *_vq, u32 num) err_state_extra: vring_free_split(&vring_split, vdev, vring_dma_dev(vq)); err: - virtqueue_reset_split(vq); + virtqueue_reinit_split(vq); return -ENOMEM; } @@ -2092,7 +2092,7 @@ static void virtqueue_vring_attach_packed(struct vring_virtqueue *vq, vq->free_head = 0; } -static void virtqueue_reset_packed(struct vring_virtqueue *vq) +static void virtqueue_reinit_packed(struct vring_virtqueue *vq) { memset(vq->packed.vring.device, 0, vq->packed.event_size_in_bytes); memset(vq->packed.vring.driver, 0, vq->packed.event_size_in_bytes); @@ -2219,7 +2219,7 @@ static int virtqueue_resize_packed(struct virtqueue *_vq, u32 num) err_state_extra: vring_free_packed(&vring_packed, vdev, vring_dma_dev(vq)); err_ring: - virtqueue_reset_packed(vq); + virtqueue_reinit_packed(vq); return -ENOMEM; } @@ -2860,9 +2860,9 @@ int virtqueue_reset(struct virtqueue *_vq, recycle_done(_vq); if (vq->packed_ring) - virtqueue_reset_packed(vq); + virtqueue_reinit_packed(vq); else - virtqueue_reset_split(vq); + virtqueue_reinit_split(vq); return virtqueue_enable_after_reset(_vq); } diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 7db904c7a7e8..3fc728efbf5c 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -2104,44 +2104,46 @@ static int invalidate_one_bucket(struct btree_trans *trans, if (bch2_bucket_is_open_safe(c, bucket.inode, bucket.offset)) return 0; - CLASS(btree_iter, alloc_iter)(trans, BTREE_ID_alloc, bucket, BTREE_ITER_cached); - struct bkey_s_c alloc_k = bch2_btree_iter_peek_slot(&alloc_iter); - ret = bkey_err(alloc_k); - if (ret) - return ret; + { + CLASS(btree_iter, alloc_iter)(trans, BTREE_ID_alloc, bucket, BTREE_ITER_cached); + struct bkey_s_c alloc_k = bch2_btree_iter_peek_slot(&alloc_iter); + ret = bkey_err(alloc_k); + if (ret) + return ret; - struct bch_alloc_v4 a_convert; - const struct bch_alloc_v4 *a = bch2_alloc_to_v4(alloc_k, &a_convert); + struct bch_alloc_v4 a_convert; + const struct bch_alloc_v4 *a = bch2_alloc_to_v4(alloc_k, &a_convert); - /* We expect harmless races here due to the btree write buffer: */ - if (lru_pos_time(lru_iter->pos) != alloc_lru_idx_read(*a)) - return 0; + /* We expect harmless races here due to the btree write buffer: */ + if (lru_pos_time(lru_iter->pos) != alloc_lru_idx_read(*a)) + return 0; - /* - * Impossible since alloc_lru_idx_read() only returns nonzero if the - * bucket is supposed to be on the cached bucket LRU (i.e. - * BCH_DATA_cached) - * - * bch2_lru_validate() also disallows lru keys with lru_pos_time() == 0 - */ - BUG_ON(a->data_type != BCH_DATA_cached); - BUG_ON(a->dirty_sectors); + /* + * Impossible since alloc_lru_idx_read() only returns nonzero if the + * bucket is supposed to be on the cached bucket LRU (i.e. + * BCH_DATA_cached) + * + * bch2_lru_validate() also disallows lru keys with lru_pos_time() == 0 + */ + BUG_ON(a->data_type != BCH_DATA_cached); + BUG_ON(a->dirty_sectors); - if (!a->cached_sectors) { - bch2_check_bucket_backpointer_mismatch(trans, ca, bucket.offset, - true, last_flushed); - return 0; - } + if (!a->cached_sectors) { + bch2_check_bucket_backpointer_mismatch(trans, ca, bucket.offset, + true, last_flushed); + return 0; + } - unsigned cached_sectors = a->cached_sectors; - u8 gen = a->gen; + unsigned cached_sectors = a->cached_sectors; + u8 gen = a->gen; - ret = invalidate_one_bucket_by_bps(trans, ca, bucket, gen, last_flushed); - if (ret) - return ret; + ret = invalidate_one_bucket_by_bps(trans, ca, bucket, gen, last_flushed); + if (ret) + return ret; - trace_and_count(c, bucket_invalidate, c, bucket.inode, bucket.offset, cached_sectors); - --*nr_to_invalidate; + trace_and_count(c, bucket_invalidate, c, bucket.inode, bucket.offset, cached_sectors); + --*nr_to_invalidate; + } fsck_err: return ret; } diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c index 1aab9a63d0cb..45d3db41225a 100644 --- a/fs/bcachefs/backpointers.c +++ b/fs/bcachefs/backpointers.c @@ -395,22 +395,24 @@ static int bch2_check_backpointer_has_valid_bucket(struct btree_trans *trans, st return ret; } - CLASS(btree_iter, alloc_iter)(trans, BTREE_ID_alloc, bucket, 0); - struct bkey_s_c alloc_k = bch2_btree_iter_peek_slot(&alloc_iter); - ret = bkey_err(alloc_k); - if (ret) - return ret; - - if (alloc_k.k->type != KEY_TYPE_alloc_v4) { - ret = bch2_backpointers_maybe_flush(trans, k, last_flushed); + { + CLASS(btree_iter, alloc_iter)(trans, BTREE_ID_alloc, bucket, 0); + struct bkey_s_c alloc_k = bch2_btree_iter_peek_slot(&alloc_iter); + ret = bkey_err(alloc_k); if (ret) return ret; - if (fsck_err(trans, backpointer_to_missing_alloc, - "backpointer for nonexistent alloc key: %llu:%llu:0\n%s", - alloc_iter.pos.inode, alloc_iter.pos.offset, - (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) - ret = bch2_backpointer_del(trans, k.k->p); + if (alloc_k.k->type != KEY_TYPE_alloc_v4) { + ret = bch2_backpointers_maybe_flush(trans, k, last_flushed); + if (ret) + return ret; + + if (fsck_err(trans, backpointer_to_missing_alloc, + "backpointer for nonexistent alloc key: %llu:%llu:0\n%s", + alloc_iter.pos.inode, alloc_iter.pos.offset, + (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) + ret = bch2_backpointer_del(trans, k.k->p); + } } fsck_err: return ret; diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 45c15bdaa6f4..16d08dfb5f19 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -386,14 +386,6 @@ do { \ ##__VA_ARGS__, bch2_err_str(_ret)); \ } while (0) -static inline int __bch2_err_trace(struct bch_fs *c, int err) -{ - trace_error_throw(c, err, _THIS_IP_); - return err; -} - -#define bch_err_throw(_c, _err) __bch2_err_trace(_c, -BCH_ERR_##_err) - /* Parameters that are useful for debugging, but should always be compiled in: */ #define BCH_DEBUG_PARAMS_ALWAYS() \ BCH_DEBUG_PARAM(key_merging_disabled, \ @@ -845,8 +837,8 @@ struct bch_fs { unsigned long errors_silent[BITS_TO_LONGS(BCH_FSCK_ERR_MAX)]; u64 btrees_lost_data; } sb; - DARRAY(enum bcachefs_metadata_version) - incompat_versions_requested; + + unsigned long incompat_versions_requested[BITS_TO_LONGS(BCH_VERSION_MINOR(bcachefs_metadata_version_current))]; struct unicode_map *cf_encoding; @@ -1153,6 +1145,15 @@ struct bch_fs { struct mutex fsck_error_counts_lock; }; +static inline int __bch2_err_trace(struct bch_fs *c, int err) +{ + this_cpu_inc(c->counters[BCH_COUNTER_error_throw]); + trace_error_throw(c, err, _THIS_IP_); + return err; +} + +#define bch_err_throw(_c, _err) __bch2_err_trace(_c, -BCH_ERR_##_err) + extern struct wait_queue_head bch2_read_only_wait; static inline bool bch2_ro_ref_tryget(struct bch_fs *c) diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index b4a04df5ea95..7a0b602c1b27 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -423,7 +423,8 @@ enum bch_bkey_type_flags { x(logged_op_truncate, 32, BKEY_TYPE_strict_btree_checks) \ x(logged_op_finsert, 33, BKEY_TYPE_strict_btree_checks) \ x(accounting, 34, BKEY_TYPE_strict_btree_checks) \ - x(inode_alloc_cursor, 35, BKEY_TYPE_strict_btree_checks) + x(inode_alloc_cursor, 35, BKEY_TYPE_strict_btree_checks) \ + x(extent_whiteout, 36, BKEY_TYPE_strict_btree_checks) enum bch_bkey_type { #define x(name, nr, ...) KEY_TYPE_##name = nr, @@ -440,6 +441,10 @@ struct bch_whiteout { struct bch_val v; }; +struct bch_extent_whiteout { + struct bch_val v; +}; + struct bch_error { struct bch_val v; }; @@ -700,7 +705,8 @@ struct bch_sb_field_ext { x(extent_flags, BCH_VERSION(1, 25)) \ x(snapshot_deletion_v2, BCH_VERSION(1, 26)) \ x(fast_device_removal, BCH_VERSION(1, 27)) \ - x(inode_has_case_insensitive, BCH_VERSION(1, 28)) + x(inode_has_case_insensitive, BCH_VERSION(1, 28)) \ + x(extent_snapshot_whiteouts, BCH_VERSION(1, 29)) enum bcachefs_metadata_version { bcachefs_metadata_version_min = 9, @@ -1340,6 +1346,7 @@ enum btree_id_flags { BTREE_IS_snapshots| \ BTREE_IS_data, \ BIT_ULL(KEY_TYPE_whiteout)| \ + BIT_ULL(KEY_TYPE_extent_whiteout)| \ BIT_ULL(KEY_TYPE_error)| \ BIT_ULL(KEY_TYPE_cookie)| \ BIT_ULL(KEY_TYPE_extent)| \ @@ -1431,9 +1438,9 @@ enum btree_id { */ #define BTREE_ID_NR_MAX 63 -static inline bool btree_id_is_alloc(enum btree_id id) +static inline bool btree_id_is_alloc(enum btree_id btree) { - switch (id) { + switch (btree) { case BTREE_ID_alloc: case BTREE_ID_backpointers: case BTREE_ID_need_discard: @@ -1447,6 +1454,33 @@ static inline bool btree_id_is_alloc(enum btree_id id) } } +/* We can reconstruct these btrees from information in other btrees */ +static inline bool btree_id_can_reconstruct(enum btree_id btree) +{ + if (btree_id_is_alloc(btree)) + return true; + + switch (btree) { + case BTREE_ID_snapshot_trees: + case BTREE_ID_deleted_inodes: + case BTREE_ID_rebalance_work: + case BTREE_ID_subvolume_children: + return true; + default: + return false; + } +} + +/* + * We can reconstruct BTREE_ID_alloc, but reconstucting it from scratch is not + * so cheap and OOMs on huge filesystems (until we have online + * check_allocations) + */ +static inline bool btree_id_recovers_from_scan(enum btree_id btree) +{ + return btree == BTREE_ID_alloc || !btree_id_can_reconstruct(btree); +} + #define BTREE_MAX_DEPTH 4U /* Btree nodes */ diff --git a/fs/bcachefs/bkey_methods.c b/fs/bcachefs/bkey_methods.c index fcd8c82cba4f..75d73677c4d8 100644 --- a/fs/bcachefs/bkey_methods.c +++ b/fs/bcachefs/bkey_methods.c @@ -41,6 +41,10 @@ static int deleted_key_validate(struct bch_fs *c, struct bkey_s_c k, .key_validate = deleted_key_validate, \ }) +#define bch2_bkey_ops_extent_whiteout ((struct bkey_ops) { \ + .key_validate = deleted_key_validate, \ +}) + static int empty_val_key_validate(struct bch_fs *c, struct bkey_s_c k, struct bkey_validate_context from) { @@ -203,7 +207,7 @@ int __bch2_bkey_validate(struct bch_fs *c, struct bkey_s_c k, ? bch2_bkey_types[k.k->type] : "(unknown)"); - if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) { + if (btree_node_type_is_extents(type) && !bkey_extent_whiteout(k.k)) { bkey_fsck_err_on(k.k->size == 0, c, bkey_extent_size_zero, "size == 0"); diff --git a/fs/bcachefs/bkey_types.h b/fs/bcachefs/bkey_types.h index b4f328f9853c..88a48ce63656 100644 --- a/fs/bcachefs/bkey_types.h +++ b/fs/bcachefs/bkey_types.h @@ -44,6 +44,11 @@ static inline void set_bkey_val_bytes(struct bkey *k, unsigned bytes) #define bkey_whiteout(_k) \ ((_k)->type == KEY_TYPE_deleted || (_k)->type == KEY_TYPE_whiteout) +#define bkey_extent_whiteout(_k) \ + ((_k)->type == KEY_TYPE_deleted || \ + (_k)->type == KEY_TYPE_whiteout || \ + (_k)->type == KEY_TYPE_extent_whiteout) + /* bkey with split value, const */ struct bkey_s_c { const struct bkey *k; diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 2f7c384a8c81..59638d09e1fd 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -214,7 +214,7 @@ void bch2_node_pin(struct bch_fs *c, struct btree *b) struct btree_cache *bc = &c->btree_cache; guard(mutex)(&bc->lock); - if (b != btree_node_root(c, b) && !btree_node_pinned(b)) { + if (!btree_node_is_root(c, b) && !btree_node_pinned(b)) { set_btree_node_pinned(b); list_move(&b->list, &bc->live[1].list); bc->live[0].nr--; @@ -788,7 +788,7 @@ struct btree *bch2_btree_node_mem_alloc(struct btree_trans *trans, bool pcpu_rea goto got_node; } - b = __btree_node_mem_alloc(c, GFP_NOWAIT|__GFP_NOWARN); + b = __btree_node_mem_alloc(c, GFP_NOWAIT); if (b) { bch2_btree_lock_init(&b->c, pcpu_read_locks ? SIX_LOCK_INIT_PCPU : 0, GFP_NOWAIT); } else { @@ -826,7 +826,7 @@ got_node: mutex_unlock(&bc->lock); - if (btree_node_data_alloc(c, b, GFP_NOWAIT|__GFP_NOWARN)) { + if (btree_node_data_alloc(c, b, GFP_NOWAIT)) { bch2_trans_unlock(trans); if (btree_node_data_alloc(c, b, GFP_KERNEL|__GFP_NOWARN)) goto err; diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h index 649e9dfd178a..035b2cb25077 100644 --- a/fs/bcachefs/btree_cache.h +++ b/fs/bcachefs/btree_cache.h @@ -144,6 +144,14 @@ static inline struct btree *btree_node_root(struct bch_fs *c, struct btree *b) return r ? r->b : NULL; } +static inline bool btree_node_is_root(struct bch_fs *c, struct btree *b) +{ + struct btree *root = btree_node_root(c, b); + + BUG_ON(b != root && b->c.level >= root->c.level); + return b == root; +} + const char *bch2_btree_id_str(enum btree_id); /* avoid */ void bch2_btree_id_to_text(struct printbuf *, enum btree_id); void bch2_btree_id_level_to_text(struct printbuf *, enum btree_id, unsigned); diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index ce3c7750a922..ae7d260589d8 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -44,27 +44,6 @@ #include <linux/rcupdate.h> #include <linux/sched/task.h> -/* - * Returns true if it's a btree we can easily reconstruct, or otherwise won't - * cause data loss if it's missing: - */ -static bool btree_id_important(enum btree_id btree) -{ - if (btree_id_is_alloc(btree)) - return false; - - switch (btree) { - case BTREE_ID_quotas: - case BTREE_ID_snapshot_trees: - case BTREE_ID_logged_ops: - case BTREE_ID_rebalance_work: - case BTREE_ID_subvolume_children: - return false; - default: - return true; - } -} - static const char * const bch2_gc_phase_strs[] = { #define x(n) #n, GC_PHASES() @@ -282,6 +261,41 @@ fsck_err: return ret; } +static int btree_check_root_boundaries(struct btree_trans *trans, struct btree *b) +{ + struct bch_fs *c = trans->c; + struct printbuf buf = PRINTBUF; + int ret = 0; + + BUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 && + !bpos_eq(bkey_i_to_btree_ptr_v2(&b->key)->v.min_key, + b->data->min_key)); + + prt_str(&buf, " at "); + bch2_btree_pos_to_text(&buf, c, b); + + if (mustfix_fsck_err_on(!bpos_eq(b->data->min_key, POS_MIN), + trans, btree_node_topology_bad_root_min_key, + "btree root with incorrect min_key%s", buf.buf)) { + ret = set_node_min(c, b, POS_MIN); + if (ret) + goto err; + } + + if (mustfix_fsck_err_on(!bpos_eq(b->data->max_key, SPOS_MAX), + trans, btree_node_topology_bad_root_max_key, + "btree root with incorrect min_key%s", buf.buf)) { + ret = set_node_max(c, b, SPOS_MAX); + if (ret) + goto err; + } + +err: +fsck_err: + printbuf_exit(&buf); + return ret; +} + static int btree_repair_node_end(struct btree_trans *trans, struct btree *b, struct btree *child, struct bpos *pulled_from_scan) { @@ -522,45 +536,55 @@ fsck_err: return ret; } -static int bch2_check_root(struct btree_trans *trans, enum btree_id btree, +static int bch2_topology_check_root(struct btree_trans *trans, enum btree_id btree, bool *reconstructed_root) { struct bch_fs *c = trans->c; struct btree_root *r = bch2_btree_id_root(c, btree); - CLASS(printbuf, buf)(); - int ret = 0; - bch2_btree_id_to_text(&buf, btree); - - if (r->error) { - bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf); + if (!r->error) + return 0; - ret = bch2_btree_has_scanned_nodes(c, btree); - if (ret < 0) - goto err; + CLASS(printbuf, buf)(); + int ret = 0; - if (!ret) { - __fsck_err(trans, - FSCK_CAN_FIX|(!btree_id_important(btree) ? FSCK_AUTOFIX : 0), - btree_root_unreadable_and_scan_found_nothing, - "no nodes found for btree %s, continue?", buf.buf); + if (!btree_id_recovers_from_scan(btree)) { + r->alive = false; + r->error = 0; + bch2_btree_root_alloc_fake_trans(trans, btree, 0); + ret = bch2_btree_lost_data(c, &buf, btree); + bch2_print_str(c, KERN_NOTICE, buf.buf); + goto out; + } - r->alive = false; - r->error = 0; - bch2_btree_root_alloc_fake_trans(trans, btree, 0); - } else { - r->alive = false; - r->error = 0; - bch2_btree_root_alloc_fake_trans(trans, btree, 1); + bch2_btree_id_to_text(&buf, btree); + bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf); - bch2_shoot_down_journal_keys(c, btree, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); - ret = bch2_get_scanned_nodes(c, btree, 0, POS_MIN, SPOS_MAX); - if (ret) - return ret; - } + ret = bch2_btree_has_scanned_nodes(c, btree); + if (ret < 0) + goto err; - *reconstructed_root = true; + if (!ret) { + __fsck_err(trans, + FSCK_CAN_FIX|(btree_id_can_reconstruct(btree) ? FSCK_AUTOFIX : 0), + btree_root_unreadable_and_scan_found_nothing, + "no nodes found for btree %s, continue?", buf.buf); + + r->alive = false; + r->error = 0; + bch2_btree_root_alloc_fake_trans(trans, btree, 0); + } else { + r->alive = false; + r->error = 0; + bch2_btree_root_alloc_fake_trans(trans, btree, 1); + + bch2_shoot_down_journal_keys(c, btree, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); + ret = bch2_get_scanned_nodes(c, btree, 0, POS_MIN, SPOS_MAX); + if (ret) + return ret; } +out: + *reconstructed_root = true; err: fsck_err: bch_err_fn(c, ret); @@ -578,7 +602,7 @@ int bch2_check_topology(struct bch_fs *c) for (unsigned i = 0; i < btree_id_nr_alive(c) && !ret; i++) { bool reconstructed_root = false; recover: - ret = lockrestart_do(trans, bch2_check_root(trans, i, &reconstructed_root)); + ret = lockrestart_do(trans, bch2_topology_check_root(trans, i, &reconstructed_root)); if (ret) break; @@ -586,7 +610,8 @@ recover: struct btree *b = r->b; btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read); - ret = bch2_btree_repair_topology_recurse(trans, b, &pulled_from_scan); + ret = btree_check_root_boundaries(trans, b) ?: + bch2_btree_repair_topology_recurse(trans, b, &pulled_from_scan); six_unlock_read(&b->c.lock); if (bch2_err_matches(ret, BCH_ERR_topology_repair_drop_this_node)) { diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index 8a03cd75a64f..276cf088539e 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -131,7 +131,7 @@ static void *btree_bounce_alloc(struct bch_fs *c, size_t size, BUG_ON(size > c->opts.btree_node_size); *used_mempool = false; - p = kvmalloc(size, __GFP_NOWARN|GFP_NOWAIT); + p = kvmalloc(size, GFP_NOWAIT); if (!p) { *used_mempool = true; p = mempool_alloc(&c->btree_bounce_pool, GFP_NOFS); diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c index ff580f76a641..546b559fe3ce 100644 --- a/fs/bcachefs/btree_iter.c +++ b/fs/bcachefs/btree_iter.c @@ -2366,7 +2366,9 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos en bch2_trans_verify_not_unlocked_or_in_restart(trans); bch2_btree_iter_verify_entry_exit(iter); - EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX)); + EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && + !(iter->flags & BTREE_ITER_nofilter_whiteouts) && + bkey_eq(end, POS_MAX)); ret = trans_maybe_inject_restart(trans, _RET_IP_); if (unlikely(ret)) { @@ -2450,10 +2452,27 @@ struct bkey_s_c bch2_btree_iter_peek_max(struct btree_iter *iter, struct bpos en continue; } - if (bkey_whiteout(k.k) && - !(iter->flags & BTREE_ITER_key_cache_fill)) { - search_key = bkey_successor(iter, k.k->p); - continue; + if (!(iter->flags & BTREE_ITER_nofilter_whiteouts)) { + /* + * KEY_TYPE_extent_whiteout indicates that there + * are no extents that overlap with this + * whiteout - meaning bkey_start_pos() is + * monotonically increasing when including + * KEY_TYPE_extent_whiteout (not + * KEY_TYPE_whiteout). + * + * Without this @end wouldn't be able to + * terminate searches and we'd have to scan + * through tons of whiteouts: + */ + if (k.k->type == KEY_TYPE_extent_whiteout && + bkey_ge(k.k->p, end)) + goto end; + + if (bkey_extent_whiteout(k.k)) { + search_key = bkey_successor(iter, k.k->p); + continue; + } } } @@ -2711,7 +2730,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *iter, struct bp saved_path = 0; } - if (!bkey_whiteout(k.k)) { + if (!bkey_extent_whiteout(k.k)) { saved_path = btree_path_clone(trans, iter->path, iter->flags & BTREE_ITER_intent, _THIS_IP_); @@ -2724,7 +2743,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev_min(struct btree_iter *iter, struct bp continue; } - if (bkey_whiteout(k.k)) { + if (bkey_extent_whiteout(k.k)) { search_key = bkey_predecessor(iter, k.k->p); search_key.snapshot = U32_MAX; continue; @@ -2865,9 +2884,9 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) iter->k = *k.k; } - if (unlikely(k.k->type == KEY_TYPE_whiteout && + if (unlikely(bkey_extent_whiteout(k.k) && (iter->flags & BTREE_ITER_filter_snapshots) && - !(iter->flags & BTREE_ITER_key_cache_fill))) + !(iter->flags & BTREE_ITER_nofilter_whiteouts))) iter->k.type = KEY_TYPE_deleted; } else { struct bpos next; @@ -2878,31 +2897,40 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) EBUG_ON(btree_iter_path(trans, iter)->level); - if (iter->flags & BTREE_ITER_intent) { - struct btree_iter iter2; + struct btree_iter iter2; - bch2_trans_copy_iter(&iter2, iter); - k = bch2_btree_iter_peek_max(&iter2, end); + bch2_trans_copy_iter(&iter2, iter); + iter2.flags |= BTREE_ITER_nofilter_whiteouts; - if (k.k && !bkey_err(k)) { - swap(iter->key_cache_path, iter2.key_cache_path); - iter->k = iter2.k; - k.k = &iter->k; + while (1) { + k = bch2_btree_iter_peek_max(&iter2, end); + if ((iter2.flags & BTREE_ITER_is_extents) && + k.k && + !bkey_err(k) && + k.k->type == KEY_TYPE_whiteout) { + bch2_btree_iter_set_pos(&iter2, k.k->p); + continue; } - bch2_trans_iter_exit(&iter2); - } else { - struct bpos pos = iter->pos; - k = bch2_btree_iter_peek_max(iter, end); - if (unlikely(bkey_err(k))) - bch2_btree_iter_set_pos(iter, pos); - else - iter->pos = pos; + break; + } + + if (k.k && !bkey_err(k)) { + swap(iter->key_cache_path, iter2.key_cache_path); + iter->k = iter2.k; + k.k = &iter->k; } + bch2_trans_iter_exit(&iter2); if (unlikely(bkey_err(k))) goto out; + if (unlikely(k.k && + bkey_extent_whiteout(k.k) && + (iter->flags & BTREE_ITER_filter_snapshots) && + !(iter->flags & BTREE_ITER_nofilter_whiteouts))) + iter->k.type = KEY_TYPE_deleted; + next = k.k ? bkey_start_pos(k.k) : POS_MAX; if (bkey_lt(iter->pos, next)) { diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index b117cb5d7f94..c8fc6ee01d96 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -954,7 +954,7 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); #define allocate_dropping_locks_errcode(_trans, _do) \ ({ \ - gfp_t _gfp = GFP_NOWAIT|__GFP_NOWARN; \ + gfp_t _gfp = GFP_NOWAIT; \ int _ret = _do; \ \ if (bch2_err_matches(_ret, ENOMEM)) { \ @@ -966,7 +966,7 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); #define allocate_dropping_locks(_trans, _ret, _do) \ ({ \ - gfp_t _gfp = GFP_NOWAIT|__GFP_NOWARN; \ + gfp_t _gfp = GFP_NOWAIT; \ typeof(_do) _p = _do; \ \ _ret = 0; \ @@ -979,7 +979,7 @@ struct bkey_s_c bch2_btree_iter_peek_and_restart_outlined(struct btree_iter *); #define allocate_dropping_locks_norelock(_trans, _lock_dropped, _do) \ ({ \ - gfp_t _gfp = GFP_NOWAIT|__GFP_NOWARN; \ + gfp_t _gfp = GFP_NOWAIT; \ typeof(_do) _p = _do; \ _lock_dropped = false; \ if (unlikely(!_p)) { \ diff --git a/fs/bcachefs/btree_key_cache.c b/fs/bcachefs/btree_key_cache.c index 72c803f7b8d1..4890cbc88e7c 100644 --- a/fs/bcachefs/btree_key_cache.c +++ b/fs/bcachefs/btree_key_cache.c @@ -325,6 +325,7 @@ static noinline int btree_key_cache_fill(struct btree_trans *trans, CLASS(btree_iter, iter)(trans, ck_path->btree_id, ck_path->pos, BTREE_ITER_intent| + BTREE_ITER_nofilter_whiteouts| BTREE_ITER_key_cache_fill| BTREE_ITER_cached_nofill); iter.flags &= ~BTREE_ITER_with_journal; diff --git a/fs/bcachefs/btree_node_scan.c b/fs/bcachefs/btree_node_scan.c index 4b7b5ca74ba1..b618a0bd1186 100644 --- a/fs/bcachefs/btree_node_scan.c +++ b/fs/bcachefs/btree_node_scan.c @@ -149,7 +149,7 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca, bch2_encrypt(c, BSET_CSUM_TYPE(&bn->keys), nonce, &bn->flags, bytes); } - if (btree_id_is_alloc(BTREE_NODE_ID(bn))) + if (btree_id_can_reconstruct(BTREE_NODE_ID(bn))) return; if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH) @@ -534,7 +534,7 @@ int bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree) int bch2_get_scanned_nodes(struct bch_fs *c, enum btree_id btree, unsigned level, struct bpos node_min, struct bpos node_max) { - if (btree_id_is_alloc(btree)) + if (!btree_id_recovers_from_scan(btree)) return 0; struct find_btree_nodes *f = &c->found_btree_nodes; diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c index 8b94a8156fbf..4d58bdb233e9 100644 --- a/fs/bcachefs/btree_trans_commit.c +++ b/fs/bcachefs/btree_trans_commit.c @@ -449,7 +449,7 @@ static int btree_key_can_insert_cached(struct btree_trans *trans, unsigned flags return 0; new_u64s = roundup_pow_of_two(u64s); - new_k = krealloc(ck->k, new_u64s * sizeof(u64), GFP_NOWAIT|__GFP_NOWARN); + new_k = krealloc(ck->k, new_u64s * sizeof(u64), GFP_NOWAIT); if (unlikely(!new_k)) return btree_key_can_insert_cached_slowpath(trans, flags, path, new_u64s); diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index ffa250008d91..e893eb938bb3 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -229,6 +229,7 @@ struct btree_node_iter { x(snapshot_field) \ x(all_snapshots) \ x(filter_snapshots) \ + x(nofilter_whiteouts) \ x(nopreserve) \ x(cached_nofill) \ x(key_cache_fill) \ @@ -839,15 +840,15 @@ static inline bool btree_node_type_has_triggers(enum btree_node_type type) return BIT_ULL(type) & BTREE_NODE_TYPE_HAS_TRIGGERS; } -static inline bool btree_id_is_extents(enum btree_id btree) -{ - const u64 mask = 0 +static const u64 btree_is_extents_mask = 0 #define x(name, nr, flags, ...) |((!!((flags) & BTREE_IS_extents)) << nr) - BCH_BTREE_IDS() +BCH_BTREE_IDS() #undef x - ; +; - return BIT_ULL(btree) & mask; +static inline bool btree_id_is_extents(enum btree_id btree) +{ + return BIT_ULL(btree) & btree_is_extents_mask; } static inline bool btree_node_type_is_extents(enum btree_node_type type) @@ -866,6 +867,11 @@ static inline bool btree_type_has_snapshots(enum btree_id btree) return BIT_ULL(btree) & btree_has_snapshots_mask; } +static inline bool btree_id_is_extents_snapshots(enum btree_id btree) +{ + return BIT_ULL(btree) & btree_has_snapshots_mask & btree_is_extents_mask; +} + static inline bool btree_type_has_snapshot_field(enum btree_id btree) { const u64 mask = 0 diff --git a/fs/bcachefs/btree_update.c b/fs/bcachefs/btree_update.c index 566478728aa2..053a837cf241 100644 --- a/fs/bcachefs/btree_update.c +++ b/fs/bcachefs/btree_update.c @@ -215,7 +215,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, return ret; } - if (bkey_le(old.k->p, new.k->p)) { + if (!back_split) { update = bch2_trans_kmalloc(trans, sizeof(*update)); if ((ret = PTR_ERR_OR_ZERO(update))) return ret; @@ -224,23 +224,21 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans, update->k.p = old.k->p; update->k.p.snapshot = new.k->p.snapshot; - if (new.k->p.snapshot != old.k->p.snapshot) { - update->k.type = KEY_TYPE_whiteout; - } else if (btree_type_has_snapshots(btree_id)) { - ret = need_whiteout_for_snapshot(trans, btree_id, update->k.p); + if (btree_type_has_snapshots(btree_id)) { + ret = new.k->p.snapshot != old.k->p.snapshot + ? 1 + : need_whiteout_for_snapshot(trans, btree_id, update->k.p); if (ret < 0) return ret; if (ret) - update->k.type = KEY_TYPE_whiteout; + update->k.type = extent_whiteout_type(trans->c, iter->btree_id, new.k); } ret = bch2_btree_insert_nonextent(trans, btree_id, update, BTREE_UPDATE_internal_snapshot_node|flags); if (ret) return ret; - } - - if (back_split) { + } else { update = bch2_bkey_make_mut_noupdate(trans, old); if ((ret = PTR_ERR_OR_ZERO(update))) return ret; @@ -267,7 +265,8 @@ static int bch2_trans_update_extent(struct btree_trans *trans, CLASS(btree_iter, iter)(trans, btree_id, bkey_start_pos(&insert->k), BTREE_ITER_intent| BTREE_ITER_with_updates| - BTREE_ITER_not_extents); + BTREE_ITER_not_extents| + BTREE_ITER_nofilter_whiteouts); struct bkey_s_c k = bch2_btree_iter_peek_max(&iter, POS(insert->k.p.inode, U64_MAX)); int ret = bkey_err(k); if (ret) @@ -285,12 +284,40 @@ static int bch2_trans_update_extent(struct btree_trans *trans, goto next; } - while (bkey_gt(insert->k.p, bkey_start_pos(k.k))) { - bool done = bkey_lt(insert->k.p, k.k->p); + while (true) { + BUG_ON(bkey_le(k.k->p, bkey_start_pos(&insert->k))); - ret = bch2_trans_update_extent_overwrite(trans, &iter, flags, k, bkey_i_to_s_c(insert)); - if (ret) - return ret; + /* + * When KEY_TYPE_whiteout is included, bkey_start_pos is not + * monotonically increasing + */ + if (k.k->type != KEY_TYPE_whiteout && bkey_le(insert->k.p, bkey_start_pos(k.k))) + break; + + bool done = k.k->type != KEY_TYPE_whiteout && bkey_lt(insert->k.p, k.k->p); + + if (bkey_extent_whiteout(k.k)) { + enum bch_bkey_type whiteout_type = extent_whiteout_type(trans->c, btree_id, &insert->k); + + if (bkey_le(k.k->p, insert->k.p) && + k.k->type != whiteout_type) { + struct bkey_i *update = bch2_bkey_make_mut_noupdate(trans, k); + ret = PTR_ERR_OR_ZERO(update); + if (ret) + return ret; + + update->k.p.snapshot = iter.snapshot; + update->k.type = whiteout_type; + + ret = bch2_trans_update(trans, &iter, update, 0); + if (ret) + return ret; + } + } else { + ret = bch2_trans_update_extent_overwrite(trans, &iter, flags, k, bkey_i_to_s_c(insert)); + if (ret) + return ret; + } if (done) goto out; diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h index 663739db82b1..18560ca80057 100644 --- a/fs/bcachefs/btree_update.h +++ b/fs/bcachefs/btree_update.h @@ -5,6 +5,7 @@ #include "btree_iter.h" #include "journal.h" #include "snapshot.h" +#include "super-io.h" struct bch_fs; struct btree; @@ -110,6 +111,22 @@ static inline int bch2_insert_snapshot_whiteouts(struct btree_trans *trans, : 0; } +static inline enum bch_bkey_type extent_whiteout_type(struct bch_fs *c, enum btree_id btree, + const struct bkey *k) +{ + /* + * KEY_TYPE_extent_whiteout indicates that there isn't a real extent + * present at that position: key start positions inclusive of + * KEY_TYPE_extent_whiteout (but not KEY_TYPE_whiteout) are + * monotonically increasing + */ + return btree_id_is_extents_snapshots(btree) && + bkey_deleted(k) && + !bch2_request_incompat_feature(c, bcachefs_metadata_version_extent_snapshot_whiteouts) + ? KEY_TYPE_extent_whiteout + : KEY_TYPE_whiteout; +} + int bch2_trans_update_extent_overwrite(struct btree_trans *, struct btree_iter *, enum btree_iter_update_trigger_flags, struct bkey_s_c, struct bkey_s_c); diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 5f4f82967105..65ca54c5b0ff 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -66,6 +66,10 @@ int bch2_btree_node_check_topology(struct btree_trans *trans, struct btree *b) bkey_init(&prev.k->k); bch2_btree_and_journal_iter_init_node_iter(trans, &iter, b); + /* + * Don't use btree_node_is_root(): we're called by btree split, after + * creating a new root but before setting it + */ if (b == btree_node_root(c, b)) { if (!bpos_eq(b->data->min_key, POS_MIN)) { bch2_log_msg_start(c, &buf); @@ -332,6 +336,20 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans, BUG_ON(b->ob.nr); mutex_lock(&c->btree_reserve_cache_lock); + if (unlikely(c->open_buckets_nr_free <= bch2_open_buckets_reserved(watermark))) { + guard(spinlock)(&c->freelist_lock); + if (c->open_buckets_nr_free <= bch2_open_buckets_reserved(watermark)) { + if (cl) + closure_wait(&c->open_buckets_wait, cl); + + ret = cl + ? bch_err_throw(c, bucket_alloc_blocked) + : bch_err_throw(c, open_buckets_empty); + mutex_unlock(&c->btree_reserve_cache_lock); + goto err; + } + } + if (c->btree_reserve_cache_nr > nr_reserve) { for (struct btree_alloc *a = c->btree_reserve_cache; a < c->btree_reserve_cache + c->btree_reserve_cache_nr;) { @@ -1655,7 +1673,7 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans, int ret = 0; bch2_verify_btree_nr_keys(b); - BUG_ON(!parent && (b != btree_node_root(c, b))); + BUG_ON(!parent && !btree_node_is_root(c, b)); BUG_ON(parent && !btree_node_intent_locked(trans->paths + path, b->c.level + 1)); ret = bch2_btree_node_check_topology(trans, b); @@ -2527,7 +2545,7 @@ static int __bch2_btree_node_update_key(struct btree_trans *trans, if (ret) goto err; } else { - BUG_ON(btree_node_root(c, b) != b); + BUG_ON(!btree_node_is_root(c, b)); struct jset_entry *e = bch2_trans_jset_entry_alloc(trans, jset_u64s(new_key->k.u64s)); diff --git a/fs/bcachefs/btree_write_buffer.c b/fs/bcachefs/btree_write_buffer.c index afad11831e1d..755fb25a8eba 100644 --- a/fs/bcachefs/btree_write_buffer.c +++ b/fs/bcachefs/btree_write_buffer.c @@ -701,8 +701,16 @@ int bch2_accounting_key_to_wb_slowpath(struct bch_fs *c, enum btree_id btree, struct bkey_i_accounting *k) { struct btree_write_buffer *wb = &c->btree_write_buffer; - struct btree_write_buffered_key new = { .btree = btree }; + if (trace_accounting_key_to_wb_slowpath_enabled()) { + CLASS(printbuf, buf)(); + prt_printf(&buf, "have: %zu\n", wb->accounting.nr); + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&k->k_i)); + trace_accounting_key_to_wb_slowpath(c, buf.buf); + } + count_event(c, accounting_key_to_wb_slowpath); + + struct btree_write_buffered_key new = { .btree = btree }; bkey_copy(&new.k, &k->k_i); int ret = darray_push(&wb->accounting, new); diff --git a/fs/bcachefs/btree_write_buffer.h b/fs/bcachefs/btree_write_buffer.h index e484cd6b90b0..b862bdf67f58 100644 --- a/fs/bcachefs/btree_write_buffer.h +++ b/fs/bcachefs/btree_write_buffer.h @@ -95,7 +95,7 @@ static inline int bch2_journal_key_to_wb(struct bch_fs *c, EBUG_ON(!dst->seq); - return k->k.type == KEY_TYPE_accounting + return bch2_bkey_is_accounting_mem(&k->k) ? bch2_accounting_key_to_wb(c, btree, bkey_i_to_accounting(k)) : __bch2_journal_key_to_wb(c, dst, btree, k); } diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c index 01838a3a189d..a314d70c6b8e 100644 --- a/fs/bcachefs/data_update.c +++ b/fs/bcachefs/data_update.c @@ -225,7 +225,7 @@ static void trace_io_move_created_rebalance2(struct data_update *m, trace_io_move_created_rebalance(c, buf.buf); - this_cpu_inc(c->counters[BCH_COUNTER_io_move_created_rebalance]); + count_event(c, io_move_created_rebalance); } noinline_for_stack @@ -693,6 +693,15 @@ int bch2_extent_drop_ptrs(struct btree_trans *trans, if (ret) return ret; + const union bch_extent_entry *entry; + struct extent_ptr_decoded p; + unsigned i = 0; + bkey_for_each_ptr_decode(k.k, bch2_bkey_ptrs_c(k), p, entry) { + if (data_opts->kill_ec_ptrs & BIT(i)) + bch2_bkey_drop_ec(n, p.ptr.dev); + i++; + } + while (data_opts->kill_ptrs) { unsigned i = 0, drop = __fls(data_opts->kill_ptrs); diff --git a/fs/bcachefs/data_update.h b/fs/bcachefs/data_update.h index 5e14d13568de..fc12aa65366f 100644 --- a/fs/bcachefs/data_update.h +++ b/fs/bcachefs/data_update.h @@ -12,6 +12,7 @@ struct moving_context; struct data_update_opts { unsigned rewrite_ptrs; unsigned kill_ptrs; + unsigned kill_ec_ptrs; u16 target; u8 extra_replicas; unsigned btree_insert_flags; diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c index 982d8ec17803..cb44b35e0f1d 100644 --- a/fs/bcachefs/dirent.c +++ b/fs/bcachefs/dirent.c @@ -740,21 +740,22 @@ found: int bch2_fsck_remove_dirent(struct btree_trans *trans, struct bpos pos) { struct bch_fs *c = trans->c; - struct bch_inode_unpacked dir_inode; - struct bch_hash_info dir_hash_info; + struct bch_inode_unpacked dir_inode; int ret = lookup_first_inode(trans, pos.inode, &dir_inode); if (ret) goto err; - dir_hash_info = bch2_hash_info_init(c, &dir_inode); + { + struct bch_hash_info dir_hash_info = bch2_hash_info_init(c, &dir_inode); - CLASS(btree_iter, iter)(trans, BTREE_ID_dirents, pos, BTREE_ITER_intent); + CLASS(btree_iter, iter)(trans, BTREE_ID_dirents, pos, BTREE_ITER_intent); - ret = bch2_btree_iter_traverse(&iter) ?: - bch2_hash_delete_at(trans, bch2_dirent_hash_desc, - &dir_hash_info, &iter, - BTREE_UPDATE_internal_snapshot_node); + ret = bch2_btree_iter_traverse(&iter) ?: + bch2_hash_delete_at(trans, bch2_dirent_hash_desc, + &dir_hash_info, &iter, + BTREE_UPDATE_internal_snapshot_node); + } err: bch_err_fn(c, ret); return ret; diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c index f96530c70262..5944ad6d0f8d 100644 --- a/fs/bcachefs/disk_accounting.c +++ b/fs/bcachefs/disk_accounting.c @@ -184,6 +184,9 @@ int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k, void *end = &acc_k + 1; int ret = 0; + if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR) + return 0; + bkey_fsck_err_on((from.flags & BCH_VALIDATE_commit) && bversion_zero(k.k->bversion), c, accounting_key_version_0, diff --git a/fs/bcachefs/disk_accounting.h b/fs/bcachefs/disk_accounting.h index 43f4b21d0aab..cc73cce98a44 100644 --- a/fs/bcachefs/disk_accounting.h +++ b/fs/bcachefs/disk_accounting.h @@ -145,6 +145,16 @@ static inline bool bch2_accounting_is_mem(struct disk_accounting_pos *acc) acc->type != BCH_DISK_ACCOUNTING_inum; } +static inline bool bch2_bkey_is_accounting_mem(struct bkey *k) +{ + if (k->type != KEY_TYPE_accounting) + return false; + + struct disk_accounting_pos acc_k; + bpos_to_disk_accounting_pos(&acc_k, k->p); + return bch2_accounting_is_mem(&acc_k); +} + /* * Update in memory counters so they match the btree update we're doing; called * from transaction commit path diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index c2840cb674b2..00e16801417a 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -35,6 +35,8 @@ #include <linux/raid/pq.h> #include <linux/raid/xor.h> +static bool bch2_stripe_is_open(struct bch_fs *, u64); + static void raid5_recov(unsigned disks, unsigned failed_idx, size_t size, void **data) { @@ -386,11 +388,20 @@ int bch2_trigger_stripe(struct btree_trans *trans, new_s->nr_redundant != old_s->nr_redundant)); if (flags & BTREE_TRIGGER_transactional) { + u64 old_lru_pos = stripe_lru_pos(old_s); + u64 new_lru_pos = stripe_lru_pos(new_s); + + if (new_lru_pos == STRIPE_LRU_POS_EMPTY && + !bch2_stripe_is_open(c, idx)) { + _new.k->type = KEY_TYPE_deleted; + set_bkey_val_u64s(_new.k, 0); + new_s = NULL; + new_lru_pos = 0; + } + int ret = bch2_lru_change(trans, - BCH_LRU_STRIPE_FRAGMENTATION, - idx, - stripe_lru_pos(old_s), - stripe_lru_pos(new_s)); + BCH_LRU_STRIPE_FRAGMENTATION, idx, + old_lru_pos, new_lru_pos); if (ret) return ret; } @@ -954,7 +965,7 @@ static int ec_stripe_delete(struct btree_trans *trans, u64 idx) */ if (k.k->type == KEY_TYPE_stripe && !bch2_stripe_is_open(trans->c, idx) && - stripe_lru_pos(bkey_s_c_to_stripe(k).v) == 1) + stripe_lru_pos(bkey_s_c_to_stripe(k).v) == STRIPE_LRU_POS_EMPTY) return bch2_btree_delete_at(trans, &iter, 0); return 0; @@ -1778,8 +1789,19 @@ static int __get_existing_stripe(struct btree_trans *trans, return 0; struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); - if (stripe_lru_pos(s.v) <= 1) - return 0; + + if (stripe_lru_pos(s.v) == STRIPE_LRU_POS_EMPTY) { + /* + * We can't guarantee that the trigger will always delete + * stripes - the stripe might still be open when the last data + * in it was deleted + */ + return !bch2_stripe_is_open(c, idx) + ? bch2_btree_delete_at(trans, &iter, 0) ?: + bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?: + bch_err_throw(c, transaction_restart_commit) + : 0; + } if (s.v->disk_label == head->disk_label && s.v->algorithm == head->algo && diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h index cec8b0f47d3d..adc1f9315eab 100644 --- a/fs/bcachefs/errcode.h +++ b/fs/bcachefs/errcode.h @@ -119,6 +119,7 @@ x(ENOENT, ENOENT_not_directory) \ x(ENOENT, ENOENT_directory_dead) \ x(ENOENT, ENOENT_subvolume) \ + x(ENOENT, ENOENT_snapshot) \ x(ENOENT, ENOENT_snapshot_tree) \ x(ENOENT, ENOENT_dirent_doesnt_match_inode) \ x(ENOENT, ENOENT_dev_not_found) \ diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h index 0c3c3a24fc6f..213814787dd6 100644 --- a/fs/bcachefs/error.h +++ b/fs/bcachefs/error.h @@ -173,7 +173,8 @@ do { \ if (!bch2_err_matches(_ret, BCH_ERR_fsck_fix) && \ !bch2_err_matches(_ret, BCH_ERR_fsck_ignore)) \ ret = _ret; \ - ret = bch_err_throw(c, fsck_delete_bkey); \ + else \ + ret = bch_err_throw(c, fsck_delete_bkey); \ goto fsck_err; \ } while (0) diff --git a/fs/bcachefs/extent_update.c b/fs/bcachefs/extent_update.c index c4b0ea1adaa8..7ddb156c765c 100644 --- a/fs/bcachefs/extent_update.c +++ b/fs/bcachefs/extent_update.c @@ -98,11 +98,13 @@ static int count_iters_for_insert(struct btree_trans *trans, return ret2 ?: ret; } -int bch2_extent_atomic_end(struct btree_trans *trans, - struct btree_iter *iter, - struct bpos *end) +int bch2_extent_trim_atomic(struct btree_trans *trans, + struct btree_iter *iter, + struct bkey_i *insert) { - unsigned nr_iters = 0; + enum bch_bkey_type whiteout_type = + extent_whiteout_type(trans->c, iter->btree_id, &insert->k); + struct bpos end = insert->k.p; struct btree_iter copy; bch2_trans_copy_iter(©, iter); @@ -111,42 +113,54 @@ int bch2_extent_atomic_end(struct btree_trans *trans, if (ret) goto err; + copy.flags |= BTREE_ITER_nofilter_whiteouts; + struct bkey_s_c k; - for_each_btree_key_max_continue_norestart(copy, *end, 0, k, ret) { + unsigned nr_iters = 0; + for_each_btree_key_continue_norestart(copy, 0, k, ret) { unsigned offset = 0; if (bkey_gt(iter->pos, bkey_start_pos(k.k))) offset = iter->pos.offset - bkey_start_offset(k.k); - ret = count_iters_for_insert(trans, k, offset, end, &nr_iters); - if (ret) - break; + if (bkey_extent_whiteout(k.k)) { + if (bpos_gt(k.k->p, insert->k.p)) { + if (k.k->type == KEY_TYPE_extent_whiteout) + break; + else + continue; + } else if (k.k->type != whiteout_type) { + nr_iters += 1; + if (nr_iters >= EXTENT_ITERS_MAX) { + end = bpos_min(end, k.k->p); + break; + } + } + } else { + if (bpos_ge(bkey_start_pos(k.k), end)) + break; + + ret = count_iters_for_insert(trans, k, offset, &end, &nr_iters); + if (ret) + break; + } } err: bch2_trans_iter_exit(©); - return ret < 0 ? ret : 0; -} - -int bch2_extent_trim_atomic(struct btree_trans *trans, - struct btree_iter *iter, - struct bkey_i *k) -{ - struct bpos end = k->k.p; - int ret = bch2_extent_atomic_end(trans, iter, &end); - if (ret) + if (ret < 0) return ret; /* tracepoint */ - if (bpos_lt(end, k->k.p)) { + if (bpos_lt(end, insert->k.p)) { if (trace_extent_trim_atomic_enabled()) { CLASS(printbuf, buf)(); bch2_bpos_to_text(&buf, end); prt_newline(&buf); - bch2_bkey_val_to_text(&buf, trans->c, bkey_i_to_s_c(k)); + bch2_bkey_val_to_text(&buf, trans->c, bkey_i_to_s_c(insert)); trace_extent_trim_atomic(trans->c, buf.buf); } - bch2_cut_back(end, k); + bch2_cut_back(end, insert); } return 0; } diff --git a/fs/bcachefs/extent_update.h b/fs/bcachefs/extent_update.h index 34467db53f45..2d956d971b11 100644 --- a/fs/bcachefs/extent_update.h +++ b/fs/bcachefs/extent_update.h @@ -4,8 +4,6 @@ #include "bcachefs.h" -int bch2_extent_atomic_end(struct btree_trans *, struct btree_iter *, - struct bpos *); int bch2_extent_trim_atomic(struct btree_trans *, struct btree_iter *, struct bkey_i *); diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index b879a586b7f6..7ab0398707d8 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -995,6 +995,22 @@ void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev) bch2_bkey_drop_ptrs_noerror(k, ptr, ptr->dev == dev); } +void bch2_bkey_drop_ec(struct bkey_i *k, unsigned dev) +{ + struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(k)); + union bch_extent_entry *entry, *ec = NULL; + + bkey_extent_entry_for_each(ptrs, entry) { + if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_stripe_ptr) + ec = entry; + else if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_ptr && + entry->ptr.dev == dev) { + bch2_bkey_extent_entry_drop(k, ec); + return; + } + } +} + const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c k, unsigned dev) { struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); @@ -1757,3 +1773,4 @@ int bch2_cut_back_s(struct bpos where, struct bkey_s k) memset(bkey_val_end(k), 0, val_u64s_delta * sizeof(u64)); return -val_u64s_delta; } + diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index 35ee03cd5065..f6dcb17108cd 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -650,6 +650,7 @@ void bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *); void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); void bch2_bkey_drop_device(struct bkey_s, unsigned); +void bch2_bkey_drop_ec(struct bkey_i *k, unsigned); #define bch2_bkey_drop_ptrs_noerror(_k, _ptr, _cond) \ do { \ diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c index 1630590068a7..456a624fe0eb 100644 --- a/fs/bcachefs/fs-io-buffered.c +++ b/fs/bcachefs/fs-io-buffered.c @@ -759,7 +759,6 @@ int bch2_write_end(const struct kiocb *iocb, struct address_space *mapping, struct bch2_folio_reservation *res = fsdata; unsigned offset = pos - folio_pos(folio); - lockdep_assert_held(&inode->v.i_rwsem); BUG_ON(offset + copied > folio_size(folio)); if (unlikely(copied < len && !folio_test_uptodate(folio))) { diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index d768a7e7a204..beb2edbd0cf8 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -268,7 +268,7 @@ restart: rht_for_each_entry_rcu_from(inode, he, rht_ptr_rcu(bkt), tbl, hash, hash) { if (inode->ei_inum.inum == inum) { ret = darray_push_gfp(&subvols, inode->ei_inum.subvol, - GFP_NOWAIT|__GFP_NOWARN); + GFP_NOWAIT); if (ret) { rcu_read_unlock(); ret = darray_make_room(&subvols, 1); @@ -511,8 +511,8 @@ struct inode *bch2_vfs_inode_get(struct bch_fs *c, subvol_inum inum) struct bch_subvolume subvol; int ret = lockrestart_do(trans, bch2_subvolume_get(trans, inum.subvol, true, &subvol) ?: - bch2_inode_find_by_inum_trans(trans, inum, &inode_u)) ?: - PTR_ERR_OR_ZERO(inode = bch2_inode_hash_init_insert(trans, inum, &inode_u, &subvol)); + bch2_inode_find_by_inum_trans(trans, inum, &inode_u) ?: + PTR_ERR_OR_ZERO(inode = bch2_inode_hash_init_insert(trans, inum, &inode_u, &subvol))); return ret ? ERR_PTR(ret) : &inode->v; } @@ -826,14 +826,6 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry, bch2_inode_update_after_write(trans, inode, &inode_u, ATTR_MTIME); - if (inode_u.bi_subvol) { - /* - * Subvolume deletion is asynchronous, but we still want to tell - * the VFS that it's been deleted here: - */ - set_nlink(&inode->v, 0); - } - if (IS_CASEFOLDED(vdir)) d_invalidate(dentry); err: @@ -865,9 +857,7 @@ static int bch2_symlink(struct mnt_idmap *idmap, if (IS_ERR(inode)) return bch2_err_class(PTR_ERR(inode)); - inode_lock(&inode->v); ret = page_symlink(&inode->v, symname, strlen(symname) + 1); - inode_unlock(&inode->v); if (unlikely(ret)) goto err; diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index d6fd25f1db1f..01c1c6372229 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -923,9 +923,10 @@ lookup_inode_for_snapshot(struct btree_trans *trans, struct inode_walker *w, str bkey_init(&whiteout.k); whiteout.k.type = KEY_TYPE_whiteout; whiteout.k.p = SPOS(0, i->inode.bi_inum, k.k->p.snapshot); - ret = bch2_btree_insert_nonextent(trans, BTREE_ID_inodes, - &whiteout, - BTREE_UPDATE_internal_snapshot_node); + ret = bch2_btree_insert_trans(trans, BTREE_ID_inodes, + &whiteout, + BTREE_ITER_cached| + BTREE_UPDATE_internal_snapshot_node); } if (ret) @@ -1443,7 +1444,7 @@ static int check_key_has_inode(struct btree_trans *trans, if (ret) return ret; - if (k.k->type == KEY_TYPE_whiteout) + if (bkey_extent_whiteout(k.k)) return 0; bool have_inode = i && !i->whiteout; @@ -1923,7 +1924,9 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, &inode->recalculate_sums); if (ret) goto err; + } + if (!bkey_extent_whiteout(k.k)) { /* * Check inodes in reverse order, from oldest snapshots to * newest, starting from the inode that matches this extent's @@ -2121,6 +2124,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * struct bkey_s_c_dirent d) { struct bch_fs *c = trans->c; + struct btree_iter subvol_iter = {}; struct bch_inode_unpacked subvol_root; u32 parent_subvol = le32_to_cpu(d.v->d_parent_subvol); u32 target_subvol = le32_to_cpu(d.v->d_child_subvol); @@ -2177,18 +2181,19 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * new_dirent->v.d_parent_subvol = cpu_to_le32(new_parent_subvol); } - CLASS(btree_iter, subvol_iter)(trans, BTREE_ID_subvolumes, POS(0, target_subvol), 0); + bch2_trans_iter_init(trans, &subvol_iter, BTREE_ID_subvolumes, POS(0, target_subvol), 0); struct bkey_s_c_subvolume s = bch2_bkey_get_typed(&subvol_iter, subvolume); ret = bkey_err(s.s_c); if (ret && !bch2_err_matches(ret, ENOENT)) - return ret; + goto err; if (ret) { if (fsck_err(trans, dirent_to_missing_subvol, "dirent points to missing subvolume\n%s", (bch2_bkey_val_to_text(&buf, c, d.s_c), buf.buf))) return bch2_fsck_remove_dirent(trans, d.k->p); - return 0; + ret = 0; + goto out; } if (le32_to_cpu(s.v->fs_path_parent) != parent_subvol) { @@ -2200,7 +2205,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * ret = bch2_inum_to_path(trans, (subvol_inum) { s.k->p.offset, le64_to_cpu(s.v->inode) }, &buf); if (ret) - return ret; + goto err; prt_newline(&buf); bch2_bkey_val_to_text(&buf, c, s.s_c); @@ -2209,7 +2214,7 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * bch2_bkey_make_mut_typed(trans, &subvol_iter, &s.s_c, 0, subvolume); ret = PTR_ERR_OR_ZERO(n); if (ret) - return ret; + goto err; n->v.fs_path_parent = cpu_to_le32(parent_subvol); } @@ -2221,11 +2226,12 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * ret = bch2_inode_find_by_inum_snapshot(trans, target_inum, target_snapshot, &subvol_root, 0); if (ret && !bch2_err_matches(ret, ENOENT)) - return ret; + goto err; if (ret) { bch_err(c, "subvol %u points to missing inode root %llu", target_subvol, target_inum); - return bch_err_throw(c, fsck_repair_unimplemented); + ret = bch_err_throw(c, fsck_repair_unimplemented); + goto err; } if (fsck_err_on(!ret && parent_subvol != subvol_root.bi_parent_subvol, @@ -2237,13 +2243,16 @@ static int check_dirent_to_subvol(struct btree_trans *trans, struct btree_iter * subvol_root.bi_snapshot = le32_to_cpu(s.v->snapshot); ret = __bch2_fsck_write_inode(trans, &subvol_root); if (ret) - return ret; + goto err; } ret = bch2_check_dirent_target(trans, iter, d, &subvol_root, true); if (ret) - return ret; + goto err; +out: +err: fsck_err: + bch2_trans_iter_exit(&subvol_iter); return ret; } diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c index 85013e8d6166..d5e5190f0663 100644 --- a/fs/bcachefs/inode.c +++ b/fs/bcachefs/inode.c @@ -463,9 +463,10 @@ int __bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked bch2_inode_pack(inode_p, inode); inode_p->inode.k.p.snapshot = inode->bi_snapshot; - return bch2_btree_insert_nonextent(trans, BTREE_ID_inodes, - &inode_p->inode.k_i, - BTREE_UPDATE_internal_snapshot_node); + return bch2_btree_insert_trans(trans, BTREE_ID_inodes, + &inode_p->inode.k_i, + BTREE_ITER_cached| + BTREE_UPDATE_internal_snapshot_node); } int bch2_fsck_write_inode(struct btree_trans *trans, struct bch_inode_unpacked *inode) diff --git a/fs/bcachefs/io_misc.c b/fs/bcachefs/io_misc.c index 3f9defd144a4..fa0b06e17d17 100644 --- a/fs/bcachefs/io_misc.c +++ b/fs/bcachefs/io_misc.c @@ -274,13 +274,15 @@ static int __bch2_resume_logged_op_truncate(struct btree_trans *trans, if (ret) goto err; - CLASS(btree_iter, fpunch_iter)(trans, BTREE_ID_extents, - POS(inum.inum, round_up(new_i_size, block_bytes(c)) >> 9), - BTREE_ITER_intent); - ret = bch2_fpunch_at(trans, &fpunch_iter, inum, U64_MAX, i_sectors_delta); + { + CLASS(btree_iter, fpunch_iter)(trans, BTREE_ID_extents, + POS(inum.inum, round_up(new_i_size, block_bytes(c)) >> 9), + BTREE_ITER_intent); + ret = bch2_fpunch_at(trans, &fpunch_iter, inum, U64_MAX, i_sectors_delta); - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - ret = 0; + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) + ret = 0; + } err: if (warn_errors) bch_err_fn(c, ret); diff --git a/fs/bcachefs/logged_ops.h b/fs/bcachefs/logged_ops.h index 30ae9ef737dd..6dea6e2ac7a8 100644 --- a/fs/bcachefs/logged_ops.h +++ b/fs/bcachefs/logged_ops.h @@ -10,7 +10,7 @@ static inline int bch2_logged_op_update(struct btree_trans *trans, struct bkey_i *op) { - return bch2_btree_insert_nonextent(trans, BTREE_ID_logged_ops, op, 0); + return bch2_btree_insert_trans(trans, BTREE_ID_logged_ops, op, BTREE_ITER_cached); } int bch2_resume_logged_ops(struct bch_fs *); diff --git a/fs/bcachefs/lru.h b/fs/bcachefs/lru.h index 8abd0aa2083a..6f1e0a7b5db5 100644 --- a/fs/bcachefs/lru.h +++ b/fs/bcachefs/lru.h @@ -24,6 +24,16 @@ static inline struct bpos lru_pos(u16 lru_id, u64 dev_bucket, u64 time) return pos; } +static inline struct bpos lru_start(u16 lru_id) +{ + return lru_pos(lru_id, 0, 0); +} + +static inline struct bpos lru_end(u16 lru_id) +{ + return lru_pos(lru_id, U64_MAX, LRU_TIME_MAX); +} + static inline enum bch_lru_type lru_type(struct bkey_s_c l) { u16 lru_id = l.k->p.inode >> 48; diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c index a38996f5366f..df6833416855 100644 --- a/fs/bcachefs/move.c +++ b/fs/bcachefs/move.c @@ -150,7 +150,7 @@ static void move_write_done(struct bch_write_op *op) bch2_write_op_to_text(&buf, op); trace_io_move_write_fail(c, buf.buf); } - this_cpu_inc(c->counters[BCH_COUNTER_io_move_write_fail]); + count_event(c, io_move_write_fail); ctxt->write_error = true; } @@ -344,9 +344,13 @@ int bch2_move_extent(struct moving_context *ctxt, if (!data_opts.rewrite_ptrs && !data_opts.extra_replicas && !data_opts.scrub) { - if (data_opts.kill_ptrs) + if (data_opts.kill_ptrs|data_opts.kill_ec_ptrs) { + this_cpu_add(c->counters[BCH_COUNTER_io_move_drop_only], k.k->size); return bch2_extent_drop_ptrs(trans, iter, k, &io_opts, &data_opts); - return 0; + } else { + this_cpu_add(c->counters[BCH_COUNTER_io_move_noop], k.k->size); + return 0; + } } struct moving_io *io = allocate_dropping_locks(trans, ret, @@ -538,7 +542,7 @@ int bch2_move_ratelimit(struct moving_context *ctxt) if (ctxt->wait_on_copygc && c->copygc_running) { bch2_moving_ctxt_flush_all(ctxt); - wait_event_killable(c->copygc_running_wq, + wait_event_freezable(c->copygc_running_wq, !c->copygc_running || (is_kthread && kthread_should_stop())); } @@ -1276,7 +1280,17 @@ static bool drop_extra_replicas_pred(struct bch_fs *c, void *arg, i++; } - return data_opts->kill_ptrs != 0; + i = 0; + bkey_for_each_ptr_decode(k.k, bch2_bkey_ptrs_c(k), p, entry) { + if (p.has_ec && durability - p.ec.redundancy >= replicas) { + data_opts->kill_ec_ptrs |= BIT(i); + durability -= p.ec.redundancy; + } + + i++; + } + + return (data_opts->kill_ptrs|data_opts->kill_ec_ptrs) != 0; } static bool scrub_pred(struct bch_fs *c, void *_arg, diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c index b0cbe3c1aab6..f36d60b8fb07 100644 --- a/fs/bcachefs/movinggc.c +++ b/fs/bcachefs/movinggc.c @@ -14,6 +14,7 @@ #include "btree_write_buffer.h" #include "buckets.h" #include "clock.h" +#include "ec.h" #include "errcode.h" #include "error.h" #include "lru.h" @@ -131,72 +132,153 @@ static bool bucket_in_flight(struct buckets_in_flight *list, return rhashtable_lookup_fast(list->table, &k, bch_move_bucket_params); } +static int try_add_copygc_bucket(struct btree_trans *trans, + struct buckets_in_flight *buckets_in_flight, + struct bpos bucket, u64 lru_time) +{ + struct move_bucket b = { .k.bucket = bucket }; + + int ret = bch2_bucket_is_movable(trans, &b, lru_time); + if (ret <= 0) + return ret; + + if (bucket_in_flight(buckets_in_flight, b.k)) + return 0; + + struct move_bucket *b_i = kmalloc(sizeof(*b_i), GFP_KERNEL); + if (!b_i) + return -ENOMEM; + + *b_i = b; + + ret = darray_push(&buckets_in_flight->to_evacuate, b_i); + if (ret) { + kfree(b_i); + return ret; + } + + ret = rhashtable_lookup_insert_fast(buckets_in_flight->table, &b_i->hash, + bch_move_bucket_params); + BUG_ON(ret); + + size_t nr_to_get = max_t(size_t, 16U, buckets_in_flight->nr / 4); + return buckets_in_flight->to_evacuate.nr >= nr_to_get; +} + static int bch2_copygc_get_buckets(struct moving_context *ctxt, struct buckets_in_flight *buckets_in_flight) { struct btree_trans *trans = ctxt->trans; - struct bch_fs *c = trans->c; - size_t nr_to_get = max_t(size_t, 16U, buckets_in_flight->nr / 4); - size_t saw = 0, in_flight = 0, not_movable = 0, sectors = 0; - int ret; - move_buckets_wait(ctxt, buckets_in_flight, false); + int ret = for_each_btree_key_max(trans, iter, BTREE_ID_lru, + lru_start(BCH_LRU_BUCKET_FRAGMENTATION), + lru_end(BCH_LRU_BUCKET_FRAGMENTATION), + 0, k, + try_add_copygc_bucket(trans, buckets_in_flight, + u64_to_bucket(k.k->p.offset), + lru_pos_time(k.k->p)) + ); - ret = bch2_btree_write_buffer_tryflush(trans); - if (bch2_err_matches(ret, EROFS)) - return ret; + return ret < 0 ? ret : 0; +} - if (bch2_fs_fatal_err_on(ret, c, "%s: from bch2_btree_write_buffer_tryflush()", bch2_err_str(ret))) - return ret; +static int bch2_copygc_get_stripe_buckets(struct moving_context *ctxt, + struct buckets_in_flight *buckets_in_flight) +{ + struct btree_trans *trans = ctxt->trans; - ret = for_each_btree_key_max(trans, iter, BTREE_ID_lru, - lru_pos(BCH_LRU_BUCKET_FRAGMENTATION, 0, 0), - lru_pos(BCH_LRU_BUCKET_FRAGMENTATION, U64_MAX, LRU_TIME_MAX), - 0, k, ({ - struct move_bucket b = { .k.bucket = u64_to_bucket(k.k->p.offset) }; - int ret2 = 0; + int ret = for_each_btree_key_max(trans, iter, BTREE_ID_lru, + lru_start(BCH_LRU_STRIPE_FRAGMENTATION), + lru_end(BCH_LRU_STRIPE_FRAGMENTATION), + 0, lru_k, ({ + CLASS(btree_iter, s_iter)(trans, BTREE_ID_stripes, POS(0, lru_k.k->p.offset), 0); + struct bkey_s_c s_k = bch2_btree_iter_peek_slot(&s_iter); + int ret2 = bkey_err(s_k); + if (ret2) + goto err; - saw++; + if (s_k.k->type != KEY_TYPE_stripe) + continue; - ret2 = bch2_bucket_is_movable(trans, &b, lru_pos_time(k.k->p)); - if (ret2 < 0) - goto err; + const struct bch_stripe *s = bkey_s_c_to_stripe(s_k).v; - if (!ret2) - not_movable++; - else if (bucket_in_flight(buckets_in_flight, b.k)) - in_flight++; - else { - struct move_bucket *b_i = kmalloc(sizeof(*b_i), GFP_KERNEL); - ret2 = b_i ? 0 : -ENOMEM; + /* write buffer race? */ + if (stripe_lru_pos(s) != lru_pos_time(lru_k.k->p)) + continue; + + unsigned nr_data = s->nr_blocks - s->nr_redundant; + for (unsigned i = 0; i < nr_data; i++) { + if (!stripe_blockcount_get(s, i)) + continue; + + const struct bch_extent_ptr *ptr = s->ptrs + i; + CLASS(bch2_dev_tryget, ca)(trans->c, ptr->dev); + if (unlikely(!ca)) + continue; + + ret2 = try_add_copygc_bucket(trans, buckets_in_flight, + PTR_BUCKET_POS(ca, ptr), U64_MAX); if (ret2) - goto err; + break; + } +err: + ret2; + })); - *b_i = b; + return ret < 0 ? ret : 0; +} + +static bool should_do_ec_copygc(struct btree_trans *trans) +{ + u64 stripe_frag_ratio = 0; + + for_each_btree_key_max(trans, iter, BTREE_ID_lru, + lru_start(BCH_LRU_STRIPE_FRAGMENTATION), + lru_end(BCH_LRU_STRIPE_FRAGMENTATION), + 0, lru_k, ({ + CLASS(btree_iter, s_iter)(trans, BTREE_ID_stripes, POS(0, lru_k.k->p.offset), 0); + struct bkey_s_c s_k = bch2_btree_iter_peek_slot(&s_iter); + int ret = bkey_err(s_k); + if (ret) + goto err; - ret2 = darray_push(&buckets_in_flight->to_evacuate, b_i); - if (ret2) { - kfree(b_i); - goto err; - } + if (s_k.k->type != KEY_TYPE_stripe) + continue; - ret2 = rhashtable_lookup_insert_fast(buckets_in_flight->table, &b_i->hash, - bch_move_bucket_params); - BUG_ON(ret2); + const struct bch_stripe *s = bkey_s_c_to_stripe(s_k).v; - sectors += b.sectors; - } + /* write buffer race? */ + if (stripe_lru_pos(s) != lru_pos_time(lru_k.k->p)) + continue; - ret2 = buckets_in_flight->to_evacuate.nr >= nr_to_get; + unsigned nr_data = s->nr_blocks - s->nr_redundant, blocks_nonempty = 0; + for (unsigned i = 0; i < nr_data; i++) + blocks_nonempty += !!stripe_blockcount_get(s, i); + + /* stripe is pending delete */ + if (!blocks_nonempty) + continue; + + /* This matches the calculation in alloc_lru_idx_fragmentation, so we can + * directly compare without actually looking up the bucket pointed to by the + * bucket fragmentation lru: + */ + stripe_frag_ratio = div_u64(blocks_nonempty * (1ULL << 31), nr_data); + break; err: - ret2; + ret; })); - pr_debug("have: %zu (%zu) saw %zu in flight %zu not movable %zu got %zu (%zu)/%zu buckets ret %i", - buckets_in_flight->nr, buckets_in_flight->sectors, - saw, in_flight, not_movable, buckets_in_flight->to_evacuate.nr, sectors, nr_to_get, ret); + CLASS(btree_iter, iter)(trans, BTREE_ID_lru, lru_start(BCH_LRU_BUCKET_FRAGMENTATION), 0); + struct bkey_s_c lru_k; - return ret < 0 ? ret : 0; + lockrestart_do(trans, bkey_err(lru_k = bch2_btree_iter_peek_max(&iter, + lru_end(BCH_LRU_BUCKET_FRAGMENTATION)))); + + u64 bucket_frag_ratio = lru_k.k && !bkey_err(lru_k) ? lru_pos_time(lru_k.k->p) : 0; + + /* Prefer normal bucket copygc */ + return stripe_frag_ratio && stripe_frag_ratio * 2 < bucket_frag_ratio; } noinline @@ -213,7 +295,18 @@ static int bch2_copygc(struct moving_context *ctxt, u64 sectors_moved = atomic64_read(&ctxt->stats->sectors_moved); int ret = 0; - ret = bch2_copygc_get_buckets(ctxt, buckets_in_flight); + move_buckets_wait(ctxt, buckets_in_flight, false); + + ret = bch2_btree_write_buffer_tryflush(trans); + if (bch2_err_matches(ret, EROFS)) + goto err; + + if (bch2_fs_fatal_err_on(ret, c, "%s: from bch2_btree_write_buffer_tryflush()", bch2_err_str(ret))) + goto err; + + ret = should_do_ec_copygc(trans) + ? bch2_copygc_get_stripe_buckets(ctxt, buckets_in_flight) + : bch2_copygc_get_buckets(ctxt, buckets_in_flight); if (ret) goto err; @@ -265,7 +358,8 @@ static u64 bch2_copygc_dev_wait_amount(struct bch_dev *ca) for (unsigned i = 0; i < BCH_DATA_NR; i++) if (data_type_movable(i)) - fragmented += usage_full.d[i].fragmented; + fragmented += usage_full.d[i].buckets * ca->mi.bucket_size - + usage_full.d[i].sectors; return max(0LL, fragmented_allowed - fragmented); } diff --git a/fs/bcachefs/namei.c b/fs/bcachefs/namei.c index da758c2767ea..d1019052f182 100644 --- a/fs/bcachefs/namei.c +++ b/fs/bcachefs/namei.c @@ -743,6 +743,7 @@ static int bch2_check_dirent_inode_dirent(struct btree_trans *trans, { struct bch_fs *c = trans->c; CLASS(printbuf, buf)(); + struct btree_iter bp_iter = {}; int ret = 0; if (inode_points_to_dirent(target, d)) @@ -773,8 +774,8 @@ static int bch2_check_dirent_inode_dirent(struct btree_trans *trans, return __bch2_fsck_write_inode(trans, target); } - CLASS(btree_iter, bp_iter)(trans, BTREE_ID_dirents, - SPOS(target->bi_dir, target->bi_dir_offset, target->bi_snapshot), 0); + bch2_trans_iter_init(trans, &bp_iter, BTREE_ID_dirents, + SPOS(target->bi_dir, target->bi_dir_offset, target->bi_snapshot), 0); struct bkey_s_c_dirent bp_dirent = bch2_bkey_get_typed(&bp_iter, dirent); ret = bkey_err(bp_dirent); if (ret && !bch2_err_matches(ret, ENOENT)) @@ -824,6 +825,8 @@ static int bch2_check_dirent_inode_dirent(struct btree_trans *trans, S_ISDIR(target->bi_mode) ? "directory" : "subvolume", target->bi_inum, target->bi_snapshot, buf.buf); } + + goto out; } else { /* * hardlinked file with nlink 0: @@ -837,11 +840,15 @@ static int bch2_check_dirent_inode_dirent(struct btree_trans *trans, target->bi_nlink++; target->bi_flags &= ~BCH_INODE_unlinked; ret = __bch2_fsck_write_inode(trans, target); + if (ret) + goto err; } } } +out: err: fsck_err: + bch2_trans_iter_exit(&bp_iter); bch_err_fn(c, ret); return ret; } diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c index c0c5fe961a83..17ca56b0e2ac 100644 --- a/fs/bcachefs/rebalance.c +++ b/fs/bcachefs/rebalance.c @@ -292,12 +292,48 @@ static int bch2_clear_rebalance_needs_scan(struct btree_trans *trans, u64 inum, : 0; } -static struct bkey_s_c next_rebalance_entry(struct btree_trans *trans, - struct btree_iter *work_iter) +#define REBALANCE_WORK_BUF_NR 1024 +DEFINE_DARRAY_NAMED(darray_rebalance_work, struct bkey_i_cookie); + +static struct bkey_i *next_rebalance_entry(struct btree_trans *trans, + darray_rebalance_work *buf, struct bpos *work_pos) { - return !kthread_should_stop() - ? bch2_btree_iter_peek(work_iter) - : bkey_s_c_null; + if (unlikely(!buf->nr)) { + /* + * Avoid contention with write buffer flush: buffer up rebalance + * work entries in a darray + */ + + BUG_ON(!buf->size);; + + bch2_trans_begin(trans); + + for_each_btree_key(trans, iter, BTREE_ID_rebalance_work, *work_pos, + BTREE_ITER_all_snapshots|BTREE_ITER_prefetch, k, ({ + /* we previously used darray_make_room */ + BUG_ON(bkey_bytes(k.k) > sizeof(buf->data[0])); + + bkey_reassemble(&darray_top(*buf).k_i, k); + buf->nr++; + + *work_pos = bpos_successor(iter.pos); + if (buf->nr == buf->size) + break; + 0; + })); + + if (!buf->nr) + return NULL; + + unsigned l = 0, r = buf->nr - 1; + while (l < r) { + swap(buf->data[l], buf->data[r]); + l++; + --r; + } + } + + return &(&darray_pop(buf))->k_i; } static int bch2_bkey_clear_needs_rebalance(struct btree_trans *trans, @@ -464,10 +500,9 @@ static int do_rebalance_scan(struct moving_context *ctxt, u64 inum, u64 cookie) per_snapshot_io_opts_init(&snapshot_io_opts, c); int ret = for_each_btree_key_max(trans, iter, BTREE_ID_extents, - r->scan_start.pos, r->scan_end.pos, - BTREE_ITER_all_snapshots| - BTREE_ITER_not_extents| - BTREE_ITER_prefetch, k, ({ + r->scan_start.pos, r->scan_end.pos, + BTREE_ITER_all_snapshots| + BTREE_ITER_prefetch, k, ({ ctxt->stats->pos = BBPOS(iter.btree_id, iter.pos); struct bch_io_opts *io_opts = bch2_move_get_io_opts(trans, @@ -524,49 +559,37 @@ static int do_rebalance(struct moving_context *ctxt) struct btree_trans *trans = ctxt->trans; struct bch_fs *c = trans->c; struct bch_fs_rebalance *r = &c->rebalance; - struct btree_iter extent_iter = { NULL }; - struct bkey_s_c k; + struct btree_iter extent_iter = {}; u32 kick = r->kick; - int ret = 0; - bch2_trans_begin(trans); + struct bpos work_pos = POS_MIN; + CLASS(darray_rebalance_work, work)(); + int ret = darray_make_room(&work, REBALANCE_WORK_BUF_NR); + if (ret) + return ret; bch2_move_stats_init(&r->work_stats, "rebalance_work"); bch2_move_stats_init(&r->scan_stats, "rebalance_scan"); - CLASS(btree_iter, rebalance_work_iter)(trans, - BTREE_ID_rebalance_work, POS_MIN, - BTREE_ITER_all_snapshots); - while (!bch2_move_ratelimit(ctxt)) { if (!bch2_rebalance_enabled(c)) { bch2_moving_ctxt_flush_all(ctxt); kthread_wait_freezable(bch2_rebalance_enabled(c) || kthread_should_stop()); + if (kthread_should_stop()) + break; } - if (kthread_should_stop()) + struct bkey_i *k = next_rebalance_entry(trans, &work, &work_pos); + if (!k) break; - bch2_trans_begin(trans); - - ret = bkey_err(k = next_rebalance_entry(trans, &rebalance_work_iter)); - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - continue; - if (ret || !k.k) - break; - - ret = k.k->type == KEY_TYPE_cookie - ? do_rebalance_scan(ctxt, k.k->p.inode, - le64_to_cpu(bkey_s_c_to_cookie(k).v->cookie)) - : do_rebalance_extent(ctxt, k.k->p, &extent_iter); - - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - continue; + ret = k->k.type == KEY_TYPE_cookie + ? do_rebalance_scan(ctxt, k->k.p.inode, + le64_to_cpu(bkey_i_to_cookie(k)->v.cookie)) + : lockrestart_do(trans, do_rebalance_extent(ctxt, k->k.p, &extent_iter)); if (ret) break; - - bch2_btree_iter_advance(&rebalance_work_iter); } bch2_trans_iter_exit(&extent_iter); diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index c57ff235a97a..29e81f96db0f 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -607,7 +607,7 @@ static int read_btree_roots(struct bch_fs *c) c, btree_root_read_error, "error reading btree root %s: %s", buf.buf, bch2_err_str(ret))) { - if (btree_id_is_alloc(i)) + if (btree_id_can_reconstruct(i)) r->error = 0; ret = 0; } @@ -626,93 +626,6 @@ fsck_err: return ret; } -static bool check_version_upgrade(struct bch_fs *c) -{ - unsigned latest_version = bcachefs_metadata_version_current; - unsigned latest_compatible = min(latest_version, - bch2_latest_compatible_version(c->sb.version)); - unsigned old_version = c->sb.version_upgrade_complete ?: c->sb.version; - unsigned new_version = 0; - bool ret = false; - - if (old_version < bcachefs_metadata_required_upgrade_below) { - if (c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible || - latest_compatible < bcachefs_metadata_required_upgrade_below) - new_version = latest_version; - else - new_version = latest_compatible; - } else { - switch (c->opts.version_upgrade) { - case BCH_VERSION_UPGRADE_compatible: - new_version = latest_compatible; - break; - case BCH_VERSION_UPGRADE_incompatible: - new_version = latest_version; - break; - case BCH_VERSION_UPGRADE_none: - new_version = min(old_version, latest_version); - break; - } - } - - if (new_version > old_version) { - CLASS(printbuf, buf)(); - - if (old_version < bcachefs_metadata_required_upgrade_below) - prt_str(&buf, "Version upgrade required:\n"); - - if (old_version != c->sb.version) { - prt_str(&buf, "Version upgrade from "); - bch2_version_to_text(&buf, c->sb.version_upgrade_complete); - prt_str(&buf, " to "); - bch2_version_to_text(&buf, c->sb.version); - prt_str(&buf, " incomplete\n"); - } - - prt_printf(&buf, "Doing %s version upgrade from ", - BCH_VERSION_MAJOR(old_version) != BCH_VERSION_MAJOR(new_version) - ? "incompatible" : "compatible"); - bch2_version_to_text(&buf, old_version); - prt_str(&buf, " to "); - bch2_version_to_text(&buf, new_version); - prt_newline(&buf); - - struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); - __le64 passes = ext->recovery_passes_required[0]; - bch2_sb_set_upgrade(c, old_version, new_version); - passes = ext->recovery_passes_required[0] & ~passes; - - if (passes) { - prt_str(&buf, " running recovery passes: "); - prt_bitflags(&buf, bch2_recovery_passes, - bch2_recovery_passes_from_stable(le64_to_cpu(passes))); - } - - bch_notice(c, "%s", buf.buf); - ret = true; - } - - if (new_version > c->sb.version_incompat_allowed && - c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible) { - CLASS(printbuf, buf)(); - - prt_str(&buf, "Now allowing incompatible features up to "); - bch2_version_to_text(&buf, new_version); - prt_str(&buf, ", previously allowed up to "); - bch2_version_to_text(&buf, c->sb.version_incompat_allowed); - prt_newline(&buf); - - bch_notice(c, "%s", buf.buf); - ret = true; - } - - if (ret) - bch2_sb_upgrade(c, new_version, - c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible); - - return ret; -} - int bch2_fs_recovery(struct bch_fs *c) { struct bch_sb_field_clean *clean = NULL; @@ -732,108 +645,6 @@ int bch2_fs_recovery(struct bch_fs *c) bch_info(c, "recovering from unclean shutdown"); } - if (!(c->sb.features & (1ULL << BCH_FEATURE_new_extent_overwrite))) { - bch_err(c, "feature new_extent_overwrite not set, filesystem no longer supported"); - ret = -EINVAL; - goto err; - } - - if (!c->sb.clean && - !(c->sb.features & (1ULL << BCH_FEATURE_extents_above_btree_updates))) { - bch_err(c, "filesystem needs recovery from older version; run fsck from older bcachefs-tools to fix"); - ret = -EINVAL; - goto err; - } - - if (c->opts.norecovery) { - c->opts.recovery_pass_last = c->opts.recovery_pass_last - ? min(c->opts.recovery_pass_last, BCH_RECOVERY_PASS_snapshots_read) - : BCH_RECOVERY_PASS_snapshots_read; - c->opts.nochanges = true; - } - - if (c->opts.nochanges) - c->opts.read_only = true; - - if (c->opts.journal_rewind) { - bch_info(c, "rewinding journal, fsck required"); - c->opts.fsck = true; - } - - if (go_rw_in_recovery(c)) { - /* - * start workqueues/kworkers early - kthread creation checks for - * pending signals, which is _very_ annoying - */ - ret = bch2_fs_init_rw(c); - if (ret) - goto err; - } - - mutex_lock(&c->sb_lock); - struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); - bool write_sb = false; - - if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb)) { - ext->recovery_passes_required[0] |= - cpu_to_le64(bch2_recovery_passes_to_stable(BIT_ULL(BCH_RECOVERY_PASS_check_topology))); - write_sb = true; - } - - u64 sb_passes = bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); - if (sb_passes) { - CLASS(printbuf, buf)(); - prt_str(&buf, "superblock requires following recovery passes to be run:\n "); - prt_bitflags(&buf, bch2_recovery_passes, sb_passes); - bch_info(c, "%s", buf.buf); - } - - if (bch2_check_version_downgrade(c)) { - CLASS(printbuf, buf)(); - - prt_str(&buf, "Version downgrade required:"); - - __le64 passes = ext->recovery_passes_required[0]; - bch2_sb_set_downgrade(c, - BCH_VERSION_MINOR(bcachefs_metadata_version_current), - BCH_VERSION_MINOR(c->sb.version)); - passes = ext->recovery_passes_required[0] & ~passes; - if (passes) { - prt_str(&buf, "\n running recovery passes: "); - prt_bitflags(&buf, bch2_recovery_passes, - bch2_recovery_passes_from_stable(le64_to_cpu(passes))); - } - - bch_info(c, "%s", buf.buf); - write_sb = true; - } - - if (check_version_upgrade(c)) - write_sb = true; - - c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); - - if (c->sb.version_upgrade_complete < bcachefs_metadata_version_autofix_errors) { - SET_BCH_SB_ERROR_ACTION(c->disk_sb.sb, BCH_ON_ERROR_fix_safe); - write_sb = true; - } - - if (write_sb) - bch2_write_super(c); - mutex_unlock(&c->sb_lock); - - if (c->sb.clean) - set_bit(BCH_FS_clean_recovery, &c->flags); - if (c->opts.fsck) - set_bit(BCH_FS_in_fsck, &c->flags); - set_bit(BCH_FS_in_recovery, &c->flags); - - ret = bch2_blacklist_table_initialize(c); - if (ret) { - bch_err(c, "error initializing blacklist table"); - goto err; - } - bch2_journal_pos_from_member_info_resume(c); if (!c->sb.clean || c->opts.retain_recovery_info) { @@ -1053,8 +864,8 @@ use_clean: } mutex_lock(&c->sb_lock); - ext = bch2_sb_field_get(c->disk_sb.sb, ext); - write_sb = false; + struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); + bool write_sb = false; if (BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb) != le16_to_cpu(c->disk_sb.sb->version)) { SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, le16_to_cpu(c->disk_sb.sb->version)); diff --git a/fs/bcachefs/sb-counters_format.h b/fs/bcachefs/sb-counters_format.h index 2e3a56bfd085..44bc12573a0c 100644 --- a/fs/bcachefs/sb-counters_format.h +++ b/fs/bcachefs/sb-counters_format.h @@ -31,6 +31,8 @@ enum counters_flags { x(io_move_fail, 38, TYPE_COUNTER) \ x(io_move_write_fail, 82, TYPE_COUNTER) \ x(io_move_start_fail, 39, TYPE_COUNTER) \ + x(io_move_drop_only, 91, TYPE_COUNTER) \ + x(io_move_noop, 92, TYPE_COUNTER) \ x(io_move_created_rebalance, 83, TYPE_COUNTER) \ x(io_move_evacuate_bucket, 84, TYPE_COUNTER) \ x(bucket_invalidate, 3, TYPE_COUNTER) \ @@ -99,7 +101,9 @@ enum counters_flags { x(trans_restart_write_buffer_flush, 75, TYPE_COUNTER) \ x(trans_restart_split_race, 76, TYPE_COUNTER) \ x(write_buffer_flush_slowpath, 77, TYPE_COUNTER) \ - x(write_buffer_flush_sync, 78, TYPE_COUNTER) + x(write_buffer_flush_sync, 78, TYPE_COUNTER) \ + x(accounting_key_to_wb_slowpath, 94, TYPE_COUNTER) \ + x(error_throw, 93, TYPE_COUNTER) enum bch_persistent_counters { #define x(t, n, ...) BCH_COUNTER_##t, diff --git a/fs/bcachefs/sb-errors_format.h b/fs/bcachefs/sb-errors_format.h index dd4ee46606d7..5317b1bfe2e5 100644 --- a/fs/bcachefs/sb-errors_format.h +++ b/fs/bcachefs/sb-errors_format.h @@ -76,6 +76,8 @@ enum bch_fsck_flags { x(btree_node_read_error, 62, FSCK_AUTOFIX) \ x(btree_node_topology_bad_min_key, 63, FSCK_AUTOFIX) \ x(btree_node_topology_bad_max_key, 64, FSCK_AUTOFIX) \ + x(btree_node_topology_bad_root_min_key, 323, FSCK_AUTOFIX) \ + x(btree_node_topology_bad_root_max_key, 324, FSCK_AUTOFIX) \ x(btree_node_topology_overwritten_by_prev_node, 65, FSCK_AUTOFIX) \ x(btree_node_topology_overwritten_by_next_node, 66, FSCK_AUTOFIX) \ x(btree_node_topology_interior_node_empty, 67, FSCK_AUTOFIX) \ @@ -334,7 +336,7 @@ enum bch_fsck_flags { x(dirent_stray_data_after_cf_name, 305, 0) \ x(rebalance_work_incorrectly_set, 309, FSCK_AUTOFIX) \ x(rebalance_work_incorrectly_unset, 310, FSCK_AUTOFIX) \ - x(MAX, 323, 0) + x(MAX, 325, 0) enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n, diff --git a/fs/bcachefs/sb-members.c b/fs/bcachefs/sb-members.c index 0573c7b00151..e3c73d903898 100644 --- a/fs/bcachefs/sb-members.c +++ b/fs/bcachefs/sb-members.c @@ -68,34 +68,13 @@ struct bch_member *bch2_members_v2_get_mut(struct bch_sb *sb, int i) return __bch2_members_v2_get_mut(bch2_sb_field_get(sb, members_v2), i); } -static struct bch_member members_v2_get(struct bch_sb_field_members_v2 *mi, int i) -{ - struct bch_member ret, *p = __bch2_members_v2_get_mut(mi, i); - memset(&ret, 0, sizeof(ret)); - memcpy(&ret, p, min_t(size_t, le16_to_cpu(mi->member_bytes), sizeof(ret))); - return ret; -} - -static struct bch_member *members_v1_get_mut(struct bch_sb_field_members_v1 *mi, int i) -{ - return (void *) mi->_members + (i * BCH_MEMBER_V1_BYTES); -} - -static struct bch_member members_v1_get(struct bch_sb_field_members_v1 *mi, int i) -{ - struct bch_member ret, *p = members_v1_get_mut(mi, i); - memset(&ret, 0, sizeof(ret)); - memcpy(&ret, p, min_t(size_t, BCH_MEMBER_V1_BYTES, sizeof(ret))); - return ret; -} - struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i) { struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(sb, members_v2); if (mi2) - return members_v2_get(mi2, i); + return bch2_members_v2_get(mi2, i); struct bch_sb_field_members_v1 *mi1 = bch2_sb_field_get(sb, members_v1); - return members_v1_get(mi1, i); + return bch2_members_v1_get(mi1, i); } static int sb_members_v2_resize_entries(struct bch_fs *c) @@ -211,33 +190,25 @@ static int validate_member(struct printbuf *err, return 0; } -static void member_to_text(struct printbuf *out, - struct bch_member m, - struct bch_sb_field_disk_groups *gi, - struct bch_sb *sb, - int i) +void bch2_member_to_text(struct printbuf *out, + struct bch_member *m, + struct bch_sb_field_disk_groups *gi, + struct bch_sb *sb, + unsigned idx) { - unsigned data_have = bch2_sb_dev_has_data(sb, i); - u64 bucket_size = le16_to_cpu(m.bucket_size); - u64 device_size = le64_to_cpu(m.nbuckets) * bucket_size; - - if (!bch2_member_alive(&m)) - return; - - prt_printf(out, "Device:\t%u\n", i); - - printbuf_indent_add(out, 2); + u64 bucket_size = le16_to_cpu(m->bucket_size); + u64 device_size = le64_to_cpu(m->nbuckets) * bucket_size; prt_printf(out, "Label:\t"); - if (BCH_MEMBER_GROUP(&m)) + if (BCH_MEMBER_GROUP(m)) bch2_disk_path_to_text_sb(out, sb, - BCH_MEMBER_GROUP(&m) - 1); + BCH_MEMBER_GROUP(m) - 1); else prt_printf(out, "(none)"); prt_newline(out); prt_printf(out, "UUID:\t"); - pr_uuid(out, m.uuid.b); + pr_uuid(out, m->uuid.b); prt_newline(out); prt_printf(out, "Size:\t"); @@ -245,40 +216,41 @@ static void member_to_text(struct printbuf *out, prt_newline(out); for (unsigned i = 0; i < BCH_MEMBER_ERROR_NR; i++) - prt_printf(out, "%s errors:\t%llu\n", bch2_member_error_strs[i], le64_to_cpu(m.errors[i])); + prt_printf(out, "%s errors:\t%llu\n", bch2_member_error_strs[i], le64_to_cpu(m->errors[i])); for (unsigned i = 0; i < BCH_IOPS_NR; i++) - prt_printf(out, "%s iops:\t%u\n", bch2_iops_measurements[i], le32_to_cpu(m.iops[i])); + prt_printf(out, "%s iops:\t%u\n", bch2_iops_measurements[i], le32_to_cpu(m->iops[i])); prt_printf(out, "Bucket size:\t"); prt_units_u64(out, bucket_size << 9); prt_newline(out); - prt_printf(out, "First bucket:\t%u\n", le16_to_cpu(m.first_bucket)); - prt_printf(out, "Buckets:\t%llu\n", le64_to_cpu(m.nbuckets)); + prt_printf(out, "First bucket:\t%u\n", le16_to_cpu(m->first_bucket)); + prt_printf(out, "Buckets:\t%llu\n", le64_to_cpu(m->nbuckets)); prt_printf(out, "Last mount:\t"); - if (m.last_mount) - bch2_prt_datetime(out, le64_to_cpu(m.last_mount)); + if (m->last_mount) + bch2_prt_datetime(out, le64_to_cpu(m->last_mount)); else prt_printf(out, "(never)"); prt_newline(out); - prt_printf(out, "Last superblock write:\t%llu\n", le64_to_cpu(m.seq)); + prt_printf(out, "Last superblock write:\t%llu\n", le64_to_cpu(m->seq)); prt_printf(out, "State:\t%s\n", - BCH_MEMBER_STATE(&m) < BCH_MEMBER_STATE_NR - ? bch2_member_states[BCH_MEMBER_STATE(&m)] + BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR + ? bch2_member_states[BCH_MEMBER_STATE(m)] : "unknown"); prt_printf(out, "Data allowed:\t"); - if (BCH_MEMBER_DATA_ALLOWED(&m)) - prt_bitflags(out, __bch2_data_types, BCH_MEMBER_DATA_ALLOWED(&m)); + if (BCH_MEMBER_DATA_ALLOWED(m)) + prt_bitflags(out, __bch2_data_types, BCH_MEMBER_DATA_ALLOWED(m)); else prt_printf(out, "(none)"); prt_newline(out); prt_printf(out, "Has data:\t"); + unsigned data_have = bch2_sb_dev_has_data(sb, idx); if (data_have) prt_bitflags(out, __bch2_data_types, data_have); else @@ -286,22 +258,36 @@ static void member_to_text(struct printbuf *out, prt_newline(out); prt_printf(out, "Btree allocated bitmap blocksize:\t"); - if (m.btree_bitmap_shift < 64) - prt_units_u64(out, 1ULL << m.btree_bitmap_shift); + if (m->btree_bitmap_shift < 64) + prt_units_u64(out, 1ULL << m->btree_bitmap_shift); else - prt_printf(out, "(invalid shift %u)", m.btree_bitmap_shift); + prt_printf(out, "(invalid shift %u)", m->btree_bitmap_shift); prt_newline(out); prt_printf(out, "Btree allocated bitmap:\t"); - bch2_prt_u64_base2_nbits(out, le64_to_cpu(m.btree_allocated_bitmap), 64); + bch2_prt_u64_base2_nbits(out, le64_to_cpu(m->btree_allocated_bitmap), 64); prt_newline(out); - prt_printf(out, "Durability:\t%llu\n", BCH_MEMBER_DURABILITY(&m) ? BCH_MEMBER_DURABILITY(&m) - 1 : 1); + prt_printf(out, "Durability:\t%llu\n", BCH_MEMBER_DURABILITY(m) ? BCH_MEMBER_DURABILITY(m) - 1 : 1); + + prt_printf(out, "Discard:\t%llu\n", BCH_MEMBER_DISCARD(m)); + prt_printf(out, "Freespace initialized:\t%llu\n", BCH_MEMBER_FREESPACE_INITIALIZED(m)); + prt_printf(out, "Resize on mount:\t%llu\n", BCH_MEMBER_RESIZE_ON_MOUNT(m)); +} + +static void member_to_text(struct printbuf *out, + struct bch_member m, + struct bch_sb_field_disk_groups *gi, + struct bch_sb *sb, + unsigned idx) +{ + if (!bch2_member_alive(&m)) + return; - prt_printf(out, "Discard:\t%llu\n", BCH_MEMBER_DISCARD(&m)); - prt_printf(out, "Freespace initialized:\t%llu\n", BCH_MEMBER_FREESPACE_INITIALIZED(&m)); - prt_printf(out, "Resize on mount:\t%llu\n", BCH_MEMBER_RESIZE_ON_MOUNT(&m)); + prt_printf(out, "Device:\t%u\n", idx); + printbuf_indent_add(out, 2); + bch2_member_to_text(out, &m, gi, sb, idx); printbuf_indent_sub(out, 2); } @@ -317,7 +303,7 @@ static int bch2_sb_members_v1_validate(struct bch_sb *sb, struct bch_sb_field *f } for (i = 0; i < sb->nr_devices; i++) { - struct bch_member m = members_v1_get(mi, i); + struct bch_member m = bch2_members_v1_get(mi, i); int ret = validate_member(err, m, sb, i); if (ret) @@ -343,7 +329,7 @@ static void bch2_sb_members_v1_to_text(struct printbuf *out, struct bch_sb *sb, prt_printf(out, "nr_devices mismatch: have %i entries, should be %u", nr, sb->nr_devices); for (unsigned i = 0; i < min(sb->nr_devices, nr); i++) - member_to_text(out, members_v1_get(mi, i), gi, sb, i); + member_to_text(out, bch2_members_v1_get(mi, i), gi, sb, i); } const struct bch_sb_field_ops bch_sb_field_ops_members_v1 = { @@ -377,7 +363,7 @@ static void bch2_sb_members_v2_to_text(struct printbuf *out, struct bch_sb *sb, */ for (unsigned i = 0; i < min(sb->nr_devices, nr); i++) - member_to_text(out, members_v2_get(mi, i), gi, sb, i); + member_to_text(out, bch2_members_v2_get(mi, i), gi, sb, i); } static int bch2_sb_members_v2_validate(struct bch_sb *sb, struct bch_sb_field *f, @@ -394,7 +380,7 @@ static int bch2_sb_members_v2_validate(struct bch_sb *sb, struct bch_sb_field *f } for (unsigned i = 0; i < sb->nr_devices; i++) { - int ret = validate_member(err, members_v2_get(mi, i), sb, i); + int ret = validate_member(err, bch2_members_v2_get(mi, i), sb, i); if (ret) return ret; } @@ -430,7 +416,7 @@ void bch2_sb_members_to_cpu(struct bch_fs *c) struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(c->disk_sb.sb, members_v2); if (mi2) for (unsigned i = 0; i < c->sb.nr_devices; i++) { - struct bch_member m = members_v2_get(mi2, i); + struct bch_member m = bch2_members_v2_get(mi2, i); bool removed = uuid_equal(&m.uuid, &BCH_SB_MEMBER_DELETED_UUID); mod_bit(i, c->devs_removed.d, removed); } diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h index 35d4ab9b6197..6de999cf71cb 100644 --- a/fs/bcachefs/sb-members.h +++ b/fs/bcachefs/sb-members.h @@ -14,11 +14,36 @@ __bch2_members_v2_get_mut(struct bch_sb_field_members_v2 *mi, unsigned i) return (void *) mi->_members + (i * le16_to_cpu(mi->member_bytes)); } +static inline struct bch_member bch2_members_v2_get(struct bch_sb_field_members_v2 *mi, int i) +{ + struct bch_member ret, *p = __bch2_members_v2_get_mut(mi, i); + memset(&ret, 0, sizeof(ret)); + memcpy(&ret, p, min_t(size_t, le16_to_cpu(mi->member_bytes), sizeof(ret))); + return ret; +} + +static inline struct bch_member *members_v1_get_mut(struct bch_sb_field_members_v1 *mi, int i) +{ + return (void *) mi->_members + (i * BCH_MEMBER_V1_BYTES); +} + +static inline struct bch_member bch2_members_v1_get(struct bch_sb_field_members_v1 *mi, int i) +{ + struct bch_member ret, *p = members_v1_get_mut(mi, i); + memset(&ret, 0, sizeof(ret)); + memcpy(&ret, p, min_t(size_t, BCH_MEMBER_V1_BYTES, sizeof(ret))); + return ret; +} + int bch2_sb_members_v2_init(struct bch_fs *c); int bch2_sb_members_cpy_v2_v1(struct bch_sb_handle *disk_sb); struct bch_member *bch2_members_v2_get_mut(struct bch_sb *sb, int i); struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i); +void bch2_member_to_text(struct printbuf *, struct bch_member *, + struct bch_sb_field_disk_groups *, + struct bch_sb *, unsigned); + static inline bool bch2_dev_is_online(struct bch_dev *ca) { return !enumerated_ref_is_zero(&ca->io_ref[READ]); diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index 5a1f81749661..84f987d3a02a 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -1146,7 +1146,7 @@ static int bch2_snapshot_node_delete(struct btree_trans *trans, u32 id) if (bch2_fs_inconsistent_on(i == 2, c, "snapshot %u missing child pointer to %u", parent_id, id)) - return ret; + return bch_err_throw(c, ENOENT_snapshot); parent->v.children[i] = cpu_to_le32(child_id); diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index c88759964575..be7ed612d28f 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -68,28 +68,33 @@ enum bcachefs_metadata_version bch2_latest_compatible_version(enum bcachefs_meta int bch2_set_version_incompat(struct bch_fs *c, enum bcachefs_metadata_version version) { - guard(mutex)(&c->sb_lock); - if (((c->sb.features & BIT_ULL(BCH_FEATURE_incompat_version_field)) && version <= c->sb.version_incompat_allowed)) { - SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb, - max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version)); - bch2_write_super(c); + guard(mutex)(&c->sb_lock); + + if (version > c->sb.version_incompat) { + SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb, + max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version)); + bch2_write_super(c); + } return 0; } else { - darray_for_each(c->incompat_versions_requested, i) - if (version == *i) - return bch_err_throw(c, may_not_use_incompat_feature); + BUILD_BUG_ON(BCH_VERSION_MAJOR(bcachefs_metadata_version_current) != 1); - darray_push(&c->incompat_versions_requested, version); - CLASS(printbuf, buf)(); - prt_str(&buf, "requested incompat feature "); - bch2_version_to_text(&buf, version); - prt_str(&buf, " currently not enabled, allowed up to "); - bch2_version_to_text(&buf, version); - prt_printf(&buf, "\n set version_upgrade=incompat to enable"); + unsigned minor = BCH_VERSION_MINOR(version); + + if (!test_bit(minor, c->incompat_versions_requested) && + !test_and_set_bit(minor, c->incompat_versions_requested)) { + CLASS(printbuf, buf)(); + prt_str(&buf, "requested incompat feature "); + bch2_version_to_text(&buf, version); + prt_str(&buf, " currently not enabled, allowed up to "); + bch2_version_to_text(&buf, version); + prt_printf(&buf, "\n set version_upgrade=incompat to enable"); + + bch_notice(c, "%s", buf.buf); + } - bch_notice(c, "%s", buf.buf); return bch_err_throw(c, may_not_use_incompat_feature); } } diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index b3b2d8353a36..ef15e614f4f3 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -55,6 +55,7 @@ #include "replicas.h" #include "sb-clean.h" #include "sb-counters.h" +#include "sb-downgrade.h" #include "sb-errors.h" #include "sb-members.h" #include "snapshot.h" @@ -653,7 +654,6 @@ static void __bch2_fs_free(struct bch_fs *c) free_percpu(c->online_reserved); } - darray_exit(&c->incompat_versions_requested); darray_exit(&c->btree_roots_extra); free_percpu(c->pcpu); free_percpu(c->usage); @@ -843,6 +843,233 @@ int bch2_fs_init_rw(struct bch_fs *c) return 0; } +static bool check_version_upgrade(struct bch_fs *c) +{ + unsigned latest_version = bcachefs_metadata_version_current; + unsigned latest_compatible = min(latest_version, + bch2_latest_compatible_version(c->sb.version)); + unsigned old_version = c->sb.version_upgrade_complete ?: c->sb.version; + unsigned new_version = 0; + bool ret = false; + + if (old_version < bcachefs_metadata_required_upgrade_below) { + if (c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible || + latest_compatible < bcachefs_metadata_required_upgrade_below) + new_version = latest_version; + else + new_version = latest_compatible; + } else { + switch (c->opts.version_upgrade) { + case BCH_VERSION_UPGRADE_compatible: + new_version = latest_compatible; + break; + case BCH_VERSION_UPGRADE_incompatible: + new_version = latest_version; + break; + case BCH_VERSION_UPGRADE_none: + new_version = min(old_version, latest_version); + break; + } + } + + if (new_version > old_version) { + CLASS(printbuf, buf)(); + + if (old_version < bcachefs_metadata_required_upgrade_below) + prt_str(&buf, "Version upgrade required:\n"); + + if (old_version != c->sb.version) { + prt_str(&buf, "Version upgrade from "); + bch2_version_to_text(&buf, c->sb.version_upgrade_complete); + prt_str(&buf, " to "); + bch2_version_to_text(&buf, c->sb.version); + prt_str(&buf, " incomplete\n"); + } + + prt_printf(&buf, "Doing %s version upgrade from ", + BCH_VERSION_MAJOR(old_version) != BCH_VERSION_MAJOR(new_version) + ? "incompatible" : "compatible"); + bch2_version_to_text(&buf, old_version); + prt_str(&buf, " to "); + bch2_version_to_text(&buf, new_version); + prt_newline(&buf); + + struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); + __le64 passes = ext->recovery_passes_required[0]; + bch2_sb_set_upgrade(c, old_version, new_version); + passes = ext->recovery_passes_required[0] & ~passes; + + if (passes) { + prt_str(&buf, " running recovery passes: "); + prt_bitflags(&buf, bch2_recovery_passes, + bch2_recovery_passes_from_stable(le64_to_cpu(passes))); + } + + bch_notice(c, "%s", buf.buf); + ret = true; + } + + if (new_version > c->sb.version_incompat_allowed && + c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible) { + CLASS(printbuf, buf)(); + + prt_str(&buf, "Now allowing incompatible features up to "); + bch2_version_to_text(&buf, new_version); + prt_str(&buf, ", previously allowed up to "); + bch2_version_to_text(&buf, c->sb.version_incompat_allowed); + prt_newline(&buf); + + bch_notice(c, "%s", buf.buf); + ret = true; + } + + if (ret) + bch2_sb_upgrade(c, new_version, + c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible); + + return ret; +} + +noinline_for_stack +static int bch2_fs_opt_version_init(struct bch_fs *c) +{ + int ret = 0; + + if (c->opts.norecovery) { + c->opts.recovery_pass_last = c->opts.recovery_pass_last + ? min(c->opts.recovery_pass_last, BCH_RECOVERY_PASS_snapshots_read) + : BCH_RECOVERY_PASS_snapshots_read; + c->opts.nochanges = true; + } + + if (c->opts.nochanges) + c->opts.read_only = true; + + if (c->opts.journal_rewind) + c->opts.fsck = true; + + CLASS(printbuf, p)(); + bch2_log_msg_start(c, &p); + + prt_str(&p, "starting version "); + bch2_version_to_text(&p, c->sb.version); + + bool first = true; + for (enum bch_opt_id i = 0; i < bch2_opts_nr; i++) { + const struct bch_option *opt = &bch2_opt_table[i]; + u64 v = bch2_opt_get_by_id(&c->opts, i); + + if (!(opt->flags & OPT_MOUNT)) + continue; + + if (v == bch2_opt_get_by_id(&bch2_opts_default, i)) + continue; + + prt_str(&p, first ? " opts=" : ","); + first = false; + bch2_opt_to_text(&p, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE); + } + + if (c->sb.version_incompat_allowed != c->sb.version) { + prt_printf(&p, "\nallowing incompatible features above "); + bch2_version_to_text(&p, c->sb.version_incompat_allowed); + } + + if (c->opts.verbose) { + prt_printf(&p, "\nfeatures: "); + prt_bitflags(&p, bch2_sb_features, c->sb.features); + } + + if (c->sb.multi_device) { + prt_printf(&p, "\nwith devices"); + for_each_online_member(c, ca, BCH_DEV_READ_REF_bch2_online_devs) { + prt_char(&p, ' '); + prt_str(&p, ca->name); + } + } + + if (c->cf_encoding) + prt_printf(&p, "\nUsing encoding defined by superblock: utf8-%u.%u.%u", + unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING), + unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING), + unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING)); + + if (c->opts.journal_rewind) + prt_printf(&p, "\nrewinding journal, fsck required"); + + scoped_guard(mutex, &c->sb_lock) { + struct bch_sb_field_ext *ext = bch2_sb_field_get_minsize(&c->disk_sb, ext, + sizeof(struct bch_sb_field_ext) / sizeof(u64)); + if (!ext) + return bch_err_throw(c, ENOSPC_sb); + + ret = bch2_sb_members_v2_init(c); + if (ret) + return ret; + + __le64 now = cpu_to_le64(ktime_get_real_seconds()); + for_each_online_member_rcu(c, ca) + bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = now; + + if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb)) + ext->recovery_passes_required[0] |= + cpu_to_le64(bch2_recovery_passes_to_stable(BIT_ULL(BCH_RECOVERY_PASS_check_topology))); + + u64 sb_passes = bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); + if (sb_passes) { + prt_str(&p, "\nsuperblock requires following recovery passes to be run:\n "); + prt_bitflags(&p, bch2_recovery_passes, sb_passes); + } + + if (bch2_check_version_downgrade(c)) { + prt_str(&p, "\nVersion downgrade required:"); + + __le64 passes = ext->recovery_passes_required[0]; + bch2_sb_set_downgrade(c, + BCH_VERSION_MINOR(bcachefs_metadata_version_current), + BCH_VERSION_MINOR(c->sb.version)); + passes = ext->recovery_passes_required[0] & ~passes; + if (passes) { + prt_str(&p, "\nrunning recovery passes: "); + prt_bitflags(&p, bch2_recovery_passes, + bch2_recovery_passes_from_stable(le64_to_cpu(passes))); + } + } + + check_version_upgrade(c); + + c->opts.recovery_passes |= bch2_recovery_passes_from_stable(le64_to_cpu(ext->recovery_passes_required[0])); + + if (c->sb.version_upgrade_complete < bcachefs_metadata_version_autofix_errors) + SET_BCH_SB_ERROR_ACTION(c->disk_sb.sb, BCH_ON_ERROR_fix_safe); + + /* Don't write the superblock, defer that until we go rw */ + } + + if (c->sb.clean) + set_bit(BCH_FS_clean_recovery, &c->flags); + if (c->opts.fsck) + set_bit(BCH_FS_in_fsck, &c->flags); + set_bit(BCH_FS_in_recovery, &c->flags); + + bch2_print_str(c, KERN_INFO, p.buf); + + if (BCH_SB_INITIALIZED(c->disk_sb.sb)) { + if (!(c->sb.features & (1ULL << BCH_FEATURE_new_extent_overwrite))) { + bch_err(c, "feature new_extent_overwrite not set, filesystem no longer supported"); + return -EINVAL; + } + + if (!c->sb.clean && + !(c->sb.features & (1ULL << BCH_FEATURE_extents_above_btree_updates))) { + bch_err(c, "filesystem needs recovery from older version; run fsck from older bcachefs-tools to fix"); + return -EINVAL; + } + } + + return 0; +} + static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, bch_sb_handles *sbs) { @@ -1014,6 +1241,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, ret = bch2_fs_async_obj_init(c) ?: + bch2_blacklist_table_initialize(c) ?: bch2_fs_btree_cache_init(c) ?: bch2_fs_btree_iter_init(c) ?: bch2_fs_btree_key_cache_init(&c->btree_key_cache) ?: @@ -1064,7 +1292,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, } #endif - for (i = 0; i < c->sb.nr_devices; i++) { + for (unsigned i = 0; i < c->sb.nr_devices; i++) { if (!bch2_member_exists(c->disk_sb.sb, i)) continue; ret = bch2_dev_alloc(c, i); @@ -1079,6 +1307,20 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts *opts, &c->clock_journal_res, (sizeof(struct jset_entry_clock) / sizeof(u64)) * 2); + ret = bch2_fs_opt_version_init(c); + if (ret) + goto err; + + /* + * start workqueues/kworkers early - kthread creation checks for pending + * signals, which is _very_ annoying + */ + if (go_rw_in_recovery(c)) { + ret = bch2_fs_init_rw(c); + if (ret) + goto err; + } + scoped_guard(mutex, &bch_fs_list_lock) ret = bch2_fs_online(c); @@ -1094,53 +1336,6 @@ err: goto out; } -noinline_for_stack -static void print_mount_opts(struct bch_fs *c) -{ - enum bch_opt_id i; - CLASS(printbuf, p)(); - bch2_log_msg_start(c, &p); - - prt_str(&p, "starting version "); - bch2_version_to_text(&p, c->sb.version); - - bool first = true; - for (i = 0; i < bch2_opts_nr; i++) { - const struct bch_option *opt = &bch2_opt_table[i]; - u64 v = bch2_opt_get_by_id(&c->opts, i); - - if (!(opt->flags & OPT_MOUNT)) - continue; - - if (v == bch2_opt_get_by_id(&bch2_opts_default, i)) - continue; - - prt_str(&p, first ? " opts=" : ","); - first = false; - bch2_opt_to_text(&p, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE); - } - - if (c->sb.version_incompat_allowed != c->sb.version) { - prt_printf(&p, "\nallowing incompatible features above "); - bch2_version_to_text(&p, c->sb.version_incompat_allowed); - } - - if (c->opts.verbose) { - prt_printf(&p, "\nfeatures: "); - prt_bitflags(&p, bch2_sb_features, c->sb.features); - } - - if (c->sb.multi_device) { - prt_printf(&p, "\nwith devices"); - for_each_online_member(c, ca, BCH_DEV_READ_REF_bch2_online_devs) { - prt_char(&p, ' '); - prt_str(&p, ca->name); - } - } - - bch2_print_str(c, KERN_INFO, p.buf); -} - static bool bch2_fs_may_start(struct bch_fs *c) { struct bch_dev *ca; @@ -1175,38 +1370,16 @@ static bool bch2_fs_may_start(struct bch_fs *c) int bch2_fs_start(struct bch_fs *c) { - time64_t now = ktime_get_real_seconds(); int ret = 0; BUG_ON(test_bit(BCH_FS_started, &c->flags)); - print_mount_opts(c); - - if (c->cf_encoding) - bch_info(c, "Using encoding defined by superblock: utf8-%u.%u.%u", - unicode_major(BCH_FS_DEFAULT_UTF8_ENCODING), - unicode_minor(BCH_FS_DEFAULT_UTF8_ENCODING), - unicode_rev(BCH_FS_DEFAULT_UTF8_ENCODING)); - if (!bch2_fs_may_start(c)) return bch_err_throw(c, insufficient_devices_to_start); scoped_guard(rwsem_write, &c->state_lock) { - guard(mutex)(&c->sb_lock); - if (!bch2_sb_field_get_minsize(&c->disk_sb, ext, - sizeof(struct bch_sb_field_ext) / sizeof(u64))) { - ret = bch_err_throw(c, ENOSPC_sb); - goto err; - } - - ret = bch2_sb_members_v2_init(c); - if (ret) - goto err; - scoped_guard(rcu) for_each_online_member_rcu(c, ca) { - bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = - cpu_to_le64(now); if (ca->mi.state == BCH_MEMBER_STATE_rw) bch2_dev_allocator_add(c, ca); } diff --git a/fs/bcachefs/trace.h b/fs/bcachefs/trace.h index 3776a1403104..269cdf1a87a4 100644 --- a/fs/bcachefs/trace.h +++ b/fs/bcachefs/trace.h @@ -1179,6 +1179,11 @@ DEFINE_EVENT(transaction_event, trans_restart_write_buffer_flush, TP_ARGS(trans, caller_ip) ); +DEFINE_EVENT(fs_str, accounting_key_to_wb_slowpath, + TP_PROTO(struct bch_fs *c, const char *str), + TP_ARGS(c, str) +); + TRACE_EVENT(path_downgrade, TP_PROTO(struct btree_trans *trans, unsigned long caller_ip, diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index d83f91b62317..bb2370829928 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2965,7 +2965,6 @@ int ext4_init_new_dir(handle_t *handle, struct inode *dir, struct inode *inode) { struct buffer_head *dir_block = NULL; - struct ext4_dir_entry_2 *de; ext4_lblk_t block = 0; int err; @@ -2982,7 +2981,6 @@ int ext4_init_new_dir(handle_t *handle, struct inode *dir, dir_block = ext4_append(handle, inode, &block); if (IS_ERR(dir_block)) return PTR_ERR(dir_block); - de = (struct ext4_dir_entry_2 *)dir_block->b_data; err = ext4_init_dirblock(handle, inode, dir_block, dir->i_ino, NULL, 0); if (err) goto out; diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index f1cea365b6f1..ca7c2265c25f 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -481,10 +481,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) server->smbd_conn->receive_credit_target); seq_printf(m, "\nPending send_pending: %x ", atomic_read(&server->smbd_conn->send_pending)); - seq_printf(m, "\nReceive buffers count_receive_queue: %x " - "count_empty_packet_queue: %x", - server->smbd_conn->count_receive_queue, - server->smbd_conn->count_empty_packet_queue); + seq_printf(m, "\nReceive buffers count_receive_queue: %x ", + server->smbd_conn->count_receive_queue); seq_printf(m, "\nMR responder_resources: %x " "max_frmr_depth: %x mr_type: %x", server->smbd_conn->responder_resources, diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 754e94a0e07f..58321e483a1a 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -13,8 +13,6 @@ #include "cifsproto.h" #include "smb2proto.h" -static struct smbd_response *get_empty_queue_buffer( - struct smbd_connection *info); static struct smbd_response *get_receive_buffer( struct smbd_connection *info); static void put_receive_buffer( @@ -23,8 +21,6 @@ static void put_receive_buffer( static int allocate_receive_buffers(struct smbd_connection *info, int num_buf); static void destroy_receive_buffers(struct smbd_connection *info); -static void put_empty_packet( - struct smbd_connection *info, struct smbd_response *response); static void enqueue_reassembly( struct smbd_connection *info, struct smbd_response *response, int data_length); @@ -281,18 +277,20 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) log_rdma_send(INFO, "smbd_request 0x%p completed wc->status=%d\n", request, wc->status); - if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { - log_rdma_send(ERR, "wc->status=%d wc->opcode=%d\n", - wc->status, wc->opcode); - smbd_disconnect_rdma_connection(request->info); - } - for (i = 0; i < request->num_sge; i++) ib_dma_unmap_single(sc->ib.dev, request->sge[i].addr, request->sge[i].length, DMA_TO_DEVICE); + if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { + log_rdma_send(ERR, "wc->status=%d wc->opcode=%d\n", + wc->status, wc->opcode); + mempool_free(request, request->info->request_mempool); + smbd_disconnect_rdma_connection(request->info); + return; + } + if (atomic_dec_and_test(&request->info->send_pending)) wake_up(&request->info->wait_send_pending); @@ -391,7 +389,6 @@ static bool process_negotiation_response( static void smbd_post_send_credits(struct work_struct *work) { int ret = 0; - int use_receive_queue = 1; int rc; struct smbd_response *response; struct smbd_connection *info = @@ -407,18 +404,9 @@ static void smbd_post_send_credits(struct work_struct *work) if (info->receive_credit_target > atomic_read(&info->receive_credits)) { while (true) { - if (use_receive_queue) - response = get_receive_buffer(info); - else - response = get_empty_queue_buffer(info); - if (!response) { - /* now switch to empty packet queue */ - if (use_receive_queue) { - use_receive_queue = 0; - continue; - } else - break; - } + response = get_receive_buffer(info); + if (!response) + break; response->type = SMBD_TRANSFER_DATA; response->first_segment = false; @@ -466,7 +454,6 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) { log_rdma_recv(INFO, "wc->status=%d opcode=%d\n", wc->status, wc->opcode); - smbd_disconnect_rdma_connection(info); goto error; } @@ -483,18 +470,15 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) info->full_packet_received = true; info->negotiate_done = process_negotiation_response(response, wc->byte_len); + put_receive_buffer(info, response); complete(&info->negotiate_completion); - break; + return; /* SMBD data transfer packet */ case SMBD_TRANSFER_DATA: data_transfer = smbd_response_payload(response); data_length = le32_to_cpu(data_transfer->data_length); - /* - * If this is a packet with data playload place the data in - * reassembly queue and wake up the reading thread - */ if (data_length) { if (info->full_packet_received) response->first_segment = true; @@ -503,16 +487,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) info->full_packet_received = false; else info->full_packet_received = true; - - enqueue_reassembly( - info, - response, - data_length); - } else - put_empty_packet(info, response); - - if (data_length) - wake_up_interruptible(&info->wait_reassembly_queue); + } atomic_dec(&info->receive_credits); info->receive_credit_target = @@ -540,15 +515,27 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) info->keep_alive_requested = KEEP_ALIVE_PENDING; } - return; + /* + * If this is a packet with data playload place the data in + * reassembly queue and wake up the reading thread + */ + if (data_length) { + enqueue_reassembly(info, response, data_length); + wake_up_interruptible(&info->wait_reassembly_queue); + } else + put_receive_buffer(info, response); - default: - log_rdma_recv(ERR, - "unexpected response type=%d\n", response->type); + return; } + /* + * This is an internal error! + */ + log_rdma_recv(ERR, "unexpected response type=%d\n", response->type); + WARN_ON_ONCE(response->type != SMBD_TRANSFER_DATA); error: put_receive_buffer(info, response); + smbd_disconnect_rdma_connection(info); } static struct rdma_cm_id *smbd_create_id( @@ -1069,6 +1056,7 @@ static int smbd_post_recv( if (rc) { ib_dma_unmap_single(sc->ib.dev, response->sge.addr, response->sge.length, DMA_FROM_DEVICE); + response->sge.length = 0; smbd_disconnect_rdma_connection(info); log_rdma_recv(ERR, "ib_post_recv failed rc=%d\n", rc); } @@ -1113,17 +1101,6 @@ static int smbd_negotiate(struct smbd_connection *info) return rc; } -static void put_empty_packet( - struct smbd_connection *info, struct smbd_response *response) -{ - spin_lock(&info->empty_packet_queue_lock); - list_add_tail(&response->list, &info->empty_packet_queue); - info->count_empty_packet_queue++; - spin_unlock(&info->empty_packet_queue_lock); - - queue_work(info->workqueue, &info->post_send_credits_work); -} - /* * Implement Connection.FragmentReassemblyBuffer defined in [MS-SMBD] 3.1.1.1 * This is a queue for reassembling upper layer payload and present to upper @@ -1172,25 +1149,6 @@ static struct smbd_response *_get_first_reassembly(struct smbd_connection *info) return ret; } -static struct smbd_response *get_empty_queue_buffer( - struct smbd_connection *info) -{ - struct smbd_response *ret = NULL; - unsigned long flags; - - spin_lock_irqsave(&info->empty_packet_queue_lock, flags); - if (!list_empty(&info->empty_packet_queue)) { - ret = list_first_entry( - &info->empty_packet_queue, - struct smbd_response, list); - list_del(&ret->list); - info->count_empty_packet_queue--; - } - spin_unlock_irqrestore(&info->empty_packet_queue_lock, flags); - - return ret; -} - /* * Get a receive buffer * For each remote send, we need to post a receive. The receive buffers are @@ -1228,8 +1186,13 @@ static void put_receive_buffer( struct smbdirect_socket *sc = &info->socket; unsigned long flags; - ib_dma_unmap_single(sc->ib.dev, response->sge.addr, - response->sge.length, DMA_FROM_DEVICE); + if (likely(response->sge.length != 0)) { + ib_dma_unmap_single(sc->ib.dev, + response->sge.addr, + response->sge.length, + DMA_FROM_DEVICE); + response->sge.length = 0; + } spin_lock_irqsave(&info->receive_queue_lock, flags); list_add_tail(&response->list, &info->receive_queue); @@ -1255,10 +1218,6 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf) spin_lock_init(&info->receive_queue_lock); info->count_receive_queue = 0; - INIT_LIST_HEAD(&info->empty_packet_queue); - spin_lock_init(&info->empty_packet_queue_lock); - info->count_empty_packet_queue = 0; - init_waitqueue_head(&info->wait_receive_queues); for (i = 0; i < num_buf; i++) { @@ -1267,6 +1226,7 @@ static int allocate_receive_buffers(struct smbd_connection *info, int num_buf) goto allocate_failed; response->info = info; + response->sge.length = 0; list_add_tail(&response->list, &info->receive_queue); info->count_receive_queue++; } @@ -1292,9 +1252,6 @@ static void destroy_receive_buffers(struct smbd_connection *info) while ((response = get_receive_buffer(info))) mempool_free(response, info->response_mempool); - - while ((response = get_empty_queue_buffer(info))) - mempool_free(response, info->response_mempool); } /* Implement idle connection timer [MS-SMBD] 3.1.6.2 */ @@ -1381,8 +1338,7 @@ void smbd_destroy(struct TCP_Server_Info *server) log_rdma_event(INFO, "free receive buffers\n"); wait_event(info->wait_receive_queues, - info->count_receive_queue + info->count_empty_packet_queue - == sp->recv_credit_max); + info->count_receive_queue == sp->recv_credit_max); destroy_receive_buffers(info); /* diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h index 75b3f491c3ad..ea04ce8a9763 100644 --- a/fs/smb/client/smbdirect.h +++ b/fs/smb/client/smbdirect.h @@ -110,10 +110,6 @@ struct smbd_connection { int count_receive_queue; spinlock_t receive_queue_lock; - struct list_head empty_packet_queue; - int count_empty_packet_queue; - spinlock_t empty_packet_queue_lock; - wait_queue_head_t wait_receive_queues; /* Reassembly queue */ diff --git a/include/crypto/hash.h b/include/crypto/hash.h index db294d452e8c..bbaeae705ef0 100644 --- a/include/crypto/hash.h +++ b/include/crypto/hash.h @@ -184,7 +184,7 @@ struct shash_desc { * Worst case is hmac(sha3-224-s390). Its context is a nested 'shash_desc' * containing a 'struct s390_sha_ctx'. */ -#define HASH_MAX_DESCSIZE (sizeof(struct shash_desc) + 360) +#define HASH_MAX_DESCSIZE (sizeof(struct shash_desc) + 361) #define MAX_SYNC_HASH_REQSIZE (sizeof(struct ahash_request) + \ HASH_MAX_DESCSIZE) diff --git a/include/linux/module.h b/include/linux/module.h index 3319a5269d28..e135cc79acee 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -244,14 +244,22 @@ struct module_kobject *lookup_or_create_module_kobject(const char *name); /* What your module does. */ #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -#ifdef MODULE +/* + * Format: __mod_device_table__kmod_<modname>__<type>__<name> + * Parts of the string `__kmod_` and `__` are used as delimiters when parsing + * a symbol in file2alias.c + */ +#define __mod_device_table(type, name) \ + __PASTE(__mod_device_table__, \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __PASTE(type, \ + __PASTE(__, name))))) + /* Creates an alias so file2alias.c can find device table. */ #define MODULE_DEVICE_TABLE(type, name) \ -static typeof(name) __mod_device_table__##type##__##name \ +static typeof(name) __mod_device_table(type, name) \ __attribute__ ((used, alias(__stringify(name)))) -#else /* !MODULE */ -#define MODULE_DEVICE_TABLE(type, name) -#endif /* Version of form [<epoch>:]<version>[-<extra-version>]. * Or for CVS/RCS ID version, everything but the number is stripped. diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index bc90c3c7b5fd..876358cfe1b1 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -144,6 +144,9 @@ int ring_buffer_write(struct trace_buffer *buffer, void ring_buffer_nest_start(struct trace_buffer *buffer); void ring_buffer_nest_end(struct trace_buffer *buffer); +DEFINE_GUARD(ring_buffer_nest, struct trace_buffer *, + ring_buffer_nest_start(_T), ring_buffer_nest_end(_T)) + struct ring_buffer_event * ring_buffer_peek(struct trace_buffer *buffer, int cpu, u64 *ts, unsigned long *lost_events); diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h index 5a41c3bbcbe3..01da4582db6d 100644 --- a/include/linux/rtc/ds1685.h +++ b/include/linux/rtc/ds1685.h @@ -8,7 +8,7 @@ * include larger, battery-backed NV-SRAM, burst-mode access, and an RTC * write counter. * - * Copyright (C) 2011-2014 Joshua Kinard <kumba@gentoo.org>. + * Copyright (C) 2011-2014 Joshua Kinard <linux@kumba.dev>. * Copyright (C) 2009 Matthias Fuchs <matthias.fuchs@esd-electronics.com>. * * References: diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 203eebad6b38..6d0f9c599ff7 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -156,12 +156,12 @@ enum sgp_type { int shmem_get_folio(struct inode *inode, pgoff_t index, loff_t write_end, struct folio **foliop, enum sgp_type sgp); struct folio *shmem_read_folio_gfp(struct address_space *mapping, - pgoff_t index, loff_t end, gfp_t gfp); + pgoff_t index, gfp_t gfp); static inline struct folio *shmem_read_folio(struct address_space *mapping, pgoff_t index) { - return shmem_read_folio_gfp(mapping, index, 0, mapping_gfp_mask(mapping)); + return shmem_read_folio_gfp(mapping, index, mapping_gfp_mask(mapping)); } static inline struct page *shmem_read_mapping_page( diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b8b06e71b73e..14b923ddb6df 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3033,6 +3033,29 @@ static inline void skb_reset_transport_header(struct sk_buff *skb) skb->transport_header = offset; } +/** + * skb_reset_transport_header_careful - conditionally reset transport header + * @skb: buffer to alter + * + * Hardened version of skb_reset_transport_header(). + * + * Returns: true if the operation was a success. + */ +static inline bool __must_check +skb_reset_transport_header_careful(struct sk_buff *skb) +{ + long offset = skb->data - skb->head; + + if (unlikely(offset != (typeof(skb->transport_header))offset)) + return false; + + if (unlikely(offset == (typeof(skb->transport_header))~0U)) + return false; + + skb->transport_header = offset; + return true; +} + static inline void skb_set_transport_header(struct sk_buff *skb, const int offset) { diff --git a/include/net/dst.h b/include/net/dst.h index 00467c1b5093..bab01363bb97 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -568,11 +568,23 @@ static inline struct net_device *dst_dev(const struct dst_entry *dst) return READ_ONCE(dst->dev); } +static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) +{ + /* In the future, use rcu_dereference(dst->dev) */ + WARN_ON_ONCE(!rcu_read_lock_held()); + return READ_ONCE(dst->dev); +} + static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) { return dst_dev(skb_dst(skb)); } +static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) +{ + return dst_dev_rcu(skb_dst(skb)); +} + static inline struct net *skb_dst_dev_net(const struct sk_buff *skb) { return dev_net(skb_dst_dev(skb)); diff --git a/include/net/udp.h b/include/net/udp.h index f8ae2c4ade14..e2af3bda90c9 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -586,6 +586,16 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk, { netdev_features_t features = NETIF_F_SG; struct sk_buff *segs; + int drop_count; + + /* + * Segmentation in UDP receive path is only for UDP GRO, drop udp + * fragmentation offload (UFO) packets. + */ + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) { + drop_count = 1; + goto drop; + } /* Avoid csum recalculation by skb_segment unless userspace explicitly * asks for the final checksum values @@ -609,16 +619,18 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk, */ segs = __skb_gso_segment(skb, features, false); if (IS_ERR_OR_NULL(segs)) { - int segs_nr = skb_shinfo(skb)->gso_segs; - - atomic_add(segs_nr, &sk->sk_drops); - SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, segs_nr); - kfree_skb(skb); - return NULL; + drop_count = skb_shinfo(skb)->gso_segs; + goto drop; } consume_skb(skb); return segs; + +drop: + atomic_add(drop_count, &sk->sk_drops); + SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, drop_count); + kfree_skb(skb); + return NULL; } static inline void udp_post_segment_fix_csum(struct sk_buff *skb) diff --git a/include/uapi/linux/raid/md_p.h b/include/uapi/linux/raid/md_p.h index ff47b6f0ba0f..b13946287277 100644 --- a/include/uapi/linux/raid/md_p.h +++ b/include/uapi/linux/raid/md_p.h @@ -173,7 +173,7 @@ typedef struct mdp_superblock_s { #else #error unspecified endianness #endif - __u32 recovery_cp; /* 11 recovery checkpoint sector count */ + __u32 resync_offset; /* 11 resync checkpoint sector count */ /* There are only valid for minor_version > 90 */ __u64 reshape_position; /* 12,13 next address in array-space for reshape */ __u32 new_level; /* 14 new level we are reshaping to */ diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index c57674a6aa0d..283348b64af9 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -260,7 +260,7 @@ * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: * - Vhost will create vhost workers as kernel threads. */ -#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8) +#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x83, __u8) /** * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. @@ -268,6 +268,6 @@ * * @return: An 8-bit value indicating the current thread mode. */ -#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8) +#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x84, __u8) #endif diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h index b4bb0ace0b26..7aa2eb766205 100644 --- a/include/uapi/linux/virtio_ids.h +++ b/include/uapi/linux/virtio_ids.h @@ -68,7 +68,6 @@ #define VIRTIO_ID_AUDIO_POLICY 39 /* virtio audio policy */ #define VIRTIO_ID_BT 40 /* virtio bluetooth */ #define VIRTIO_ID_GPIO 41 /* virtio gpio */ -#define VIRTIO_ID_MEDIA 48 /* virtio media */ /* * Virtio Transitional IDs diff --git a/include/uapi/linux/vt.h b/include/uapi/linux/vt.h index b60fcdfb2746..714483d68c69 100644 --- a/include/uapi/linux/vt.h +++ b/include/uapi/linux/vt.h @@ -14,9 +14,9 @@ /* Note: the ioctl VT_GETSTATE does not work for consoles 16 and higher (since it returns a short) */ -/* 'V' to avoid collision with termios and kd */ +/* 0x56 is 'V', to avoid collision with termios and kd */ -#define VT_OPENQRY _IO('V', 0x00) /* find available vt */ +#define VT_OPENQRY 0x5600 /* find available vt */ struct vt_mode { __u8 mode; /* vt mode */ @@ -25,8 +25,8 @@ struct vt_mode { __s16 acqsig; /* signal to raise on acquisition */ __s16 frsig; /* unused (set to 0) */ }; -#define VT_GETMODE _IO('V', 0x01) /* get mode of active vt */ -#define VT_SETMODE _IO('V', 0x02) /* set mode of active vt */ +#define VT_GETMODE 0x5601 /* get mode of active vt */ +#define VT_SETMODE 0x5602 /* set mode of active vt */ #define VT_AUTO 0x00 /* auto vt switching */ #define VT_PROCESS 0x01 /* process controls switching */ #define VT_ACKACQ 0x02 /* acknowledge switch */ @@ -36,21 +36,21 @@ struct vt_stat { __u16 v_signal; /* signal to send */ __u16 v_state; /* vt bitmask */ }; -#define VT_GETSTATE _IO('V', 0x03) /* get global vt state info */ -#define VT_SENDSIG _IO('V', 0x04) /* signal to send to bitmask of vts */ +#define VT_GETSTATE 0x5603 /* get global vt state info */ +#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ -#define VT_RELDISP _IO('V', 0x05) /* release display */ +#define VT_RELDISP 0x5605 /* release display */ -#define VT_ACTIVATE _IO('V', 0x06) /* make vt active */ -#define VT_WAITACTIVE _IO('V', 0x07) /* wait for vt active */ -#define VT_DISALLOCATE _IO('V', 0x08) /* free memory associated to vt */ +#define VT_ACTIVATE 0x5606 /* make vt active */ +#define VT_WAITACTIVE 0x5607 /* wait for vt active */ +#define VT_DISALLOCATE 0x5608 /* free memory associated to vt */ struct vt_sizes { __u16 v_rows; /* number of rows */ __u16 v_cols; /* number of columns */ __u16 v_scrollsize; /* number of lines of scrollback */ }; -#define VT_RESIZE _IO('V', 0x09) /* set kernel's idea of screensize */ +#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */ struct vt_consize { __u16 v_rows; /* number of rows */ @@ -60,10 +60,10 @@ struct vt_consize { __u16 v_vcol; /* number of pixel columns on screen */ __u16 v_ccol; /* number of pixel columns per character */ }; -#define VT_RESIZEX _IO('V', 0x0A) /* set kernel's idea of screensize + more */ -#define VT_LOCKSWITCH _IO('V', 0x0B) /* disallow vt switching */ -#define VT_UNLOCKSWITCH _IO('V', 0x0C) /* allow vt switching */ -#define VT_GETHIFONTMASK _IO('V', 0x0D) /* return hi font mask */ +#define VT_RESIZEX 0x560A /* set kernel's idea of screensize + more */ +#define VT_LOCKSWITCH 0x560B /* disallow vt switching */ +#define VT_UNLOCKSWITCH 0x560C /* allow vt switching */ +#define VT_GETHIFONTMASK 0x560D /* return hi font mask */ struct vt_event { __u32 event; @@ -77,14 +77,14 @@ struct vt_event { __u32 pad[4]; /* Padding for expansion */ }; -#define VT_WAITEVENT _IO('V', 0x0E) /* Wait for an event */ +#define VT_WAITEVENT 0x560E /* Wait for an event */ struct vt_setactivate { __u32 console; struct vt_mode mode; }; -#define VT_SETACTIVATE _IO('V', 0x0F) /* Activate and set the mode of a console */ +#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ /* get console size and cursor position */ struct vt_consizecsrpos { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 399f03e62508..c4f69a9e9af6 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -21445,7 +21445,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) &target_size); if (cnt == 0 || cnt >= INSN_BUF_SIZE || (ctx_field_size && !target_size)) { - verifier_bug(env, "error during ctx access conversion"); + verifier_bug(env, "error during ctx access conversion (%d)", cnt); return -EFAULT; } @@ -23114,6 +23114,8 @@ static void free_states(struct bpf_verifier_env *env) for (i = 0; i < env->scc_cnt; ++i) { info = env->scc_info[i]; + if (!info) + continue; for (j = 0; j < info->num_visits; j++) free_backedges(&info->visits[j]); kvfree(info); @@ -24554,6 +24556,7 @@ dfs_continue: err = -ENOMEM; goto exit; } + env->scc_cnt = next_scc_id; exit: kvfree(stack); kvfree(pre); diff --git a/kernel/fork.c b/kernel/fork.c index c4ada32598bd..af673856499d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -689,6 +689,7 @@ void __mmdrop(struct mm_struct *mm) mm_pasid_drop(mm); mm_destroy_cid(mm); percpu_counter_destroy_many(mm->rss_stat, NR_MM_COUNTERS); + futex_hash_free(mm); free_mm(mm); } @@ -1137,7 +1138,6 @@ static inline void __mmput(struct mm_struct *mm) if (mm->binfmt) module_put(mm->binfmt->module); lru_gen_del_mm(mm); - futex_hash_free(mm); mmdrop(mm); } diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 8708a1205f82..b2c1f14b8129 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -95,9 +95,41 @@ static struct notifier_block panic_block = { .notifier_call = hung_task_panic, }; +static bool task_is_hung(struct task_struct *t, unsigned long timeout) +{ + unsigned long switch_count = t->nvcsw + t->nivcsw; + unsigned int state = READ_ONCE(t->__state); + + /* + * skip the TASK_KILLABLE tasks -- these can be killed + * skip the TASK_IDLE tasks -- those are genuinely idle + * skip the TASK_FROZEN task -- it reasonably stops scheduling by freezer + */ + if (!(state & TASK_UNINTERRUPTIBLE) || + (state & (TASK_WAKEKILL | TASK_NOLOAD | TASK_FROZEN))) + return false; + + /* + * When a freshly created task is scheduled once, changes its state to + * TASK_UNINTERRUPTIBLE without having ever been switched out once, it + * musn't be checked. + */ + if (unlikely(!switch_count)) + return false; + + if (switch_count != t->last_switch_count) { + t->last_switch_count = switch_count; + t->last_switch_time = jiffies; + return false; + } + if (time_is_after_jiffies(t->last_switch_time + timeout * HZ)) + return false; + + return true; +} #ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER -static void debug_show_blocker(struct task_struct *task) +static void debug_show_blocker(struct task_struct *task, unsigned long timeout) { struct task_struct *g, *t; unsigned long owner, blocker, blocker_type; @@ -174,41 +206,21 @@ static void debug_show_blocker(struct task_struct *task) t->pid, rwsem_blocked_by); break; } - sched_show_task(t); + /* Avoid duplicated task dump, skip if the task is also hung. */ + if (!task_is_hung(t, timeout)) + sched_show_task(t); return; } } #else -static inline void debug_show_blocker(struct task_struct *task) +static inline void debug_show_blocker(struct task_struct *task, unsigned long timeout) { } #endif static void check_hung_task(struct task_struct *t, unsigned long timeout) { - unsigned long switch_count = t->nvcsw + t->nivcsw; - - /* - * Ensure the task is not frozen. - * Also, skip vfork and any other user process that freezer should skip. - */ - if (unlikely(READ_ONCE(t->__state) & TASK_FROZEN)) - return; - - /* - * When a freshly created task is scheduled once, changes its state to - * TASK_UNINTERRUPTIBLE without having ever been switched out once, it - * musn't be checked. - */ - if (unlikely(!switch_count)) - return; - - if (switch_count != t->last_switch_count) { - t->last_switch_count = switch_count; - t->last_switch_time = jiffies; - return; - } - if (time_is_after_jiffies(t->last_switch_time + timeout * HZ)) + if (!task_is_hung(t, timeout)) return; /* @@ -243,7 +255,7 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" " disables this message.\n"); sched_show_task(t); - debug_show_blocker(t); + debug_show_blocker(t, timeout); hung_task_show_lock = true; if (sysctl_hung_task_all_cpu_backtrace) @@ -299,7 +311,6 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) hung_task_show_lock = false; rcu_read_lock(); for_each_process_thread(g, t) { - unsigned int state; if (!max_count--) goto unlock; @@ -308,15 +319,8 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) goto unlock; last_break = jiffies; } - /* - * skip the TASK_KILLABLE tasks -- these can be killed - * skip the TASK_IDLE tasks -- those are genuinely idle - */ - state = READ_ONCE(t->__state); - if ((state & TASK_UNINTERRUPTIBLE) && - !(state & TASK_WAKEKILL) && - !(state & TASK_NOLOAD)) - check_hung_task(t, timeout); + + check_hung_task(t, timeout); } unlock: rcu_read_unlock(); diff --git a/kernel/panic.c b/kernel/panic.c index 27747cecb1af..6255cafa06ed 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -78,12 +78,6 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list); EXPORT_SYMBOL(panic_notifier_list); #ifdef CONFIG_SYSCTL -static int sysctl_panic_print_handler(const struct ctl_table *table, int write, - void *buffer, size_t *lenp, loff_t *ppos) -{ - pr_info_once("Kernel: 'panic_print' sysctl interface will be obsoleted by both 'panic_sys_info' and 'panic_console_replay'\n"); - return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); -} /* * Taint values can only be increased @@ -128,6 +122,13 @@ static int proc_taint(const struct ctl_table *table, int write, return err; } +static int sysctl_panic_print_handler(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + pr_info_once("Kernel: 'panic_print' sysctl interface will be obsoleted by both 'panic_sys_info' and 'panic_console_replay'\n"); + return proc_doulongvec_minmax(table, write, buffer, lenp, ppos); +} + static const struct ctl_table kern_panic_table[] = { #ifdef CONFIG_SMP { @@ -183,13 +184,6 @@ static const struct ctl_table kern_panic_table[] = { .mode = 0644, .proc_handler = proc_douintvec, }, - { - .procname = "panic_sys_info", - .data = &panic_print, - .maxlen = sizeof(panic_print), - .mode = 0644, - .proc_handler = sysctl_sys_info_handler, - }, #if (defined(CONFIG_X86_32) || defined(CONFIG_PARISC)) && \ defined(CONFIG_DEBUG_STACKOVERFLOW) { @@ -200,6 +194,13 @@ static const struct ctl_table kern_panic_table[] = { .proc_handler = proc_dointvec, }, #endif + { + .procname = "panic_sys_info", + .data = &panic_print, + .maxlen = sizeof(panic_print), + .mode = 0644, + .proc_handler = sysctl_sys_info_handler, + }, }; static __init int kernel_panic_sysctls_init(void) diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 2024c1d36402..59fdb7ebbf22 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -176,7 +176,7 @@ struct psi_group psi_system = { .pcpu = &system_group_pcpu, }; -static DEFINE_PER_CPU(seqcount_t, psi_seq); +static DEFINE_PER_CPU(seqcount_t, psi_seq) = SEQCNT_ZERO(psi_seq); static inline void psi_write_begin(int cpu) { @@ -204,11 +204,7 @@ static void poll_timer_fn(struct timer_list *t); static void group_init(struct psi_group *group) { - int cpu; - group->enabled = true; - for_each_possible_cpu(cpu) - seqcount_init(per_cpu_ptr(&psi_seq, cpu)); group->avg_last_update = sched_clock(); group->avg_next_update = group->avg_last_update + psi_period; mutex_init(&group->avgs_lock); diff --git a/kernel/smp.c b/kernel/smp.c index 4649fa4872ff..56f83aa58ec8 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -1018,7 +1018,7 @@ void __init smp_init(void) * @cond_func: A callback function that is passed a cpu id and * the info parameter. The function is called * with preemption disabled. The function should - * return a blooean value indicating whether to IPI + * return a boolean value indicating whether to IPI * the specified CPU. * @func: The function to run on all applicable CPUs. * This must be fast and non-blocking. diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5176e0270f07..bb71a0dc9d69 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4812,26 +4812,26 @@ int ring_buffer_write(struct trace_buffer *buffer, int ret = -EBUSY; int cpu; - preempt_disable_notrace(); + guard(preempt_notrace)(); if (atomic_read(&buffer->record_disabled)) - goto out; + return -EBUSY; cpu = raw_smp_processor_id(); if (!cpumask_test_cpu(cpu, buffer->cpumask)) - goto out; + return -EBUSY; cpu_buffer = buffer->buffers[cpu]; if (atomic_read(&cpu_buffer->record_disabled)) - goto out; + return -EBUSY; if (length > buffer->max_data_size) - goto out; + return -EBUSY; if (unlikely(trace_recursive_lock(cpu_buffer))) - goto out; + return -EBUSY; event = rb_reserve_next_event(buffer, cpu_buffer, length); if (!event) @@ -4849,10 +4849,6 @@ int ring_buffer_write(struct trace_buffer *buffer, out_unlock: trace_recursive_unlock(cpu_buffer); - - out: - preempt_enable_notrace(); - return ret; } EXPORT_SYMBOL_GPL(ring_buffer_write); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 9e99000c7c3a..4283ed4e8f59 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -432,15 +432,13 @@ static void ftrace_exports(struct ring_buffer_event *event, int flag) { struct trace_export *export; - preempt_disable_notrace(); + guard(preempt_notrace)(); export = rcu_dereference_raw_check(ftrace_exports_list); while (export) { trace_process_export(export, event, flag); export = rcu_dereference_raw_check(export->next); } - - preempt_enable_notrace(); } static inline void @@ -497,27 +495,18 @@ int register_ftrace_export(struct trace_export *export) if (WARN_ON_ONCE(!export->write)) return -1; - mutex_lock(&ftrace_export_lock); + guard(mutex)(&ftrace_export_lock); add_ftrace_export(&ftrace_exports_list, export); - mutex_unlock(&ftrace_export_lock); - return 0; } EXPORT_SYMBOL_GPL(register_ftrace_export); int unregister_ftrace_export(struct trace_export *export) { - int ret; - - mutex_lock(&ftrace_export_lock); - - ret = rm_ftrace_export(&ftrace_exports_list, export); - - mutex_unlock(&ftrace_export_lock); - - return ret; + guard(mutex)(&ftrace_export_lock); + return rm_ftrace_export(&ftrace_exports_list, export); } EXPORT_SYMBOL_GPL(unregister_ftrace_export); @@ -640,9 +629,8 @@ void trace_array_put(struct trace_array *this_tr) if (!this_tr) return; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); __trace_array_put(this_tr); - mutex_unlock(&trace_types_lock); } EXPORT_SYMBOL_GPL(trace_array_put); @@ -1160,13 +1148,11 @@ int __trace_array_puts(struct trace_array *tr, unsigned long ip, trace_ctx = tracing_gen_ctx(); buffer = tr->array_buffer.buffer; - ring_buffer_nest_start(buffer); + guard(ring_buffer_nest)(buffer); event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, trace_ctx); - if (!event) { - size = 0; - goto out; - } + if (!event) + return 0; entry = ring_buffer_event_data(event); entry->ip = ip; @@ -1182,8 +1168,6 @@ int __trace_array_puts(struct trace_array *tr, unsigned long ip, __buffer_unlock_commit(buffer, event); ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); - out: - ring_buffer_nest_end(buffer); return size; } EXPORT_SYMBOL_GPL(__trace_array_puts); @@ -1213,7 +1197,6 @@ int __trace_bputs(unsigned long ip, const char *str) struct bputs_entry *entry; unsigned int trace_ctx; int size = sizeof(struct bputs_entry); - int ret = 0; if (!printk_binsafe(tr)) return __trace_puts(ip, str, strlen(str)); @@ -1227,11 +1210,11 @@ int __trace_bputs(unsigned long ip, const char *str) trace_ctx = tracing_gen_ctx(); buffer = tr->array_buffer.buffer; - ring_buffer_nest_start(buffer); + guard(ring_buffer_nest)(buffer); event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, trace_ctx); if (!event) - goto out; + return 0; entry = ring_buffer_event_data(event); entry->ip = ip; @@ -1240,10 +1223,7 @@ int __trace_bputs(unsigned long ip, const char *str) __buffer_unlock_commit(buffer, event); ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); - ret = 1; - out: - ring_buffer_nest_end(buffer); - return ret; + return 1; } EXPORT_SYMBOL_GPL(__trace_bputs); @@ -1432,13 +1412,8 @@ static int tracing_arm_snapshot_locked(struct trace_array *tr) int tracing_arm_snapshot(struct trace_array *tr) { - int ret; - - mutex_lock(&trace_types_lock); - ret = tracing_arm_snapshot_locked(tr); - mutex_unlock(&trace_types_lock); - - return ret; + guard(mutex)(&trace_types_lock); + return tracing_arm_snapshot_locked(tr); } void tracing_disarm_snapshot(struct trace_array *tr) @@ -1841,7 +1816,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, ret = get_user(ch, ubuf++); if (ret) - goto out; + return ret; read++; cnt--; @@ -1855,7 +1830,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, while (cnt && isspace(ch)) { ret = get_user(ch, ubuf++); if (ret) - goto out; + return ret; read++; cnt--; } @@ -1865,8 +1840,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, /* only spaces were written */ if (isspace(ch) || !ch) { *ppos += read; - ret = read; - goto out; + return read; } } @@ -1874,13 +1848,12 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, while (cnt && !isspace(ch) && ch) { if (parser->idx < parser->size - 1) parser->buffer[parser->idx++] = ch; - else { - ret = -EINVAL; - goto out; - } + else + return -EINVAL; + ret = get_user(ch, ubuf++); if (ret) - goto out; + return ret; read++; cnt--; } @@ -1895,15 +1868,11 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, /* Make sure the parsed string always terminates with '\0'. */ parser->buffer[parser->idx] = 0; } else { - ret = -EINVAL; - goto out; + return -EINVAL; } *ppos += read; - ret = read; - -out: - return ret; + return read; } /* TODO add a seq_buf_to_buffer() */ @@ -2405,10 +2374,10 @@ int __init register_tracer(struct tracer *type) mutex_unlock(&trace_types_lock); if (ret || !default_bootup_tracer) - goto out_unlock; + return ret; if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE)) - goto out_unlock; + return 0; printk(KERN_INFO "Starting tracer '%s'\n", type->name); /* Do we want this tracer to start on bootup? */ @@ -2420,8 +2389,7 @@ int __init register_tracer(struct tracer *type) /* disable other selftests, since this will break it. */ disable_tracing_selftest("running a tracer"); - out_unlock: - return ret; + return 0; } static void tracing_reset_cpu(struct array_buffer *buf, int cpu) @@ -2498,9 +2466,8 @@ void tracing_reset_all_online_cpus_unlocked(void) void tracing_reset_all_online_cpus(void) { - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); tracing_reset_all_online_cpus_unlocked(); - mutex_unlock(&trace_types_lock); } int is_tracing_stopped(void) @@ -2511,18 +2478,17 @@ int is_tracing_stopped(void) static void tracing_start_tr(struct trace_array *tr) { struct trace_buffer *buffer; - unsigned long flags; if (tracing_disabled) return; - raw_spin_lock_irqsave(&tr->start_lock, flags); + guard(raw_spinlock_irqsave)(&tr->start_lock); if (--tr->stop_count) { if (WARN_ON_ONCE(tr->stop_count < 0)) { /* Someone screwed up their debugging */ tr->stop_count = 0; } - goto out; + return; } /* Prevent the buffers from switching */ @@ -2539,9 +2505,6 @@ static void tracing_start_tr(struct trace_array *tr) #endif arch_spin_unlock(&tr->max_lock); - - out: - raw_spin_unlock_irqrestore(&tr->start_lock, flags); } /** @@ -2559,11 +2522,10 @@ void tracing_start(void) static void tracing_stop_tr(struct trace_array *tr) { struct trace_buffer *buffer; - unsigned long flags; - raw_spin_lock_irqsave(&tr->start_lock, flags); + guard(raw_spinlock_irqsave)(&tr->start_lock); if (tr->stop_count++) - goto out; + return; /* Prevent the buffers from switching */ arch_spin_lock(&tr->max_lock); @@ -2579,9 +2541,6 @@ static void tracing_stop_tr(struct trace_array *tr) #endif arch_spin_unlock(&tr->max_lock); - - out: - raw_spin_unlock_irqrestore(&tr->start_lock, flags); } /** @@ -2694,12 +2653,12 @@ void trace_buffered_event_enable(void) per_cpu(trace_buffered_event, cpu) = event; - preempt_disable(); - if (cpu == smp_processor_id() && - __this_cpu_read(trace_buffered_event) != - per_cpu(trace_buffered_event, cpu)) - WARN_ON_ONCE(1); - preempt_enable(); + scoped_guard(preempt,) { + if (cpu == smp_processor_id() && + __this_cpu_read(trace_buffered_event) != + per_cpu(trace_buffered_event, cpu)) + WARN_ON_ONCE(1); + } } } @@ -3044,7 +3003,7 @@ static void __ftrace_trace_stack(struct trace_array *tr, skip++; #endif - preempt_disable_notrace(); + guard(preempt_notrace)(); stackidx = __this_cpu_inc_return(ftrace_stack_reserve) - 1; @@ -3102,8 +3061,6 @@ static void __ftrace_trace_stack(struct trace_array *tr, /* Again, don't let gcc optimize things here */ barrier(); __this_cpu_dec(ftrace_stack_reserve); - preempt_enable_notrace(); - } static inline void ftrace_trace_stack(struct trace_array *tr, @@ -3186,9 +3143,9 @@ ftrace_trace_userstack(struct trace_array *tr, * prevent recursion, since the user stack tracing may * trigger other kernel events. */ - preempt_disable(); + guard(preempt)(); if (__this_cpu_read(user_stack_count)) - goto out; + return; __this_cpu_inc(user_stack_count); @@ -3206,8 +3163,6 @@ ftrace_trace_userstack(struct trace_array *tr, out_drop_count: __this_cpu_dec(user_stack_count); - out: - preempt_enable(); } #else /* CONFIG_USER_STACKTRACE_SUPPORT */ static void ftrace_trace_userstack(struct trace_array *tr, @@ -3389,7 +3344,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) pause_graph_tracing(); trace_ctx = tracing_gen_ctx(); - preempt_disable_notrace(); + guard(preempt_notrace)(); tbuffer = get_trace_buf(); if (!tbuffer) { @@ -3404,26 +3359,23 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) size = sizeof(*entry) + sizeof(u32) * len; buffer = tr->array_buffer.buffer; - ring_buffer_nest_start(buffer); - event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, - trace_ctx); - if (!event) - goto out; - entry = ring_buffer_event_data(event); - entry->ip = ip; - entry->fmt = fmt; - - memcpy(entry->buf, tbuffer, sizeof(u32) * len); - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(tr, buffer, trace_ctx, 6, NULL); + scoped_guard(ring_buffer_nest, buffer) { + event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, + trace_ctx); + if (!event) + goto out_put; + entry = ring_buffer_event_data(event); + entry->ip = ip; + entry->fmt = fmt; -out: - ring_buffer_nest_end(buffer); + memcpy(entry->buf, tbuffer, sizeof(u32) * len); + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(tr, buffer, trace_ctx, 6, NULL); + } out_put: put_trace_buf(); out_nobuffer: - preempt_enable_notrace(); unpause_graph_tracing(); return len; @@ -3447,7 +3399,7 @@ int __trace_array_vprintk(struct trace_buffer *buffer, pause_graph_tracing(); trace_ctx = tracing_gen_ctx(); - preempt_disable_notrace(); + guard(preempt_notrace)(); tbuffer = get_trace_buf(); @@ -3459,24 +3411,22 @@ int __trace_array_vprintk(struct trace_buffer *buffer, len = vscnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); size = sizeof(*entry) + len + 1; - ring_buffer_nest_start(buffer); - event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, - trace_ctx); - if (!event) - goto out; - entry = ring_buffer_event_data(event); - entry->ip = ip; - - memcpy(&entry->buf, tbuffer, len + 1); - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(printk_trace, buffer, trace_ctx, 6, NULL); + scoped_guard(ring_buffer_nest, buffer) { + event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, + trace_ctx); + if (!event) + goto out; + entry = ring_buffer_event_data(event); + entry->ip = ip; + memcpy(&entry->buf, tbuffer, len + 1); + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(printk_trace, buffer, trace_ctx, 6, NULL); + } out: - ring_buffer_nest_end(buffer); put_trace_buf(); out_nobuffer: - preempt_enable_notrace(); unpause_graph_tracing(); return len; @@ -4800,20 +4750,16 @@ int tracing_open_file_tr(struct inode *inode, struct file *filp) if (ret) return ret; - mutex_lock(&event_mutex); + guard(mutex)(&event_mutex); /* Fail if the file is marked for removal */ if (file->flags & EVENT_FILE_FL_FREED) { trace_array_put(file->tr); - ret = -ENODEV; + return -ENODEV; } else { event_file_get(file); } - mutex_unlock(&event_mutex); - if (ret) - return ret; - filp->private_data = inode->i_private; return 0; @@ -5090,7 +5036,7 @@ tracing_cpumask_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos) { struct trace_array *tr = file_inode(filp)->i_private; - char *mask_str; + char *mask_str __free(kfree) = NULL; int len; len = snprintf(NULL, 0, "%*pb\n", @@ -5101,16 +5047,10 @@ tracing_cpumask_read(struct file *filp, char __user *ubuf, len = snprintf(mask_str, len, "%*pb\n", cpumask_pr_args(tr->tracing_cpumask)); - if (len >= count) { - count = -EINVAL; - goto out_err; - } - count = simple_read_from_buffer(ubuf, count, ppos, mask_str, len); - -out_err: - kfree(mask_str); + if (len >= count) + return -EINVAL; - return count; + return simple_read_from_buffer(ubuf, count, ppos, mask_str, len); } int tracing_set_cpumask(struct trace_array *tr, @@ -5957,9 +5897,9 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf, char buf[MAX_TRACER_SIZE+2]; int r; - mutex_lock(&trace_types_lock); - r = sprintf(buf, "%s\n", tr->current_trace->name); - mutex_unlock(&trace_types_lock); + scoped_guard(mutex, &trace_types_lock) { + r = sprintf(buf, "%s\n", tr->current_trace->name); + } return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -6261,15 +6201,13 @@ int tracing_update_buffers(struct trace_array *tr) { int ret = 0; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); update_last_data(tr); if (!tr->ring_buffer_expanded) ret = __tracing_resize_ring_buffer(tr, trace_buf_size, RING_BUFFER_ALL_CPUS); - mutex_unlock(&trace_types_lock); - return ret; } @@ -6566,7 +6504,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) if (ret) return ret; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); cpu = tracing_get_cpu(inode); ret = open_pipe_on_cpu(tr, cpu); if (ret) @@ -6610,7 +6548,6 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) tr->trace_ref++; - mutex_unlock(&trace_types_lock); return ret; fail: @@ -6619,7 +6556,6 @@ fail_alloc_iter: close_pipe_on_cpu(tr, cpu); fail_pipe_on_cpu: __trace_array_put(tr); - mutex_unlock(&trace_types_lock); return ret; } @@ -6628,14 +6564,13 @@ static int tracing_release_pipe(struct inode *inode, struct file *file) struct trace_iterator *iter = file->private_data; struct trace_array *tr = inode->i_private; - mutex_lock(&trace_types_lock); - - tr->trace_ref--; + scoped_guard(mutex, &trace_types_lock) { + tr->trace_ref--; - if (iter->trace->pipe_close) - iter->trace->pipe_close(iter); - close_pipe_on_cpu(tr, iter->cpu_file); - mutex_unlock(&trace_types_lock); + if (iter->trace->pipe_close) + iter->trace->pipe_close(iter); + close_pipe_on_cpu(tr, iter->cpu_file); + } free_trace_iter_content(iter); kfree(iter); @@ -7438,7 +7373,7 @@ int tracing_set_clock(struct trace_array *tr, const char *clockstr) if (i == ARRAY_SIZE(trace_clocks)) return -EINVAL; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); tr->clock_id = i; @@ -7462,8 +7397,6 @@ int tracing_set_clock(struct trace_array *tr, const char *clockstr) tscratch->clock_id = i; } - mutex_unlock(&trace_types_lock); - return 0; } @@ -7515,15 +7448,13 @@ static int tracing_time_stamp_mode_show(struct seq_file *m, void *v) { struct trace_array *tr = m->private; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); if (ring_buffer_time_stamp_abs(tr->array_buffer.buffer)) seq_puts(m, "delta [absolute]\n"); else seq_puts(m, "[delta] absolute\n"); - mutex_unlock(&trace_types_lock); - return 0; } @@ -8111,14 +8042,14 @@ static void clear_tracing_err_log(struct trace_array *tr) { struct tracing_log_err *err, *next; - mutex_lock(&tracing_err_log_lock); + guard(mutex)(&tracing_err_log_lock); + list_for_each_entry_safe(err, next, &tr->err_log, list) { list_del(&err->list); free_tracing_log_err(err); } tr->n_err_log_entries = 0; - mutex_unlock(&tracing_err_log_lock); } static void *tracing_err_log_seq_start(struct seq_file *m, loff_t *pos) @@ -8389,7 +8320,7 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) struct ftrace_buffer_info *info = file->private_data; struct trace_iterator *iter = &info->iter; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); iter->tr->trace_ref--; @@ -8400,8 +8331,6 @@ static int tracing_buffers_release(struct inode *inode, struct file *file) info->spare_cpu, info->spare); kvfree(info); - mutex_unlock(&trace_types_lock); - return 0; } @@ -8609,14 +8538,13 @@ static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned * An ioctl call with cmd 0 to the ring buffer file will wake up all * waiters */ - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); /* Make sure the waiters see the new wait_index */ (void)atomic_fetch_inc_release(&iter->wait_index); ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file); - mutex_unlock(&trace_types_lock); return 0; } @@ -8957,12 +8885,12 @@ ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash, out_reg: ret = tracing_arm_snapshot(tr); if (ret < 0) - goto out; + return ret; ret = register_ftrace_function_probe(glob, tr, ops, count); if (ret < 0) tracing_disarm_snapshot(tr); - out: + return ret < 0 ? ret : 0; } @@ -9106,10 +9034,9 @@ trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt, return -EINVAL; if (!!(topt->flags->val & topt->opt->bit) != val) { - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); ret = __set_tracer_option(topt->tr, topt->flags, topt->opt, !val); - mutex_unlock(&trace_types_lock); if (ret) return ret; } @@ -9418,7 +9345,7 @@ rb_simple_write(struct file *filp, const char __user *ubuf, return ret; if (buffer) { - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); if (!!val == tracer_tracing_is_on(tr)) { val = 0; /* do nothing */ } else if (val) { @@ -9432,7 +9359,6 @@ rb_simple_write(struct file *filp, const char __user *ubuf, /* Wake up any waiters */ ring_buffer_wake_waiters(buffer, RING_BUFFER_ALL_CPUS); } - mutex_unlock(&trace_types_lock); } (*ppos)++; @@ -9816,10 +9742,9 @@ static void __update_tracer_options(struct trace_array *tr) static void update_tracer_options(struct trace_array *tr) { - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); tracer_options_updated = true; __update_tracer_options(tr); - mutex_unlock(&trace_types_lock); } /* Must have trace_types_lock held */ @@ -9841,11 +9766,10 @@ struct trace_array *trace_array_find_get(const char *instance) { struct trace_array *tr; - mutex_lock(&trace_types_lock); + guard(mutex)(&trace_types_lock); tr = trace_array_find(instance); if (tr) tr->ref++; - mutex_unlock(&trace_types_lock); return tr; } @@ -10803,7 +10727,8 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, size_t count, loff_t *ppos, int (*createfn)(const char *)) { - char *kbuf, *buf, *tmp; + char *kbuf __free(kfree) = NULL; + char *buf, *tmp; int ret = 0; size_t done = 0; size_t size; @@ -10818,10 +10743,9 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, if (size >= WRITE_BUFSIZE) size = WRITE_BUFSIZE - 1; - if (copy_from_user(kbuf, buffer + done, size)) { - ret = -EFAULT; - goto out; - } + if (copy_from_user(kbuf, buffer + done, size)) + return -EFAULT; + kbuf[size] = '\0'; buf = kbuf; do { @@ -10837,8 +10761,7 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, /* This can accept WRITE_BUFSIZE - 2 ('\n' + '\0') */ pr_warn("Line length is too long: Should be less than %d\n", WRITE_BUFSIZE - 2); - ret = -EINVAL; - goto out; + return -EINVAL; } } done += size; @@ -10851,17 +10774,12 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, ret = createfn(buf); if (ret) - goto out; + return ret; buf += size; } while (done < count); } - ret = done; - -out: - kfree(kbuf); - - return ret; + return done; } #ifdef CONFIG_TRACER_MAX_TRACE @@ -11064,7 +10982,7 @@ __init static int tracer_alloc_buffers(void) BUILD_BUG_ON(TRACE_ITER_LAST_BIT > TRACE_FLAGS_MAX_SIZE); if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) - goto out; + return -ENOMEM; if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL)) goto out_free_buffer_mask; @@ -11182,7 +11100,6 @@ out_free_cpumask: free_cpumask_var(global_trace.tracing_cpumask); out_free_buffer_mask: free_cpumask_var(tracing_buffer_mask); -out: return ret; } diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 33cfbd4ed76d..f24ee61f8884 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -536,12 +536,12 @@ static notrace void trace_event_raw_event_synth(void *__data, * is being performed within another event. */ buffer = trace_file->tr->array_buffer.buffer; - ring_buffer_nest_start(buffer); + guard(ring_buffer_nest)(buffer); entry = trace_event_buffer_reserve(&fbuffer, trace_file, sizeof(*entry) + fields_size); if (!entry) - goto out; + return; for (i = 0, n_u64 = 0; i < event->n_fields; i++) { val_idx = var_ref_idx[i]; @@ -584,8 +584,6 @@ static notrace void trace_event_raw_event_synth(void *__data, } trace_event_buffer_commit(&fbuffer); -out: - ring_buffer_nest_end(buffer); } static void free_synth_event_print_fmt(struct trace_event_call *call) diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 0b3db02030a7..97db0b0ccf3e 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -701,6 +701,7 @@ void print_function_args(struct trace_seq *s, unsigned long *args, struct btf *btf; s32 tid, nr = 0; int a, p, x; + u16 encode; trace_seq_printf(s, "("); @@ -744,7 +745,12 @@ void print_function_args(struct trace_seq *s, unsigned long *args, trace_seq_printf(s, "0x%lx", arg); break; case BTF_KIND_INT: - trace_seq_printf(s, "%ld", arg); + encode = btf_int_encoding(t); + /* Print unsigned ints as hex */ + if (encode & BTF_INT_SIGNED) + trace_seq_printf(s, "%ld", arg); + else + trace_seq_printf(s, "0x%lx", arg); break; case BTF_KIND_ENUM: trace_seq_printf(s, "%ld", arg); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index acee7f75600b..1cb4734e58e1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3244,7 +3244,6 @@ config TEST_KEXEC_HANDOVER If unsure, say N. - config RATELIMIT_KUNIT_TEST tristate "KUnit Test for correctness and stress of ratelimit" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/localversion-next b/localversion-next new file mode 100644 index 000000000000..2eb4c4941a5f --- /dev/null +++ b/localversion-next @@ -0,0 +1 @@ +-next-20250805 diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c index d19031f275a3..830107b6dd08 100644 --- a/mm/debug_vm_pgtable.c +++ b/mm/debug_vm_pgtable.c @@ -990,29 +990,34 @@ static void __init destroy_args(struct pgtable_debug_args *args) /* Free page table entries */ if (args->start_ptep) { + pmd_clear(args->pmdp); pte_free(args->mm, args->start_ptep); mm_dec_nr_ptes(args->mm); } if (args->start_pmdp) { + pud_clear(args->pudp); pmd_free(args->mm, args->start_pmdp); mm_dec_nr_pmds(args->mm); } if (args->start_pudp) { + p4d_clear(args->p4dp); pud_free(args->mm, args->start_pudp); mm_dec_nr_puds(args->mm); } - if (args->start_p4dp) + if (args->start_p4dp) { + pgd_clear(args->pgdp); p4d_free(args->mm, args->start_p4dp); + } /* Free vma and mm struct */ if (args->vma) vm_area_free(args->vma); if (args->mm) - mmdrop(args->mm); + mmput(args->mm); } static struct page * __init diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c index e0968acc03aa..f4b17984b627 100644 --- a/mm/kasan/kasan_test_c.c +++ b/mm/kasan/kasan_test_c.c @@ -1578,9 +1578,11 @@ static void kasan_strings(struct kunit *test) ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); + OPTIMIZER_HIDE_VAR(ptr); src = kmalloc(KASAN_GRANULE_SIZE, GFP_KERNEL | __GFP_ZERO); strscpy(src, "f0cacc1a0000000", KASAN_GRANULE_SIZE); + OPTIMIZER_HIDE_VAR(src); /* * Make sure that strscpy() does not trigger KASAN if it overreads into diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 620abd95e680..84265983f239 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -470,6 +470,7 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) { unsigned long flags; struct kmemleak_object *object; + bool warn = false; /* try the slab allocator first */ if (object_cache) { @@ -488,8 +489,10 @@ static struct kmemleak_object *mem_pool_alloc(gfp_t gfp) else if (mem_pool_free_count) object = &mem_pool[--mem_pool_free_count]; else - pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); + warn = true; raw_spin_unlock_irqrestore(&kmemleak_lock, flags); + if (warn) + pr_warn_once("Memory pool empty, consider increasing CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE\n"); return object; } diff --git a/mm/mempool.c b/mm/mempool.c index 204a216b6418..1c38e873e546 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -136,7 +136,7 @@ static void kasan_unpoison_element(mempool_t *pool, void *element) static __always_inline void add_element(mempool_t *pool, void *element) { - BUG_ON(pool->curr_nr >= pool->min_nr); + BUG_ON(pool->min_nr != 0 && pool->curr_nr >= pool->min_nr); poison_element(pool, element); if (kasan_poison_element(pool, element)) pool->elements[pool->curr_nr++] = element; @@ -202,16 +202,20 @@ int mempool_init_node(mempool_t *pool, int min_nr, mempool_alloc_t *alloc_fn, pool->alloc = alloc_fn; pool->free = free_fn; init_waitqueue_head(&pool->wait); - - pool->elements = kmalloc_array_node(min_nr, sizeof(void *), + /* + * max() used here to ensure storage for at least 1 element to support + * zero minimum pool + */ + pool->elements = kmalloc_array_node(max(1, min_nr), sizeof(void *), gfp_mask, node_id); if (!pool->elements) return -ENOMEM; /* - * First pre-allocate the guaranteed number of buffers. + * First pre-allocate the guaranteed number of buffers, + * also pre-allocate 1 element for zero minimum pool. */ - while (pool->curr_nr < pool->min_nr) { + while (pool->curr_nr < max(1, pool->min_nr)) { void *element; element = pool->alloc(gfp_mask, pool->pool_data); @@ -555,20 +559,12 @@ void mempool_free(void *element, mempool_t *pool) * wake-up path of previous test. This explicit check ensures the * allocation of element when both min_nr and curr_nr are 0, and * any active waiters are properly awakened. - * - * Inline the same logic as previous test, add_element() cannot be - * directly used here since it has BUG_ON to deny if min_nr equals - * curr_nr, so here picked rest of add_element() to use without - * BUG_ON check. */ if (unlikely(pool->min_nr == 0 && READ_ONCE(pool->curr_nr) == 0)) { spin_lock_irqsave(&pool->lock, flags); if (likely(pool->curr_nr == 0)) { - /* Inline the logic of add_element() */ - poison_element(pool, element); - if (kasan_poison_element(pool, element)) - pool->elements[pool->curr_nr++] = element; + add_element(pool, element); spin_unlock_irqrestore(&pool->lock, flags); if (wq_has_sleeper(&pool->wait)) wake_up(&pool->wait); diff --git a/mm/shmem.c b/mm/shmem.c index 2b41460c316e..e2c76a30802b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -5970,7 +5970,6 @@ int shmem_zero_setup(struct vm_area_struct *vma) * shmem_read_folio_gfp - read into page cache, using specified page allocation flags. * @mapping: the folio's address_space * @index: the folio index - * @end: end of a read if allocating a new folio * @gfp: the page allocator flags to use if allocating * * This behaves as a tmpfs "read_cache_page_gfp(mapping, index, gfp)", @@ -5983,15 +5982,15 @@ int shmem_zero_setup(struct vm_area_struct *vma) * with the mapping_gfp_mask(), to avoid OOMing the machine unnecessarily. */ struct folio *shmem_read_folio_gfp(struct address_space *mapping, - pgoff_t index, loff_t end, gfp_t gfp) + pgoff_t index, gfp_t gfp) { #ifdef CONFIG_SHMEM struct inode *inode = mapping->host; struct folio *folio; int error; - error = shmem_get_folio_gfp(inode, index, end, &folio, SGP_CACHE, - gfp, NULL, NULL); + error = shmem_get_folio_gfp(inode, index, i_size_read(inode), + &folio, SGP_CACHE, gfp, NULL, NULL); if (error) return ERR_PTR(error); @@ -6009,7 +6008,7 @@ EXPORT_SYMBOL_GPL(shmem_read_folio_gfp); struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, pgoff_t index, gfp_t gfp) { - struct folio *folio = shmem_read_folio_gfp(mapping, index, 0, gfp); + struct folio *folio = shmem_read_folio_gfp(mapping, index, gfp); struct page *page; if (IS_ERR(folio)) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index cbed91b09640..5431c9dd7fd7 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1453,10 +1453,15 @@ out: folio_unlock(src_folio); folio_put(src_folio); } - if (dst_pte) - pte_unmap(dst_pte); + /* + * Unmap in reverse order (LIFO) to maintain proper kmap_local + * index ordering when CONFIG_HIGHPTE is enabled. We mapped dst_pte + * first, then src_pte, so we must unmap src_pte first, then dst_pte. + */ if (src_pte) pte_unmap(src_pte); + if (dst_pte) + pte_unmap(dst_pte); mmu_notifier_invalidate_range_end(&range); if (si) put_swap_device(si); diff --git a/net/core/filter.c b/net/core/filter.c index c09a85c17496..da391e2b0788 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9458,6 +9458,9 @@ static bool flow_dissector_is_valid_access(int off, int size, if (off < 0 || off >= sizeof(struct __sk_buff)) return false; + if (off % size != 0) + return false; + if (type == BPF_WRITE) return false; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 10a1d182fd84..84e7f8a2f50f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -425,15 +425,20 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb) int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) { - struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev; + struct net_device *dev, *indev = skb->dev; + int ret_val; + rcu_read_lock(); + dev = skb_dst_dev_rcu(skb); skb->dev = dev; skb->protocol = htons(ETH_P_IP); - return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, - net, sk, skb, indev, dev, - ip_finish_output, - !(IPCB(skb)->flags & IPSKB_REROUTED)); + ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, + net, sk, skb, indev, dev, + ip_finish_output, + !(IPCB(skb)->flags & IPSKB_REROUTED)); + rcu_read_unlock(); + return ret_val; } EXPORT_SYMBOL(ip_output); diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 9822163428b0..fce91183797a 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -148,7 +148,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, ops = rcu_dereference(inet6_offloads[proto]); if (likely(ops && ops->callbacks.gso_segment)) { - skb_reset_transport_header(skb); + if (!skb_reset_transport_header_careful(skb)) + goto out; + segs = ops->callbacks.gso_segment(skb, features); if (!segs) skb->network_header = skb_mac_header(skb) + nhoff - skb->head; diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c index 3e4fb9ddcd36..46e667a50d98 100644 --- a/net/netfilter/nf_bpf_link.c +++ b/net/netfilter/nf_bpf_link.c @@ -296,6 +296,9 @@ static bool nf_is_valid_access(int off, int size, enum bpf_access_type type, if (off < 0 || off >= sizeof(struct bpf_nf_ctx)) return false; + if (off % size != 0) + return false; + if (type == BPF_WRITE) return false; diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index e759e43ad27e..39b735386996 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -43,6 +43,11 @@ static struct static_key_false taprio_have_working_mqprio; #define TAPRIO_SUPPORTED_FLAGS \ (TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST | TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD) #define TAPRIO_FLAGS_INVALID U32_MAX +/* Minimum value for picos_per_byte to ensure non-zero duration + * for minimum-sized Ethernet frames (ETH_ZLEN = 60). + * 60 * 17 > PSEC_PER_NSEC (1000) + */ +#define TAPRIO_PICOS_PER_BYTE_MIN 17 struct sched_entry { /* Durations between this GCL entry and the GCL entry where the @@ -1284,7 +1289,8 @@ static void taprio_start_sched(struct Qdisc *sch, } static void taprio_set_picos_per_byte(struct net_device *dev, - struct taprio_sched *q) + struct taprio_sched *q, + struct netlink_ext_ack *extack) { struct ethtool_link_ksettings ecmd; int speed = SPEED_10; @@ -1300,6 +1306,15 @@ static void taprio_set_picos_per_byte(struct net_device *dev, skip: picos_per_byte = (USEC_PER_SEC * 8) / speed; + if (picos_per_byte < TAPRIO_PICOS_PER_BYTE_MIN) { + if (!extack) + pr_warn("Link speed %d is too high. Schedule may be inaccurate.\n", + speed); + NL_SET_ERR_MSG_FMT_MOD(extack, + "Link speed %d is too high. Schedule may be inaccurate.", + speed); + picos_per_byte = TAPRIO_PICOS_PER_BYTE_MIN; + } atomic64_set(&q->picos_per_byte, picos_per_byte); netdev_dbg(dev, "taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n", @@ -1324,7 +1339,7 @@ static int taprio_dev_notifier(struct notifier_block *nb, unsigned long event, if (dev != qdisc_dev(q->root)) continue; - taprio_set_picos_per_byte(dev, q); + taprio_set_picos_per_byte(dev, q, NULL); stab = rtnl_dereference(q->root->stab); @@ -1844,7 +1859,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt, q->flags = taprio_flags; /* Needed for length_to_duration() during netlink attribute parsing */ - taprio_set_picos_per_byte(dev, q); + taprio_set_picos_per_byte(dev, q, extack); err = taprio_parse_mqprio_opt(dev, mqprio, extack, q->flags); if (err < 0) diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index e0573009598a..7cf7fe95e41d 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -36,9 +36,9 @@ #include "poll.c" #include "property.c" #include "rbtree.c" -#include "regulator.c" #include "rcu.c" #include "refcount.c" +#include "regulator.c" #include "security.c" #include "signal.c" #include "slab.c" diff --git a/rust/kernel/device_id.rs b/rust/kernel/device_id.rs index 70d57814ff79..62c42da12e9d 100644 --- a/rust/kernel/device_id.rs +++ b/rust/kernel/device_id.rs @@ -195,10 +195,10 @@ macro_rules! module_device_table { ($table_type: literal, $module_table_name:ident, $table_name:ident) => { #[rustfmt::skip] #[export_name = - concat!("__mod_device_table__", $table_type, - "__", module_path!(), - "_", line!(), - "_", stringify!($table_name)) + concat!("__mod_device_table__", line!(), + "__kmod_", module_path!(), + "__", $table_type, + "__", stringify!($table_name)) ] static $module_table_name: [::core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] = unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) }; diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index fdab5aa90215..dbbe3bf0cf23 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -53,11 +53,6 @@ endif # vmlinux.unstripped # --------------------------------------------------------------------------- -ifdef CONFIG_MODULES -targets += .vmlinux.export.o -vmlinux.unstripped: .vmlinux.export.o -endif - ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX vmlinux.unstripped: arch/$(SRCARCH)/tools/vmlinux.arch.o @@ -72,8 +67,8 @@ cmd_link_vmlinux = \ $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -targets += vmlinux.unstripped -vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE +targets += vmlinux.unstripped .vmlinux.export.o +vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE +$(call if_changed_dep,link_vmlinux) ifdef CONFIG_DEBUG_INFO_BTF vmlinux.unstripped: $(RESOLVE_BTFIDS) @@ -89,8 +84,11 @@ endif remove-section-y := .modinfo remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' +remove-symbols := -w --strip-symbol='__mod_device_table__*' + quiet_cmd_strip_relocs = OBJCOPY $@ - cmd_strip_relocs = $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) $< $@ + cmd_strip_relocs = $(OBJCOPY) $(addprefix --remove-section=,$(remove-section-y)) \ + $(remove-symbols) $< $@ targets += vmlinux vmlinux: vmlinux.unstripped FORCE diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 51367c2bfc21..433849ff7529 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -73,10 +73,7 @@ vmlinux_link() objs="${objs} .builtin-dtbs.o" fi - if is_enabled CONFIG_MODULES; then - objs="${objs} .vmlinux.export.o" - fi - + objs="${objs} .vmlinux.export.o" objs="${objs} init/version-timestamp.o" if [ "${SRCARCH}" = "um" ]; then diff --git a/scripts/mksysmap b/scripts/mksysmap index a607a0059d11..c4531eacde20 100755 --- a/scripts/mksysmap +++ b/scripts/mksysmap @@ -59,6 +59,9 @@ # EXPORT_SYMBOL (namespace) / __kstrtabns_/d +# MODULE_DEVICE_TABLE (symbol name) +/ __mod_device_table__/d + # --------------------------------------------------------------------------- # Ignored suffixes # (do not forget '$' after each pattern) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 00586119a25b..7da9735e7ab3 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1476,8 +1476,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, { void *symval; char *zeros = NULL; - const char *type, *name; - size_t typelen; + const char *type, *name, *modname; + size_t typelen, modnamelen; static const char *prefix = "__mod_device_table__"; /* We're looking for a section relative symbol */ @@ -1488,10 +1488,20 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) return; - /* All our symbols are of form __mod_device_table__<type>__<name>. */ + /* All our symbols are of form __mod_device_table__kmod_<modname>__<type>__<name>. */ if (!strstarts(symname, prefix)) return; - type = symname + strlen(prefix); + + modname = strstr(symname, "__kmod_"); + if (!modname) + return; + modname += strlen("__kmod_"); + + type = strstr(modname, "__"); + if (!type) + return; + modnamelen = type - modname; + type += strlen("__"); name = strstr(type, "__"); if (!name) @@ -1517,5 +1527,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, } } + if (mod->is_vmlinux) { + struct module_alias *alias; + + /* + * If this is vmlinux, record the name of the builtin module. + * Traverse the linked list in the reverse order, and set the + * builtin_modname unless it has already been set in the + * previous call. + */ + list_for_each_entry_reverse(alias, &mod->aliases, node) { + if (alias->builtin_modname) + break; + alias->builtin_modname = xstrndup(modname, modnamelen); + } + } + free(zeros); } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5ca7c268294e..47c8aa2a6939 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -2067,11 +2067,26 @@ static void write_if_changed(struct buffer *b, const char *fname) static void write_vmlinux_export_c_file(struct module *mod) { struct buffer buf = { }; + struct module_alias *alias, *next; buf_printf(&buf, "#include <linux/export-internal.h>\n"); add_exported_symbols(&buf, mod); + + buf_printf(&buf, + "#include <linux/module.h>\n" + "#undef __MODULE_INFO_PREFIX\n" + "#define __MODULE_INFO_PREFIX\n"); + + list_for_each_entry_safe(alias, next, &mod->aliases, node) { + buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n", + alias->builtin_modname, alias->str); + list_del(&alias->node); + free(alias->builtin_modname); + free(alias); + } + write_if_changed(&buf, ".vmlinux.export.c"); free(buf.p); } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9133e4c3803f..2aecb8f25c87 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -99,10 +99,12 @@ buf_write(struct buffer *buf, const char *s, int len); * struct module_alias - auto-generated MODULE_ALIAS() * * @node: linked to module::aliases + * @modname: name of the builtin module (only for vmlinux) * @str: a string for MODULE_ALIAS() */ struct module_alias { struct list_head node; + char *builtin_modname; char str[]; }; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 261a9d3a0afe..50d5345ff5cb 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -243,6 +243,9 @@ static void free_ruleset(struct aa_ruleset *rules) { int i; + if (!rules) + return; + aa_put_pdb(rules->file); aa_put_pdb(rules->policy); aa_free_cap_rules(&rules->caps); @@ -335,7 +338,6 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy, profile = kzalloc(struct_size(profile, label.rules, 1), gfp); if (!profile) return NULL; - profile->n_rules = 1; if (!aa_policy_init(&profile->base, NULL, hname, gfp)) goto fail; @@ -346,6 +348,7 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy, profile->label.rules[0] = aa_alloc_ruleset(gfp); if (!profile->label.rules[0]) goto fail; + profile->n_rules = 1; /* update being set needed by fs interface */ if (!proxy) { diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 2554b42eeb0f..e27a36e4e92a 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -7110,6 +7110,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1854, 0x0440, "LG CQ6", ALC256_FIXUP_HEADPHONE_AMP_VOL), SND_PCI_QUIRK(0x1854, 0x0441, "LG CQ6 AIO", ALC256_FIXUP_HEADPHONE_AMP_VOL), SND_PCI_QUIRK(0x1854, 0x0488, "LG gram 16 (16Z90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), + SND_PCI_QUIRK(0x1854, 0x0489, "LG gram 16 (16Z90R-A)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x1854, 0x048a, "LG gram 17 (17ZD90R)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index b24ee38fad72..bff92505e408 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1336,11 +1336,10 @@ static void retire_capture_urb(struct snd_usb_substream *subs, for (i = 0; i < urb->number_of_packets; i++) { cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset + subs->pkt_offset_adj; - if (urb->iso_frame_desc[i].status && printk_ratelimit()) { - dev_dbg(&subs->dev->dev, "frame %d active: %d\n", - i, urb->iso_frame_desc[i].status); - // continue; - } + if (urb->iso_frame_desc[i].status) + dev_dbg_ratelimited(&subs->dev->dev, + "frame %d active: %d\n", i, + urb->iso_frame_desc[i].status); bytes = urb->iso_frame_desc[i].actual_length; if (subs->stream_offset_adj > 0) { unsigned int adj = min(subs->stream_offset_adj, bytes); diff --git a/tools/accounting/getdelays.c b/tools/accounting/getdelays.c index 3feac0482fe9..21cb3c3d1331 100644 --- a/tools/accounting/getdelays.c +++ b/tools/accounting/getdelays.c @@ -194,75 +194,108 @@ static int get_family_id(int sd) #define average_ms(t, c) (t / 1000000ULL / (c ? c : 1)) #define delay_ms(t) (t / 1000000ULL) +/* + * Version compatibility note: + * Field availability depends on taskstats version (t->version), + * corresponding to TASKSTATS_VERSION in kernel headers + * see include/uapi/linux/taskstats.h + * + * Version feature mapping: + * version >= 11 - supports COMPACT statistics + * version >= 13 - supports WPCOPY statistics + * version >= 14 - supports IRQ statistics + * version >= 16 - supports *_max and *_min delay statistics + * + * Always verify version before accessing version-dependent fields + * to maintain backward compatibility. + */ +#define PRINT_CPU_DELAY(version, t) \ + do { \ + if (version >= 16) { \ + printf("%-10s%15s%15s%15s%15s%15s%15s%15s\n", \ + "CPU", "count", "real total", "virtual total", \ + "delay total", "delay average", "delay max", "delay min"); \ + printf(" %15llu%15llu%15llu%15llu%15.3fms%13.6fms%13.6fms\n", \ + (unsigned long long)(t)->cpu_count, \ + (unsigned long long)(t)->cpu_run_real_total, \ + (unsigned long long)(t)->cpu_run_virtual_total, \ + (unsigned long long)(t)->cpu_delay_total, \ + average_ms((double)(t)->cpu_delay_total, (t)->cpu_count), \ + delay_ms((double)(t)->cpu_delay_max), \ + delay_ms((double)(t)->cpu_delay_min)); \ + } else { \ + printf("%-10s%15s%15s%15s%15s%15s\n", \ + "CPU", "count", "real total", "virtual total", \ + "delay total", "delay average"); \ + printf(" %15llu%15llu%15llu%15llu%15.3fms\n", \ + (unsigned long long)(t)->cpu_count, \ + (unsigned long long)(t)->cpu_run_real_total, \ + (unsigned long long)(t)->cpu_run_virtual_total, \ + (unsigned long long)(t)->cpu_delay_total, \ + average_ms((double)(t)->cpu_delay_total, (t)->cpu_count)); \ + } \ + } while (0) +#define PRINT_FILED_DELAY(name, version, t, count, total, max, min) \ + do { \ + if (version >= 16) { \ + printf("%-10s%15s%15s%15s%15s%15s\n", \ + name, "count", "delay total", "delay average", \ + "delay max", "delay min"); \ + printf(" %15llu%15llu%15.3fms%13.6fms%13.6fms\n", \ + (unsigned long long)(t)->count, \ + (unsigned long long)(t)->total, \ + average_ms((double)(t)->total, (t)->count), \ + delay_ms((double)(t)->max), \ + delay_ms((double)(t)->min)); \ + } else { \ + printf("%-10s%15s%15s%15s\n", \ + name, "count", "delay total", "delay average"); \ + printf(" %15llu%15llu%15.3fms\n", \ + (unsigned long long)(t)->count, \ + (unsigned long long)(t)->total, \ + average_ms((double)(t)->total, (t)->count)); \ + } \ + } while (0) + static void print_delayacct(struct taskstats *t) { - printf("\n\nCPU %15s%15s%15s%15s%15s%15s%15s\n" - " %15llu%15llu%15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "IO %15s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "SWAP %15s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "RECLAIM %12s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "THRASHING%12s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "COMPACT %12s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "WPCOPY %12s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n" - "IRQ %15s%15s%15s%15s%15s\n" - " %15llu%15llu%15.3fms%13.6fms%13.6fms\n", - "count", "real total", "virtual total", - "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->cpu_count, - (unsigned long long)t->cpu_run_real_total, - (unsigned long long)t->cpu_run_virtual_total, - (unsigned long long)t->cpu_delay_total, - average_ms((double)t->cpu_delay_total, t->cpu_count), - delay_ms((double)t->cpu_delay_max), - delay_ms((double)t->cpu_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->blkio_count, - (unsigned long long)t->blkio_delay_total, - average_ms((double)t->blkio_delay_total, t->blkio_count), - delay_ms((double)t->blkio_delay_max), - delay_ms((double)t->blkio_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->swapin_count, - (unsigned long long)t->swapin_delay_total, - average_ms((double)t->swapin_delay_total, t->swapin_count), - delay_ms((double)t->swapin_delay_max), - delay_ms((double)t->swapin_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->freepages_count, - (unsigned long long)t->freepages_delay_total, - average_ms((double)t->freepages_delay_total, t->freepages_count), - delay_ms((double)t->freepages_delay_max), - delay_ms((double)t->freepages_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->thrashing_count, - (unsigned long long)t->thrashing_delay_total, - average_ms((double)t->thrashing_delay_total, t->thrashing_count), - delay_ms((double)t->thrashing_delay_max), - delay_ms((double)t->thrashing_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->compact_count, - (unsigned long long)t->compact_delay_total, - average_ms((double)t->compact_delay_total, t->compact_count), - delay_ms((double)t->compact_delay_max), - delay_ms((double)t->compact_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->wpcopy_count, - (unsigned long long)t->wpcopy_delay_total, - average_ms((double)t->wpcopy_delay_total, t->wpcopy_count), - delay_ms((double)t->wpcopy_delay_max), - delay_ms((double)t->wpcopy_delay_min), - "count", "delay total", "delay average", "delay max", "delay min", - (unsigned long long)t->irq_count, - (unsigned long long)t->irq_delay_total, - average_ms((double)t->irq_delay_total, t->irq_count), - delay_ms((double)t->irq_delay_max), - delay_ms((double)t->irq_delay_min)); + printf("\n\n"); + + PRINT_CPU_DELAY(t->version, t); + + PRINT_FILED_DELAY("IO", t->version, t, + blkio_count, blkio_delay_total, + blkio_delay_max, blkio_delay_min); + + PRINT_FILED_DELAY("SWAP", t->version, t, + swapin_count, swapin_delay_total, + swapin_delay_max, swapin_delay_min); + + PRINT_FILED_DELAY("RECLAIM", t->version, t, + freepages_count, freepages_delay_total, + freepages_delay_max, freepages_delay_min); + + PRINT_FILED_DELAY("THRASHING", t->version, t, + thrashing_count, thrashing_delay_total, + thrashing_delay_max, thrashing_delay_min); + + if (t->version >= 11) { + PRINT_FILED_DELAY("COMPACT", t->version, t, + compact_count, compact_delay_total, + compact_delay_max, compact_delay_min); + } + + if (t->version >= 13) { + PRINT_FILED_DELAY("WPCOPY", t->version, t, + wpcopy_count, wpcopy_delay_total, + wpcopy_delay_max, wpcopy_delay_min); + } + + if (t->version >= 14) { + PRINT_FILED_DELAY("IRQ", t->version, t, + irq_count, irq_delay_total, + irq_delay_max, irq_delay_min); + } } static void task_context_switch_counts(struct taskstats *t) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e2b295fe4d2f..a7018a3b0437 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -872,7 +872,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine, char *allocated_name = NULL; int ret = 0; - if (!dso__has_build_id(dso)) + if (!dso__has_build_id(dso) || !dso__hit(dso)) return 0; if (dso__is_kcore(dso)) { diff --git a/tools/testing/selftests/bpf/progs/verifier_ctx.c b/tools/testing/selftests/bpf/progs/verifier_ctx.c index 0450840c92d9..424463094760 100644 --- a/tools/testing/selftests/bpf/progs/verifier_ctx.c +++ b/tools/testing/selftests/bpf/progs/verifier_ctx.c @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 /* Converted from tools/testing/selftests/bpf/verifier/ctx.c */ -#include <linux/bpf.h> +#include "vmlinux.h" #include <bpf/bpf_helpers.h> #include "bpf_misc.h" +#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) + SEC("tc") __description("context stores via BPF_ATOMIC") __failure __msg("BPF_ATOMIC stores into R1 ctx is not allowed") @@ -243,4 +245,23 @@ narrow_load("sockops", bpf_sock_ops, skb_data); narrow_load("sockops", bpf_sock_ops, skb_data_end); narrow_load("sockops", bpf_sock_ops, skb_hwtstamp); +#define unaligned_access(type, ctx, field) \ + SEC(type) \ + __description("unaligned access on field " #field " of " #ctx) \ + __failure __msg("invalid bpf_context access") \ + __naked void unaligned_ctx_access_##ctx##field(void) \ + { \ + asm volatile (" \ + r1 = *(u%[size] *)(r1 + %[off]); \ + r0 = 0; \ + exit;" \ + : \ + : __imm_const(size, sizeof_field(struct ctx, field) * 8), \ + __imm_const(off, offsetof(struct ctx, field) + 1) \ + : __clobber_all); \ + } + +unaligned_access("flow_dissector", __sk_buff, data); +unaligned_access("netfilter", bpf_nf_ctx, skb); + char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/mm/uffd-stress.c b/tools/testing/selftests/mm/uffd-stress.c index 40af7f67c407..c0f64df5085c 100644 --- a/tools/testing/selftests/mm/uffd-stress.c +++ b/tools/testing/selftests/mm/uffd-stress.c @@ -51,7 +51,7 @@ static char *zeropage; pthread_attr_t attr; #define swap(a, b) \ - do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) + do { __auto_type __tmp = (a); (a) = (b); (b) = __tmp; } while (0) const char *examples = "# Run anonymous memory test on 100MiB region with 99999 bounces:\n" diff --git a/tools/testing/selftests/net/test_neigh.sh b/tools/testing/selftests/net/test_neigh.sh index 388056472b5b..7c594bf6ead0 100755 --- a/tools/testing/selftests/net/test_neigh.sh +++ b/tools/testing/selftests/net/test_neigh.sh @@ -289,11 +289,11 @@ extern_valid_common() orig_base_reachable=$(ip -j ntable show name "$tbl_name" | jq '.[] | select(has("thresh1")) | .["base_reachable"]') run_cmd "ip ntable change name $tbl_name thresh1 10 base_reachable 10000" orig_gc_stale=$(ip -n "$ns1" -j ntable show name "$tbl_name" dev veth0 | jq '.[]["gc_stale"]') - run_cmd "ip -n $ns1 ntable change name $tbl_name dev veth0 gc_stale 5000" - # Wait orig_base_reachable/2 for the new interval to take effect. - run_cmd "sleep $(((orig_base_reachable / 1000) / 2 + 2))" + run_cmd "ip -n $ns1 ntable change name $tbl_name dev veth0 gc_stale 1000" run_cmd "ip -n $ns1 neigh add $ip_addr lladdr $mac nud stale dev veth0 extern_valid" run_cmd "ip -n $ns1 neigh add ${subnet}3 lladdr $mac nud stale dev veth0" + # Wait orig_base_reachable/2 for the new interval to take effect. + run_cmd "sleep $(((orig_base_reachable / 1000) / 2 + 2))" for i in {1..20}; do run_cmd "ip -n $ns1 neigh add ${subnet}$((i + 4)) nud none dev veth0" done diff --git a/tools/testing/selftests/net/vlan_hw_filter.sh b/tools/testing/selftests/net/vlan_hw_filter.sh index 0fb56baf28e4..e195d5cab6f7 100755 --- a/tools/testing/selftests/net/vlan_hw_filter.sh +++ b/tools/testing/selftests/net/vlan_hw_filter.sh @@ -55,10 +55,10 @@ test_vlan0_del_crash_01() { ip netns exec ${NETNS} ip link add bond0 type bond mode 0 ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off - ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link set dev bond0 up ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on - ip netns exec ${NETNS} ifconfig bond0 down - ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link set dev bond0 down + ip netns exec ${NETNS} ip link set dev bond0 up ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" cleanup } @@ -68,11 +68,11 @@ test_vlan0_del_crash_02() { setup ip netns exec ${NETNS} ip link add bond0 type bond mode 0 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off - ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link set dev bond0 up ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q - ip netns exec ${NETNS} ifconfig bond0 down - ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link set dev bond0 down + ip netns exec ${NETNS} ip link set dev bond0 up ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" cleanup } @@ -84,9 +84,9 @@ test_vlan0_del_crash_03() { ip netns exec ${NETNS} ip link add bond0 type bond mode 0 ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off - ip netns exec ${NETNS} ifconfig bond0 up + ip netns exec ${NETNS} ip link set dev bond0 up ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on - ip netns exec ${NETNS} ifconfig bond0 down + ip netns exec ${NETNS} ip link set dev bond0 down ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" cleanup } |