Bring in the shared branch with the kbuild tree to enable '-fms-extensions' for 6.19. Further namespace cleanup work requires this extension.
Unified · Split
| @@ -27,6 +27,7 @@ Alan Cox <alan@lxorguk.ukuu.org.uk> · 26 unmodified lines | |||
| 27 | Alan Cox <root@hraefn.swansea.linux.org.uk> | 27 | Alan Cox <root@hraefn.swansea.linux.org.uk> |
| 28 | Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com> | 28 | Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com> |
| 29 | Aleksey Gorelov <aleksey_gorelov@phoenix.com> | 29 | Aleksey Gorelov <aleksey_gorelov@phoenix.com> |
| 30 | Alex Williamson <alex@shazbot.org> <alex.williamson@redhat.com> | ||
| 30 | Alexander Lobakin <alobakin@pm.me> <alobakin@dlink.ru> | 31 | Alexander Lobakin <alobakin@pm.me> <alobakin@dlink.ru> |
| 31 | Alexander Lobakin <alobakin@pm.me> <alobakin@marvell.com> | 32 | Alexander Lobakin <alobakin@pm.me> <alobakin@marvell.com> |
| 32 | Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru> | 33 | Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru> |
| @@ -142,7 +142,9 @@ allOf: · 141 unmodified lines | |||
| 142 | required: | 142 | required: |
| 143 | - orientation-switch | 143 | - orientation-switch |
| 144 | then: | 144 | then: |
| 145 | $ref: /schemas/usb/usb-switch.yaml# | 145 | allOf: |
| 146 | - $ref: /schemas/usb/usb-switch.yaml# | ||
| 147 | - $ref: /schemas/usb/usb-switch-ports.yaml# | ||
| 146 | 148 | ||
| 147 | unevaluatedProperties: false | 149 | unevaluatedProperties: false |
| 148 | 150 | ||
| @@ -24,6 +24,10 @@ properties: · 23 unmodified lines | |||
| 24 | - enum: | 24 | - enum: |
| 25 | - qcom,qcs8300-qmp-ufs-phy | 25 | - qcom,qcs8300-qmp-ufs-phy |
| 26 | - const: qcom,sa8775p-qmp-ufs-phy | 26 | - const: qcom,sa8775p-qmp-ufs-phy |
| 27 | - items: | ||
| 28 | - enum: | ||
| 29 | - qcom,kaanapali-qmp-ufs-phy | ||
| 30 | - const: qcom,sm8750-qmp-ufs-phy | ||
| 27 | - enum: | 31 | - enum: |
| 28 | - qcom,msm8996-qmp-ufs-phy | 32 | - qcom,msm8996-qmp-ufs-phy |
| 29 | - qcom,msm8998-qmp-ufs-phy | 33 | - qcom,msm8998-qmp-ufs-phy |
| @@ -125,7 +125,9 @@ allOf: · 124 unmodified lines | |||
| 125 | contains: | 125 | contains: |
| 126 | const: google,gs101-usb31drd-phy | 126 | const: google,gs101-usb31drd-phy |
| 127 | then: | 127 | then: |
| 128 | $ref: /schemas/usb/usb-switch.yaml# | 128 | allOf: |
| 129 | - $ref: /schemas/usb/usb-switch.yaml# | ||
| 130 | - $ref: /schemas/usb/usb-switch-ports.yaml# | ||
| 129 | 131 | ||
| 130 | properties: | 132 | properties: |
| 131 | clocks: | 133 | clocks: |
| @@ -197,6 +197,7 @@ allOf: · 196 unmodified lines | |||
| 197 | - renesas,rcar-gen2-scif | 197 | - renesas,rcar-gen2-scif |
| 198 | - renesas,rcar-gen3-scif | 198 | - renesas,rcar-gen3-scif |
| 199 | - renesas,rcar-gen4-scif | 199 | - renesas,rcar-gen4-scif |
| 200 | - renesas,rcar-gen5-scif | ||
| 200 | then: | 201 | then: |
| 201 | properties: | 202 | properties: |
| 202 | interrupts: | 203 | interrupts: |
| @@ -14,9 +14,14 @@ allOf: · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | properties: | 15 | properties: |
| 16 | compatible: | 16 | compatible: |
| 17 | enum: | 17 | oneOf: |
| 18 | - cdns,spi-r1p6 | 18 | - enum: |
| 19 | - xlnx,zynq-spi-r1p6 | 19 | - xlnx,zynq-spi-r1p6 |
| 20 | - items: | ||
| 21 | - enum: | ||
| 22 | - xlnx,zynqmp-spi-r1p6 | ||
| 23 | - xlnx,versal-net-spi-r1p6 | ||
| 24 | - const: cdns,spi-r1p6 | ||
| 20 | 25 | ||
| 21 | reg: | 26 | reg: |
| 22 | maxItems: 1 | 27 | maxItems: 1 |
| @@ -34,6 +34,7 @@ properties: · 33 unmodified lines | |||
| 34 | - rockchip,rk3328-spi | 34 | - rockchip,rk3328-spi |
| 35 | - rockchip,rk3368-spi | 35 | - rockchip,rk3368-spi |
| 36 | - rockchip,rk3399-spi | 36 | - rockchip,rk3399-spi |
| 37 | - rockchip,rk3506-spi | ||
| 37 | - rockchip,rk3528-spi | 38 | - rockchip,rk3528-spi |
| 38 | - rockchip,rk3562-spi | 39 | - rockchip,rk3562-spi |
| 39 | - rockchip,rk3568-spi | 40 | - rockchip,rk3568-spi |
| @@ -15,6 +15,7 @@ select: · 14 unmodified lines | |||
| 15 | compatible: | 15 | compatible: |
| 16 | contains: | 16 | contains: |
| 17 | enum: | 17 | enum: |
| 18 | - qcom,kaanapali-ufshc | ||
| 18 | - qcom,sm8650-ufshc | 19 | - qcom,sm8650-ufshc |
| 19 | - qcom,sm8750-ufshc | 20 | - qcom,sm8750-ufshc |
| 20 | required: | 21 | required: |
| @@ -24,6 +25,7 @@ properties: · 3 unmodified lines | |||
| 24 | compatible: | 25 | compatible: |
| 25 | items: | 26 | items: |
| 26 | - enum: | 27 | - enum: |
| 28 | - qcom,kaanapali-ufshc | ||
| 27 | - qcom,sm8650-ufshc | 29 | - qcom,sm8650-ufshc |
| 28 | - qcom,sm8750-ufshc | 30 | - qcom,sm8750-ufshc |
| 29 | - const: qcom,ufshc | 31 | - const: qcom,ufshc |
| @@ -76,6 +76,7 @@ required: · 75 unmodified lines | |||
| 76 | 76 | ||
| 77 | allOf: | 77 | allOf: |
| 78 | - $ref: usb-switch.yaml# | 78 | - $ref: usb-switch.yaml# |
| 79 | - $ref: usb-switch-ports.yaml# | ||
| 79 | 80 | ||
| 80 | additionalProperties: false | 81 | additionalProperties: false |
| 81 | 82 | ||
| @@ -89,13 +89,21 @@ required: · 88 unmodified lines | |||
| 89 | - reg | 89 | - reg |
| 90 | - "#address-cells" | 90 | - "#address-cells" |
| 91 | - "#size-cells" | 91 | - "#size-cells" |
| 92 | - dma-ranges | ||
| 93 | - ranges | 92 | - ranges |
| 94 | - clocks | 93 | - clocks |
| 95 | - clock-names | 94 | - clock-names |
| 96 | - interrupts | 95 | - interrupts |
| 97 | - power-domains | 96 | - power-domains |
| 98 | 97 | ||
| 98 | allOf: | ||
| 99 | - if: | ||
| 100 | properties: | ||
| 101 | compatible: | ||
| 102 | const: fsl,imx8mp-dwc3 | ||
| 103 | then: | ||
| 104 | required: | ||
| 105 | - dma-ranges | ||
| 106 | |||
| 99 | additionalProperties: false | 107 | additionalProperties: false |
| 100 | 108 | ||
| 101 | examples: | 109 | examples: |
| @@ -52,6 +52,7 @@ required: · 51 unmodified lines | |||
| 52 | 52 | ||
| 53 | allOf: | 53 | allOf: |
| 54 | - $ref: usb-switch.yaml# | 54 | - $ref: usb-switch.yaml# |
| 55 | - $ref: usb-switch-ports.yaml# | ||
| 55 | - if: | 56 | - if: |
| 56 | required: | 57 | required: |
| 57 | - mode-switch | 58 | - mode-switch |
| @@ -46,6 +46,7 @@ required: · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | allOf: | 47 | allOf: |
| 48 | - $ref: usb-switch.yaml# | 48 | - $ref: usb-switch.yaml# |
| 49 | - $ref: usb-switch-ports.yaml# | ||
| 49 | 50 | ||
| 50 | additionalProperties: false | 51 | additionalProperties: false |
| 51 | 52 | ||
| @@ -91,6 +91,7 @@ required: · 90 unmodified lines | |||
| 91 | 91 | ||
| 92 | allOf: | 92 | allOf: |
| 93 | - $ref: usb-switch.yaml# | 93 | - $ref: usb-switch.yaml# |
| 94 | - $ref: usb-switch-ports.yaml# | ||
| 94 | 95 | ||
| 95 | additionalProperties: false | 96 | additionalProperties: false |
| 96 | 97 | ||
| @@ -81,6 +81,7 @@ required: · 80 unmodified lines | |||
| 81 | 81 | ||
| 82 | allOf: | 82 | allOf: |
| 83 | - $ref: usb-switch.yaml# | 83 | - $ref: usb-switch.yaml# |
| 84 | - $ref: usb-switch-ports.yaml# | ||
| 84 | 85 | ||
| 85 | additionalProperties: false | 86 | additionalProperties: false |
| 86 | 87 | ||
| @@ -68,6 +68,7 @@ properties: · 67 unmodified lines | |||
| 68 | - qcom,sm8550-dwc3 | 68 | - qcom,sm8550-dwc3 |
| 69 | - qcom,sm8650-dwc3 | 69 | - qcom,sm8650-dwc3 |
| 70 | - qcom,x1e80100-dwc3 | 70 | - qcom,x1e80100-dwc3 |
| 71 | - qcom,x1e80100-dwc3-mp | ||
| 71 | - const: qcom,snps-dwc3 | 72 | - const: qcom,snps-dwc3 |
| 72 | 73 | ||
| 73 | reg: | 74 | reg: |
| @@ -460,8 +461,10 @@ allOf: · 386 unmodified lines | |||
| 460 | then: | 461 | then: |
| 461 | properties: | 462 | properties: |
| 462 | interrupts: | 463 | interrupts: |
| 464 | minItems: 4 | ||
| 463 | maxItems: 5 | 465 | maxItems: 5 |
| 464 | interrupt-names: | 466 | interrupt-names: |
| 467 | minItems: 4 | ||
| 465 | items: | 468 | items: |
| 466 | - const: dwc_usb3 | 469 | - const: dwc_usb3 |
| 467 | - const: pwr_event | 470 | - const: pwr_event |
| @@ -60,6 +60,7 @@ required: · 59 unmodified lines | |||
| 60 | 60 | ||
| 61 | allOf: | 61 | allOf: |
| 62 | - $ref: usb-switch.yaml# | 62 | - $ref: usb-switch.yaml# |
| 63 | - $ref: usb-switch-ports.yaml# | ||
| 63 | 64 | ||
| 64 | additionalProperties: false | 65 | additionalProperties: false |
| 65 | 66 | ||
| @@ -11,6 +11,7 @@ maintainers: · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | allOf: | 12 | allOf: |
| 13 | - $ref: usb-switch.yaml# | 13 | - $ref: usb-switch.yaml# |
| 14 | - $ref: usb-switch-ports.yaml# | ||
| 14 | 15 | ||
| 15 | properties: | 16 | properties: |
| 16 | compatible: | 17 | compatible: |
| @@ -0,0 +1,68 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/usb/usb-switch-ports.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: USB Orientation and Mode Switches Ports Graph Properties | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
| 11 | |||
| 12 | description: | ||
| 13 | Ports Graph properties for devices handling USB mode and orientation switching. | ||
| 14 | |||
| 15 | properties: | ||
| 16 | port: | ||
| 17 | $ref: /schemas/graph.yaml#/$defs/port-base | ||
| 18 | description: | ||
| 19 | A port node to link the device to a TypeC controller for the purpose of | ||
| 20 | handling altmode muxing and orientation switching. | ||
| 21 | |||
| 22 | properties: | ||
| 23 | endpoint: | ||
| 24 | $ref: /schemas/graph.yaml#/$defs/endpoint-base | ||
| 25 | unevaluatedProperties: false | ||
| 26 | properties: | ||
| 27 | data-lanes: | ||
| 28 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 29 | minItems: 1 | ||
| 30 | maxItems: 8 | ||
| 31 | uniqueItems: true | ||
| 32 | items: | ||
| 33 | maximum: 8 | ||
| 34 | |||
| 35 | ports: | ||
| 36 | $ref: /schemas/graph.yaml#/properties/ports | ||
| 37 | properties: | ||
| 38 | port@0: | ||
| 39 | $ref: /schemas/graph.yaml#/properties/port | ||
| 40 | description: | ||
| 41 | Super Speed (SS) Output endpoint to the Type-C connector | ||
| 42 | |||
| 43 | port@1: | ||
| 44 | $ref: /schemas/graph.yaml#/$defs/port-base | ||
| 45 | description: | ||
| 46 | Super Speed (SS) Input endpoint from the Super-Speed PHY | ||
| 47 | unevaluatedProperties: false | ||
| 48 | |||
| 49 | properties: | ||
| 50 | endpoint: | ||
| 51 | $ref: /schemas/graph.yaml#/$defs/endpoint-base | ||
| 52 | unevaluatedProperties: false | ||
| 53 | properties: | ||
| 54 | data-lanes: | ||
| 55 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 56 | minItems: 1 | ||
| 57 | maxItems: 8 | ||
| 58 | uniqueItems: true | ||
| 59 | items: | ||
| 60 | maximum: 8 | ||
| 61 | |||
| 62 | oneOf: | ||
| 63 | - required: | ||
| 64 | - port | ||
| 65 | - required: | ||
| 66 | - ports | ||
| 67 | |||
| 68 | additionalProperties: true | ||
| @@ -25,56 +25,4 @@ properties: · 24 unmodified lines | |||
| 25 | description: Possible handler of SuperSpeed signals retiming | 25 | description: Possible handler of SuperSpeed signals retiming |
| 26 | type: boolean | 26 | type: boolean |
| 27 | 27 | ||
| 28 | port: | ||
| 29 | $ref: /schemas/graph.yaml#/$defs/port-base | ||
| 30 | description: | ||
| 31 | A port node to link the device to a TypeC controller for the purpose of | ||
| 32 | handling altmode muxing and orientation switching. | ||
| 33 | |||
| 34 | properties: | ||
| 35 | endpoint: | ||
| 36 | $ref: /schemas/graph.yaml#/$defs/endpoint-base | ||
| 37 | unevaluatedProperties: false | ||
| 38 | properties: | ||
| 39 | data-lanes: | ||
| 40 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 41 | minItems: 1 | ||
| 42 | maxItems: 8 | ||
| 43 | uniqueItems: true | ||
| 44 | items: | ||
| 45 | maximum: 8 | ||
| 46 | |||
| 47 | ports: | ||
| 48 | $ref: /schemas/graph.yaml#/properties/ports | ||
| 49 | properties: | ||
| 50 | port@0: | ||
| 51 | $ref: /schemas/graph.yaml#/properties/port | ||
| 52 | description: | ||
| 53 | Super Speed (SS) Output endpoint to the Type-C connector | ||
| 54 | |||
| 55 | port@1: | ||
| 56 | $ref: /schemas/graph.yaml#/$defs/port-base | ||
| 57 | description: | ||
| 58 | Super Speed (SS) Input endpoint from the Super-Speed PHY | ||
| 59 | unevaluatedProperties: false | ||
| 60 | |||
| 61 | properties: | ||
| 62 | endpoint: | ||
| 63 | $ref: /schemas/graph.yaml#/$defs/endpoint-base | ||
| 64 | unevaluatedProperties: false | ||
| 65 | properties: | ||
| 66 | data-lanes: | ||
| 67 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 68 | minItems: 1 | ||
| 69 | maxItems: 8 | ||
| 70 | uniqueItems: true | ||
| 71 | items: | ||
| 72 | maximum: 8 | ||
| 73 | |||
| 74 | oneOf: | ||
| 75 | - required: | ||
| 76 | - port | ||
| 77 | - required: | ||
| 78 | - ports | ||
| 79 | |||
| 80 | additionalProperties: true | 28 | additionalProperties: true |
| @@ -11,6 +11,7 @@ found on https://linux-ax25.in-berlin.de. · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | There is a mailing list for discussing Linux amateur radio matters | 12 | There is a mailing list for discussing Linux amateur radio matters |
| 13 | called linux-hams@vger.kernel.org. To subscribe to it, send a message to | 13 | called linux-hams@vger.kernel.org. To subscribe to it, send a message to |
| 14 | majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body | 14 | linux-hams+subscribe@vger.kernel.org or use the web interface at |
| 15 | of the message, the subject field is ignored. You don't need to be | 15 | https://vger.kernel.org. The subject and body of the message are |
| 16 | subscribed to post but of course that means you might miss an answer. | 16 | ignored. You don't need to be subscribed to post but of course that |
| 17 | means you might miss an answer. | ||
| @@ -137,16 +137,20 @@ d. Checksum offload header v5 · 136 unmodified lines | |||
| 137 | 137 | ||
| 138 | Checksum offload header fields are in big endian format. | 138 | Checksum offload header fields are in big endian format. |
| 139 | 139 | ||
| 140 | Packet format:: | ||
| 141 | |||
| 140 | Bit 0 - 6 7 8-15 16-31 | 142 | Bit 0 - 6 7 8-15 16-31 |
| 141 | Function Header Type Next Header Checksum Valid Reserved | 143 | Function Header Type Next Header Checksum Valid Reserved |
| 142 | 144 | ||
| 143 | Header Type is to indicate the type of header, this usually is set to CHECKSUM | 145 | Header Type is to indicate the type of header, this usually is set to CHECKSUM |
| 144 | 146 | ||
| 145 | Header types | 147 | Header types |
| 146 | = ========================================== | 148 | |
| 149 | = =============== | ||
| 147 | 0 Reserved | 150 | 0 Reserved |
| 148 | 1 Reserved | 151 | 1 Reserved |
| 149 | 2 checksum header | 152 | 2 checksum header |
| 153 | = =============== | ||
| 150 | 154 | ||
| 151 | Checksum Valid is to indicate whether the header checksum is valid. Value of 1 | 155 | Checksum Valid is to indicate whether the header checksum is valid. Value of 1 |
| 152 | implies that checksum is calculated on this packet and is valid, value of 0 | 156 | implies that checksum is calculated on this packet and is valid, value of 0 |
| @@ -183,9 +187,11 @@ rmnet in a single linear skb. rmnet will process the individual · 30 unmodified lines | |||
| 183 | packets and either ACK the MAP command or deliver the IP packet to the | 187 | packets and either ACK the MAP command or deliver the IP packet to the |
| 184 | network stack as needed | 188 | network stack as needed |
| 185 | 189 | ||
| 186 | MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding.... | 190 | Packet format:: |
| 191 | |||
| 192 | MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding.... | ||
| 187 | 193 | ||
| 188 | MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad... | 194 | MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad... |
| 189 | 195 | ||
| 190 | 3. Userspace configuration | 196 | 3. Userspace configuration |
| 191 | ========================== | 197 | ========================== |
| @@ -96,9 +96,8 @@ needed to these network configuration daemons to make sure that an IP is · 95 unmodified lines | |||
| 96 | received only on the 'failover' device. | 96 | received only on the 'failover' device. |
| 97 | 97 | ||
| 98 | Below is the patch snippet used with 'cloud-ifupdown-helper' script found on | 98 | Below is the patch snippet used with 'cloud-ifupdown-helper' script found on |
| 99 | Debian cloud images: | 99 | Debian cloud images:: |
| 100 | 100 | ||
| 101 | :: | ||
| 102 | @@ -27,6 +27,8 @@ do_setup() { | 101 | @@ -27,6 +27,8 @@ do_setup() { |
| 103 | local working="$cfgdir/.$INTERFACE" | 102 | local working="$cfgdir/.$INTERFACE" |
| 104 | local final="$cfgdir/$INTERFACE" | 103 | local final="$cfgdir/$INTERFACE" |
| @@ -172,9 +171,8 @@ appropriate FDB entry is added. · 67 unmodified lines | |||
| 172 | 171 | ||
| 173 | The following script is executed on the destination hypervisor once migration | 172 | The following script is executed on the destination hypervisor once migration |
| 174 | completes, and it reattaches the VF to the VM and brings down the virtio-net | 173 | completes, and it reattaches the VF to the VM and brings down the virtio-net |
| 175 | interface. | 174 | interface:: |
| 176 | 175 | ||
| 177 | :: | ||
| 178 | # reattach-vf.sh | 176 | # reattach-vf.sh |
| 179 | #!/bin/bash | 177 | #!/bin/bash |
| 180 | 178 | ||
| @@ -1997,6 +1997,10 @@ F: include/uapi/linux/if_arcnet.h · 1996 unmodified lines | |||
| 1997 | 1997 | ||
| 1998 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) | 1998 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) |
| 1999 | M: Arnd Bergmann <arnd@arndb.de> | 1999 | M: Arnd Bergmann <arnd@arndb.de> |
| 2000 | M: Krzysztof Kozlowski <krzk@kernel.org> | ||
| 2001 | M: Alexandre Belloni <alexandre.belloni@bootlin.com> | ||
| 2002 | M: Linus Walleij <linus.walleij@linaro.org> | ||
| 2003 | R: Drew Fustini <fustini@kernel.org> | ||
| 2000 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2004 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2001 | L: soc@lists.linux.dev | 2005 | L: soc@lists.linux.dev |
| 2002 | S: Maintained | 2006 | S: Maintained |
| @@ -3841,6 +3845,7 @@ F: drivers/hwmon/asus-ec-sensors.c · 1838 unmodified lines | |||
| 3841 | ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS | 3845 | ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS |
| 3842 | M: Corentin Chary <corentin.chary@gmail.com> | 3846 | M: Corentin Chary <corentin.chary@gmail.com> |
| 3843 | M: Luke D. Jones <luke@ljones.dev> | 3847 | M: Luke D. Jones <luke@ljones.dev> |
| 3848 | M: Denis Benato <benato.denis96@gmail.com> | ||
| 3844 | L: platform-driver-x86@vger.kernel.org | 3849 | L: platform-driver-x86@vger.kernel.org |
| 3845 | S: Maintained | 3850 | S: Maintained |
| 3846 | W: https://asus-linux.org/ | 3851 | W: https://asus-linux.org/ |
| @@ -13111,6 +13116,15 @@ F: include/uapi/linux/io_uring.h · 9264 unmodified lines | |||
| 13111 | F: include/uapi/linux/io_uring/ | 13116 | F: include/uapi/linux/io_uring/ |
| 13112 | F: io_uring/ | 13117 | F: io_uring/ |
| 13113 | 13118 | ||
| 13119 | IO_URING ZCRX | ||
| 13120 | M: Pavel Begunkov <asml.silence@gmail.com> | ||
| 13121 | L: io-uring@vger.kernel.org | ||
| 13122 | L: netdev@vger.kernel.org | ||
| 13123 | T: git https://github.com/isilence/linux.git zcrx/for-next | ||
| 13124 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git | ||
| 13125 | S: Maintained | ||
| 13126 | F: io_uring/zcrx.* | ||
| 13127 | |||
| 13114 | IPMI SUBSYSTEM | 13128 | IPMI SUBSYSTEM |
| 13115 | M: Corey Minyard <corey@minyard.net> | 13129 | M: Corey Minyard <corey@minyard.net> |
| 13116 | L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers) | 13130 | L: openipmi-developer@lists.sourceforge.net (moderated for non-subscribers) |
| @@ -14394,6 +14408,7 @@ F: tools/memory-model/ · 1277 unmodified lines | |||
| 14394 | 14408 | ||
| 14395 | LINUX-NEXT TREE | 14409 | LINUX-NEXT TREE |
| 14396 | M: Stephen Rothwell <sfr@canb.auug.org.au> | 14410 | M: Stephen Rothwell <sfr@canb.auug.org.au> |
| 14411 | M: Mark Brown <broonie@kernel.org> | ||
| 14397 | L: linux-next@vger.kernel.org | 14412 | L: linux-next@vger.kernel.org |
| 14398 | S: Supported | 14413 | S: Supported |
| 14399 | B: mailto:linux-next@vger.kernel.org and the appropriate development tree | 14414 | B: mailto:linux-next@vger.kernel.org and the appropriate development tree |
| @@ -26885,7 +26900,7 @@ S: Maintained · 12485 unmodified lines | |||
| 26885 | F: drivers/vfio/cdx/* | 26900 | F: drivers/vfio/cdx/* |
| 26886 | 26901 | ||
| 26887 | VFIO DRIVER | 26902 | VFIO DRIVER |
| 26888 | M: Alex Williamson <alex.williamson@redhat.com> | 26903 | M: Alex Williamson <alex@shazbot.org> |
| 26889 | L: kvm@vger.kernel.org | 26904 | L: kvm@vger.kernel.org |
| 26890 | S: Maintained | 26905 | S: Maintained |
| 26891 | T: git https://github.com/awilliam/linux-vfio.git | 26906 | T: git https://github.com/awilliam/linux-vfio.git |
| @@ -27048,7 +27063,7 @@ T: git git://linuxtv.org/media.git · 156 unmodified lines | |||
| 27048 | F: drivers/media/test-drivers/vimc/* | 27063 | F: drivers/media/test-drivers/vimc/* |
| 27049 | 27064 | ||
| 27050 | VIRT LIB | 27065 | VIRT LIB |
| 27051 | M: Alex Williamson <alex.williamson@redhat.com> | 27066 | M: Alex Williamson <alex@shazbot.org> |
| 27052 | M: Paolo Bonzini <pbonzini@redhat.com> | 27067 | M: Paolo Bonzini <pbonzini@redhat.com> |
| 27053 | L: kvm@vger.kernel.org | 27068 | L: kvm@vger.kernel.org |
| 27054 | S: Supported | 27069 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 18 | 3 | PATCHLEVEL = 18 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc3 |
| 6 | NAME = Baby Opossum Posse | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -1061,6 +1061,9 @@ NOSTDINC_FLAGS += -nostdinc · 1052 unmodified lines | |||
| 1061 | # perform bounds checking. | 1061 | # perform bounds checking. |
| 1062 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) | 1062 | KBUILD_CFLAGS += $(call cc-option, -fstrict-flex-arrays=3) |
| 1063 | 1063 | ||
| 1064 | # Allow including a tagged struct or union anonymously in another struct/union. | ||
| 1065 | KBUILD_CFLAGS += -fms-extensions | ||
| 1066 | |||
| 1064 | # disable invalid "can't wrap" optimizations for signed / pointers | 1067 | # disable invalid "can't wrap" optimizations for signed / pointers |
| 1065 | KBUILD_CFLAGS += -fno-strict-overflow | 1068 | KBUILD_CFLAGS += -fno-strict-overflow |
| 1066 | 1069 | ||
| @@ -77,6 +77,14 @@ · 76 unmodified lines | |||
| 77 | /delete-property/ pinctrl-0; | 77 | /delete-property/ pinctrl-0; |
| 78 | }; | 78 | }; |
| 79 | 79 | ||
| 80 | &pm { | ||
| 81 | clocks = <&firmware_clocks 5>, | ||
| 82 | <&clocks BCM2835_CLOCK_PERI_IMAGE>, | ||
| 83 | <&clocks BCM2835_CLOCK_H264>, | ||
| 84 | <&clocks BCM2835_CLOCK_ISP>; | ||
| 85 | clock-names = "v3d", "peri_image", "h264", "isp"; | ||
| 86 | }; | ||
| 87 | |||
| 80 | &rmem { | 88 | &rmem { |
| 81 | /* | 89 | /* |
| 82 | * RPi4's co-processor will copy the board's bootloader configuration | 90 | * RPi4's co-processor will copy the board's bootloader configuration |
| @@ -13,7 +13,16 @@ · 12 unmodified lines | |||
| 13 | clock-names = "pixel", "hdmi"; | 13 | clock-names = "pixel", "hdmi"; |
| 14 | }; | 14 | }; |
| 15 | 15 | ||
| 16 | &pm { | ||
| 17 | clocks = <&firmware_clocks 5>, | ||
| 18 | <&clocks BCM2835_CLOCK_PERI_IMAGE>, | ||
| 19 | <&clocks BCM2835_CLOCK_H264>, | ||
| 20 | <&clocks BCM2835_CLOCK_ISP>; | ||
| 21 | clock-names = "v3d", "peri_image", "h264", "isp"; | ||
| 22 | }; | ||
| 23 | |||
| 16 | &v3d { | 24 | &v3d { |
| 25 | clocks = <&firmware_clocks 5>; | ||
| 17 | power-domains = <&power RPI_POWER_DOMAIN_V3D>; | 26 | power-domains = <&power RPI_POWER_DOMAIN_V3D>; |
| 18 | }; | 27 | }; |
| 19 | 28 | ||
| @@ -326,6 +326,8 @@ · 325 unmodified lines | |||
| 326 | <0x7fffe000 0x2000>; | 326 | <0x7fffe000 0x2000>; |
| 327 | interrupt-controller; | 327 | interrupt-controller; |
| 328 | #address-cells = <0>; | 328 | #address-cells = <0>; |
| 329 | interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | | ||
| 330 | IRQ_TYPE_LEVEL_HIGH)>; | ||
| 329 | #interrupt-cells = <3>; | 331 | #interrupt-cells = <3>; |
| 330 | }; | 332 | }; |
| 331 | 333 | ||
| @@ -293,7 +293,8 @@ static inline pmd_t set_pmd_bit(pmd_t pmd, pgprot_t prot) · 292 unmodified lines | |||
| 293 | static inline pte_t pte_mkwrite_novma(pte_t pte) | 293 | static inline pte_t pte_mkwrite_novma(pte_t pte) |
| 294 | { | 294 | { |
| 295 | pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); | 295 | pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); |
| 296 | pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); | 296 | if (pte_sw_dirty(pte)) |
| 297 | pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); | ||
| 297 | return pte; | 298 | return pte; |
| 298 | } | 299 | } |
| 299 | 300 | ||
| @@ -63,7 +63,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ · 62 unmodified lines | |||
| 63 | $(filter -Werror,$(KBUILD_CPPFLAGS)) \ | 63 | $(filter -Werror,$(KBUILD_CPPFLAGS)) \ |
| 64 | -Werror-implicit-function-declaration \ | 64 | -Werror-implicit-function-declaration \ |
| 65 | -Wno-format-security \ | 65 | -Wno-format-security \ |
| 66 | -std=gnu11 | 66 | -std=gnu11 -fms-extensions |
| 67 | VDSO_CFLAGS += -O2 | 67 | VDSO_CFLAGS += -O2 |
| 68 | # Some useful compiler-dependent flags from top-level Makefile | 68 | # Some useful compiler-dependent flags from top-level Makefile |
| 69 | VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) | 69 | VDSO_CFLAGS += $(call cc32-option,-Wno-pointer-sign) |
| @@ -71,6 +71,7 @@ VDSO_CFLAGS += -fno-strict-overflow · 1 unmodified line | |||
| 71 | VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) | 71 | VDSO_CFLAGS += $(call cc32-option,-Werror=strict-prototypes) |
| 72 | VDSO_CFLAGS += -Werror=date-time | 72 | VDSO_CFLAGS += -Werror=date-time |
| 73 | VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types) | 73 | VDSO_CFLAGS += $(call cc32-option,-Werror=incompatible-pointer-types) |
| 74 | VDSO_CFLAGS += $(if $(CONFIG_CC_IS_CLANG),-Wno-microsoft-anon-tag) | ||
| 74 | 75 | ||
| 75 | # Compile as THUMB2 or ARM. Unwinding via frame-pointers in THUMB2 is | 76 | # Compile as THUMB2 or ARM. Unwinding via frame-pointers in THUMB2 is |
| 76 | # unreliable. | 77 | # unreliable. |
| @@ -35,7 +35,7 @@ void copy_highpage(struct page *to, struct page *from) · 34 unmodified lines | |||
| 35 | from != folio_page(src, 0)) | 35 | from != folio_page(src, 0)) |
| 36 | return; | 36 | return; |
| 37 | 37 | ||
| 38 | WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst)); | 38 | folio_try_hugetlb_mte_tagging(dst); |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * Populate tags for all subpages. | 41 | * Populate tags for all subpages. |
| @@ -51,8 +51,13 @@ void copy_highpage(struct page *to, struct page *from) · 9 unmodified lines | |||
| 51 | } | 51 | } |
| 52 | folio_set_hugetlb_mte_tagged(dst); | 52 | folio_set_hugetlb_mte_tagged(dst); |
| 53 | } else if (page_mte_tagged(from)) { | 53 | } else if (page_mte_tagged(from)) { |
| 54 | /* It's a new page, shouldn't have been tagged yet */ | 54 | /* |
| 55 | WARN_ON_ONCE(!try_page_mte_tagging(to)); | 55 | * Most of the time it's a new page that shouldn't have been |
| 56 | * tagged yet. However, folio migration can end up reusing the | ||
| 57 | * same page without untagging it. Ignore the warning if the | ||
| 58 | * page is already tagged. | ||
| 59 | */ | ||
| 60 | try_page_mte_tagging(to); | ||
| 56 | 61 | ||
| 57 | mte_copy_page_tags(kto, kfrom); | 62 | mte_copy_page_tags(kto, kfrom); |
| 58 | set_page_mte_tagged(to); | 63 | set_page_mte_tagged(to); |
| @@ -21,7 +21,7 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma, · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | folio = page_folio(pfn_to_page(pfn)); | 22 | folio = page_folio(pfn_to_page(pfn)); |
| 23 | 23 | ||
| 24 | if (test_and_set_bit(PG_dcache_clean, &folio->flags)) | 24 | if (test_and_set_bit(PG_dcache_clean, &folio->flags.f)) |
| 25 | return; | 25 | return; |
| 26 | 26 | ||
| 27 | icache_inv_range(address, address + nr*PAGE_SIZE); | 27 | icache_inv_range(address, address + nr*PAGE_SIZE); |
| @@ -20,8 +20,8 @@ · 19 unmodified lines | |||
| 20 | 20 | ||
| 21 | static inline void flush_dcache_folio(struct folio *folio) | 21 | static inline void flush_dcache_folio(struct folio *folio) |
| 22 | { | 22 | { |
| 23 | if (test_bit(PG_dcache_clean, &folio->flags)) | 23 | if (test_bit(PG_dcache_clean, &folio->flags.f)) |
| 24 | clear_bit(PG_dcache_clean, &folio->flags); | 24 | clear_bit(PG_dcache_clean, &folio->flags.f); |
| 25 | } | 25 | } |
| 26 | #define flush_dcache_folio flush_dcache_folio | 26 | #define flush_dcache_folio flush_dcache_folio |
| 27 | 27 | ||
| @@ -19,7 +19,7 @@ ccflags-vdso := \ · 18 unmodified lines | |||
| 19 | cflags-vdso := $(ccflags-vdso) \ | 19 | cflags-vdso := $(ccflags-vdso) \ |
| 20 | -isystem $(shell $(CC) -print-file-name=include) \ | 20 | -isystem $(shell $(CC) -print-file-name=include) \ |
| 21 | $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ | 21 | $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ |
| 22 | -std=gnu11 -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \ | 22 | -std=gnu11 -fms-extensions -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \ |
| 23 | -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ | 23 | -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ |
| 24 | $(call cc-option, -fno-asynchronous-unwind-tables) \ | 24 | $(call cc-option, -fno-asynchronous-unwind-tables) \ |
| 25 | $(call cc-option, -fno-stack-protector) | 25 | $(call cc-option, -fno-stack-protector) |
| @@ -47,7 +47,7 @@ static struct resource standard_io_resources[] = { · 46 unmodified lines | |||
| 47 | .name = "keyboard", | 47 | .name = "keyboard", |
| 48 | .start = 0x60, | 48 | .start = 0x60, |
| 49 | .end = 0x6f, | 49 | .end = 0x6f, |
| 50 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | 50 | .flags = IORESOURCE_IO |
| 51 | }, | 51 | }, |
| 52 | { | 52 | { |
| 53 | .name = "dma page reg", | 53 | .name = "dma page reg", |
| @@ -213,7 +213,7 @@ void __init plat_mem_setup(void) · 159 unmodified lines | |||
| 213 | 213 | ||
| 214 | /* Request I/O space for devices used on the Malta board. */ | 214 | /* Request I/O space for devices used on the Malta board. */ |
| 215 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | 215 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) |
| 216 | request_resource(&ioport_resource, standard_io_resources+i); | 216 | insert_resource(&ioport_resource, standard_io_resources + i); |
| 217 | 217 | ||
| 218 | /* | 218 | /* |
| 219 | * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. | 219 | * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. |
| @@ -230,8 +230,7 @@ void __init mips_pcibios_init(void) · 229 unmodified lines | |||
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | /* PIIX4 ACPI starts at 0x1000 */ | 232 | /* PIIX4 ACPI starts at 0x1000 */ |
| 233 | if (controller->io_resource->start < 0x00001000UL) | 233 | PCIBIOS_MIN_IO = 0x1000; |
| 234 | controller->io_resource->start = 0x00001000UL; | ||
| 235 | 234 | ||
| 236 | iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ | 235 | iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ |
| 237 | ioport_resource.end = controller->io_resource->end; | 236 | ioport_resource.end = controller->io_resource->end; |
| @@ -18,7 +18,7 @@ KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os · 17 unmodified lines | |||
| 18 | ifndef CONFIG_64BIT | 18 | ifndef CONFIG_64BIT |
| 19 | KBUILD_CFLAGS += -mfast-indirect-calls | 19 | KBUILD_CFLAGS += -mfast-indirect-calls |
| 20 | endif | 20 | endif |
| 21 | KBUILD_CFLAGS += -std=gnu11 | 21 | KBUILD_CFLAGS += -std=gnu11 -fms-extensions |
| 22 | 22 | ||
| 23 | LDFLAGS_vmlinux := -X -e startup --as-needed -T | 23 | LDFLAGS_vmlinux := -X -e startup --as-needed -T |
| 24 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE | 24 | $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE |
| @@ -70,7 +70,7 @@ BOOTCPPFLAGS := -nostdinc $(LINUXINCLUDE) · 69 unmodified lines | |||
| 70 | BOOTCPPFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) | 70 | BOOTCPPFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) |
| 71 | 71 | ||
| 72 | BOOTCFLAGS := $(BOOTTARGETFLAGS) \ | 72 | BOOTCFLAGS := $(BOOTTARGETFLAGS) \ |
| 73 | -std=gnu11 \ | 73 | -std=gnu11 -fms-extensions \ |
| 74 | -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ | 74 | -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
| 75 | -fno-strict-aliasing -O2 \ | 75 | -fno-strict-aliasing -O2 \ |
| 76 | -msoft-float -mno-altivec -mno-vsx \ | 76 | -msoft-float -mno-altivec -mno-vsx \ |
| @@ -86,6 +86,7 @@ BOOTARFLAGS := -crD · 9 unmodified lines | |||
| 86 | 86 | ||
| 87 | ifdef CONFIG_CC_IS_CLANG | 87 | ifdef CONFIG_CC_IS_CLANG |
| 88 | BOOTCFLAGS += $(CLANG_FLAGS) | 88 | BOOTCFLAGS += $(CLANG_FLAGS) |
| 89 | BOOTCFLAGS += -Wno-microsoft-anon-tag | ||
| 89 | BOOTAFLAGS += $(CLANG_FLAGS) | 90 | BOOTAFLAGS += $(CLANG_FLAGS) |
| 90 | endif | 91 | endif |
| 91 | 92 | ||
| @@ -84,15 +84,9 @@ · 83 unmodified lines | |||
| 84 | .endm | 84 | .endm |
| 85 | 85 | ||
| 86 | #ifdef CONFIG_SMP | 86 | #ifdef CONFIG_SMP |
| 87 | #ifdef CONFIG_32BIT | ||
| 88 | #define PER_CPU_OFFSET_SHIFT 2 | ||
| 89 | #else | ||
| 90 | #define PER_CPU_OFFSET_SHIFT 3 | ||
| 91 | #endif | ||
| 92 | |||
| 93 | .macro asm_per_cpu dst sym tmp | 87 | .macro asm_per_cpu dst sym tmp |
| 94 | lw \tmp, TASK_TI_CPU_NUM(tp) | 88 | lw \tmp, TASK_TI_CPU_NUM(tp) |
| 95 | slli \tmp, \tmp, PER_CPU_OFFSET_SHIFT | 89 | slli \tmp, \tmp, RISCV_LGPTR |
| 96 | la \dst, __per_cpu_offset | 90 | la \dst, __per_cpu_offset |
| 97 | add \dst, \dst, \tmp | 91 | add \dst, \dst, \tmp |
| 98 | REG_L \tmp, 0(\dst) | 92 | REG_L \tmp, 0(\dst) |
| @@ -31,6 +31,8 @@ struct riscv_isainfo { · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); | 32 | DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); |
| 33 | 33 | ||
| 34 | extern const struct seq_operations cpuinfo_op; | ||
| 35 | |||
| 34 | /* Per-cpu ISA extensions. */ | 36 | /* Per-cpu ISA extensions. */ |
| 35 | extern struct riscv_isainfo hart_isa[NR_CPUS]; | 37 | extern struct riscv_isainfo hart_isa[NR_CPUS]; |
| 36 | 38 | ||
| @@ -42,4 +42,11 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair, · 41 unmodified lines | |||
| 42 | return pair->value == other_pair->value; | 42 | return pair->value == other_pair->value; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_MMU | ||
| 46 | void riscv_hwprobe_register_async_probe(void); | ||
| 47 | void riscv_hwprobe_complete_async_probe(void); | ||
| 48 | #else | ||
| 49 | static inline void riscv_hwprobe_register_async_probe(void) {} | ||
| 50 | static inline void riscv_hwprobe_complete_async_probe(void) {} | ||
| 51 | #endif | ||
| 45 | #endif | 52 | #endif |
| @@ -69,6 +69,8 @@ typedef struct { · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | #define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) | 70 | #define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) |
| 71 | 71 | ||
| 72 | #define MAX_POSSIBLE_PHYSMEM_BITS 56 | ||
| 73 | |||
| 72 | /* | 74 | /* |
| 73 | * rv64 PTE format: | 75 | * rv64 PTE format: |
| 74 | * | 63 | 62 61 | 60 54 | 53 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 76 | * | 63 | 62 61 | 60 54 | 53 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| @@ -654,6 +654,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) · 653 unmodified lines | |||
| 654 | return __pgprot(prot); | 654 | return __pgprot(prot); |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | #define pgprot_dmacoherent pgprot_writecombine | ||
| 658 | |||
| 657 | /* | 659 | /* |
| 658 | * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By | 660 | * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By |
| 659 | * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in | 661 | * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in |
| @@ -12,6 +12,12 @@ struct vdso_arch_data { · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | /* Boolean indicating all CPUs have the same static hwprobe values. */ | 13 | /* Boolean indicating all CPUs have the same static hwprobe values. */ |
| 14 | __u8 homogeneous_cpus; | 14 | __u8 homogeneous_cpus; |
| 15 | |||
| 16 | /* | ||
| 17 | * A gate to check and see if the hwprobe data is actually ready, as | ||
| 18 | * probing is deferred to avoid boot slowdowns. | ||
| 19 | */ | ||
| 20 | __u8 ready; | ||
| 15 | }; | 21 | }; |
| 16 | 22 | ||
| 17 | #endif /* __RISCV_ASM_VDSO_ARCH_DATA_H */ | 23 | #endif /* __RISCV_ASM_VDSO_ARCH_DATA_H */ |
| @@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo · 61 unmodified lines | |||
| 62 | return -ENODEV; | 62 | return -ENODEV; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | if (!of_device_is_available(node)) { | 65 | if (!of_device_is_available(node)) |
| 66 | pr_info("CPU with hartid=%lu is not available\n", *hart); | ||
| 67 | return -ENODEV; | 66 | return -ENODEV; |
| 68 | } | ||
| 69 | 67 | ||
| 70 | if (of_property_read_string(node, "riscv,isa-base", &isa)) | 68 | if (of_property_read_string(node, "riscv,isa-base", &isa)) |
| 71 | goto old_interface; | 69 | goto old_interface; |
| @@ -932,9 +932,9 @@ static int has_thead_homogeneous_vlenb(void) · 931 unmodified lines | |||
| 932 | { | 932 | { |
| 933 | int cpu; | 933 | int cpu; |
| 934 | u32 prev_vlenb = 0; | 934 | u32 prev_vlenb = 0; |
| 935 | u32 vlenb; | 935 | u32 vlenb = 0; |
| 936 | 936 | ||
| 937 | /* Ignore thead,vlenb property if xtheavector is not enabled in the kernel */ | 937 | /* Ignore thead,vlenb property if xtheadvector is not enabled in the kernel */ |
| 938 | if (!IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR)) | 938 | if (!IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR)) |
| 939 | return 0; | 939 | return 0; |
| 940 | 940 | ||
| @@ -40,6 +40,17 @@ enum ipi_message_type { · 39 unmodified lines | |||
| 40 | IPI_MAX | 40 | IPI_MAX |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | static const char * const ipi_names[] = { | ||
| 44 | [IPI_RESCHEDULE] = "Rescheduling interrupts", | ||
| 45 | [IPI_CALL_FUNC] = "Function call interrupts", | ||
| 46 | [IPI_CPU_STOP] = "CPU stop interrupts", | ||
| 47 | [IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts", | ||
| 48 | [IPI_IRQ_WORK] = "IRQ work interrupts", | ||
| 49 | [IPI_TIMER] = "Timer broadcast interrupts", | ||
| 50 | [IPI_CPU_BACKTRACE] = "CPU backtrace interrupts", | ||
| 51 | [IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts", | ||
| 52 | }; | ||
| 53 | |||
| 43 | unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = { | 54 | unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = { |
| 44 | [0 ... NR_CPUS-1] = INVALID_HARTID | 55 | [0 ... NR_CPUS-1] = INVALID_HARTID |
| 45 | }; | 56 | }; |
| @@ -199,7 +210,7 @@ void riscv_ipi_set_virq_range(int virq, int nr) · 153 unmodified lines | |||
| 199 | /* Request IPIs */ | 210 | /* Request IPIs */ |
| 200 | for (i = 0; i < nr_ipi; i++) { | 211 | for (i = 0; i < nr_ipi; i++) { |
| 201 | err = request_percpu_irq(ipi_virq_base + i, handle_IPI, | 212 | err = request_percpu_irq(ipi_virq_base + i, handle_IPI, |
| 202 | "IPI", &ipi_dummy_dev); | 213 | ipi_names[i], &ipi_dummy_dev); |
| 203 | WARN_ON(err); | 214 | WARN_ON(err); |
| 204 | 215 | ||
| 205 | ipi_desc[i] = irq_to_desc(ipi_virq_base + i); | 216 | ipi_desc[i] = irq_to_desc(ipi_virq_base + i); |
| @@ -210,17 +221,6 @@ void riscv_ipi_set_virq_range(int virq, int nr) · 4 unmodified lines | |||
| 210 | riscv_ipi_enable(); | 221 | riscv_ipi_enable(); |
| 211 | } | 222 | } |
| 212 | 223 | ||
| 213 | static const char * const ipi_names[] = { | ||
| 214 | [IPI_RESCHEDULE] = "Rescheduling interrupts", | ||
| 215 | [IPI_CALL_FUNC] = "Function call interrupts", | ||
| 216 | [IPI_CPU_STOP] = "CPU stop interrupts", | ||
| 217 | [IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts", | ||
| 218 | [IPI_IRQ_WORK] = "IRQ work interrupts", | ||
| 219 | [IPI_TIMER] = "Timer broadcast interrupts", | ||
| 220 | [IPI_CPU_BACKTRACE] = "CPU backtrace interrupts", | ||
| 221 | [IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts", | ||
| 222 | }; | ||
| 223 | |||
| 224 | void show_ipi_stats(struct seq_file *p, int prec) | 224 | void show_ipi_stats(struct seq_file *p, int prec) |
| 225 | { | 225 | { |
| 226 | unsigned int cpu, i; | 226 | unsigned int cpu, i; |
| @@ -5,6 +5,9 @@ · 4 unmodified lines | |||
| 5 | * more details. | 5 | * more details. |
| 6 | */ | 6 | */ |
| 7 | #include <linux/syscalls.h> | 7 | #include <linux/syscalls.h> |
| 8 | #include <linux/completion.h> | ||
| 9 | #include <linux/atomic.h> | ||
| 10 | #include <linux/once.h> | ||
| 8 | #include <asm/cacheflush.h> | 11 | #include <asm/cacheflush.h> |
| 9 | #include <asm/cpufeature.h> | 12 | #include <asm/cpufeature.h> |
| 10 | #include <asm/hwprobe.h> | 13 | #include <asm/hwprobe.h> |
| @@ -28,6 +31,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, · 17 unmodified lines | |||
| 28 | bool first = true; | 31 | bool first = true; |
| 29 | int cpu; | 32 | int cpu; |
| 30 | 33 | ||
| 34 | if (pair->key != RISCV_HWPROBE_KEY_MVENDORID && | ||
| 35 | pair->key != RISCV_HWPROBE_KEY_MIMPID && | ||
| 36 | pair->key != RISCV_HWPROBE_KEY_MARCHID) | ||
| 37 | goto out; | ||
| 38 | |||
| 31 | for_each_cpu(cpu, cpus) { | 39 | for_each_cpu(cpu, cpus) { |
| 32 | u64 cpu_id; | 40 | u64 cpu_id; |
| 33 | 41 | ||
| @@ -58,6 +66,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair, · 24 unmodified lines | |||
| 58 | } | 66 | } |
| 59 | } | 67 | } |
| 60 | 68 | ||
| 69 | out: | ||
| 61 | pair->value = id; | 70 | pair->value = id; |
| 62 | } | 71 | } |
| 63 | 72 | ||
| @@ -454,28 +463,32 @@ static int hwprobe_get_cpus(struct riscv_hwprobe __user *pairs, · 390 unmodified lines | |||
| 454 | return 0; | 463 | return 0; |
| 455 | } | 464 | } |
| 456 | 465 | ||
| 457 | static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs, | 466 | #ifdef CONFIG_MMU |
| 458 | size_t pair_count, size_t cpusetsize, | ||
| 459 | unsigned long __user *cpus_user, | ||
| 460 | unsigned int flags) | ||
| 461 | { | ||
| 462 | if (flags & RISCV_HWPROBE_WHICH_CPUS) | ||
| 463 | return hwprobe_get_cpus(pairs, pair_count, cpusetsize, | ||
| 464 | cpus_user, flags); | ||
| 465 | 467 | ||
| 466 | return hwprobe_get_values(pairs, pair_count, cpusetsize, | 468 | static DECLARE_COMPLETION(boot_probes_done); |
| 467 | cpus_user, flags); | 469 | static atomic_t pending_boot_probes = ATOMIC_INIT(1); |
| 470 | |||
| 471 | void riscv_hwprobe_register_async_probe(void) | ||
| 472 | { | ||
| 473 | atomic_inc(&pending_boot_probes); | ||
| 468 | } | 474 | } |
| 469 | 475 | ||
| 470 | #ifdef CONFIG_MMU | 476 | void riscv_hwprobe_complete_async_probe(void) |
| 477 | { | ||
| 478 | if (atomic_dec_and_test(&pending_boot_probes)) | ||
| 479 | complete(&boot_probes_done); | ||
| 480 | } | ||
| 471 | 481 | ||
| 472 | static int __init init_hwprobe_vdso_data(void) | 482 | static int complete_hwprobe_vdso_data(void) |
| 473 | { | 483 | { |
| 474 | struct vdso_arch_data *avd = vdso_k_arch_data; | 484 | struct vdso_arch_data *avd = vdso_k_arch_data; |
| 475 | u64 id_bitsmash = 0; | 485 | u64 id_bitsmash = 0; |
| 476 | struct riscv_hwprobe pair; | 486 | struct riscv_hwprobe pair; |
| 477 | int key; | 487 | int key; |
| 478 | 488 | ||
| 489 | if (unlikely(!atomic_dec_and_test(&pending_boot_probes))) | ||
| 490 | wait_for_completion(&boot_probes_done); | ||
| 491 | |||
| 479 | /* | 492 | /* |
| 480 | * Initialize vDSO data with the answers for the "all CPUs" case, to | 493 | * Initialize vDSO data with the answers for the "all CPUs" case, to |
| 481 | * save a syscall in the common case. | 494 | * save a syscall in the common case. |
| @@ -503,13 +516,52 @@ static int __init init_hwprobe_vdso_data(void) · 21 unmodified lines | |||
| 503 | * vDSO should defer to the kernel for exotic cpu masks. | 516 | * vDSO should defer to the kernel for exotic cpu masks. |
| 504 | */ | 517 | */ |
| 505 | avd->homogeneous_cpus = id_bitsmash != 0 && id_bitsmash != -1; | 518 | avd->homogeneous_cpus = id_bitsmash != 0 && id_bitsmash != -1; |
| 519 | |||
| 520 | /* | ||
| 521 | * Make sure all the VDSO values are visible before we look at them. | ||
| 522 | * This pairs with the implicit "no speculativly visible accesses" | ||
| 523 | * barrier in the VDSO hwprobe code. | ||
| 524 | */ | ||
| 525 | smp_wmb(); | ||
| 526 | avd->ready = true; | ||
| 527 | return 0; | ||
| 528 | } | ||
| 529 | |||
| 530 | static int __init init_hwprobe_vdso_data(void) | ||
| 531 | { | ||
| 532 | struct vdso_arch_data *avd = vdso_k_arch_data; | ||
| 533 | |||
| 534 | /* | ||
| 535 | * Prevent the vDSO cached values from being used, as they're not ready | ||
| 536 | * yet. | ||
| 537 | */ | ||
| 538 | avd->ready = false; | ||
| 506 | return 0; | 539 | return 0; |
| 507 | } | 540 | } |
| 508 | 541 | ||
| 509 | arch_initcall_sync(init_hwprobe_vdso_data); | 542 | arch_initcall_sync(init_hwprobe_vdso_data); |
| 510 | 543 | ||
| 544 | #else | ||
| 545 | |||
| 546 | static int complete_hwprobe_vdso_data(void) { return 0; } | ||
| 547 | |||
| 511 | #endif /* CONFIG_MMU */ | 548 | #endif /* CONFIG_MMU */ |
| 512 | 549 | ||
| 550 | static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs, | ||
| 551 | size_t pair_count, size_t cpusetsize, | ||
| 552 | unsigned long __user *cpus_user, | ||
| 553 | unsigned int flags) | ||
| 554 | { | ||
| 555 | DO_ONCE_SLEEPABLE(complete_hwprobe_vdso_data); | ||
| 556 | |||
| 557 | if (flags & RISCV_HWPROBE_WHICH_CPUS) | ||
| 558 | return hwprobe_get_cpus(pairs, pair_count, cpusetsize, | ||
| 559 | cpus_user, flags); | ||
| 560 | |||
| 561 | return hwprobe_get_values(pairs, pair_count, cpusetsize, | ||
| 562 | cpus_user, flags); | ||
| 563 | } | ||
| 564 | |||
| 513 | SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs, | 565 | SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs, |
| 514 | size_t, pair_count, size_t, cpusetsize, unsigned long __user *, | 566 | size_t, pair_count, size_t, cpusetsize, unsigned long __user *, |
| 515 | cpus, unsigned int, flags) | 567 | cpus, unsigned int, flags) |
| @@ -379,6 +379,7 @@ free: · 378 unmodified lines | |||
| 379 | static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused) | 379 | static int __init vec_check_unaligned_access_speed_all_cpus(void *unused __always_unused) |
| 380 | { | 380 | { |
| 381 | schedule_on_each_cpu(check_vector_unaligned_access); | 381 | schedule_on_each_cpu(check_vector_unaligned_access); |
| 382 | riscv_hwprobe_complete_async_probe(); | ||
| 382 | 383 | ||
| 383 | return 0; | 384 | return 0; |
| 384 | } | 385 | } |
| @@ -473,8 +474,12 @@ static int __init check_unaligned_access_all_cpus(void) · 88 unmodified lines | |||
| 473 | per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param; | 474 | per_cpu(vector_misaligned_access, cpu) = unaligned_vector_speed_param; |
| 474 | } else if (!check_vector_unaligned_access_emulated_all_cpus() && | 475 | } else if (!check_vector_unaligned_access_emulated_all_cpus() && |
| 475 | IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) { | 476 | IS_ENABLED(CONFIG_RISCV_PROBE_VECTOR_UNALIGNED_ACCESS)) { |
| 476 | kthread_run(vec_check_unaligned_access_speed_all_cpus, | 477 | riscv_hwprobe_register_async_probe(); |
| 477 | NULL, "vec_check_unaligned_access_speed_all_cpus"); | 478 | if (IS_ERR(kthread_run(vec_check_unaligned_access_speed_all_cpus, |
| 479 | NULL, "vec_check_unaligned_access_speed_all_cpus"))) { | ||
| 480 | pr_warn("Failed to create vec_unalign_check kthread\n"); | ||
| 481 | riscv_hwprobe_complete_async_probe(); | ||
| 482 | } | ||
| 478 | } | 483 | } |
| 479 | 484 | ||
| 480 | /* | 485 | /* |
| @@ -27,7 +27,7 @@ static int riscv_vdso_get_values(struct riscv_hwprobe *pairs, size_t pair_count, · 26 unmodified lines | |||
| 27 | * homogeneous, then this function can handle requests for arbitrary | 27 | * homogeneous, then this function can handle requests for arbitrary |
| 28 | * masks. | 28 | * masks. |
| 29 | */ | 29 | */ |
| 30 | if ((flags != 0) || (!all_cpus && !avd->homogeneous_cpus)) | 30 | if (flags != 0 || (!all_cpus && !avd->homogeneous_cpus) || unlikely(!avd->ready)) |
| 31 | return riscv_hwprobe(pairs, pair_count, cpusetsize, cpus, flags); | 31 | return riscv_hwprobe(pairs, pair_count, cpusetsize, cpus, flags); |
| 32 | 32 | ||
| 33 | /* This is something we can handle, fill out the pairs. */ | 33 | /* This is something we can handle, fill out the pairs. */ |
| @@ -22,7 +22,7 @@ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ · 21 unmodified lines | |||
| 22 | ifndef CONFIG_AS_IS_LLVM | 22 | ifndef CONFIG_AS_IS_LLVM |
| 23 | KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf)) | 23 | KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf)) |
| 24 | endif | 24 | endif |
| 25 | KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack -std=gnu11 | 25 | KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack -std=gnu11 -fms-extensions |
| 26 | KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY | 26 | KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY |
| 27 | KBUILD_CFLAGS_DECOMPRESSOR += -D__DECOMPRESSOR | 27 | KBUILD_CFLAGS_DECOMPRESSOR += -D__DECOMPRESSOR |
| 28 | KBUILD_CFLAGS_DECOMPRESSOR += -Wno-pointer-sign | 28 | KBUILD_CFLAGS_DECOMPRESSOR += -Wno-pointer-sign |
| @@ -35,6 +35,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-membe · 6 unmodified lines | |||
| 35 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) | 35 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) |
| 36 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) | 36 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) |
| 37 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds) | 37 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds) |
| 38 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_IS_CLANG),-Wno-microsoft-anon-tag) | ||
| 38 | 39 | ||
| 39 | UTS_MACHINE := s390x | 40 | UTS_MACHINE := s390x |
| 40 | STACK_SIZE := $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384)) | 41 | STACK_SIZE := $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384)) |
| @@ -13,7 +13,7 @@ CFLAGS_sha256.o := -D__NO_FORTIFY · 12 unmodified lines | |||
| 13 | $(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE | 13 | $(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE |
| 14 | $(call if_changed_rule,as_o_S) | 14 | $(call if_changed_rule,as_o_S) |
| 15 | 15 | ||
| 16 | KBUILD_CFLAGS := -std=gnu11 -fno-strict-aliasing -Wall -Wstrict-prototypes | 16 | KBUILD_CFLAGS := -std=gnu11 -fms-extensions -fno-strict-aliasing -Wall -Wstrict-prototypes |
| 17 | KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare | 17 | KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare |
| 18 | KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding | 18 | KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding |
| 19 | KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common | 19 | KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common |
| @@ -21,6 +21,7 @@ KBUILD_CFLAGS += -fno-stack-protector · 1 unmodified line | |||
| 21 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | 21 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 22 | KBUILD_CFLAGS += -D__DISABLE_EXPORTS | 22 | KBUILD_CFLAGS += -D__DISABLE_EXPORTS |
| 23 | KBUILD_CFLAGS += $(CLANG_FLAGS) | 23 | KBUILD_CFLAGS += $(CLANG_FLAGS) |
| 24 | KBUILD_CFLAGS += $(if $(CONFIG_CC_IS_CLANG),-Wno-microsoft-anon-tag) | ||
| 24 | KBUILD_CFLAGS += $(call cc-option,-fno-PIE) | 25 | KBUILD_CFLAGS += $(call cc-option,-fno-PIE) |
| 25 | KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS)) | 26 | KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS)) |
| 26 | KBUILD_AFLAGS += -D__DISABLE_EXPORTS | 27 | KBUILD_AFLAGS += -D__DISABLE_EXPORTS |
| @@ -48,7 +48,8 @@ endif · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | # How to compile the 16-bit code. Note we always compile for -march=i386; | 49 | # How to compile the 16-bit code. Note we always compile for -march=i386; |
| 50 | # that way we can complain to the user if the CPU is insufficient. | 50 | # that way we can complain to the user if the CPU is insufficient. |
| 51 | REALMODE_CFLAGS := -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ | 51 | REALMODE_CFLAGS := -std=gnu11 -fms-extensions -m16 -g -Os \ |
| 52 | -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ | ||
| 52 | -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ | 53 | -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ |
| 53 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ | 54 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
| 54 | -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) | 55 | -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) |
| @@ -60,6 +61,7 @@ REALMODE_CFLAGS += $(cc_stack_align4) · 5 unmodified lines | |||
| 60 | REALMODE_CFLAGS += $(CLANG_FLAGS) | 61 | REALMODE_CFLAGS += $(CLANG_FLAGS) |
| 61 | ifdef CONFIG_CC_IS_CLANG | 62 | ifdef CONFIG_CC_IS_CLANG |
| 62 | REALMODE_CFLAGS += -Wno-gnu | 63 | REALMODE_CFLAGS += -Wno-gnu |
| 64 | REALMODE_CFLAGS += -Wno-microsoft-anon-tag | ||
| 63 | endif | 65 | endif |
| 64 | export REALMODE_CFLAGS | 66 | export REALMODE_CFLAGS |
| 65 | 67 | ||
| @@ -25,7 +25,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ · 24 unmodified lines | |||
| 25 | # avoid errors with '-march=i386', and future flags may depend on the target to | 25 | # avoid errors with '-march=i386', and future flags may depend on the target to |
| 26 | # be valid. | 26 | # be valid. |
| 27 | KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) | 27 | KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) |
| 28 | KBUILD_CFLAGS += -std=gnu11 | 28 | KBUILD_CFLAGS += -std=gnu11 -fms-extensions |
| 29 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIE | 29 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIE |
| 30 | KBUILD_CFLAGS += -Wundef | 30 | KBUILD_CFLAGS += -Wundef |
| 31 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING | 31 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| @@ -36,7 +36,10 @@ KBUILD_CFLAGS += -mno-mmx -mno-sse · 4 unmodified lines | |||
| 36 | KBUILD_CFLAGS += -ffreestanding -fshort-wchar | 36 | KBUILD_CFLAGS += -ffreestanding -fshort-wchar |
| 37 | KBUILD_CFLAGS += -fno-stack-protector | 37 | KBUILD_CFLAGS += -fno-stack-protector |
| 38 | KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) | 38 | KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) |
| 39 | KBUILD_CFLAGS += $(call cc-disable-warning, gnu) | 39 | ifdef CONFIG_CC_IS_CLANG |
| 40 | KBUILD_CFLAGS += -Wno-gnu | ||
| 41 | KBUILD_CFLAGS += -Wno-microsoft-anon-tag | ||
| 42 | endif | ||
| 40 | KBUILD_CFLAGS += -Wno-pointer-sign | 43 | KBUILD_CFLAGS += -Wno-pointer-sign |
| 41 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables | 44 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables |
| 42 | KBUILD_CFLAGS += -D__DISABLE_EXPORTS | 45 | KBUILD_CFLAGS += -D__DISABLE_EXPORTS |
| @@ -1463,7 +1463,9 @@ static void __init retbleed_update_mitigation(void) · 1462 unmodified lines | |||
| 1463 | break; | 1463 | break; |
| 1464 | default: | 1464 | default: |
| 1465 | if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF) { | 1465 | if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF) { |
| 1466 | pr_err(RETBLEED_INTEL_MSG); | 1466 | if (retbleed_mitigation != RETBLEED_MITIGATION_NONE) |
| 1467 | pr_err(RETBLEED_INTEL_MSG); | ||
| 1468 | |||
| 1467 | retbleed_mitigation = RETBLEED_MITIGATION_NONE; | 1469 | retbleed_mitigation = RETBLEED_MITIGATION_NONE; |
| 1468 | } | 1470 | } |
| 1469 | } | 1471 | } |
| @@ -1825,13 +1827,6 @@ void unpriv_ebpf_notify(int new_state) · 355 unmodified lines | |||
| 1825 | } | 1827 | } |
| 1826 | #endif | 1828 | #endif |
| 1827 | 1829 | ||
| 1828 | static inline bool match_option(const char *arg, int arglen, const char *opt) | ||
| 1829 | { | ||
| 1830 | int len = strlen(opt); | ||
| 1831 | |||
| 1832 | return len == arglen && !strncmp(arg, opt, len); | ||
| 1833 | } | ||
| 1834 | |||
| 1835 | /* The kernel command line selection for spectre v2 */ | 1830 | /* The kernel command line selection for spectre v2 */ |
| 1836 | enum spectre_v2_mitigation_cmd { | 1831 | enum spectre_v2_mitigation_cmd { |
| 1837 | SPECTRE_V2_CMD_NONE, | 1832 | SPECTRE_V2_CMD_NONE, |
| @@ -194,7 +194,7 @@ static bool need_sha_check(u32 cur_rev) · 193 unmodified lines | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | switch (cur_rev >> 8) { | 196 | switch (cur_rev >> 8) { |
| 197 | case 0x80012: return cur_rev <= 0x800126f; break; | 197 | case 0x80012: return cur_rev <= 0x8001277; break; |
| 198 | case 0x80082: return cur_rev <= 0x800820f; break; | 198 | case 0x80082: return cur_rev <= 0x800820f; break; |
| 199 | case 0x83010: return cur_rev <= 0x830107c; break; | 199 | case 0x83010: return cur_rev <= 0x830107c; break; |
| 200 | case 0x86001: return cur_rev <= 0x860010e; break; | 200 | case 0x86001: return cur_rev <= 0x860010e; break; |
| @@ -458,7 +458,16 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r) · 457 unmodified lines | |||
| 458 | r->mon.mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS; | 458 | r->mon.mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS; |
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | if (rdt_cpu_has(X86_FEATURE_ABMC)) { | 461 | /* |
| 462 | * resctrl assumes a system that supports assignable counters can | ||
| 463 | * switch to "default" mode. Ensure that there is a "default" mode | ||
| 464 | * to switch to. This enforces a dependency between the independent | ||
| 465 | * X86_FEATURE_ABMC and X86_FEATURE_CQM_MBM_TOTAL/X86_FEATURE_CQM_MBM_LOCAL | ||
| 466 | * hardware features. | ||
| 467 | */ | ||
| 468 | if (rdt_cpu_has(X86_FEATURE_ABMC) && | ||
| 469 | (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL) || | ||
| 470 | rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL))) { | ||
| 462 | r->mon.mbm_cntr_assignable = true; | 471 | r->mon.mbm_cntr_assignable = true; |
| 463 | cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx); | 472 | cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx); |
| 464 | r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1; | 473 | r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1; |
| @@ -184,6 +184,16 @@ static int blk_validate_integrity_limits(struct queue_limits *lim) · 183 unmodified lines | |||
| 184 | if (!bi->interval_exp) | 184 | if (!bi->interval_exp) |
| 185 | bi->interval_exp = ilog2(lim->logical_block_size); | 185 | bi->interval_exp = ilog2(lim->logical_block_size); |
| 186 | 186 | ||
| 187 | /* | ||
| 188 | * The PI generation / validation helpers do not expect intervals to | ||
| 189 | * straddle multiple bio_vecs. Enforce alignment so that those are | ||
| 190 | * never generated, and that each buffer is aligned as expected. | ||
| 191 | */ | ||
| 192 | if (bi->csum_type) { | ||
| 193 | lim->dma_alignment = max(lim->dma_alignment, | ||
| 194 | (1U << bi->interval_exp) - 1); | ||
| 195 | } | ||
| 196 | |||
| 187 | return 0; | 197 | return 0; |
| 188 | } | 198 | } |
| 189 | 199 | ||
| @@ -95,6 +95,11 @@ acpi_tb_print_table_header(acpi_physical_address address, · 94 unmodified lines | |||
| 95 | { | 95 | { |
| 96 | struct acpi_table_header local_header; | 96 | struct acpi_table_header local_header; |
| 97 | 97 | ||
| 98 | #pragma GCC diagnostic push | ||
| 99 | #if defined(__GNUC__) && __GNUC__ >= 11 | ||
| 100 | #pragma GCC diagnostic ignored "-Wstringop-overread" | ||
| 101 | #endif | ||
| 102 | |||
| 98 | if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) { | 103 | if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) { |
| 99 | 104 | ||
| 100 | /* FACS only has signature and length fields */ | 105 | /* FACS only has signature and length fields */ |
| @@ -143,4 +148,5 @@ acpi_tb_print_table_header(acpi_physical_address address, · 42 unmodified lines | |||
| 143 | local_header.asl_compiler_id, | 148 | local_header.asl_compiler_id, |
| 144 | local_header.asl_compiler_revision)); | 149 | local_header.asl_compiler_revision)); |
| 145 | } | 150 | } |
| 151 | #pragma GCC diagnostic pop | ||
| 146 | } | 152 | } |
| @@ -1107,7 +1107,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, · 1106 unmodified lines | |||
| 1107 | size_t num_args, | 1107 | size_t num_args, |
| 1108 | struct fwnode_reference_args *args) | 1108 | struct fwnode_reference_args *args) |
| 1109 | { | 1109 | { |
| 1110 | return acpi_fwnode_get_reference_args(fwnode, propname, NULL, index, num_args, args); | 1110 | return acpi_fwnode_get_reference_args(fwnode, propname, NULL, num_args, index, args); |
| 1111 | } | 1111 | } |
| 1112 | EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); | 1112 | EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); |
| 1113 | 1113 | ||
| @@ -61,30 +61,6 @@ static int rimt_set_fwnode(struct acpi_rimt_node *rimt_node, · 60 unmodified lines | |||
| 61 | return 0; | 61 | return 0; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /** | ||
| 65 | * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node | ||
| 66 | * | ||
| 67 | * @node: RIMT table node to be looked-up | ||
| 68 | * | ||
| 69 | * Returns: fwnode_handle pointer on success, NULL on failure | ||
| 70 | */ | ||
| 71 | static struct fwnode_handle *rimt_get_fwnode(struct acpi_rimt_node *node) | ||
| 72 | { | ||
| 73 | struct fwnode_handle *fwnode = NULL; | ||
| 74 | struct rimt_fwnode *curr; | ||
| 75 | |||
| 76 | spin_lock(&rimt_fwnode_lock); | ||
| 77 | list_for_each_entry(curr, &rimt_fwnode_list, list) { | ||
| 78 | if (curr->rimt_node == node) { | ||
| 79 | fwnode = curr->fwnode; | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | spin_unlock(&rimt_fwnode_lock); | ||
| 84 | |||
| 85 | return fwnode; | ||
| 86 | } | ||
| 87 | |||
| 88 | static acpi_status rimt_match_node_callback(struct acpi_rimt_node *node, | 64 | static acpi_status rimt_match_node_callback(struct acpi_rimt_node *node, |
| 89 | void *context) | 65 | void *context) |
| 90 | { | 66 | { |
| @@ -202,6 +178,67 @@ static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type, · 111 unmodified lines | |||
| 202 | return NULL; | 178 | return NULL; |
| 203 | } | 179 | } |
| 204 | 180 | ||
| 181 | /* | ||
| 182 | * RISC-V supports IOMMU as a PCI device or a platform device. | ||
| 183 | * When it is a platform device, there should be a namespace device as | ||
| 184 | * well along with RIMT. To create the link between RIMT information and | ||
| 185 | * the platform device, the IOMMU driver should register itself with the | ||
| 186 | * RIMT module. This is true for PCI based IOMMU as well. | ||
| 187 | */ | ||
| 188 | int rimt_iommu_register(struct device *dev) | ||
| 189 | { | ||
| 190 | struct fwnode_handle *rimt_fwnode; | ||
| 191 | struct acpi_rimt_node *node; | ||
| 192 | |||
| 193 | node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_IOMMU, dev); | ||
| 194 | if (!node) { | ||
| 195 | pr_err("Could not find IOMMU node in RIMT\n"); | ||
| 196 | return -ENODEV; | ||
| 197 | } | ||
| 198 | |||
| 199 | if (dev_is_pci(dev)) { | ||
| 200 | rimt_fwnode = acpi_alloc_fwnode_static(); | ||
| 201 | if (!rimt_fwnode) | ||
| 202 | return -ENOMEM; | ||
| 203 | |||
| 204 | rimt_fwnode->dev = dev; | ||
| 205 | if (!dev->fwnode) | ||
| 206 | dev->fwnode = rimt_fwnode; | ||
| 207 | |||
| 208 | rimt_set_fwnode(node, rimt_fwnode); | ||
| 209 | } else { | ||
| 210 | rimt_set_fwnode(node, dev->fwnode); | ||
| 211 | } | ||
| 212 | |||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | #ifdef CONFIG_IOMMU_API | ||
| 217 | |||
| 218 | /** | ||
| 219 | * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node | ||
| 220 | * | ||
| 221 | * @node: RIMT table node to be looked-up | ||
| 222 | * | ||
| 223 | * Returns: fwnode_handle pointer on success, NULL on failure | ||
| 224 | */ | ||
| 225 | static struct fwnode_handle *rimt_get_fwnode(struct acpi_rimt_node *node) | ||
| 226 | { | ||
| 227 | struct fwnode_handle *fwnode = NULL; | ||
| 228 | struct rimt_fwnode *curr; | ||
| 229 | |||
| 230 | spin_lock(&rimt_fwnode_lock); | ||
| 231 | list_for_each_entry(curr, &rimt_fwnode_list, list) { | ||
| 232 | if (curr->rimt_node == node) { | ||
| 233 | fwnode = curr->fwnode; | ||
| 234 | break; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | spin_unlock(&rimt_fwnode_lock); | ||
| 238 | |||
| 239 | return fwnode; | ||
| 240 | } | ||
| 241 | |||
| 205 | static bool rimt_pcie_rc_supports_ats(struct acpi_rimt_node *node) | 242 | static bool rimt_pcie_rc_supports_ats(struct acpi_rimt_node *node) |
| 206 | { | 243 | { |
| 207 | struct acpi_rimt_pcie_rc *pci_rc; | 244 | struct acpi_rimt_pcie_rc *pci_rc; |
| @@ -290,43 +327,6 @@ static struct acpi_rimt_node *rimt_node_get_id(struct acpi_rimt_node *node, · 82 unmodified lines | |||
| 290 | return NULL; | 327 | return NULL; |
| 291 | } | 328 | } |
| 292 | 329 | ||
| 293 | /* | ||
| 294 | * RISC-V supports IOMMU as a PCI device or a platform device. | ||
| 295 | * When it is a platform device, there should be a namespace device as | ||
| 296 | * well along with RIMT. To create the link between RIMT information and | ||
| 297 | * the platform device, the IOMMU driver should register itself with the | ||
| 298 | * RIMT module. This is true for PCI based IOMMU as well. | ||
| 299 | */ | ||
| 300 | int rimt_iommu_register(struct device *dev) | ||
| 301 | { | ||
| 302 | struct fwnode_handle *rimt_fwnode; | ||
| 303 | struct acpi_rimt_node *node; | ||
| 304 | |||
| 305 | node = rimt_scan_node(ACPI_RIMT_NODE_TYPE_IOMMU, dev); | ||
| 306 | if (!node) { | ||
| 307 | pr_err("Could not find IOMMU node in RIMT\n"); | ||
| 308 | return -ENODEV; | ||
| 309 | } | ||
| 310 | |||
| 311 | if (dev_is_pci(dev)) { | ||
| 312 | rimt_fwnode = acpi_alloc_fwnode_static(); | ||
| 313 | if (!rimt_fwnode) | ||
| 314 | return -ENOMEM; | ||
| 315 | |||
| 316 | rimt_fwnode->dev = dev; | ||
| 317 | if (!dev->fwnode) | ||
| 318 | dev->fwnode = rimt_fwnode; | ||
| 319 | |||
| 320 | rimt_set_fwnode(node, rimt_fwnode); | ||
| 321 | } else { | ||
| 322 | rimt_set_fwnode(node, dev->fwnode); | ||
| 323 | } | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | #ifdef CONFIG_IOMMU_API | ||
| 329 | |||
| 330 | static struct acpi_rimt_node *rimt_node_map_id(struct acpi_rimt_node *node, | 330 | static struct acpi_rimt_node *rimt_node_map_id(struct acpi_rimt_node *node, |
| 331 | u32 id_in, u32 *id_out, | 331 | u32 id_in, u32 *id_out, |
| 332 | u8 type_mask) | 332 | u8 type_mask) |
| @@ -851,17 +851,8 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong, · 850 unmodified lines | |||
| 851 | } else { | 851 | } else { |
| 852 | if (!internal) | 852 | if (!internal) |
| 853 | node->local_weak_refs++; | 853 | node->local_weak_refs++; |
| 854 | if (!node->has_weak_ref && list_empty(&node->work.entry)) { | 854 | if (!node->has_weak_ref && target_list && list_empty(&node->work.entry)) |
| 855 | if (target_list == NULL) { | ||
| 856 | pr_err("invalid inc weak node for %d\n", | ||
| 857 | node->debug_id); | ||
| 858 | return -EINVAL; | ||
| 859 | } | ||
| 860 | /* | ||
| 861 | * See comment above | ||
| 862 | */ | ||
| 863 | binder_enqueue_work_ilocked(&node->work, target_list); | 855 | binder_enqueue_work_ilocked(&node->work, target_list); |
| 864 | } | ||
| 865 | } | 856 | } |
| 866 | return 0; | 857 | return 0; |
| 867 | } | 858 | } |
| @@ -2418,10 +2409,10 @@ err_fd_not_accepted: · 1550 unmodified lines | |||
| 2418 | 2409 | ||
| 2419 | /** | 2410 | /** |
| 2420 | * struct binder_ptr_fixup - data to be fixed-up in target buffer | 2411 | * struct binder_ptr_fixup - data to be fixed-up in target buffer |
| 2421 | * @offset offset in target buffer to fixup | 2412 | * @offset: offset in target buffer to fixup |
| 2422 | * @skip_size bytes to skip in copy (fixup will be written later) | 2413 | * @skip_size: bytes to skip in copy (fixup will be written later) |
| 2423 | * @fixup_data data to write at fixup offset | 2414 | * @fixup_data: data to write at fixup offset |
| 2424 | * @node list node | 2415 | * @node: list node |
| 2425 | * | 2416 | * |
| 2426 | * This is used for the pointer fixup list (pf) which is created and consumed | 2417 | * This is used for the pointer fixup list (pf) which is created and consumed |
| 2427 | * during binder_transaction() and is only accessed locally. No | 2418 | * during binder_transaction() and is only accessed locally. No |
| @@ -2438,10 +2429,10 @@ struct binder_ptr_fixup { · 10 unmodified lines | |||
| 2438 | 2429 | ||
| 2439 | /** | 2430 | /** |
| 2440 | * struct binder_sg_copy - scatter-gather data to be copied | 2431 | * struct binder_sg_copy - scatter-gather data to be copied |
| 2441 | * @offset offset in target buffer | 2432 | * @offset: offset in target buffer |
| 2442 | * @sender_uaddr user address in source buffer | 2433 | * @sender_uaddr: user address in source buffer |
| 2443 | * @length bytes to copy | 2434 | * @length: bytes to copy |
| 2444 | * @node list node | 2435 | * @node: list node |
| 2445 | * | 2436 | * |
| 2446 | * This is used for the sg copy list (sgc) which is created and consumed | 2437 | * This is used for the sg copy list (sgc) which is created and consumed |
| 2447 | * during binder_transaction() and is only accessed locally. No | 2438 | * during binder_transaction() and is only accessed locally. No |
| @@ -4063,14 +4054,15 @@ binder_freeze_notification_done(struct binder_proc *proc, · 1615 unmodified lines | |||
| 4063 | 4054 | ||
| 4064 | /** | 4055 | /** |
| 4065 | * binder_free_buf() - free the specified buffer | 4056 | * binder_free_buf() - free the specified buffer |
| 4066 | * @proc: binder proc that owns buffer | 4057 | * @proc: binder proc that owns buffer |
| 4067 | * @buffer: buffer to be freed | 4058 | * @thread: binder thread performing the buffer release |
| 4068 | * @is_failure: failed to send transaction | 4059 | * @buffer: buffer to be freed |
| 4060 | * @is_failure: failed to send transaction | ||
| 4069 | * | 4061 | * |
| 4070 | * If buffer for an async transaction, enqueue the next async | 4062 | * If the buffer is for an async transaction, enqueue the next async |
| 4071 | * transaction from the node. | 4063 | * transaction from the node. |
| 4072 | * | 4064 | * |
| 4073 | * Cleanup buffer and free it. | 4065 | * Cleanup the buffer and free it. |
| 4074 | */ | 4066 | */ |
| 4075 | static void | 4067 | static void |
| 4076 | binder_free_buf(struct binder_proc *proc, | 4068 | binder_free_buf(struct binder_proc *proc, |
| @@ -106,13 +106,22 @@ impl DeliverToRead for FreezeMessage { · 105 unmodified lines | |||
| 106 | return Ok(true); | 106 | return Ok(true); |
| 107 | } | 107 | } |
| 108 | if freeze.is_clearing { | 108 | if freeze.is_clearing { |
| 109 | _removed_listener = freeze_entry.remove_node(); | 109 | kernel::warn_on!(freeze.num_cleared_duplicates != 0); |
| 110 | if freeze.num_pending_duplicates > 0 { | ||
| 111 | // The primary freeze listener was deleted, so convert a pending duplicate back | ||
| 112 | // into the primary one. | ||
| 113 | freeze.num_pending_duplicates -= 1; | ||
| 114 | freeze.is_pending = true; | ||
| 115 | freeze.is_clearing = true; | ||
| 116 | } else { | ||
| 117 | _removed_listener = freeze_entry.remove_node(); | ||
| 118 | } | ||
| 110 | drop(node_refs); | 119 | drop(node_refs); |
| 111 | writer.write_code(BR_CLEAR_FREEZE_NOTIFICATION_DONE)?; | 120 | writer.write_code(BR_CLEAR_FREEZE_NOTIFICATION_DONE)?; |
| 112 | writer.write_payload(&self.cookie.0)?; | 121 | writer.write_payload(&self.cookie.0)?; |
| 113 | Ok(true) | 122 | Ok(true) |
| 114 | } else { | 123 | } else { |
| 115 | let is_frozen = freeze.node.owner.inner.lock().is_frozen; | 124 | let is_frozen = freeze.node.owner.inner.lock().is_frozen.is_fully_frozen(); |
| 116 | if freeze.last_is_frozen == Some(is_frozen) { | 125 | if freeze.last_is_frozen == Some(is_frozen) { |
| 117 | return Ok(true); | 126 | return Ok(true); |
| 118 | } | 127 | } |
| @@ -245,8 +254,9 @@ impl Process { · 126 unmodified lines | |||
| 245 | ); | 254 | ); |
| 246 | return Err(EINVAL); | 255 | return Err(EINVAL); |
| 247 | } | 256 | } |
| 248 | if freeze.is_clearing { | 257 | let is_frozen = freeze.node.owner.inner.lock().is_frozen.is_fully_frozen(); |
| 249 | // Immediately send another FreezeMessage for BR_CLEAR_FREEZE_NOTIFICATION_DONE. | 258 | if freeze.is_clearing || freeze.last_is_frozen != Some(is_frozen) { |
| 259 | // Immediately send another FreezeMessage. | ||
| 250 | clear_msg = Some(FreezeMessage::init(alloc, cookie)); | 260 | clear_msg = Some(FreezeMessage::init(alloc, cookie)); |
| 251 | } | 261 | } |
| 252 | freeze.is_pending = false; | 262 | freeze.is_pending = false; |
| @@ -687,7 +687,7 @@ impl Node { · 686 unmodified lines | |||
| 687 | ); | 687 | ); |
| 688 | } | 688 | } |
| 689 | if inner.freeze_list.is_empty() { | 689 | if inner.freeze_list.is_empty() { |
| 690 | _unused_capacity = mem::replace(&mut inner.freeze_list, KVVec::new()); | 690 | _unused_capacity = mem::take(&mut inner.freeze_list); |
| 691 | } | 691 | } |
| 692 | } | 692 | } |
| 693 | 693 | ||
| @@ -72,6 +72,33 @@ impl Mapping { · 71 unmodified lines | |||
| 72 | const PROC_DEFER_FLUSH: u8 = 1; | 72 | const PROC_DEFER_FLUSH: u8 = 1; |
| 73 | const PROC_DEFER_RELEASE: u8 = 2; | 73 | const PROC_DEFER_RELEASE: u8 = 2; |
| 74 | 74 | ||
| 75 | #[derive(Copy, Clone)] | ||
| 76 | pub(crate) enum IsFrozen { | ||
| 77 | Yes, | ||
| 78 | No, | ||
| 79 | InProgress, | ||
| 80 | } | ||
| 81 | |||
| 82 | impl IsFrozen { | ||
| 83 | /// Whether incoming transactions should be rejected due to freeze. | ||
| 84 | pub(crate) fn is_frozen(self) -> bool { | ||
| 85 | match self { | ||
| 86 | IsFrozen::Yes => true, | ||
| 87 | IsFrozen::No => false, | ||
| 88 | IsFrozen::InProgress => true, | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | /// Whether freeze notifications consider this process frozen. | ||
| 93 | pub(crate) fn is_fully_frozen(self) -> bool { | ||
| 94 | match self { | ||
| 95 | IsFrozen::Yes => true, | ||
| 96 | IsFrozen::No => false, | ||
| 97 | IsFrozen::InProgress => false, | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 75 | /// The fields of `Process` protected by the spinlock. | 102 | /// The fields of `Process` protected by the spinlock. |
| 76 | pub(crate) struct ProcessInner { | 103 | pub(crate) struct ProcessInner { |
| 77 | is_manager: bool, | 104 | is_manager: bool, |
| @@ -98,7 +125,7 @@ pub(crate) struct ProcessInner { · 20 unmodified lines | |||
| 98 | /// are woken up. | 125 | /// are woken up. |
| 99 | outstanding_txns: u32, | 126 | outstanding_txns: u32, |
| 100 | /// Process is frozen and unable to service binder transactions. | 127 | /// Process is frozen and unable to service binder transactions. |
| 101 | pub(crate) is_frozen: bool, | 128 | pub(crate) is_frozen: IsFrozen, |
| 102 | /// Process received sync transactions since last frozen. | 129 | /// Process received sync transactions since last frozen. |
| 103 | pub(crate) sync_recv: bool, | 130 | pub(crate) sync_recv: bool, |
| 104 | /// Process received async transactions since last frozen. | 131 | /// Process received async transactions since last frozen. |
| @@ -124,7 +151,7 @@ impl ProcessInner { · 19 unmodified lines | |||
| 124 | started_thread_count: 0, | 151 | started_thread_count: 0, |
| 125 | defer_work: 0, | 152 | defer_work: 0, |
| 126 | outstanding_txns: 0, | 153 | outstanding_txns: 0, |
| 127 | is_frozen: false, | 154 | is_frozen: IsFrozen::No, |
| 128 | sync_recv: false, | 155 | sync_recv: false, |
| 129 | async_recv: false, | 156 | async_recv: false, |
| 130 | binderfs_file: None, | 157 | binderfs_file: None, |
| @@ -1260,7 +1287,7 @@ impl Process { · 1129 unmodified lines | |||
| 1260 | let is_manager = { | 1287 | let is_manager = { |
| 1261 | let mut inner = self.inner.lock(); | 1288 | let mut inner = self.inner.lock(); |
| 1262 | inner.is_dead = true; | 1289 | inner.is_dead = true; |
| 1263 | inner.is_frozen = false; | 1290 | inner.is_frozen = IsFrozen::No; |
| 1264 | inner.sync_recv = false; | 1291 | inner.sync_recv = false; |
| 1265 | inner.async_recv = false; | 1292 | inner.async_recv = false; |
| 1266 | inner.is_manager | 1293 | inner.is_manager |
| @@ -1346,10 +1373,6 @@ impl Process { · 79 unmodified lines | |||
| 1346 | .alloc | 1373 | .alloc |
| 1347 | .take_for_each(|offset, size, debug_id, odata| { | 1374 | .take_for_each(|offset, size, debug_id, odata| { |
| 1348 | let ptr = offset + address; | 1375 | let ptr = offset + address; |
| 1349 | pr_warn!( | ||
| 1350 | "{}: removing orphan mapping {offset}:{size}\n", | ||
| 1351 | self.pid_in_current_ns() | ||
| 1352 | ); | ||
| 1353 | let mut alloc = | 1376 | let mut alloc = |
| 1354 | Allocation::new(self.clone(), debug_id, offset, size, ptr, false); | 1377 | Allocation::new(self.clone(), debug_id, offset, size, ptr, false); |
| 1355 | if let Some(data) = odata { | 1378 | if let Some(data) = odata { |
| @@ -1371,7 +1394,7 @@ impl Process { · 15 unmodified lines | |||
| 1371 | return; | 1394 | return; |
| 1372 | } | 1395 | } |
| 1373 | inner.outstanding_txns -= 1; | 1396 | inner.outstanding_txns -= 1; |
| 1374 | inner.is_frozen && inner.outstanding_txns == 0 | 1397 | inner.is_frozen.is_frozen() && inner.outstanding_txns == 0 |
| 1375 | }; | 1398 | }; |
| 1376 | 1399 | ||
| 1377 | if wake { | 1400 | if wake { |
| @@ -1385,7 +1408,7 @@ impl Process { · 7 unmodified lines | |||
| 1385 | let mut inner = self.inner.lock(); | 1408 | let mut inner = self.inner.lock(); |
| 1386 | inner.sync_recv = false; | 1409 | inner.sync_recv = false; |
| 1387 | inner.async_recv = false; | 1410 | inner.async_recv = false; |
| 1388 | inner.is_frozen = false; | 1411 | inner.is_frozen = IsFrozen::No; |
| 1389 | drop(inner); | 1412 | drop(inner); |
| 1390 | msgs.send_messages(); | 1413 | msgs.send_messages(); |
| 1391 | return Ok(()); | 1414 | return Ok(()); |
| @@ -1394,7 +1417,7 @@ impl Process { · 2 unmodified lines | |||
| 1394 | let mut inner = self.inner.lock(); | 1417 | let mut inner = self.inner.lock(); |
| 1395 | inner.sync_recv = false; | 1418 | inner.sync_recv = false; |
| 1396 | inner.async_recv = false; | 1419 | inner.async_recv = false; |
| 1397 | inner.is_frozen = true; | 1420 | inner.is_frozen = IsFrozen::InProgress; |
| 1398 | 1421 | ||
| 1399 | if info.timeout_ms > 0 { | 1422 | if info.timeout_ms > 0 { |
| 1400 | let mut jiffies = kernel::time::msecs_to_jiffies(info.timeout_ms); | 1423 | let mut jiffies = kernel::time::msecs_to_jiffies(info.timeout_ms); |
| @@ -1408,7 +1431,7 @@ impl Process { · 7 unmodified lines | |||
| 1408 | .wait_interruptible_timeout(&mut inner, jiffies) | 1431 | .wait_interruptible_timeout(&mut inner, jiffies) |
| 1409 | { | 1432 | { |
| 1410 | CondVarTimeoutResult::Signal { .. } => { | 1433 | CondVarTimeoutResult::Signal { .. } => { |
| 1411 | inner.is_frozen = false; | 1434 | inner.is_frozen = IsFrozen::No; |
| 1412 | return Err(ERESTARTSYS); | 1435 | return Err(ERESTARTSYS); |
| 1413 | } | 1436 | } |
| 1414 | CondVarTimeoutResult::Woken { jiffies: remaining } => { | 1437 | CondVarTimeoutResult::Woken { jiffies: remaining } => { |
| @@ -1422,17 +1445,18 @@ impl Process { · 7 unmodified lines | |||
| 1422 | } | 1445 | } |
| 1423 | 1446 | ||
| 1424 | if inner.txns_pending_locked() { | 1447 | if inner.txns_pending_locked() { |
| 1425 | inner.is_frozen = false; | 1448 | inner.is_frozen = IsFrozen::No; |
| 1426 | Err(EAGAIN) | 1449 | Err(EAGAIN) |
| 1427 | } else { | 1450 | } else { |
| 1428 | drop(inner); | 1451 | drop(inner); |
| 1429 | match self.prepare_freeze_messages() { | 1452 | match self.prepare_freeze_messages() { |
| 1430 | Ok(batch) => { | 1453 | Ok(batch) => { |
| 1454 | self.inner.lock().is_frozen = IsFrozen::Yes; | ||
| 1431 | batch.send_messages(); | 1455 | batch.send_messages(); |
| 1432 | Ok(()) | 1456 | Ok(()) |
| 1433 | } | 1457 | } |
| 1434 | Err(kernel::alloc::AllocError) => { | 1458 | Err(kernel::alloc::AllocError) => { |
| 1435 | self.inner.lock().is_frozen = false; | 1459 | self.inner.lock().is_frozen = IsFrozen::No; |
| 1436 | Err(ENOMEM) | 1460 | Err(ENOMEM) |
| 1437 | } | 1461 | } |
| 1438 | } | 1462 | } |
| @@ -249,7 +249,7 @@ impl Transaction { · 248 unmodified lines | |||
| 249 | 249 | ||
| 250 | if oneway { | 250 | if oneway { |
| 251 | if let Some(target_node) = self.target_node.clone() { | 251 | if let Some(target_node) = self.target_node.clone() { |
| 252 | if process_inner.is_frozen { | 252 | if process_inner.is_frozen.is_frozen() { |
| 253 | process_inner.async_recv = true; | 253 | process_inner.async_recv = true; |
| 254 | if self.flags & TF_UPDATE_TXN != 0 { | 254 | if self.flags & TF_UPDATE_TXN != 0 { |
| 255 | if let Some(t_outdated) = | 255 | if let Some(t_outdated) = |
| @@ -270,7 +270,7 @@ impl Transaction { · 14 unmodified lines | |||
| 270 | } | 270 | } |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | if process_inner.is_frozen { | 273 | if process_inner.is_frozen.is_frozen() { |
| 274 | return Err(BinderError::new_frozen_oneway()); | 274 | return Err(BinderError::new_frozen_oneway()); |
| 275 | } else { | 275 | } else { |
| 276 | return Ok(()); | 276 | return Ok(()); |
| @@ -280,7 +280,7 @@ impl Transaction { · 3 unmodified lines | |||
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | if process_inner.is_frozen { | 283 | if process_inner.is_frozen.is_frozen() { |
| 284 | process_inner.sync_recv = true; | 284 | process_inner.sync_recv = true; |
| 285 | return Err(BinderError::new_frozen()); | 285 | return Err(BinderError::new_frozen()); |
| 286 | } | 286 | } |
| @@ -292,7 +292,7 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu) · 291 unmodified lines | |||
| 292 | * frequency (by keeping the initial capacity_freq_ref value). | 292 | * frequency (by keeping the initial capacity_freq_ref value). |
| 293 | */ | 293 | */ |
| 294 | cpu_clk = of_clk_get(cpu_node, 0); | 294 | cpu_clk = of_clk_get(cpu_node, 0); |
| 295 | if (!PTR_ERR_OR_ZERO(cpu_clk)) { | 295 | if (!IS_ERR_OR_NULL(cpu_clk)) { |
| 296 | per_cpu(capacity_freq_ref, cpu) = | 296 | per_cpu(capacity_freq_ref, cpu) = |
| 297 | clk_get_rate(cpu_clk) / HZ_PER_KHZ; | 297 | clk_get_rate(cpu_clk) / HZ_PER_KHZ; |
| 298 | clk_put(cpu_clk); | 298 | clk_put(cpu_clk); |
| @@ -1784,7 +1784,7 @@ static int fw_devlink_dev_sync_state(struct device *dev, void *data) · 1783 unmodified lines | |||
| 1784 | return 0; | 1784 | return 0; |
| 1785 | 1785 | ||
| 1786 | if (fw_devlink_sync_state == FW_DEVLINK_SYNC_STATE_STRICT) { | 1786 | if (fw_devlink_sync_state == FW_DEVLINK_SYNC_STATE_STRICT) { |
| 1787 | dev_warn(sup, "sync_state() pending due to %s\n", | 1787 | dev_info(sup, "sync_state() pending due to %s\n", |
| 1788 | dev_name(link->consumer)); | 1788 | dev_name(link->consumer)); |
| 1789 | return 0; | 1789 | return 0; |
| 1790 | } | 1790 | } |
| @@ -23,50 +23,46 @@ struct devcd_entry { · 22 unmodified lines | |||
| 23 | void *data; | 23 | void *data; |
| 24 | size_t datalen; | 24 | size_t datalen; |
| 25 | /* | 25 | /* |
| 26 | * Here, mutex is required to serialize the calls to del_wk work between | 26 | * There are 2 races for which mutex is required. |
| 27 | * user/kernel space which happens when devcd is added with device_add() | ||
| 28 | * and that sends uevent to user space. User space reads the uevents, | ||
| 29 | * and calls to devcd_data_write() which try to modify the work which is | ||
| 30 | * not even initialized/queued from devcoredump. | ||
| 31 | * | 27 | * |
| 28 | * The first race is between device creation and userspace writing to | ||
| 29 | * schedule immediately destruction. | ||
| 32 | * | 30 | * |
| 31 | * This race is handled by arming the timer before device creation, but | ||
| 32 | * when device creation fails the timer still exists. | ||
| 33 | * | 33 | * |
| 34 | * cpu0(X) cpu1(Y) | 34 | * To solve this, hold the mutex during device_add(), and set |
| 35 | * init_completed on success before releasing the mutex. | ||
| 35 | * | 36 | * |
| 36 | * dev_coredump() uevent sent to user space | 37 | * That way the timer will never fire until device_add() is called, |
| 37 | * device_add() ======================> user space process Y reads the | 38 | * it will do nothing if init_completed is not set. The timer is also |
| 38 | * uevents writes to devcd fd | 39 | * cancelled in that case. |
| 39 | * which results into writes to | ||
| 40 | * | 40 | * |
| 41 | * devcd_data_write() | 41 | * The second race involves multiple parallel invocations of devcd_free(), |
| 42 | * mod_delayed_work() | 42 | * add a deleted flag so only 1 can call the destructor. |
| 43 | * try_to_grab_pending() | ||
| 44 | * timer_delete() | ||
| 45 | * debug_assert_init() | ||
| 46 | * INIT_DELAYED_WORK() | ||
| 47 | * schedule_delayed_work() | ||
| 48 | * | ||
| 49 | * | ||
| 50 | * Also, mutex alone would not be enough to avoid scheduling of | ||
| 51 | * del_wk work after it get flush from a call to devcd_free() | ||
| 52 | * mentioned as below. | ||
| 53 | * | ||
| 54 | * disabled_store() | ||
| 55 | * devcd_free() | ||
| 56 | * mutex_lock() devcd_data_write() | ||
| 57 | * flush_delayed_work() | ||
| 58 | * mutex_unlock() | ||
| 59 | * mutex_lock() | ||
| 60 | * mod_delayed_work() | ||
| 61 | * mutex_unlock() | ||
| 62 | * So, delete_work flag is required. | ||
| 63 | */ | 43 | */ |
| 64 | struct mutex mutex; | 44 | struct mutex mutex; |
| 65 | bool delete_work; | 45 | bool init_completed, deleted; |
| 66 | struct module *owner; | 46 | struct module *owner; |
| 67 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, | 47 | ssize_t (*read)(char *buffer, loff_t offset, size_t count, |
| 68 | void *data, size_t datalen); | 48 | void *data, size_t datalen); |
| 69 | void (*free)(void *data); | 49 | void (*free)(void *data); |
| 50 | /* | ||
| 51 | * If nothing interferes and device_add() was returns success, | ||
| 52 | * del_wk will destroy the device after the timer fires. | ||
| 53 | * | ||
| 54 | * Multiple userspace processes can interfere in the working of the timer: | ||
| 55 | * - Writing to the coredump will reschedule the timer to run immediately, | ||
| 56 | * if still armed. | ||
| 57 | * | ||
| 58 | * This is handled by using "if (cancel_delayed_work()) { | ||
| 59 | * schedule_delayed_work() }", to prevent re-arming after having | ||
| 60 | * been previously fired. | ||
| 61 | * - Writing to /sys/class/devcoredump/disabled will destroy the | ||
| 62 | * coredump synchronously. | ||
| 63 | * This is handled by using disable_delayed_work_sync(), and then | ||
| 64 | * checking if deleted flag is set with &devcd->mutex held. | ||
| 65 | */ | ||
| 70 | struct delayed_work del_wk; | 66 | struct delayed_work del_wk; |
| 71 | struct device *failing_dev; | 67 | struct device *failing_dev; |
| 72 | }; | 68 | }; |
| @@ -95,14 +91,27 @@ static void devcd_dev_release(struct device *dev) · 22 unmodified lines | |||
| 95 | kfree(devcd); | 91 | kfree(devcd); |
| 96 | } | 92 | } |
| 97 | 93 | ||
| 94 | static void __devcd_del(struct devcd_entry *devcd) | ||
| 95 | { | ||
| 96 | devcd->deleted = true; | ||
| 97 | device_del(&devcd->devcd_dev); | ||
| 98 | put_device(&devcd->devcd_dev); | ||
| 99 | } | ||
| 100 | |||
| 98 | static void devcd_del(struct work_struct *wk) | 101 | static void devcd_del(struct work_struct *wk) |
| 99 | { | 102 | { |
| 100 | struct devcd_entry *devcd; | 103 | struct devcd_entry *devcd; |
| 104 | bool init_completed; | ||
| 101 | 105 | ||
| 102 | devcd = container_of(wk, struct devcd_entry, del_wk.work); | 106 | devcd = container_of(wk, struct devcd_entry, del_wk.work); |
| 103 | 107 | ||
| 104 | device_del(&devcd->devcd_dev); | 108 | /* devcd->mutex serializes against dev_coredumpm_timeout */ |
| 105 | put_device(&devcd->devcd_dev); | 109 | mutex_lock(&devcd->mutex); |
| 110 | init_completed = devcd->init_completed; | ||
| 111 | mutex_unlock(&devcd->mutex); | ||
| 112 | |||
| 113 | if (init_completed) | ||
| 114 | __devcd_del(devcd); | ||
| 106 | } | 115 | } |
| 107 | 116 | ||
| 108 | static ssize_t devcd_data_read(struct file *filp, struct kobject *kobj, | 117 | static ssize_t devcd_data_read(struct file *filp, struct kobject *kobj, |
| @@ -122,12 +131,12 @@ static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj, · 13 unmodified lines | |||
| 122 | struct device *dev = kobj_to_dev(kobj); | 131 | struct device *dev = kobj_to_dev(kobj); |
| 123 | struct devcd_entry *devcd = dev_to_devcd(dev); | 132 | struct devcd_entry *devcd = dev_to_devcd(dev); |
| 124 | 133 | ||
| 125 | mutex_lock(&devcd->mutex); | 134 | /* |
| 126 | if (!devcd->delete_work) { | 135 | * Although it's tempting to use mod_delayed work here, |
| 127 | devcd->delete_work = true; | 136 | * that will cause a reschedule if the timer already fired. |
| 128 | mod_delayed_work(system_wq, &devcd->del_wk, 0); | 137 | */ |
| 129 | } | 138 | if (cancel_delayed_work(&devcd->del_wk)) |
| 130 | mutex_unlock(&devcd->mutex); | 139 | schedule_delayed_work(&devcd->del_wk, 0); |
| 131 | 140 | ||
| 132 | return count; | 141 | return count; |
| 133 | } | 142 | } |
| @@ -151,11 +160,21 @@ static int devcd_free(struct device *dev, void *data) · 17 unmodified lines | |||
| 151 | { | 160 | { |
| 152 | struct devcd_entry *devcd = dev_to_devcd(dev); | 161 | struct devcd_entry *devcd = dev_to_devcd(dev); |
| 153 | 162 | ||
| 163 | /* | ||
| 164 | * To prevent a race with devcd_data_write(), disable work and | ||
| 165 | * complete manually instead. | ||
| 166 | * | ||
| 167 | * We cannot rely on the return value of | ||
| 168 | * disable_delayed_work_sync() here, because it might be in the | ||
| 169 | * middle of a cancel_delayed_work + schedule_delayed_work pair. | ||
| 170 | * | ||
| 171 | * devcd->mutex here guards against multiple parallel invocations | ||
| 172 | * of devcd_free(). | ||
| 173 | */ | ||
| 174 | disable_delayed_work_sync(&devcd->del_wk); | ||
| 154 | mutex_lock(&devcd->mutex); | 175 | mutex_lock(&devcd->mutex); |
| 155 | if (!devcd->delete_work) | 176 | if (!devcd->deleted) |
| 156 | devcd->delete_work = true; | 177 | __devcd_del(devcd); |
| 157 | |||
| 158 | flush_delayed_work(&devcd->del_wk); | ||
| 159 | mutex_unlock(&devcd->mutex); | 178 | mutex_unlock(&devcd->mutex); |
| 160 | return 0; | 179 | return 0; |
| 161 | } | 180 | } |
| @@ -179,12 +198,10 @@ static ssize_t disabled_show(const struct class *class, const struct class_attri · 17 unmodified lines | |||
| 179 | * put_device() <- last reference | 198 | * put_device() <- last reference |
| 180 | * error = fn(dev, data) devcd_dev_release() | 199 | * error = fn(dev, data) devcd_dev_release() |
| 181 | * devcd_free(dev, data) kfree(devcd) | 200 | * devcd_free(dev, data) kfree(devcd) |
| 182 | * mutex_lock(&devcd->mutex); | ||
| 183 | * | 201 | * |
| 184 | * | 202 | * |
| 185 | * In the above diagram, it looks like disabled_store() would be racing with parallelly | 203 | * In the above diagram, it looks like disabled_store() would be racing with parallelly |
| 186 | * running devcd_del() and result in memory abort while acquiring devcd->mutex which | 204 | * running devcd_del() and result in memory abort after dropping its last reference with |
| 187 | * is called after kfree of devcd memory after dropping its last reference with | ||
| 188 | * put_device(). However, this will not happens as fn(dev, data) runs | 205 | * put_device(). However, this will not happens as fn(dev, data) runs |
| 189 | * with its own reference to device via klist_node so it is not its last reference. | 206 | * with its own reference to device via klist_node so it is not its last reference. |
| 190 | * so, above situation would not occur. | 207 | * so, above situation would not occur. |
| @@ -374,7 +391,7 @@ void dev_coredumpm_timeout(struct device *dev, struct module *owner, · 183 unmodified lines | |||
| 374 | devcd->read = read; | 391 | devcd->read = read; |
| 375 | devcd->free = free; | 392 | devcd->free = free; |
| 376 | devcd->failing_dev = get_device(dev); | 393 | devcd->failing_dev = get_device(dev); |
| 377 | devcd->delete_work = false; | 394 | devcd->deleted = false; |
| 378 | 395 | ||
| 379 | mutex_init(&devcd->mutex); | 396 | mutex_init(&devcd->mutex); |
| 380 | device_initialize(&devcd->devcd_dev); | 397 | device_initialize(&devcd->devcd_dev); |
| @@ -383,8 +400,14 @@ void dev_coredumpm_timeout(struct device *dev, struct module *owner, · 2 unmodified lines | |||
| 383 | atomic_inc_return(&devcd_count)); | 400 | atomic_inc_return(&devcd_count)); |
| 384 | devcd->devcd_dev.class = &devcd_class; | 401 | devcd->devcd_dev.class = &devcd_class; |
| 385 | 402 | ||
| 386 | mutex_lock(&devcd->mutex); | ||
| 387 | dev_set_uevent_suppress(&devcd->devcd_dev, true); | 403 | dev_set_uevent_suppress(&devcd->devcd_dev, true); |
| 404 | |||
| 405 | /* devcd->mutex prevents devcd_del() completing until init finishes */ | ||
| 406 | mutex_lock(&devcd->mutex); | ||
| 407 | devcd->init_completed = false; | ||
| 408 | INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); | ||
| 409 | schedule_delayed_work(&devcd->del_wk, timeout); | ||
| 410 | |||
| 388 | if (device_add(&devcd->devcd_dev)) | 411 | if (device_add(&devcd->devcd_dev)) |
| 389 | goto put_device; | 412 | goto put_device; |
| 390 | 413 | ||
| @@ -401,13 +424,20 @@ void dev_coredumpm_timeout(struct device *dev, struct module *owner, · 10 unmodified lines | |||
| 401 | 424 | ||
| 402 | dev_set_uevent_suppress(&devcd->devcd_dev, false); | 425 | dev_set_uevent_suppress(&devcd->devcd_dev, false); |
| 403 | kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); | 426 | kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); |
| 404 | INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); | 427 | |
| 405 | schedule_delayed_work(&devcd->del_wk, timeout); | 428 | /* |
| 429 | * Safe to run devcd_del() now that we are done with devcd_dev. | ||
| 430 | * Alternatively we could have taken a ref on devcd_dev before | ||
| 431 | * dropping the lock. | ||
| 432 | */ | ||
| 433 | devcd->init_completed = true; | ||
| 406 | mutex_unlock(&devcd->mutex); | 434 | mutex_unlock(&devcd->mutex); |
| 407 | return; | 435 | return; |
| 408 | put_device: | 436 | put_device: |
| 409 | put_device(&devcd->devcd_dev); | ||
| 410 | mutex_unlock(&devcd->mutex); | 437 | mutex_unlock(&devcd->mutex); |
| 438 | cancel_delayed_work_sync(&devcd->del_wk); | ||
| 439 | put_device(&devcd->devcd_dev); | ||
| 440 | |||
| 411 | put_module: | 441 | put_module: |
| 412 | module_put(owner); | 442 | module_put(owner); |
| 413 | free: | 443 | free: |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | |||
| 52 | static DEFINE_IDR(nbd_index_idr); | 52 | static DEFINE_IDR(nbd_index_idr); |
| 53 | static DEFINE_MUTEX(nbd_index_mutex); | 53 | static DEFINE_MUTEX(nbd_index_mutex); |
| 54 | static struct workqueue_struct *nbd_del_wq; | 54 | static struct workqueue_struct *nbd_del_wq; |
| 55 | static struct cred *nbd_cred; | ||
| 55 | static int nbd_total_devices = 0; | 56 | static int nbd_total_devices = 0; |
| 56 | 57 | ||
| 57 | struct nbd_sock { | 58 | struct nbd_sock { |
| @@ -554,6 +555,7 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, · 496 unmodified lines | |||
| 554 | int result; | 555 | int result; |
| 555 | struct msghdr msg = {} ; | 556 | struct msghdr msg = {} ; |
| 556 | unsigned int noreclaim_flag; | 557 | unsigned int noreclaim_flag; |
| 558 | const struct cred *old_cred; | ||
| 557 | 559 | ||
| 558 | if (unlikely(!sock)) { | 560 | if (unlikely(!sock)) { |
| 559 | dev_err_ratelimited(disk_to_dev(nbd->disk), | 561 | dev_err_ratelimited(disk_to_dev(nbd->disk), |
| @@ -562,6 +564,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, · 2 unmodified lines | |||
| 562 | return -EINVAL; | 564 | return -EINVAL; |
| 563 | } | 565 | } |
| 564 | 566 | ||
| 567 | old_cred = override_creds(nbd_cred); | ||
| 568 | |||
| 565 | msg.msg_iter = *iter; | 569 | msg.msg_iter = *iter; |
| 566 | 570 | ||
| 567 | noreclaim_flag = memalloc_noreclaim_save(); | 571 | noreclaim_flag = memalloc_noreclaim_save(); |
| @@ -586,6 +590,8 @@ static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, · 18 unmodified lines | |||
| 586 | 590 | ||
| 587 | memalloc_noreclaim_restore(noreclaim_flag); | 591 | memalloc_noreclaim_restore(noreclaim_flag); |
| 588 | 592 | ||
| 593 | revert_creds(old_cred); | ||
| 594 | |||
| 589 | return result; | 595 | return result; |
| 590 | } | 596 | } |
| 591 | 597 | ||
| @@ -2677,7 +2683,15 @@ static int __init nbd_init(void) · 2085 unmodified lines | |||
| 2677 | return -ENOMEM; | 2683 | return -ENOMEM; |
| 2678 | } | 2684 | } |
| 2679 | 2685 | ||
| 2686 | nbd_cred = prepare_kernel_cred(&init_task); | ||
| 2687 | if (!nbd_cred) { | ||
| 2688 | destroy_workqueue(nbd_del_wq); | ||
| 2689 | unregister_blkdev(NBD_MAJOR, "nbd"); | ||
| 2690 | return -ENOMEM; | ||
| 2691 | } | ||
| 2692 | |||
| 2680 | if (genl_register_family(&nbd_genl_family)) { | 2693 | if (genl_register_family(&nbd_genl_family)) { |
| 2694 | put_cred(nbd_cred); | ||
| 2681 | destroy_workqueue(nbd_del_wq); | 2695 | destroy_workqueue(nbd_del_wq); |
| 2682 | unregister_blkdev(NBD_MAJOR, "nbd"); | 2696 | unregister_blkdev(NBD_MAJOR, "nbd"); |
| 2683 | return -EINVAL; | 2697 | return -EINVAL; |
| @@ -2732,6 +2746,7 @@ static void __exit nbd_cleanup(void) · 48 unmodified lines | |||
| 2732 | /* Also wait for nbd_dev_remove_work() completes */ | 2746 | /* Also wait for nbd_dev_remove_work() completes */ |
| 2733 | destroy_workqueue(nbd_del_wq); | 2747 | destroy_workqueue(nbd_del_wq); |
| 2734 | 2748 | ||
| 2749 | put_cred(nbd_cred); | ||
| 2735 | idr_destroy(&nbd_index_idr); | 2750 | idr_destroy(&nbd_index_idr); |
| 2736 | unregister_blkdev(NBD_MAJOR, "nbd"); | 2751 | unregister_blkdev(NBD_MAJOR, "nbd"); |
| 2737 | } | 2752 | } |
| @@ -317,7 +317,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, · 316 unmodified lines | |||
| 317 | unsigned int count = 0; | 317 | unsigned int count = 0; |
| 318 | const unsigned int num_sample_bytes = comedi_bytes_per_sample(s); | 318 | const unsigned int num_sample_bytes = comedi_bytes_per_sample(s); |
| 319 | 319 | ||
| 320 | if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { | 320 | if (!s->munge || (async->cmd.flags & CMDF_RAWDATA) || async->cmd.chanlist_len == 0) { |
| 321 | async->munge_count += num_bytes; | 321 | async->munge_count += num_bytes; |
| 322 | return num_bytes; | 322 | return num_bytes; |
| 323 | } | 323 | } |
| @@ -1614,7 +1614,11 @@ static int amd_pstate_cpu_offline(struct cpufreq_policy *policy) · 1613 unmodified lines | |||
| 1614 | * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the | 1614 | * min_perf value across kexec reboots. If this CPU is just onlined normally after this, the |
| 1615 | * limits, epp and desired perf will get reset to the cached values in cpudata struct | 1615 | * limits, epp and desired perf will get reset to the cached values in cpudata struct |
| 1616 | */ | 1616 | */ |
| 1617 | return amd_pstate_update_perf(policy, perf.bios_min_perf, 0U, 0U, 0U, false); | 1617 | return amd_pstate_update_perf(policy, perf.bios_min_perf, |
| 1618 | FIELD_GET(AMD_CPPC_DES_PERF_MASK, cpudata->cppc_req_cached), | ||
| 1619 | FIELD_GET(AMD_CPPC_MAX_PERF_MASK, cpudata->cppc_req_cached), | ||
| 1620 | FIELD_GET(AMD_CPPC_EPP_PERF_MASK, cpudata->cppc_req_cached), | ||
| 1621 | false); | ||
| 1618 | } | 1622 | } |
| 1619 | 1623 | ||
| 1620 | static int amd_pstate_suspend(struct cpufreq_policy *policy) | 1624 | static int amd_pstate_suspend(struct cpufreq_policy *policy) |
| @@ -188,20 +188,17 @@ again: · 187 unmodified lines | |||
| 188 | * | 188 | * |
| 189 | * This can deal with workloads that have long pauses interspersed | 189 | * This can deal with workloads that have long pauses interspersed |
| 190 | * with sporadic activity with a bunch of short pauses. | 190 | * with sporadic activity with a bunch of short pauses. |
| 191 | * | ||
| 192 | * However, if the number of remaining samples is too small to exclude | ||
| 193 | * any more outliers, allow the deepest available idle state to be | ||
| 194 | * selected because there are systems where the time spent by CPUs in | ||
| 195 | * deep idle states is correlated to the maximum frequency the CPUs | ||
| 196 | * can get to. On those systems, shallow idle states should be avoided | ||
| 197 | * unless there is a clear indication that the given CPU is most likley | ||
| 198 | * going to be woken up shortly. | ||
| 191 | */ | 199 | */ |
| 192 | if (divisor * 4 <= INTERVALS * 3) { | 200 | if (divisor * 4 <= INTERVALS * 3) |
| 193 | /* | ||
| 194 | * If there are sufficiently many data points still under | ||
| 195 | * consideration after the outliers have been eliminated, | ||
| 196 | * returning without a prediction would be a mistake because it | ||
| 197 | * is likely that the next interval will not exceed the current | ||
| 198 | * maximum, so return the latter in that case. | ||
| 199 | */ | ||
| 200 | if (divisor >= INTERVALS / 2) | ||
| 201 | return max; | ||
| 202 | |||
| 203 | return UINT_MAX; | 201 | return UINT_MAX; |
| 204 | } | ||
| 205 | 202 | ||
| 206 | /* Update the thresholds for the next round. */ | 203 | /* Update the thresholds for the next round. */ |
| 207 | if (avg - min > max - avg) | 204 | if (avg - min > max - avg) |
| @@ -269,7 +269,7 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, · 268 unmodified lines | |||
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static int allocate_tlabel(struct fw_card *card) | 271 | static int allocate_tlabel(struct fw_card *card) |
| 272 | __must_hold(&card->transactions_lock) | 272 | __must_hold(&card->transactions.lock) |
| 273 | { | 273 | { |
| 274 | int tlabel; | 274 | int tlabel; |
| 275 | 275 | ||
| @@ -167,6 +167,7 @@ static inline void __init init_ohci1394_initialize(struct ohci *ohci) · 166 unmodified lines | |||
| 167 | 167 | ||
| 168 | /** | 168 | /** |
| 169 | * init_ohci1394_wait_for_busresets - wait until bus resets are completed | 169 | * init_ohci1394_wait_for_busresets - wait until bus resets are completed |
| 170 | * @ohci: Pointer to the OHCI-1394 controller structure | ||
| 170 | * | 171 | * |
| 171 | * OHCI1394 initialization itself and any device going on- or offline | 172 | * OHCI1394 initialization itself and any device going on- or offline |
| 172 | * and any cable issue cause a IEEE1394 bus reset. The OHCI1394 spec | 173 | * and any cable issue cause a IEEE1394 bus reset. The OHCI1394 spec |
| @@ -189,6 +190,8 @@ static inline void __init init_ohci1394_wait_for_busresets(struct ohci *ohci) · 16 unmodified lines | |||
| 189 | 190 | ||
| 190 | /** | 191 | /** |
| 191 | * init_ohci1394_enable_physical_dma - Enable physical DMA for remote debugging | 192 | * init_ohci1394_enable_physical_dma - Enable physical DMA for remote debugging |
| 193 | * @ohci: Pointer to the OHCI-1394 controller structure | ||
| 194 | * | ||
| 192 | * This enables remote DMA access over IEEE1394 from every host for the low | 195 | * This enables remote DMA access over IEEE1394 from every host for the low |
| 193 | * 4GB of address space. DMA accesses above 4GB are not available currently. | 196 | * 4GB of address space. DMA accesses above 4GB are not available currently. |
| 194 | */ | 197 | */ |
| @@ -201,6 +204,8 @@ static inline void __init init_ohci1394_enable_physical_dma(struct ohci *ohci) · 6 unmodified lines | |||
| 201 | 204 | ||
| 202 | /** | 205 | /** |
| 203 | * init_ohci1394_reset_and_init_dma - init controller and enable DMA | 206 | * init_ohci1394_reset_and_init_dma - init controller and enable DMA |
| 207 | * @ohci: Pointer to the OHCI-1394 controller structure | ||
| 208 | * | ||
| 204 | * This initializes the given controller and enables physical DMA engine in it. | 209 | * This initializes the given controller and enables physical DMA engine in it. |
| 205 | */ | 210 | */ |
| 206 | static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci) | 211 | static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci) |
| @@ -230,6 +235,10 @@ static inline void __init init_ohci1394_reset_and_init_dma(struct ohci *ohci) · 23 unmodified lines | |||
| 230 | 235 | ||
| 231 | /** | 236 | /** |
| 232 | * init_ohci1394_controller - Map the registers of the controller and init DMA | 237 | * init_ohci1394_controller - Map the registers of the controller and init DMA |
| 238 | * @num: PCI bus number | ||
| 239 | * @slot: PCI device number | ||
| 240 | * @func: PCI function number | ||
| 241 | * | ||
| 233 | * This maps the registers of the specified controller and initializes it | 242 | * This maps the registers of the specified controller and initializes it |
| 234 | */ | 243 | */ |
| 235 | static inline void __init init_ohci1394_controller(int num, int slot, int func) | 244 | static inline void __init init_ohci1394_controller(int num, int slot, int func) |
| @@ -284,6 +293,7 @@ void __init init_ohci1394_dma_on_all_controllers(void) · 48 unmodified lines | |||
| 284 | 293 | ||
| 285 | /** | 294 | /** |
| 286 | * setup_ohci1394_dma - enables early OHCI1394 DMA initialization | 295 | * setup_ohci1394_dma - enables early OHCI1394 DMA initialization |
| 296 | * @opt: Kernel command line parameter string | ||
| 287 | */ | 297 | */ |
| 288 | static int __init setup_ohci1394_dma(char *opt) | 298 | static int __init setup_ohci1394_dma(char *opt) |
| 289 | { | 299 | { |
| @@ -649,6 +649,26 @@ static u16 ffa_memory_attributes_get(u32 func_id) · 648 unmodified lines | |||
| 649 | return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; | 649 | return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; |
| 650 | } | 650 | } |
| 651 | 651 | ||
| 652 | static void ffa_emad_impdef_value_init(u32 version, void *dst, void *src) | ||
| 653 | { | ||
| 654 | struct ffa_mem_region_attributes *ep_mem_access; | ||
| 655 | |||
| 656 | if (FFA_EMAD_HAS_IMPDEF_FIELD(version)) | ||
| 657 | memcpy(dst, src, sizeof(ep_mem_access->impdef_val)); | ||
| 658 | } | ||
| 659 | |||
| 660 | static void | ||
| 661 | ffa_mem_region_additional_setup(u32 version, struct ffa_mem_region *mem_region) | ||
| 662 | { | ||
| 663 | if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version)) { | ||
| 664 | mem_region->ep_mem_size = 0; | ||
| 665 | } else { | ||
| 666 | mem_region->ep_mem_size = ffa_emad_size_get(version); | ||
| 667 | mem_region->ep_mem_offset = sizeof(*mem_region); | ||
| 668 | memset(mem_region->reserved, 0, 12); | ||
| 669 | } | ||
| 670 | } | ||
| 671 | |||
| 652 | static int | 672 | static int |
| 653 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, | 673 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, |
| 654 | struct ffa_mem_ops_args *args) | 674 | struct ffa_mem_ops_args *args) |
| @@ -667,27 +687,24 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, · 12 unmodified lines | |||
| 667 | mem_region->flags = args->flags; | 687 | mem_region->flags = args->flags; |
| 668 | mem_region->sender_id = drv_info->vm_id; | 688 | mem_region->sender_id = drv_info->vm_id; |
| 669 | mem_region->attributes = ffa_memory_attributes_get(func_id); | 689 | mem_region->attributes = ffa_memory_attributes_get(func_id); |
| 670 | ep_mem_access = buffer + | ||
| 671 | ffa_mem_desc_offset(buffer, 0, drv_info->version); | ||
| 672 | composite_offset = ffa_mem_desc_offset(buffer, args->nattrs, | 690 | composite_offset = ffa_mem_desc_offset(buffer, args->nattrs, |
| 673 | drv_info->version); | 691 | drv_info->version); |
| 674 | 692 | ||
| 675 | for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { | 693 | for (idx = 0; idx < args->nattrs; idx++) { |
| 694 | ep_mem_access = buffer + | ||
| 695 | ffa_mem_desc_offset(buffer, idx, drv_info->version); | ||
| 676 | ep_mem_access->receiver = args->attrs[idx].receiver; | 696 | ep_mem_access->receiver = args->attrs[idx].receiver; |
| 677 | ep_mem_access->attrs = args->attrs[idx].attrs; | 697 | ep_mem_access->attrs = args->attrs[idx].attrs; |
| 678 | ep_mem_access->composite_off = composite_offset; | 698 | ep_mem_access->composite_off = composite_offset; |
| 679 | ep_mem_access->flag = 0; | 699 | ep_mem_access->flag = 0; |
| 680 | ep_mem_access->reserved = 0; | 700 | ep_mem_access->reserved = 0; |
| 701 | ffa_emad_impdef_value_init(drv_info->version, | ||
| 702 | ep_mem_access->impdef_val, | ||
| 703 | args->attrs[idx].impdef_val); | ||
| 681 | } | 704 | } |
| 682 | mem_region->handle = 0; | 705 | mem_region->handle = 0; |
| 683 | mem_region->ep_count = args->nattrs; | 706 | mem_region->ep_count = args->nattrs; |
| 684 | if (drv_info->version <= FFA_VERSION_1_0) { | 707 | ffa_mem_region_additional_setup(drv_info->version, mem_region); |
| 685 | mem_region->ep_mem_size = 0; | ||
| 686 | } else { | ||
| 687 | mem_region->ep_mem_size = sizeof(*ep_mem_access); | ||
| 688 | mem_region->ep_mem_offset = sizeof(*mem_region); | ||
| 689 | memset(mem_region->reserved, 0, 12); | ||
| 690 | } | ||
| 691 | 708 | ||
| 692 | composite = buffer + composite_offset; | 709 | composite = buffer + composite_offset; |
| 693 | composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg); | 710 | composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg); |
| @@ -309,16 +309,36 @@ enum debug_counters { · 308 unmodified lines | |||
| 309 | SCMI_DEBUG_COUNTERS_LAST | 309 | SCMI_DEBUG_COUNTERS_LAST |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | static inline void scmi_inc_count(atomic_t *arr, int stat) | 312 | /** |
| 313 | * struct scmi_debug_info - Debug common info | ||
| 314 | * @top_dentry: A reference to the top debugfs dentry | ||
| 315 | * @name: Name of this SCMI instance | ||
| 316 | * @type: Type of this SCMI instance | ||
| 317 | * @is_atomic: Flag to state if the transport of this instance is atomic | ||
| 318 | * @counters: An array of atomic_c's used for tracking statistics (if enabled) | ||
| 319 | */ | ||
| 320 | struct scmi_debug_info { | ||
| 321 | struct dentry *top_dentry; | ||
| 322 | const char *name; | ||
| 323 | const char *type; | ||
| 324 | bool is_atomic; | ||
| 325 | atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; | ||
| 326 | }; | ||
| 327 | |||
| 328 | static inline void scmi_inc_count(struct scmi_debug_info *dbg, int stat) | ||
| 313 | { | 329 | { |
| 314 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) | 330 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { |
| 315 | atomic_inc(&arr[stat]); | 331 | if (dbg) |
| 332 | atomic_inc(&dbg->counters[stat]); | ||
| 333 | } | ||
| 316 | } | 334 | } |
| 317 | 335 | ||
| 318 | static inline void scmi_dec_count(atomic_t *arr, int stat) | 336 | static inline void scmi_dec_count(struct scmi_debug_info *dbg, int stat) |
| 319 | { | 337 | { |
| 320 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) | 338 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { |
| 321 | atomic_dec(&arr[stat]); | 339 | if (dbg) |
| 340 | atomic_dec(&dbg->counters[stat]); | ||
| 341 | } | ||
| 322 | } | 342 | } |
| 323 | 343 | ||
| 324 | enum scmi_bad_msg { | 344 | enum scmi_bad_msg { |
| @@ -115,22 +115,6 @@ struct scmi_protocol_instance { · 114 unmodified lines | |||
| 115 | 115 | ||
| 116 | #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph) | 116 | #define ph_to_pi(h) container_of(h, struct scmi_protocol_instance, ph) |
| 117 | 117 | ||
| 118 | /** | ||
| 119 | * struct scmi_debug_info - Debug common info | ||
| 120 | * @top_dentry: A reference to the top debugfs dentry | ||
| 121 | * @name: Name of this SCMI instance | ||
| 122 | * @type: Type of this SCMI instance | ||
| 123 | * @is_atomic: Flag to state if the transport of this instance is atomic | ||
| 124 | * @counters: An array of atomic_c's used for tracking statistics (if enabled) | ||
| 125 | */ | ||
| 126 | struct scmi_debug_info { | ||
| 127 | struct dentry *top_dentry; | ||
| 128 | const char *name; | ||
| 129 | const char *type; | ||
| 130 | bool is_atomic; | ||
| 131 | atomic_t counters[SCMI_DEBUG_COUNTERS_LAST]; | ||
| 132 | }; | ||
| 133 | |||
| 134 | /** | 118 | /** |
| 135 | * struct scmi_info - Structure representing a SCMI instance | 119 | * struct scmi_info - Structure representing a SCMI instance |
| 136 | * | 120 | * |
| @@ -610,7 +594,7 @@ scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer, · 473 unmodified lines | |||
| 610 | /* Set in-flight */ | 594 | /* Set in-flight */ |
| 611 | set_bit(xfer->hdr.seq, minfo->xfer_alloc_table); | 595 | set_bit(xfer->hdr.seq, minfo->xfer_alloc_table); |
| 612 | hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq); | 596 | hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq); |
| 613 | scmi_inc_count(info->dbg->counters, XFERS_INFLIGHT); | 597 | scmi_inc_count(info->dbg, XFERS_INFLIGHT); |
| 614 | 598 | ||
| 615 | xfer->pending = true; | 599 | xfer->pending = true; |
| 616 | } | 600 | } |
| @@ -819,8 +803,9 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 202 unmodified lines | |||
| 819 | hash_del(&xfer->node); | 803 | hash_del(&xfer->node); |
| 820 | xfer->pending = false; | 804 | xfer->pending = false; |
| 821 | 805 | ||
| 822 | scmi_dec_count(info->dbg->counters, XFERS_INFLIGHT); | 806 | scmi_dec_count(info->dbg, XFERS_INFLIGHT); |
| 823 | } | 807 | } |
| 808 | xfer->flags = 0; | ||
| 824 | hlist_add_head(&xfer->node, &minfo->free_xfers); | 809 | hlist_add_head(&xfer->node, &minfo->free_xfers); |
| 825 | } | 810 | } |
| 826 | spin_unlock_irqrestore(&minfo->xfer_lock, flags); | 811 | spin_unlock_irqrestore(&minfo->xfer_lock, flags); |
| @@ -839,8 +824,6 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 12 unmodified lines | |||
| 839 | { | 824 | { |
| 840 | struct scmi_info *info = handle_to_scmi_info(handle); | 825 | struct scmi_info *info = handle_to_scmi_info(handle); |
| 841 | 826 | ||
| 842 | xfer->flags &= ~SCMI_XFER_FLAG_IS_RAW; | ||
| 843 | xfer->flags &= ~SCMI_XFER_FLAG_CHAN_SET; | ||
| 844 | return __scmi_xfer_put(&info->tx_minfo, xfer); | 827 | return __scmi_xfer_put(&info->tx_minfo, xfer); |
| 845 | } | 828 | } |
| 846 | 829 | ||
| @@ -1034,7 +1017,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) · 187 unmodified lines | |||
| 1034 | spin_unlock_irqrestore(&minfo->xfer_lock, flags); | 1017 | spin_unlock_irqrestore(&minfo->xfer_lock, flags); |
| 1035 | 1018 | ||
| 1036 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); | 1019 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED); |
| 1037 | scmi_inc_count(info->dbg->counters, ERR_MSG_UNEXPECTED); | 1020 | scmi_inc_count(info->dbg, ERR_MSG_UNEXPECTED); |
| 1038 | 1021 | ||
| 1039 | return xfer; | 1022 | return xfer; |
| 1040 | } | 1023 | } |
| @@ -1062,7 +1045,7 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr) · 21 unmodified lines | |||
| 1062 | msg_type, xfer_id, msg_hdr, xfer->state); | 1045 | msg_type, xfer_id, msg_hdr, xfer->state); |
| 1063 | 1046 | ||
| 1064 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); | 1047 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID); |
| 1065 | scmi_inc_count(info->dbg->counters, ERR_MSG_INVALID); | 1048 | scmi_inc_count(info->dbg, ERR_MSG_INVALID); |
| 1066 | 1049 | ||
| 1067 | /* On error the refcount incremented above has to be dropped */ | 1050 | /* On error the refcount incremented above has to be dropped */ |
| 1068 | __scmi_xfer_put(minfo, xfer); | 1051 | __scmi_xfer_put(minfo, xfer); |
| @@ -1107,7 +1090,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, · 38 unmodified lines | |||
| 1107 | PTR_ERR(xfer)); | 1090 | PTR_ERR(xfer)); |
| 1108 | 1091 | ||
| 1109 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); | 1092 | scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM); |
| 1110 | scmi_inc_count(info->dbg->counters, ERR_MSG_NOMEM); | 1093 | scmi_inc_count(info->dbg, ERR_MSG_NOMEM); |
| 1111 | 1094 | ||
| 1112 | scmi_clear_channel(info, cinfo); | 1095 | scmi_clear_channel(info, cinfo); |
| 1113 | return; | 1096 | return; |
| @@ -1123,7 +1106,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, · 9 unmodified lines | |||
| 1123 | trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, | 1106 | trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, |
| 1124 | xfer->hdr.id, "NOTI", xfer->hdr.seq, | 1107 | xfer->hdr.id, "NOTI", xfer->hdr.seq, |
| 1125 | xfer->hdr.status, xfer->rx.buf, xfer->rx.len); | 1108 | xfer->hdr.status, xfer->rx.buf, xfer->rx.len); |
| 1126 | scmi_inc_count(info->dbg->counters, NOTIFICATION_OK); | 1109 | scmi_inc_count(info->dbg, NOTIFICATION_OK); |
| 1127 | 1110 | ||
| 1128 | scmi_notify(cinfo->handle, xfer->hdr.protocol_id, | 1111 | scmi_notify(cinfo->handle, xfer->hdr.protocol_id, |
| 1129 | xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); | 1112 | xfer->hdr.id, xfer->rx.buf, xfer->rx.len, ts); |
| @@ -1183,10 +1166,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, · 53 unmodified lines | |||
| 1183 | if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { | 1166 | if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { |
| 1184 | scmi_clear_channel(info, cinfo); | 1167 | scmi_clear_channel(info, cinfo); |
| 1185 | complete(xfer->async_done); | 1168 | complete(xfer->async_done); |
| 1186 | scmi_inc_count(info->dbg->counters, DELAYED_RESPONSE_OK); | 1169 | scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); |
| 1187 | } else { | 1170 | } else { |
| 1188 | complete(&xfer->done); | 1171 | complete(&xfer->done); |
| 1189 | scmi_inc_count(info->dbg->counters, RESPONSE_OK); | 1172 | scmi_inc_count(info->dbg, RESPONSE_OK); |
| 1190 | } | 1173 | } |
| 1191 | 1174 | ||
| 1192 | if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { | 1175 | if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { |
| @@ -1296,7 +1279,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, · 103 unmodified lines | |||
| 1296 | "timed out in resp(caller: %pS) - polling\n", | 1279 | "timed out in resp(caller: %pS) - polling\n", |
| 1297 | (void *)_RET_IP_); | 1280 | (void *)_RET_IP_); |
| 1298 | ret = -ETIMEDOUT; | 1281 | ret = -ETIMEDOUT; |
| 1299 | scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_POLLED_TIMEOUT); | 1282 | scmi_inc_count(info->dbg, XFERS_RESPONSE_POLLED_TIMEOUT); |
| 1300 | } | 1283 | } |
| 1301 | } | 1284 | } |
| 1302 | 1285 | ||
| @@ -1321,7 +1304,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, · 18 unmodified lines | |||
| 1321 | "RESP" : "resp", | 1304 | "RESP" : "resp", |
| 1322 | xfer->hdr.seq, xfer->hdr.status, | 1305 | xfer->hdr.seq, xfer->hdr.status, |
| 1323 | xfer->rx.buf, xfer->rx.len); | 1306 | xfer->rx.buf, xfer->rx.len); |
| 1324 | scmi_inc_count(info->dbg->counters, RESPONSE_POLLED_OK); | 1307 | scmi_inc_count(info->dbg, RESPONSE_POLLED_OK); |
| 1325 | 1308 | ||
| 1326 | if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { | 1309 | if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { |
| 1327 | scmi_raw_message_report(info->raw, xfer, | 1310 | scmi_raw_message_report(info->raw, xfer, |
| @@ -1336,7 +1319,7 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, · 8 unmodified lines | |||
| 1336 | dev_err(dev, "timed out in resp(caller: %pS)\n", | 1319 | dev_err(dev, "timed out in resp(caller: %pS)\n", |
| 1337 | (void *)_RET_IP_); | 1320 | (void *)_RET_IP_); |
| 1338 | ret = -ETIMEDOUT; | 1321 | ret = -ETIMEDOUT; |
| 1339 | scmi_inc_count(info->dbg->counters, XFERS_RESPONSE_TIMEOUT); | 1322 | scmi_inc_count(info->dbg, XFERS_RESPONSE_TIMEOUT); |
| 1340 | } | 1323 | } |
| 1341 | } | 1324 | } |
| 1342 | 1325 | ||
| @@ -1420,13 +1403,13 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 77 unmodified lines | |||
| 1420 | !is_transport_polling_capable(info->desc)) { | 1403 | !is_transport_polling_capable(info->desc)) { |
| 1421 | dev_warn_once(dev, | 1404 | dev_warn_once(dev, |
| 1422 | "Polling mode is not supported by transport.\n"); | 1405 | "Polling mode is not supported by transport.\n"); |
| 1423 | scmi_inc_count(info->dbg->counters, SENT_FAIL_POLLING_UNSUPPORTED); | 1406 | scmi_inc_count(info->dbg, SENT_FAIL_POLLING_UNSUPPORTED); |
| 1424 | return -EINVAL; | 1407 | return -EINVAL; |
| 1425 | } | 1408 | } |
| 1426 | 1409 | ||
| 1427 | cinfo = idr_find(&info->tx_idr, pi->proto->id); | 1410 | cinfo = idr_find(&info->tx_idr, pi->proto->id); |
| 1428 | if (unlikely(!cinfo)) { | 1411 | if (unlikely(!cinfo)) { |
| 1429 | scmi_inc_count(info->dbg->counters, SENT_FAIL_CHANNEL_NOT_FOUND); | 1412 | scmi_inc_count(info->dbg, SENT_FAIL_CHANNEL_NOT_FOUND); |
| 1430 | return -EINVAL; | 1413 | return -EINVAL; |
| 1431 | } | 1414 | } |
| 1432 | /* True ONLY if also supported by transport. */ | 1415 | /* True ONLY if also supported by transport. */ |
| @@ -1461,19 +1444,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 28 unmodified lines | |||
| 1461 | ret = info->desc->ops->send_message(cinfo, xfer); | 1444 | ret = info->desc->ops->send_message(cinfo, xfer); |
| 1462 | if (ret < 0) { | 1445 | if (ret < 0) { |
| 1463 | dev_dbg(dev, "Failed to send message %d\n", ret); | 1446 | dev_dbg(dev, "Failed to send message %d\n", ret); |
| 1464 | scmi_inc_count(info->dbg->counters, SENT_FAIL); | 1447 | scmi_inc_count(info->dbg, SENT_FAIL); |
| 1465 | return ret; | 1448 | return ret; |
| 1466 | } | 1449 | } |
| 1467 | 1450 | ||
| 1468 | trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, | 1451 | trace_scmi_msg_dump(info->id, cinfo->id, xfer->hdr.protocol_id, |
| 1469 | xfer->hdr.id, "CMND", xfer->hdr.seq, | 1452 | xfer->hdr.id, "CMND", xfer->hdr.seq, |
| 1470 | xfer->hdr.status, xfer->tx.buf, xfer->tx.len); | 1453 | xfer->hdr.status, xfer->tx.buf, xfer->tx.len); |
| 1471 | scmi_inc_count(info->dbg->counters, SENT_OK); | 1454 | scmi_inc_count(info->dbg, SENT_OK); |
| 1472 | 1455 | ||
| 1473 | ret = scmi_wait_for_message_response(cinfo, xfer); | 1456 | ret = scmi_wait_for_message_response(cinfo, xfer); |
| 1474 | if (!ret && xfer->hdr.status) { | 1457 | if (!ret && xfer->hdr.status) { |
| 1475 | ret = scmi_to_linux_errno(xfer->hdr.status); | 1458 | ret = scmi_to_linux_errno(xfer->hdr.status); |
| 1476 | scmi_inc_count(info->dbg->counters, ERR_PROTOCOL); | 1459 | scmi_inc_count(info->dbg, ERR_PROTOCOL); |
| 1477 | } | 1460 | } |
| 1478 | 1461 | ||
| 1479 | if (info->desc->ops->mark_txdone) | 1462 | if (info->desc->ops->mark_txdone) |
| @@ -3044,9 +3027,6 @@ static int scmi_debugfs_raw_mode_setup(struct scmi_info *info) · 1564 unmodified lines | |||
| 3044 | u8 channels[SCMI_MAX_CHANNELS] = {}; | 3027 | u8 channels[SCMI_MAX_CHANNELS] = {}; |
| 3045 | DECLARE_BITMAP(protos, SCMI_MAX_CHANNELS) = {}; | 3028 | DECLARE_BITMAP(protos, SCMI_MAX_CHANNELS) = {}; |
| 3046 | 3029 | ||
| 3047 | if (!info->dbg) | ||
| 3048 | return -EINVAL; | ||
| 3049 | |||
| 3050 | /* Enumerate all channels to collect their ids */ | 3030 | /* Enumerate all channels to collect their ids */ |
| 3051 | idr_for_each_entry(&info->tx_idr, cinfo, id) { | 3031 | idr_for_each_entry(&info->tx_idr, cinfo, id) { |
| 3052 | /* | 3032 | /* |
| @@ -3218,7 +3198,7 @@ static int scmi_probe(struct platform_device *pdev) · 165 unmodified lines | |||
| 3218 | if (!info->dbg) | 3198 | if (!info->dbg) |
| 3219 | dev_warn(dev, "Failed to setup SCMI debugfs.\n"); | 3199 | dev_warn(dev, "Failed to setup SCMI debugfs.\n"); |
| 3220 | 3200 | ||
| 3221 | if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { | 3201 | if (info->dbg && IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { |
| 3222 | ret = scmi_debugfs_raw_mode_setup(info); | 3202 | ret = scmi_debugfs_raw_mode_setup(info); |
| 3223 | if (!coex) { | 3203 | if (!coex) { |
| 3224 | if (ret) | 3204 | if (ret) |
| @@ -3423,6 +3403,9 @@ int scmi_inflight_count(const struct scmi_handle *handle) · 198 unmodified lines | |||
| 3423 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { | 3403 | if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) { |
| 3424 | struct scmi_info *info = handle_to_scmi_info(handle); | 3404 | struct scmi_info *info = handle_to_scmi_info(handle); |
| 3425 | 3405 | ||
| 3406 | if (!info->dbg) | ||
| 3407 | return 0; | ||
| 3408 | |||
| 3426 | return atomic_read(&info->dbg->counters[XFERS_INFLIGHT]); | 3409 | return atomic_read(&info->dbg->counters[XFERS_INFLIGHT]); |
| 3427 | } else { | 3410 | } else { |
| 3428 | return 0; | 3411 | return 0; |
| @@ -11,12 +11,12 @@ cflags-y := $(KBUILD_CFLAGS) · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | cflags-$(CONFIG_X86_32) := -march=i386 | 12 | cflags-$(CONFIG_X86_32) := -march=i386 |
| 13 | cflags-$(CONFIG_X86_64) := -mcmodel=small | 13 | cflags-$(CONFIG_X86_64) := -mcmodel=small |
| 14 | cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ | 14 | cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 -fms-extensions \ |
| 15 | -fPIC -fno-strict-aliasing -mno-red-zone \ | 15 | -fPIC -fno-strict-aliasing -mno-red-zone \ |
| 16 | -mno-mmx -mno-sse -fshort-wchar \ | 16 | -mno-mmx -mno-sse -fshort-wchar \ |
| 17 | -Wno-pointer-sign \ | 17 | -Wno-pointer-sign \ |
| 18 | $(call cc-disable-warning, address-of-packed-member) \ | 18 | $(call cc-disable-warning, address-of-packed-member) \ |
| 19 | $(call cc-disable-warning, gnu) \ | 19 | $(if $(CONFIG_CC_IS_CLANG),-Wno-gnu -Wno-microsoft-anon-tag) \ |
| 20 | -fno-asynchronous-unwind-tables \ | 20 | -fno-asynchronous-unwind-tables \ |
| 21 | $(CLANG_FLAGS) | 21 | $(CLANG_FLAGS) |
| 22 | 22 | ||
| @@ -59,6 +59,7 @@ static const struct regmap_config idio_16_regmap_config = { · 58 unmodified lines | |||
| 59 | .reg_stride = 1, | 59 | .reg_stride = 1, |
| 60 | .val_bits = 8, | 60 | .val_bits = 8, |
| 61 | .io_port = true, | 61 | .io_port = true, |
| 62 | .max_register = 0x5, | ||
| 62 | .wr_table = &idio_16_wr_table, | 63 | .wr_table = &idio_16_wr_table, |
| 63 | .rd_table = &idio_16_rd_table, | 64 | .rd_table = &idio_16_rd_table, |
| 64 | .volatile_table = &idio_16_rd_table, | 65 | .volatile_table = &idio_16_rd_table, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16" | 7 | #define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16" |
| 8 | 8 | ||
| 9 | #include <linux/bitmap.h> | ||
| 9 | #include <linux/bits.h> | 10 | #include <linux/bits.h> |
| 10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 11 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| @@ -107,6 +108,7 @@ int devm_idio_16_regmap_register(struct device *const dev, · 95 unmodified lines | |||
| 107 | struct idio_16_data *data; | 108 | struct idio_16_data *data; |
| 108 | struct regmap_irq_chip *chip; | 109 | struct regmap_irq_chip *chip; |
| 109 | struct regmap_irq_chip_data *chip_data; | 110 | struct regmap_irq_chip_data *chip_data; |
| 111 | DECLARE_BITMAP(fixed_direction_output, IDIO_16_NGPIO); | ||
| 110 | 112 | ||
| 111 | if (!config->parent) | 113 | if (!config->parent) |
| 112 | return -EINVAL; | 114 | return -EINVAL; |
| @@ -164,6 +166,9 @@ int devm_idio_16_regmap_register(struct device *const dev, · 51 unmodified lines | |||
| 164 | gpio_config.irq_domain = regmap_irq_get_domain(chip_data); | 166 | gpio_config.irq_domain = regmap_irq_get_domain(chip_data); |
| 165 | gpio_config.reg_mask_xlate = idio_16_reg_mask_xlate; | 167 | gpio_config.reg_mask_xlate = idio_16_reg_mask_xlate; |
| 166 | 168 | ||
| 169 | bitmap_from_u64(fixed_direction_output, GENMASK_U64(15, 0)); | ||
| 170 | gpio_config.fixed_direction_output = fixed_direction_output; | ||
| 171 | |||
| 167 | return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config)); | 172 | return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config)); |
| 168 | } | 173 | } |
| 169 | EXPORT_SYMBOL_GPL(devm_idio_16_regmap_register); | 174 | EXPORT_SYMBOL_GPL(devm_idio_16_regmap_register); |
| @@ -286,22 +286,14 @@ static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, · 285 unmodified lines | |||
| 286 | { | 286 | { |
| 287 | const struct ljca_gpio_packet *packet = evt_data; | 287 | const struct ljca_gpio_packet *packet = evt_data; |
| 288 | struct ljca_gpio_dev *ljca_gpio = context; | 288 | struct ljca_gpio_dev *ljca_gpio = context; |
| 289 | int i, irq; | 289 | int i; |
| 290 | 290 | ||
| 291 | if (cmd != LJCA_GPIO_INT_EVENT) | 291 | if (cmd != LJCA_GPIO_INT_EVENT) |
| 292 | return; | 292 | return; |
| 293 | 293 | ||
| 294 | for (i = 0; i < packet->num; i++) { | 294 | for (i = 0; i < packet->num; i++) { |
| 295 | irq = irq_find_mapping(ljca_gpio->gc.irq.domain, | 295 | generic_handle_domain_irq(ljca_gpio->gc.irq.domain, |
| 296 | packet->item[i].index); | 296 | packet->item[i].index); |
| 297 | if (!irq) { | ||
| 298 | dev_err(ljca_gpio->gc.parent, | ||
| 299 | "gpio_id %u does not mapped to IRQ yet\n", | ||
| 300 | packet->item[i].index); | ||
| 301 | return; | ||
| 302 | } | ||
| 303 | |||
| 304 | generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq); | ||
| 305 | set_bit(packet->item[i].index, ljca_gpio->reenable_irqs); | 297 | set_bit(packet->item[i].index, ljca_gpio->reenable_irqs); |
| 306 | } | 298 | } |
| 307 | 299 | ||
| @@ -41,6 +41,7 @@ static const struct regmap_config idio_16_regmap_config = { · 40 unmodified lines | |||
| 41 | .reg_stride = 1, | 41 | .reg_stride = 1, |
| 42 | .val_bits = 8, | 42 | .val_bits = 8, |
| 43 | .io_port = true, | 43 | .io_port = true, |
| 44 | .max_register = 0x7, | ||
| 44 | .wr_table = &idio_16_wr_table, | 45 | .wr_table = &idio_16_wr_table, |
| 45 | .rd_table = &idio_16_rd_table, | 46 | .rd_table = &idio_16_rd_table, |
| 46 | .volatile_table = &idio_16_rd_table, | 47 | .volatile_table = &idio_16_rd_table, |
| @@ -31,6 +31,7 @@ struct gpio_regmap { · 30 unmodified lines | |||
| 31 | unsigned int reg_clr_base; | 31 | unsigned int reg_clr_base; |
| 32 | unsigned int reg_dir_in_base; | 32 | unsigned int reg_dir_in_base; |
| 33 | unsigned int reg_dir_out_base; | 33 | unsigned int reg_dir_out_base; |
| 34 | unsigned long *fixed_direction_output; | ||
| 34 | 35 | ||
| 35 | #ifdef CONFIG_REGMAP_IRQ | 36 | #ifdef CONFIG_REGMAP_IRQ |
| 36 | int regmap_irq_line; | 37 | int regmap_irq_line; |
| @@ -134,6 +135,13 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, · 97 unmodified lines | |||
| 134 | unsigned int base, val, reg, mask; | 135 | unsigned int base, val, reg, mask; |
| 135 | int invert, ret; | 136 | int invert, ret; |
| 136 | 137 | ||
| 138 | if (gpio->fixed_direction_output) { | ||
| 139 | if (test_bit(offset, gpio->fixed_direction_output)) | ||
| 140 | return GPIO_LINE_DIRECTION_OUT; | ||
| 141 | else | ||
| 142 | return GPIO_LINE_DIRECTION_IN; | ||
| 143 | } | ||
| 144 | |||
| 137 | if (gpio->reg_dat_base && !gpio->reg_set_base) | 145 | if (gpio->reg_dat_base && !gpio->reg_set_base) |
| 138 | return GPIO_LINE_DIRECTION_IN; | 146 | return GPIO_LINE_DIRECTION_IN; |
| 139 | if (gpio->reg_set_base && !gpio->reg_dat_base) | 147 | if (gpio->reg_set_base && !gpio->reg_dat_base) |
| @@ -284,6 +292,17 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 144 unmodified lines | |||
| 284 | goto err_free_gpio; | 292 | goto err_free_gpio; |
| 285 | } | 293 | } |
| 286 | 294 | ||
| 295 | if (config->fixed_direction_output) { | ||
| 296 | gpio->fixed_direction_output = bitmap_alloc(chip->ngpio, | ||
| 297 | GFP_KERNEL); | ||
| 298 | if (!gpio->fixed_direction_output) { | ||
| 299 | ret = -ENOMEM; | ||
| 300 | goto err_free_gpio; | ||
| 301 | } | ||
| 302 | bitmap_copy(gpio->fixed_direction_output, | ||
| 303 | config->fixed_direction_output, chip->ngpio); | ||
| 304 | } | ||
| 305 | |||
| 287 | /* if not set, assume there is only one register */ | 306 | /* if not set, assume there is only one register */ |
| 288 | gpio->ngpio_per_reg = config->ngpio_per_reg; | 307 | gpio->ngpio_per_reg = config->ngpio_per_reg; |
| 289 | if (!gpio->ngpio_per_reg) | 308 | if (!gpio->ngpio_per_reg) |
| @@ -300,7 +319,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 10 unmodified lines | |||
| 300 | 319 | ||
| 301 | ret = gpiochip_add_data(chip, gpio); | 320 | ret = gpiochip_add_data(chip, gpio); |
| 302 | if (ret < 0) | 321 | if (ret < 0) |
| 303 | goto err_free_gpio; | 322 | goto err_free_bitmap; |
| 304 | 323 | ||
| 305 | #ifdef CONFIG_REGMAP_IRQ | 324 | #ifdef CONFIG_REGMAP_IRQ |
| 306 | if (config->regmap_irq_chip) { | 325 | if (config->regmap_irq_chip) { |
| @@ -309,7 +328,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 2 unmodified lines | |||
| 309 | config->regmap_irq_line, config->regmap_irq_flags, | 328 | config->regmap_irq_line, config->regmap_irq_flags, |
| 310 | 0, config->regmap_irq_chip, &gpio->irq_chip_data); | 329 | 0, config->regmap_irq_chip, &gpio->irq_chip_data); |
| 311 | if (ret) | 330 | if (ret) |
| 312 | goto err_free_gpio; | 331 | goto err_free_bitmap; |
| 313 | 332 | ||
| 314 | irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); | 333 | irq_domain = regmap_irq_get_domain(gpio->irq_chip_data); |
| 315 | } else | 334 | } else |
| @@ -326,6 +345,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config · 10 unmodified lines | |||
| 326 | 345 | ||
| 327 | err_remove_gpiochip: | 346 | err_remove_gpiochip: |
| 328 | gpiochip_remove(chip); | 347 | gpiochip_remove(chip); |
| 348 | err_free_bitmap: | ||
| 349 | bitmap_free(gpio->fixed_direction_output); | ||
| 329 | err_free_gpio: | 350 | err_free_gpio: |
| 330 | kfree(gpio); | 351 | kfree(gpio); |
| 331 | return ERR_PTR(ret); | 352 | return ERR_PTR(ret); |
| @@ -344,6 +365,7 @@ void gpio_regmap_unregister(struct gpio_regmap *gpio) · 12 unmodified lines | |||
| 344 | #endif | 365 | #endif |
| 345 | 366 | ||
| 346 | gpiochip_remove(&gpio->gpio_chip); | 367 | gpiochip_remove(&gpio->gpio_chip); |
| 368 | bitmap_free(gpio->fixed_direction_output); | ||
| 347 | kfree(gpio); | 369 | kfree(gpio); |
| 348 | } | 370 | } |
| 349 | EXPORT_SYMBOL_GPL(gpio_regmap_unregister); | 371 | EXPORT_SYMBOL_GPL(gpio_regmap_unregister); |
| @@ -291,6 +291,19 @@ acpi_gpio_to_gpiod_flags(const struct acpi_resource_gpio *agpio, int polarity) · 290 unmodified lines | |||
| 291 | return GPIOD_ASIS; | 291 | return GPIOD_ASIS; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static void acpi_gpio_set_debounce_timeout(struct gpio_desc *desc, | ||
| 295 | unsigned int acpi_debounce) | ||
| 296 | { | ||
| 297 | int ret; | ||
| 298 | |||
| 299 | /* ACPI uses hundredths of milliseconds units */ | ||
| 300 | acpi_debounce *= 10; | ||
| 301 | ret = gpio_set_debounce_timeout(desc, acpi_debounce); | ||
| 302 | if (ret) | ||
| 303 | gpiod_warn(desc, "Failed to set debounce-timeout %u: %d\n", | ||
| 304 | acpi_debounce, ret); | ||
| 305 | } | ||
| 306 | |||
| 294 | static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, | 307 | static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, |
| 295 | struct acpi_resource_gpio *agpio, | 308 | struct acpi_resource_gpio *agpio, |
| 296 | unsigned int index, | 309 | unsigned int index, |
| @@ -300,18 +313,12 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, · 3 unmodified lines | |||
| 300 | enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, polarity); | 313 | enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, polarity); |
| 301 | unsigned int pin = agpio->pin_table[index]; | 314 | unsigned int pin = agpio->pin_table[index]; |
| 302 | struct gpio_desc *desc; | 315 | struct gpio_desc *desc; |
| 303 | int ret; | ||
| 304 | 316 | ||
| 305 | desc = gpiochip_request_own_desc(chip, pin, label, polarity, flags); | 317 | desc = gpiochip_request_own_desc(chip, pin, label, polarity, flags); |
| 306 | if (IS_ERR(desc)) | 318 | if (IS_ERR(desc)) |
| 307 | return desc; | 319 | return desc; |
| 308 | 320 | ||
| 309 | /* ACPI uses hundredths of milliseconds units */ | 321 | acpi_gpio_set_debounce_timeout(desc, agpio->debounce_timeout); |
| 310 | ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout * 10); | ||
| 311 | if (ret) | ||
| 312 | dev_warn(chip->parent, | ||
| 313 | "Failed to set debounce-timeout for pin 0x%04X, err %d\n", | ||
| 314 | pin, ret); | ||
| 315 | 322 | ||
| 316 | return desc; | 323 | return desc; |
| 317 | } | 324 | } |
| @@ -375,8 +382,8 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, · 57 unmodified lines | |||
| 375 | desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event"); | 382 | desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event"); |
| 376 | if (IS_ERR(desc)) { | 383 | if (IS_ERR(desc)) { |
| 377 | dev_err(chip->parent, | 384 | dev_err(chip->parent, |
| 378 | "Failed to request GPIO for pin 0x%04X, err %ld\n", | 385 | "Failed to request GPIO for pin 0x%04X, err %pe\n", |
| 379 | pin, PTR_ERR(desc)); | 386 | pin, desc); |
| 380 | return AE_OK; | 387 | return AE_OK; |
| 381 | } | 388 | } |
| 382 | 389 | ||
| @@ -944,7 +951,6 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, · 561 unmodified lines | |||
| 944 | bool can_fallback = acpi_can_fallback_to_crs(adev, con_id); | 951 | bool can_fallback = acpi_can_fallback_to_crs(adev, con_id); |
| 945 | struct acpi_gpio_info info = {}; | 952 | struct acpi_gpio_info info = {}; |
| 946 | struct gpio_desc *desc; | 953 | struct gpio_desc *desc; |
| 947 | int ret; | ||
| 948 | 954 | ||
| 949 | desc = __acpi_find_gpio(fwnode, con_id, idx, can_fallback, &info); | 955 | desc = __acpi_find_gpio(fwnode, con_id, idx, can_fallback, &info); |
| 950 | if (IS_ERR(desc)) | 956 | if (IS_ERR(desc)) |
| @@ -959,10 +965,7 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, · 8 unmodified lines | |||
| 959 | acpi_gpio_update_gpiod_flags(dflags, &info); | 965 | acpi_gpio_update_gpiod_flags(dflags, &info); |
| 960 | acpi_gpio_update_gpiod_lookup_flags(lookupflags, &info); | 966 | acpi_gpio_update_gpiod_lookup_flags(lookupflags, &info); |
| 961 | 967 | ||
| 962 | /* ACPI uses hundredths of milliseconds units */ | 968 | acpi_gpio_set_debounce_timeout(desc, info.debounce); |
| 963 | ret = gpio_set_debounce_timeout(desc, info.debounce * 10); | ||
| 964 | if (ret) | ||
| 965 | return ERR_PTR(ret); | ||
| 966 | 969 | ||
| 967 | return desc; | 970 | return desc; |
| 968 | } | 971 | } |
| @@ -551,13 +551,13 @@ static void schedule_dc_vmin_vmax(struct amdgpu_device *adev, · 550 unmodified lines | |||
| 551 | struct dc_stream_state *stream, | 551 | struct dc_stream_state *stream, |
| 552 | struct dc_crtc_timing_adjust *adjust) | 552 | struct dc_crtc_timing_adjust *adjust) |
| 553 | { | 553 | { |
| 554 | struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL); | 554 | struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_NOWAIT); |
| 555 | if (!offload_work) { | 555 | if (!offload_work) { |
| 556 | drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n"); | 556 | drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n"); |
| 557 | return; | 557 | return; |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_KERNEL); | 560 | struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_NOWAIT); |
| 561 | if (!adjust_copy) { | 561 | if (!adjust_copy) { |
| 562 | drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n"); | 562 | drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n"); |
| 563 | kfree(offload_work); | 563 | kfree(offload_work); |
| @@ -200,6 +200,9 @@ void dcn401_init_hw(struct dc *dc) · 199 unmodified lines | |||
| 200 | */ | 200 | */ |
| 201 | struct dc_link *link = dc->links[i]; | 201 | struct dc_link *link = dc->links[i]; |
| 202 | 202 | ||
| 203 | if (link->ep_type != DISPLAY_ENDPOINT_PHY) | ||
| 204 | continue; | ||
| 205 | |||
| 203 | link->link_enc->funcs->hw_init(link->link_enc); | 206 | link->link_enc->funcs->hw_init(link->link_enc); |
| 204 | 207 | ||
| 205 | /* Check for enabled DIG to identify enabled display */ | 208 | /* Check for enabled DIG to identify enabled display */ |
| @@ -44,7 +44,13 @@ · 43 unmodified lines | |||
| 44 | */ | 44 | */ |
| 45 | #define MAX_PIPES 6 | 45 | #define MAX_PIPES 6 |
| 46 | #define MAX_PHANTOM_PIPES (MAX_PIPES / 2) | 46 | #define MAX_PHANTOM_PIPES (MAX_PIPES / 2) |
| 47 | #define MAX_LINKS (MAX_PIPES * 2 +2) | 47 | |
| 48 | #define MAX_DPIA 6 | ||
| 49 | #define MAX_CONNECTOR 6 | ||
| 50 | #define MAX_VIRTUAL_LINKS 4 | ||
| 51 | |||
| 52 | #define MAX_LINKS (MAX_DPIA + MAX_CONNECTOR + MAX_VIRTUAL_LINKS) | ||
| 53 | |||
| 48 | #define MAX_DIG_LINK_ENCODERS 7 | 54 | #define MAX_DIG_LINK_ENCODERS 7 |
| 49 | #define MAX_DWB_PIPES 1 | 55 | #define MAX_DWB_PIPES 1 |
| 50 | #define MAX_HPO_DP2_ENCODERS 4 | 56 | #define MAX_HPO_DP2_ENCODERS 4 |
| @@ -78,6 +78,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link, · 77 unmodified lines | |||
| 78 | struct audio_output audio_output[MAX_PIPES]; | 78 | struct audio_output audio_output[MAX_PIPES]; |
| 79 | struct dc_stream_state *streams_on_link[MAX_PIPES]; | 79 | struct dc_stream_state *streams_on_link[MAX_PIPES]; |
| 80 | int num_streams_on_link = 0; | 80 | int num_streams_on_link = 0; |
| 81 | struct dc *dc = (struct dc *)link->dc; | ||
| 81 | 82 | ||
| 82 | needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) != | 83 | needs_divider_update = (link->dc->link_srv->dp_get_encoding_format(link_setting) != |
| 83 | link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings)); | 84 | link->dc->link_srv->dp_get_encoding_format((const struct dc_link_settings *) &link->cur_link_settings)); |
| @@ -150,7 +151,7 @@ static void dp_retrain_link_dp_test(struct dc_link *link, · 66 unmodified lines | |||
| 150 | if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) { | 151 | if (streams_on_link[i] && streams_on_link[i]->link && streams_on_link[i]->link == link) { |
| 151 | stream_update.stream = streams_on_link[i]; | 152 | stream_update.stream = streams_on_link[i]; |
| 152 | stream_update.dpms_off = &dpms_off; | 153 | stream_update.dpms_off = &dpms_off; |
| 153 | dc_update_planes_and_stream(state->clk_mgr->ctx->dc, NULL, 0, streams_on_link[i], &stream_update); | 154 | dc_update_planes_and_stream(dc, NULL, 0, streams_on_link[i], &stream_update); |
| 154 | } | 155 | } |
| 155 | } | 156 | } |
| 156 | } | 157 | } |
| @@ -174,6 +174,33 @@ static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color) · 173 unmodified lines | |||
| 174 | *p = color & 0xff; | 174 | *p = color & 0xff; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | /* | ||
| 178 | * Special case if the pixel crosses page boundaries | ||
| 179 | */ | ||
| 180 | static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page, | ||
| 181 | unsigned int offset, u32 color) | ||
| 182 | { | ||
| 183 | u8 *vaddr2; | ||
| 184 | u8 *p = vaddr + offset; | ||
| 185 | |||
| 186 | vaddr2 = kmap_local_page_try_from_panic(next_page); | ||
| 187 | |||
| 188 | *p++ = color & 0xff; | ||
| 189 | color >>= 8; | ||
| 190 | |||
| 191 | if (offset == PAGE_SIZE - 1) | ||
| 192 | p = vaddr2; | ||
| 193 | |||
| 194 | *p++ = color & 0xff; | ||
| 195 | color >>= 8; | ||
| 196 | |||
| 197 | if (offset == PAGE_SIZE - 2) | ||
| 198 | p = vaddr2; | ||
| 199 | |||
| 200 | *p = color & 0xff; | ||
| 201 | kunmap_local(vaddr2); | ||
| 202 | } | ||
| 203 | |||
| 177 | static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color) | 204 | static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color) |
| 178 | { | 205 | { |
| 179 | u32 *p = vaddr + offset; | 206 | u32 *p = vaddr + offset; |
| @@ -231,7 +258,14 @@ static void drm_panic_blit_page(struct page **pages, unsigned int dpitch, · 51 unmodified lines | |||
| 231 | page = new_page; | 258 | page = new_page; |
| 232 | vaddr = kmap_local_page_try_from_panic(pages[page]); | 259 | vaddr = kmap_local_page_try_from_panic(pages[page]); |
| 233 | } | 260 | } |
| 234 | if (vaddr) | 261 | if (!vaddr) |
| 262 | continue; | ||
| 263 | |||
| 264 | // Special case for 24bit, as a pixel might cross page boundaries | ||
| 265 | if (cpp == 3 && offset + 3 > PAGE_SIZE) | ||
| 266 | drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], | ||
| 267 | offset, fg32); | ||
| 268 | else | ||
| 235 | drm_panic_write_pixel(vaddr, offset, fg32, cpp); | 269 | drm_panic_write_pixel(vaddr, offset, fg32, cpp); |
| 236 | } | 270 | } |
| 237 | } | 271 | } |
| @@ -321,7 +355,15 @@ static void drm_panic_fill_page(struct page **pages, unsigned int dpitch, · 83 unmodified lines | |||
| 321 | page = new_page; | 355 | page = new_page; |
| 322 | vaddr = kmap_local_page_try_from_panic(pages[page]); | 356 | vaddr = kmap_local_page_try_from_panic(pages[page]); |
| 323 | } | 357 | } |
| 324 | drm_panic_write_pixel(vaddr, offset, color, cpp); | 358 | if (!vaddr) |
| 359 | continue; | ||
| 360 | |||
| 361 | // Special case for 24bit, as a pixel might cross page boundaries | ||
| 362 | if (cpp == 3 && offset + 3 > PAGE_SIZE) | ||
| 363 | drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], | ||
| 364 | offset, color); | ||
| 365 | else | ||
| 366 | drm_panic_write_pixel(vaddr, offset, color, cpp); | ||
| 325 | } | 367 | } |
| 326 | } | 368 | } |
| 327 | if (vaddr) | 369 | if (vaddr) |
| @@ -429,6 +471,9 @@ static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *f · 101 unmodified lines | |||
| 429 | static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, | 471 | static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, |
| 430 | const struct font_desc *font, u32 fg_color) | 472 | const struct font_desc *font, u32 fg_color) |
| 431 | { | 473 | { |
| 474 | if (rect->x2 > sb->width || rect->y2 > sb->height) | ||
| 475 | return; | ||
| 476 | |||
| 432 | if (logo_mono) | 477 | if (logo_mono) |
| 433 | drm_panic_blit(sb, rect, logo_mono->data, | 478 | drm_panic_blit(sb, rect, logo_mono->data, |
| 434 | DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); | 479 | DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); |
| @@ -477,7 +522,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_ · 42 unmodified lines | |||
| 477 | struct drm_panic_line *line, int yoffset, u32 fg_color) | 522 | struct drm_panic_line *line, int yoffset, u32 fg_color) |
| 478 | { | 523 | { |
| 479 | int chars_per_row = sb->width / font->width; | 524 | int chars_per_row = sb->width / font->width; |
| 480 | struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, sb->height); | 525 | struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height); |
| 481 | struct drm_panic_line line_wrap; | 526 | struct drm_panic_line line_wrap; |
| 482 | 527 | ||
| 483 | if (line->len > chars_per_row) { | 528 | if (line->len > chars_per_row) { |
| @@ -520,7 +565,7 @@ static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb) · 36 unmodified lines | |||
| 520 | struct drm_panic_line line; | 565 | struct drm_panic_line line; |
| 521 | int yoffset; | 566 | int yoffset; |
| 522 | 567 | ||
| 523 | if (!font) | 568 | if (!font || font->width > sb->width) |
| 524 | return; | 569 | return; |
| 525 | 570 | ||
| 526 | yoffset = sb->height - font->height - (sb->height % font->height) / 2; | 571 | yoffset = sb->height - font->height - (sb->height % font->height) / 2; |
| @@ -733,7 +778,10 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb) · 206 unmodified lines | |||
| 733 | pr_debug("QR width %d and scale %d\n", qr_width, scale); | 778 | pr_debug("QR width %d and scale %d\n", qr_width, scale); |
| 734 | r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); | 779 | r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); |
| 735 | 780 | ||
| 736 | v_margin = (sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg)) / 5; | 781 | v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg); |
| 782 | if (v_margin < 0) | ||
| 783 | return -ENOSPC; | ||
| 784 | v_margin /= 5; | ||
| 737 | 785 | ||
| 738 | drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); | 786 | drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); |
| 739 | r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, | 787 | r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, |
| @@ -746,7 +794,7 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb) · 6 unmodified lines | |||
| 746 | /* Fill with the background color, and draw text on top */ | 794 | /* Fill with the background color, and draw text on top */ |
| 747 | drm_panic_fill(sb, &r_screen, bg_color); | 795 | drm_panic_fill(sb, &r_screen, bg_color); |
| 748 | 796 | ||
| 749 | if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr)) | 797 | if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas)) |
| 750 | drm_panic_logo_draw(sb, &r_logo, font, fg_color); | 798 | drm_panic_logo_draw(sb, &r_logo, font, fg_color); |
| 751 | 799 | ||
| 752 | draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); | 800 | draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); |
| @@ -2117,6 +2117,7 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) · 2116 unmodified lines | |||
| 2117 | 2117 | ||
| 2118 | intel_frontbuffer_put(intel_fb->frontbuffer); | 2118 | intel_frontbuffer_put(intel_fb->frontbuffer); |
| 2119 | 2119 | ||
| 2120 | kfree(intel_fb->panic); | ||
| 2120 | kfree(intel_fb); | 2121 | kfree(intel_fb); |
| 2121 | } | 2122 | } |
| 2122 | 2123 | ||
| @@ -2215,16 +2216,22 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb, · 92 unmodified lines | |||
| 2215 | struct intel_display *display = to_intel_display(obj->dev); | 2216 | struct intel_display *display = to_intel_display(obj->dev); |
| 2216 | struct drm_framebuffer *fb = &intel_fb->base; | 2217 | struct drm_framebuffer *fb = &intel_fb->base; |
| 2217 | u32 max_stride; | 2218 | u32 max_stride; |
| 2218 | int ret = -EINVAL; | 2219 | int ret; |
| 2219 | int i; | 2220 | int i; |
| 2220 | 2221 | ||
| 2222 | intel_fb->panic = intel_panic_alloc(); | ||
| 2223 | if (!intel_fb->panic) | ||
| 2224 | return -ENOMEM; | ||
| 2225 | |||
| 2221 | /* | 2226 | /* |
| 2222 | * intel_frontbuffer_get() must be done before | 2227 | * intel_frontbuffer_get() must be done before |
| 2223 | * intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race. | 2228 | * intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race. |
| 2224 | */ | 2229 | */ |
| 2225 | intel_fb->frontbuffer = intel_frontbuffer_get(obj); | 2230 | intel_fb->frontbuffer = intel_frontbuffer_get(obj); |
| 2226 | if (!intel_fb->frontbuffer) | 2231 | if (!intel_fb->frontbuffer) { |
| 2227 | return -ENOMEM; | 2232 | ret = -ENOMEM; |
| 2233 | goto err_free_panic; | ||
| 2234 | } | ||
| 2228 | 2235 | ||
| 2229 | ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd); | 2236 | ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd); |
| 2230 | if (ret) | 2237 | if (ret) |
| @@ -2323,6 +2330,9 @@ err_bo_framebuffer_fini: · 92 unmodified lines | |||
| 2323 | intel_fb_bo_framebuffer_fini(obj); | 2330 | intel_fb_bo_framebuffer_fini(obj); |
| 2324 | err_frontbuffer_put: | 2331 | err_frontbuffer_put: |
| 2325 | intel_frontbuffer_put(intel_fb->frontbuffer); | 2332 | intel_frontbuffer_put(intel_fb->frontbuffer); |
| 2333 | err_free_panic: | ||
| 2334 | kfree(intel_fb->panic); | ||
| 2335 | |||
| 2326 | return ret; | 2336 | return ret; |
| 2327 | } | 2337 | } |
| 2328 | 2338 | ||
| @@ -2349,20 +2359,11 @@ intel_user_framebuffer_create(struct drm_device *dev, · 20 unmodified lines | |||
| 2349 | struct intel_framebuffer *intel_framebuffer_alloc(void) | 2359 | struct intel_framebuffer *intel_framebuffer_alloc(void) |
| 2350 | { | 2360 | { |
| 2351 | struct intel_framebuffer *intel_fb; | 2361 | struct intel_framebuffer *intel_fb; |
| 2352 | struct intel_panic *panic; | ||
| 2353 | 2362 | ||
| 2354 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); | 2363 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
| 2355 | if (!intel_fb) | 2364 | if (!intel_fb) |
| 2356 | return NULL; | 2365 | return NULL; |
| 2357 | 2366 | ||
| 2358 | panic = intel_panic_alloc(); | ||
| 2359 | if (!panic) { | ||
| 2360 | kfree(intel_fb); | ||
| 2361 | return NULL; | ||
| 2362 | } | ||
| 2363 | |||
| 2364 | intel_fb->panic = panic; | ||
| 2365 | |||
| 2366 | return intel_fb; | 2367 | return intel_fb; |
| 2367 | } | 2368 | } |
| 2368 | 2369 | ||
| @@ -1175,10 +1175,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx) · 1174 unmodified lines | |||
| 1175 | break; | 1175 | break; |
| 1176 | 1176 | ||
| 1177 | case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP: | 1177 | case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP: |
| 1178 | /* Partial unmaps might trigger a remap with either a prev or a next VA, | 1178 | /* Two VMAs can be needed for an unmap, as an unmap can happen |
| 1179 | * but not both. | 1179 | * in the middle of a drm_gpuva, requiring a remap with both |
| 1180 | * prev & next VA. Or an unmap can span more than one drm_gpuva | ||
| 1181 | * where the first and last ones are covered partially, requring | ||
| 1182 | * a remap for the first with a prev VA and remap for the last | ||
| 1183 | * with a next VA. | ||
| 1180 | */ | 1184 | */ |
| 1181 | vma_count = 1; | 1185 | vma_count = 2; |
| 1182 | break; | 1186 | break; |
| 1183 | 1187 | ||
| 1184 | default: | 1188 | default: |
| @@ -361,7 +361,7 @@ static void dw_hdmi_rk3228_setup_hpd(struct dw_hdmi *dw_hdmi, void *data) · 360 unmodified lines | |||
| 361 | 361 | ||
| 362 | regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2, | 362 | regmap_write(hdmi->regmap, RK3228_GRF_SOC_CON2, |
| 363 | FIELD_PREP_WM16(RK3228_HDMI_SDAIN_MSK, 1) | | 363 | FIELD_PREP_WM16(RK3228_HDMI_SDAIN_MSK, 1) | |
| 364 | FIELD_PREP_WM16(RK3328_HDMI_SCLIN_MSK, 1)); | 364 | FIELD_PREP_WM16(RK3228_HDMI_SCLIN_MSK, 1)); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | static enum drm_connector_status | 367 | static enum drm_connector_status |
| @@ -292,6 +292,9 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt) · 291 unmodified lines | |||
| 292 | ggtt->pt_ops = &xelp_pt_ops; | 292 | ggtt->pt_ops = &xelp_pt_ops; |
| 293 | 293 | ||
| 294 | ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM); | 294 | ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM); |
| 295 | if (!ggtt->wq) | ||
| 296 | return -ENOMEM; | ||
| 297 | |||
| 295 | __xe_ggtt_init_early(ggtt, xe_wopcm_size(xe)); | 298 | __xe_ggtt_init_early(ggtt, xe_wopcm_size(xe)); |
| 296 | 299 | ||
| 297 | err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt); | 300 | err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt); |
| @@ -2022,7 +2022,7 @@ static int op_prepare(struct xe_vm *vm, · 2021 unmodified lines | |||
| 2022 | case DRM_GPUVA_OP_MAP: | 2022 | case DRM_GPUVA_OP_MAP: |
| 2023 | if ((!op->map.immediate && xe_vm_in_fault_mode(vm) && | 2023 | if ((!op->map.immediate && xe_vm_in_fault_mode(vm) && |
| 2024 | !op->map.invalidate_on_bind) || | 2024 | !op->map.invalidate_on_bind) || |
| 2025 | op->map.is_cpu_addr_mirror) | 2025 | (op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR)) |
| 2026 | break; | 2026 | break; |
| 2027 | 2027 | ||
| 2028 | err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma, | 2028 | err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma, |
| @@ -2252,7 +2252,7 @@ static void op_commit(struct xe_vm *vm, · 223 unmodified lines | |||
| 2252 | switch (op->base.op) { | 2252 | switch (op->base.op) { |
| 2253 | case DRM_GPUVA_OP_MAP: | 2253 | case DRM_GPUVA_OP_MAP: |
| 2254 | if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) || | 2254 | if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) || |
| 2255 | op->map.is_cpu_addr_mirror) | 2255 | (op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR)) |
| 2256 | break; | 2256 | break; |
| 2257 | 2257 | ||
| 2258 | bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence, | 2258 | bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence, |
| @@ -302,6 +302,11 @@ static int xe_svm_range_set_default_attr(struct xe_vm *vm, u64 range_start, u64 · 301 unmodified lines | |||
| 302 | if (!vma) | 302 | if (!vma) |
| 303 | return -EINVAL; | 303 | return -EINVAL; |
| 304 | 304 | ||
| 305 | if (!(vma->gpuva.flags & XE_VMA_MADV_AUTORESET)) { | ||
| 306 | drm_dbg(&vm->xe->drm, "Skipping madvise reset for vma.\n"); | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 305 | if (xe_vma_has_default_mem_attrs(vma)) | 310 | if (xe_vma_has_default_mem_attrs(vma)) |
| 306 | return 0; | 311 | return 0; |
| 307 | 312 | ||
| @@ -616,6 +616,13 @@ static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask, · 615 unmodified lines | |||
| 616 | vops->pt_update_ops[i].num_ops += inc_val; | 616 | vops->pt_update_ops[i].num_ops += inc_val; |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | #define XE_VMA_CREATE_MASK ( \ | ||
| 620 | XE_VMA_READ_ONLY | \ | ||
| 621 | XE_VMA_DUMPABLE | \ | ||
| 622 | XE_VMA_SYSTEM_ALLOCATOR | \ | ||
| 623 | DRM_GPUVA_SPARSE | \ | ||
| 624 | XE_VMA_MADV_AUTORESET) | ||
| 625 | |||
| 619 | static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma, | 626 | static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma, |
| 620 | u8 tile_mask) | 627 | u8 tile_mask) |
| 621 | { | 628 | { |
| @@ -628,8 +635,7 @@ static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma, · 6 unmodified lines | |||
| 628 | op->base.map.gem.offset = vma->gpuva.gem.offset; | 635 | op->base.map.gem.offset = vma->gpuva.gem.offset; |
| 629 | op->map.vma = vma; | 636 | op->map.vma = vma; |
| 630 | op->map.immediate = true; | 637 | op->map.immediate = true; |
| 631 | op->map.dumpable = vma->gpuva.flags & XE_VMA_DUMPABLE; | 638 | op->map.vma_flags = vma->gpuva.flags & XE_VMA_CREATE_MASK; |
| 632 | op->map.is_null = xe_vma_is_null(vma); | ||
| 633 | } | 639 | } |
| 634 | 640 | ||
| 635 | static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma, | 641 | static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma, |
| @@ -932,11 +938,6 @@ static void xe_vma_free(struct xe_vma *vma) · 296 unmodified lines | |||
| 932 | kfree(vma); | 938 | kfree(vma); |
| 933 | } | 939 | } |
| 934 | 940 | ||
| 935 | #define VMA_CREATE_FLAG_READ_ONLY BIT(0) | ||
| 936 | #define VMA_CREATE_FLAG_IS_NULL BIT(1) | ||
| 937 | #define VMA_CREATE_FLAG_DUMPABLE BIT(2) | ||
| 938 | #define VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR BIT(3) | ||
| 939 | |||
| 940 | static struct xe_vma *xe_vma_create(struct xe_vm *vm, | 941 | static struct xe_vma *xe_vma_create(struct xe_vm *vm, |
| 941 | struct xe_bo *bo, | 942 | struct xe_bo *bo, |
| 942 | u64 bo_offset_or_userptr, | 943 | u64 bo_offset_or_userptr, |
| @@ -947,11 +948,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 4 unmodified lines | |||
| 947 | struct xe_vma *vma; | 948 | struct xe_vma *vma; |
| 948 | struct xe_tile *tile; | 949 | struct xe_tile *tile; |
| 949 | u8 id; | 950 | u8 id; |
| 950 | bool read_only = (flags & VMA_CREATE_FLAG_READ_ONLY); | 951 | bool is_null = (flags & DRM_GPUVA_SPARSE); |
| 951 | bool is_null = (flags & VMA_CREATE_FLAG_IS_NULL); | 952 | bool is_cpu_addr_mirror = (flags & XE_VMA_SYSTEM_ALLOCATOR); |
| 952 | bool dumpable = (flags & VMA_CREATE_FLAG_DUMPABLE); | ||
| 953 | bool is_cpu_addr_mirror = | ||
| 954 | (flags & VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR); | ||
| 955 | 953 | ||
| 956 | xe_assert(vm->xe, start < end); | 954 | xe_assert(vm->xe, start < end); |
| 957 | xe_assert(vm->xe, end < vm->size); | 955 | xe_assert(vm->xe, end < vm->size); |
| @@ -972,10 +970,6 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 14 unmodified lines | |||
| 972 | if (!vma) | 970 | if (!vma) |
| 973 | return ERR_PTR(-ENOMEM); | 971 | return ERR_PTR(-ENOMEM); |
| 974 | 972 | ||
| 975 | if (is_cpu_addr_mirror) | ||
| 976 | vma->gpuva.flags |= XE_VMA_SYSTEM_ALLOCATOR; | ||
| 977 | if (is_null) | ||
| 978 | vma->gpuva.flags |= DRM_GPUVA_SPARSE; | ||
| 979 | if (bo) | 973 | if (bo) |
| 980 | vma->gpuva.gem.obj = &bo->ttm.base; | 974 | vma->gpuva.gem.obj = &bo->ttm.base; |
| 981 | } | 975 | } |
| @@ -986,10 +980,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, · 4 unmodified lines | |||
| 986 | vma->gpuva.vm = &vm->gpuvm; | 980 | vma->gpuva.vm = &vm->gpuvm; |
| 987 | vma->gpuva.va.addr = start; | 981 | vma->gpuva.va.addr = start; |
| 988 | vma->gpuva.va.range = end - start + 1; | 982 | vma->gpuva.va.range = end - start + 1; |
| 989 | if (read_only) | 983 | vma->gpuva.flags = flags; |
| 990 | vma->gpuva.flags |= XE_VMA_READ_ONLY; | ||
| 991 | if (dumpable) | ||
| 992 | vma->gpuva.flags |= XE_VMA_DUMPABLE; | ||
| 993 | 984 | ||
| 994 | for_each_tile(tile, vm->xe, id) | 985 | for_each_tile(tile, vm->xe, id) |
| 995 | vma->tile_mask |= 0x1 << id; | 986 | vma->tile_mask |= 0x1 << id; |
| @@ -2272,12 +2263,16 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops, · 1276 unmodified lines | |||
| 2272 | if (__op->op == DRM_GPUVA_OP_MAP) { | 2263 | if (__op->op == DRM_GPUVA_OP_MAP) { |
| 2273 | op->map.immediate = | 2264 | op->map.immediate = |
| 2274 | flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE; | 2265 | flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE; |
| 2275 | op->map.read_only = | 2266 | if (flags & DRM_XE_VM_BIND_FLAG_READONLY) |
| 2276 | flags & DRM_XE_VM_BIND_FLAG_READONLY; | 2267 | op->map.vma_flags |= XE_VMA_READ_ONLY; |
| 2277 | op->map.is_null = flags & DRM_XE_VM_BIND_FLAG_NULL; | 2268 | if (flags & DRM_XE_VM_BIND_FLAG_NULL) |
| 2278 | op->map.is_cpu_addr_mirror = flags & | 2269 | op->map.vma_flags |= DRM_GPUVA_SPARSE; |
| 2279 | DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR; | 2270 | if (flags & DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR) |
| 2280 | op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE; | 2271 | op->map.vma_flags |= XE_VMA_SYSTEM_ALLOCATOR; |
| 2272 | if (flags & DRM_XE_VM_BIND_FLAG_DUMPABLE) | ||
| 2273 | op->map.vma_flags |= XE_VMA_DUMPABLE; | ||
| 2274 | if (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) | ||
| 2275 | op->map.vma_flags |= XE_VMA_MADV_AUTORESET; | ||
| 2281 | op->map.pat_index = pat_index; | 2276 | op->map.pat_index = pat_index; |
| 2282 | op->map.invalidate_on_bind = | 2277 | op->map.invalidate_on_bind = |
| 2283 | __xe_vm_needs_clear_scratch_pages(vm, flags); | 2278 | __xe_vm_needs_clear_scratch_pages(vm, flags); |
| @@ -2590,14 +2585,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops, · 306 unmodified lines | |||
| 2590 | .pat_index = op->map.pat_index, | 2585 | .pat_index = op->map.pat_index, |
| 2591 | }; | 2586 | }; |
| 2592 | 2587 | ||
| 2593 | flags |= op->map.read_only ? | 2588 | flags |= op->map.vma_flags & XE_VMA_CREATE_MASK; |
| 2594 | VMA_CREATE_FLAG_READ_ONLY : 0; | ||
| 2595 | flags |= op->map.is_null ? | ||
| 2596 | VMA_CREATE_FLAG_IS_NULL : 0; | ||
| 2597 | flags |= op->map.dumpable ? | ||
| 2598 | VMA_CREATE_FLAG_DUMPABLE : 0; | ||
| 2599 | flags |= op->map.is_cpu_addr_mirror ? | ||
| 2600 | VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0; | ||
| 2601 | 2589 | ||
| 2602 | vma = new_vma(vm, &op->base.map, &default_attr, | 2590 | vma = new_vma(vm, &op->base.map, &default_attr, |
| 2603 | flags); | 2591 | flags); |
| @@ -2606,7 +2594,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops, · 2 unmodified lines | |||
| 2606 | 2594 | ||
| 2607 | op->map.vma = vma; | 2595 | op->map.vma = vma; |
| 2608 | if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) && | 2596 | if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) && |
| 2609 | !op->map.is_cpu_addr_mirror) || | 2597 | !(op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR)) || |
| 2610 | op->map.invalidate_on_bind) | 2598 | op->map.invalidate_on_bind) |
| 2611 | xe_vma_ops_incr_pt_update_ops(vops, | 2599 | xe_vma_ops_incr_pt_update_ops(vops, |
| 2612 | op->tile_mask, 1); | 2600 | op->tile_mask, 1); |
| @@ -2637,18 +2625,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops, · 24 unmodified lines | |||
| 2637 | op->remap.start = xe_vma_start(old); | 2625 | op->remap.start = xe_vma_start(old); |
| 2638 | op->remap.range = xe_vma_size(old); | 2626 | op->remap.range = xe_vma_size(old); |
| 2639 | 2627 | ||
| 2640 | flags |= op->base.remap.unmap->va->flags & | 2628 | flags |= op->base.remap.unmap->va->flags & XE_VMA_CREATE_MASK; |
| 2641 | XE_VMA_READ_ONLY ? | ||
| 2642 | VMA_CREATE_FLAG_READ_ONLY : 0; | ||
| 2643 | flags |= op->base.remap.unmap->va->flags & | ||
| 2644 | DRM_GPUVA_SPARSE ? | ||
| 2645 | VMA_CREATE_FLAG_IS_NULL : 0; | ||
| 2646 | flags |= op->base.remap.unmap->va->flags & | ||
| 2647 | XE_VMA_DUMPABLE ? | ||
| 2648 | VMA_CREATE_FLAG_DUMPABLE : 0; | ||
| 2649 | flags |= xe_vma_is_cpu_addr_mirror(old) ? | ||
| 2650 | VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0; | ||
| 2651 | |||
| 2652 | if (op->base.remap.prev) { | 2629 | if (op->base.remap.prev) { |
| 2653 | vma = new_vma(vm, op->base.remap.prev, | 2630 | vma = new_vma(vm, op->base.remap.prev, |
| 2654 | &old->attr, flags); | 2631 | &old->attr, flags); |
| @@ -3279,7 +3256,8 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO); · 624 unmodified lines | |||
| 3279 | DRM_XE_VM_BIND_FLAG_NULL | \ | 3256 | DRM_XE_VM_BIND_FLAG_NULL | \ |
| 3280 | DRM_XE_VM_BIND_FLAG_DUMPABLE | \ | 3257 | DRM_XE_VM_BIND_FLAG_DUMPABLE | \ |
| 3281 | DRM_XE_VM_BIND_FLAG_CHECK_PXP | \ | 3258 | DRM_XE_VM_BIND_FLAG_CHECK_PXP | \ |
| 3282 | DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR) | 3259 | DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR | \ |
| 3260 | DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) | ||
| 3283 | 3261 | ||
| 3284 | #ifdef TEST_VM_OPS_ERROR | 3262 | #ifdef TEST_VM_OPS_ERROR |
| 3285 | #define SUPPORTED_FLAGS (SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR) | 3263 | #define SUPPORTED_FLAGS (SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR) |
| @@ -3394,7 +3372,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, · 108 unmodified lines | |||
| 3394 | XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC && | 3372 | XE_IOCTL_DBG(xe, (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC && |
| 3395 | !(BIT(prefetch_region) & xe->info.mem_region_mask))) || | 3373 | !(BIT(prefetch_region) & xe->info.mem_region_mask))) || |
| 3396 | XE_IOCTL_DBG(xe, obj && | 3374 | XE_IOCTL_DBG(xe, obj && |
| 3397 | op == DRM_XE_VM_BIND_OP_UNMAP)) { | 3375 | op == DRM_XE_VM_BIND_OP_UNMAP) || |
| 3376 | XE_IOCTL_DBG(xe, (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) && | ||
| 3377 | (!is_cpu_addr_mirror || op != DRM_XE_VM_BIND_OP_MAP))) { | ||
| 3398 | err = -EINVAL; | 3378 | err = -EINVAL; |
| 3399 | goto free_bind_ops; | 3379 | goto free_bind_ops; |
| 3400 | } | 3380 | } |
| @@ -4212,7 +4192,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm, · 811 unmodified lines | |||
| 4212 | struct xe_vma_ops vops; | 4192 | struct xe_vma_ops vops; |
| 4213 | struct drm_gpuva_ops *ops = NULL; | 4193 | struct drm_gpuva_ops *ops = NULL; |
| 4214 | struct drm_gpuva_op *__op; | 4194 | struct drm_gpuva_op *__op; |
| 4215 | bool is_cpu_addr_mirror = false; | 4195 | unsigned int vma_flags = 0; |
| 4216 | bool remap_op = false; | 4196 | bool remap_op = false; |
| 4217 | struct xe_vma_mem_attr tmp_attr; | 4197 | struct xe_vma_mem_attr tmp_attr; |
| 4218 | u16 default_pat; | 4198 | u16 default_pat; |
| @@ -4242,15 +4222,17 @@ static int xe_vm_alloc_vma(struct xe_vm *vm, · 23 unmodified lines | |||
| 4242 | vma = gpuva_to_vma(op->base.unmap.va); | 4222 | vma = gpuva_to_vma(op->base.unmap.va); |
| 4243 | XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma)); | 4223 | XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma)); |
| 4244 | default_pat = vma->attr.default_pat_index; | 4224 | default_pat = vma->attr.default_pat_index; |
| 4225 | vma_flags = vma->gpuva.flags; | ||
| 4245 | } | 4226 | } |
| 4246 | 4227 | ||
| 4247 | if (__op->op == DRM_GPUVA_OP_REMAP) { | 4228 | if (__op->op == DRM_GPUVA_OP_REMAP) { |
| 4248 | vma = gpuva_to_vma(op->base.remap.unmap->va); | 4229 | vma = gpuva_to_vma(op->base.remap.unmap->va); |
| 4249 | default_pat = vma->attr.default_pat_index; | 4230 | default_pat = vma->attr.default_pat_index; |
| 4231 | vma_flags = vma->gpuva.flags; | ||
| 4250 | } | 4232 | } |
| 4251 | 4233 | ||
| 4252 | if (__op->op == DRM_GPUVA_OP_MAP) { | 4234 | if (__op->op == DRM_GPUVA_OP_MAP) { |
| 4253 | op->map.is_cpu_addr_mirror = true; | 4235 | op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK; |
| 4254 | op->map.pat_index = default_pat; | 4236 | op->map.pat_index = default_pat; |
| 4255 | } | 4237 | } |
| 4256 | } else { | 4238 | } else { |
| @@ -4259,11 +4241,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm, · 2 unmodified lines | |||
| 4259 | xe_assert(vm->xe, !remap_op); | 4241 | xe_assert(vm->xe, !remap_op); |
| 4260 | xe_assert(vm->xe, xe_vma_has_no_bo(vma)); | 4242 | xe_assert(vm->xe, xe_vma_has_no_bo(vma)); |
| 4261 | remap_op = true; | 4243 | remap_op = true; |
| 4262 | 4244 | vma_flags = vma->gpuva.flags; | |
| 4263 | if (xe_vma_is_cpu_addr_mirror(vma)) | ||
| 4264 | is_cpu_addr_mirror = true; | ||
| 4265 | else | ||
| 4266 | is_cpu_addr_mirror = false; | ||
| 4267 | } | 4245 | } |
| 4268 | 4246 | ||
| 4269 | if (__op->op == DRM_GPUVA_OP_MAP) { | 4247 | if (__op->op == DRM_GPUVA_OP_MAP) { |
| @@ -4272,10 +4250,10 @@ static int xe_vm_alloc_vma(struct xe_vm *vm, · 2 unmodified lines | |||
| 4272 | /* | 4250 | /* |
| 4273 | * In case of madvise ops DRM_GPUVA_OP_MAP is | 4251 | * In case of madvise ops DRM_GPUVA_OP_MAP is |
| 4274 | * always after DRM_GPUVA_OP_REMAP, so ensure | 4252 | * always after DRM_GPUVA_OP_REMAP, so ensure |
| 4275 | * we assign op->map.is_cpu_addr_mirror true | 4253 | * to propagate the flags from the vma we're |
| 4276 | * if REMAP is for xe_vma_is_cpu_addr_mirror vma | 4254 | * unmapping. |
| 4277 | */ | 4255 | */ |
| 4278 | op->map.is_cpu_addr_mirror = is_cpu_addr_mirror; | 4256 | op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK; |
| 4279 | } | 4257 | } |
| 4280 | } | 4258 | } |
| 4281 | print_op(vm->xe, __op); | 4259 | print_op(vm->xe, __op); |
| @@ -46,6 +46,7 @@ struct xe_vm_pgtable_update_op; · 45 unmodified lines | |||
| 46 | #define XE_VMA_PTE_COMPACT (DRM_GPUVA_USERBITS << 7) | 46 | #define XE_VMA_PTE_COMPACT (DRM_GPUVA_USERBITS << 7) |
| 47 | #define XE_VMA_DUMPABLE (DRM_GPUVA_USERBITS << 8) | 47 | #define XE_VMA_DUMPABLE (DRM_GPUVA_USERBITS << 8) |
| 48 | #define XE_VMA_SYSTEM_ALLOCATOR (DRM_GPUVA_USERBITS << 9) | 48 | #define XE_VMA_SYSTEM_ALLOCATOR (DRM_GPUVA_USERBITS << 9) |
| 49 | #define XE_VMA_MADV_AUTORESET (DRM_GPUVA_USERBITS << 10) | ||
| 49 | 50 | ||
| 50 | /** | 51 | /** |
| 51 | * struct xe_vma_mem_attr - memory attributes associated with vma | 52 | * struct xe_vma_mem_attr - memory attributes associated with vma |
| @@ -345,17 +346,10 @@ struct xe_vm { · 293 unmodified lines | |||
| 345 | struct xe_vma_op_map { | 346 | struct xe_vma_op_map { |
| 346 | /** @vma: VMA to map */ | 347 | /** @vma: VMA to map */ |
| 347 | struct xe_vma *vma; | 348 | struct xe_vma *vma; |
| 349 | unsigned int vma_flags; | ||
| 348 | /** @immediate: Immediate bind */ | 350 | /** @immediate: Immediate bind */ |
| 349 | bool immediate; | 351 | bool immediate; |
| 350 | /** @read_only: Read only */ | 352 | /** @read_only: Read only */ |
| 351 | bool read_only; | ||
| 352 | /** @is_null: is NULL binding */ | ||
| 353 | bool is_null; | ||
| 354 | /** @is_cpu_addr_mirror: is CPU address mirror binding */ | ||
| 355 | bool is_cpu_addr_mirror; | ||
| 356 | /** @dumpable: whether BO is dumped on GPU hang */ | ||
| 357 | bool dumpable; | ||
| 358 | /** @invalidate: invalidate the VMA before bind */ | ||
| 359 | bool invalidate_on_bind; | 353 | bool invalidate_on_bind; |
| 360 | /** @pat_index: The pat index to use for this operation. */ | 354 | /** @pat_index: The pat index to use for this operation. */ |
| 361 | u16 pat_index; | 355 | u16 pat_index; |
| @@ -107,6 +107,9 @@ static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data * · 106 unmodified lines | |||
| 107 | nb_sensors = data[0]; | 107 | nb_sensors = data[0]; |
| 108 | 108 | ||
| 109 | hwmon->sensors = devm_kzalloc(dev, sizeof(*hwmon->sensors) * nb_sensors, GFP_KERNEL); | 109 | hwmon->sensors = devm_kzalloc(dev, sizeof(*hwmon->sensors) * nb_sensors, GFP_KERNEL); |
| 110 | if (!hwmon->sensors) | ||
| 111 | return -ENOMEM; | ||
| 112 | |||
| 110 | sensor = hwmon->sensors; | 113 | sensor = hwmon->sensors; |
| 111 | 114 | ||
| 112 | for (i = 0; i < nb_sensors; i++) { | 115 | for (i = 0; i < nb_sensors; i++) { |
| @@ -615,14 +615,14 @@ static int gpd_fan_probe(struct platform_device *pdev) · 614 unmodified lines | |||
| 615 | const struct device *hwdev; | 615 | const struct device *hwdev; |
| 616 | 616 | ||
| 617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 617 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 618 | if (IS_ERR(res)) | 618 | if (!res) |
| 619 | return dev_err_probe(dev, PTR_ERR(res), | 619 | return dev_err_probe(dev, -EINVAL, |
| 620 | "Failed to get platform resource\n"); | 620 | "Failed to get platform resource\n"); |
| 621 | 621 | ||
| 622 | region = devm_request_region(dev, res->start, | 622 | region = devm_request_region(dev, res->start, |
| 623 | resource_size(res), DRIVER_NAME); | 623 | resource_size(res), DRIVER_NAME); |
| 624 | if (IS_ERR(region)) | 624 | if (!region) |
| 625 | return dev_err_probe(dev, PTR_ERR(region), | 625 | return dev_err_probe(dev, -EBUSY, |
| 626 | "Failed to request region\n"); | 626 | "Failed to request region\n"); |
| 627 | 627 | ||
| 628 | hwdev = devm_hwmon_device_register_with_info(dev, | 628 | hwdev = devm_hwmon_device_register_with_info(dev, |
| @@ -631,7 +631,7 @@ static int gpd_fan_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 631 | &gpd_fan_chip_info, | 631 | &gpd_fan_chip_info, |
| 632 | NULL); | 632 | NULL); |
| 633 | if (IS_ERR(hwdev)) | 633 | if (IS_ERR(hwdev)) |
| 634 | return dev_err_probe(dev, PTR_ERR(region), | 634 | return dev_err_probe(dev, PTR_ERR(hwdev), |
| 635 | "Failed to register hwmon device\n"); | 635 | "Failed to register hwmon device\n"); |
| 636 | 636 | ||
| 637 | return 0; | 637 | return 0; |
| @@ -336,10 +336,9 @@ static int isl68137_probe_from_dt(struct device *dev, · 335 unmodified lines | |||
| 336 | struct isl68137_data *data) | 336 | struct isl68137_data *data) |
| 337 | { | 337 | { |
| 338 | const struct device_node *np = dev->of_node; | 338 | const struct device_node *np = dev->of_node; |
| 339 | struct device_node *child; | ||
| 340 | int err; | 339 | int err; |
| 341 | 340 | ||
| 342 | for_each_child_of_node(np, child) { | 341 | for_each_child_of_node_scoped(np, child) { |
| 343 | if (strcmp(child->name, "channel")) | 342 | if (strcmp(child->name, "channel")) |
| 344 | continue; | 343 | continue; |
| 345 | 344 | ||
| @@ -336,18 +336,18 @@ static struct pmbus_driver_info max34440_info[] = { · 335 unmodified lines | |||
| 336 | .format[PSC_CURRENT_IN] = direct, | 336 | .format[PSC_CURRENT_IN] = direct, |
| 337 | .format[PSC_CURRENT_OUT] = direct, | 337 | .format[PSC_CURRENT_OUT] = direct, |
| 338 | .format[PSC_TEMPERATURE] = direct, | 338 | .format[PSC_TEMPERATURE] = direct, |
| 339 | .m[PSC_VOLTAGE_IN] = 1, | 339 | .m[PSC_VOLTAGE_IN] = 125, |
| 340 | .b[PSC_VOLTAGE_IN] = 0, | 340 | .b[PSC_VOLTAGE_IN] = 0, |
| 341 | .R[PSC_VOLTAGE_IN] = 0, | 341 | .R[PSC_VOLTAGE_IN] = 0, |
| 342 | .m[PSC_VOLTAGE_OUT] = 1, | 342 | .m[PSC_VOLTAGE_OUT] = 125, |
| 343 | .b[PSC_VOLTAGE_OUT] = 0, | 343 | .b[PSC_VOLTAGE_OUT] = 0, |
| 344 | .R[PSC_VOLTAGE_OUT] = 0, | 344 | .R[PSC_VOLTAGE_OUT] = 0, |
| 345 | .m[PSC_CURRENT_IN] = 1, | 345 | .m[PSC_CURRENT_IN] = 250, |
| 346 | .b[PSC_CURRENT_IN] = 0, | 346 | .b[PSC_CURRENT_IN] = 0, |
| 347 | .R[PSC_CURRENT_IN] = 2, | 347 | .R[PSC_CURRENT_IN] = -1, |
| 348 | .m[PSC_CURRENT_OUT] = 1, | 348 | .m[PSC_CURRENT_OUT] = 250, |
| 349 | .b[PSC_CURRENT_OUT] = 0, | 349 | .b[PSC_CURRENT_OUT] = 0, |
| 350 | .R[PSC_CURRENT_OUT] = 2, | 350 | .R[PSC_CURRENT_OUT] = -1, |
| 351 | .m[PSC_TEMPERATURE] = 1, | 351 | .m[PSC_TEMPERATURE] = 1, |
| 352 | .b[PSC_TEMPERATURE] = 0, | 352 | .b[PSC_TEMPERATURE] = 0, |
| 353 | .R[PSC_TEMPERATURE] = 2, | 353 | .R[PSC_TEMPERATURE] = 2, |
| @@ -291,24 +291,26 @@ out: · 290 unmodified lines | |||
| 291 | return data; | 291 | return data; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static int temp1_input_read(struct device *dev) | 294 | static int temp1_input_read(struct device *dev, long *temp) |
| 295 | { | 295 | { |
| 296 | struct sht3x_data *data = sht3x_update_client(dev); | 296 | struct sht3x_data *data = sht3x_update_client(dev); |
| 297 | 297 | ||
| 298 | if (IS_ERR(data)) | 298 | if (IS_ERR(data)) |
| 299 | return PTR_ERR(data); | 299 | return PTR_ERR(data); |
| 300 | 300 | ||
| 301 | return data->temperature; | 301 | *temp = data->temperature; |
| 302 | return 0; | ||
| 302 | } | 303 | } |
| 303 | 304 | ||
| 304 | static int humidity1_input_read(struct device *dev) | 305 | static int humidity1_input_read(struct device *dev, long *humidity) |
| 305 | { | 306 | { |
| 306 | struct sht3x_data *data = sht3x_update_client(dev); | 307 | struct sht3x_data *data = sht3x_update_client(dev); |
| 307 | 308 | ||
| 308 | if (IS_ERR(data)) | 309 | if (IS_ERR(data)) |
| 309 | return PTR_ERR(data); | 310 | return PTR_ERR(data); |
| 310 | 311 | ||
| 311 | return data->humidity; | 312 | *humidity = data->humidity; |
| 313 | return 0; | ||
| 312 | } | 314 | } |
| 313 | 315 | ||
| 314 | /* | 316 | /* |
| @@ -706,6 +708,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, · 391 unmodified lines | |||
| 706 | u32 attr, int channel, long *val) | 708 | u32 attr, int channel, long *val) |
| 707 | { | 709 | { |
| 708 | enum sht3x_limits index; | 710 | enum sht3x_limits index; |
| 711 | int ret; | ||
| 709 | 712 | ||
| 710 | switch (type) { | 713 | switch (type) { |
| 711 | case hwmon_chip: | 714 | case hwmon_chip: |
| @@ -720,10 +723,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, · 8 unmodified lines | |||
| 720 | case hwmon_temp: | 723 | case hwmon_temp: |
| 721 | switch (attr) { | 724 | switch (attr) { |
| 722 | case hwmon_temp_input: | 725 | case hwmon_temp_input: |
| 723 | *val = temp1_input_read(dev); | 726 | return temp1_input_read(dev, val); |
| 724 | break; | ||
| 725 | case hwmon_temp_alarm: | 727 | case hwmon_temp_alarm: |
| 726 | *val = temp1_alarm_read(dev); | 728 | ret = temp1_alarm_read(dev); |
| 729 | if (ret < 0) | ||
| 730 | return ret; | ||
| 731 | *val = ret; | ||
| 727 | break; | 732 | break; |
| 728 | case hwmon_temp_max: | 733 | case hwmon_temp_max: |
| 729 | index = limit_max; | 734 | index = limit_max; |
| @@ -748,10 +753,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, · 18 unmodified lines | |||
| 748 | case hwmon_humidity: | 753 | case hwmon_humidity: |
| 749 | switch (attr) { | 754 | switch (attr) { |
| 750 | case hwmon_humidity_input: | 755 | case hwmon_humidity_input: |
| 751 | *val = humidity1_input_read(dev); | 756 | return humidity1_input_read(dev, val); |
| 752 | break; | ||
| 753 | case hwmon_humidity_alarm: | 757 | case hwmon_humidity_alarm: |
| 754 | *val = humidity1_alarm_read(dev); | 758 | ret = humidity1_alarm_read(dev); |
| 759 | if (ret < 0) | ||
| 760 | return ret; | ||
| 761 | *val = ret; | ||
| 755 | break; | 762 | break; |
| 756 | case hwmon_humidity_max: | 763 | case hwmon_humidity_max: |
| 757 | index = limit_max; | 764 | index = limit_max; |
| @@ -2,9 +2,11 @@ · 1 unmodified line | |||
| 2 | config AMD_SBRMI_I2C | 2 | config AMD_SBRMI_I2C |
| 3 | tristate "AMD side band RMI support" | 3 | tristate "AMD side band RMI support" |
| 4 | depends on I2C | 4 | depends on I2C |
| 5 | depends on ARM || ARM64 || COMPILE_TEST | ||
| 5 | select REGMAP_I2C | 6 | select REGMAP_I2C |
| 6 | help | 7 | help |
| 7 | Side band RMI over I2C support for AMD out of band management. | 8 | Side band RMI over I2C support for AMD out of band management. |
| 9 | This driver is intended to run on the BMC, not the managed node. | ||
| 8 | 10 | ||
| 9 | This driver can also be built as a module. If so, the module will | 11 | This driver can also be built as a module. If so, the module will |
| 10 | be called sbrmi-i2c. | 12 | be called sbrmi-i2c. |
| @@ -381,6 +381,8 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, · 380 unmodified lines | |||
| 381 | } | 381 | } |
| 382 | spin_unlock(&fl->lock); | 382 | spin_unlock(&fl->lock); |
| 383 | 383 | ||
| 384 | dma_buf_put(buf); | ||
| 385 | |||
| 384 | return ret; | 386 | return ret; |
| 385 | } | 387 | } |
| 386 | 388 | ||
| @@ -120,6 +120,8 @@ · 119 unmodified lines | |||
| 120 | #define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */ | 120 | #define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */ |
| 121 | #define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */ | 121 | #define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */ |
| 122 | 122 | ||
| 123 | #define MEI_DEV_ID_WCL_P 0x4D70 /* Wildcat Lake P */ | ||
| 124 | |||
| 123 | /* | 125 | /* |
| 124 | * MEI HW Section | 126 | * MEI HW Section |
| 125 | */ | 127 | */ |
| @@ -134,8 +134,7 @@ static bool mei_lb_check_response(const struct device *dev, ssize_t bytes, · 133 unmodified lines | |||
| 134 | return true; | 134 | return true; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static int mei_lb_push_payload(struct device *dev, | 137 | static int mei_lb_push_payload(struct device *dev, u32 type, u32 flags, |
| 138 | enum intel_lb_type type, u32 flags, | ||
| 139 | const void *payload, size_t payload_size) | 138 | const void *payload, size_t payload_size) |
| 140 | { | 139 | { |
| 141 | struct mei_cl_device *cldev; | 140 | struct mei_cl_device *cldev; |
| @@ -127,6 +127,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 126 unmodified lines | |||
| 127 | {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)}, | 127 | {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)}, |
| 128 | {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)}, | 128 | {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)}, |
| 129 | 129 | ||
| 130 | {MEI_PCI_DEVICE(MEI_DEV_ID_WCL_P, MEI_ME_PCH15_CFG)}, | ||
| 131 | |||
| 130 | /* required last entry */ | 132 | /* required last entry */ |
| 131 | {0, } | 133 | {0, } |
| 132 | }; | 134 | }; |
| @@ -109,19 +109,19 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 108 unmodified lines | |||
| 109 | goto end; | 109 | goto end; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | err = mei_register(dev, &pdev->dev); | ||
| 113 | if (err) | ||
| 114 | goto release_irq; | ||
| 115 | |||
| 112 | if (mei_start(dev)) { | 116 | if (mei_start(dev)) { |
| 113 | dev_err(&pdev->dev, "init hw failure.\n"); | 117 | dev_err(&pdev->dev, "init hw failure.\n"); |
| 114 | err = -ENODEV; | 118 | err = -ENODEV; |
| 115 | goto release_irq; | 119 | goto deregister; |
| 116 | } | 120 | } |
| 117 | 121 | ||
| 118 | pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT); | 122 | pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT); |
| 119 | pm_runtime_use_autosuspend(&pdev->dev); | 123 | pm_runtime_use_autosuspend(&pdev->dev); |
| 120 | 124 | ||
| 121 | err = mei_register(dev, &pdev->dev); | ||
| 122 | if (err) | ||
| 123 | goto stop; | ||
| 124 | |||
| 125 | pci_set_drvdata(pdev, dev); | 125 | pci_set_drvdata(pdev, dev); |
| 126 | 126 | ||
| 127 | /* | 127 | /* |
| @@ -144,8 +144,8 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 16 unmodified lines | |||
| 144 | 144 | ||
| 145 | return 0; | 145 | return 0; |
| 146 | 146 | ||
| 147 | stop: | 147 | deregister: |
| 148 | mei_stop(dev); | 148 | mei_deregister(dev); |
| 149 | release_irq: | 149 | release_irq: |
| 150 | mei_cancel_work(dev); | 150 | mei_cancel_work(dev); |
| 151 | mei_disable_interrupts(dev); | 151 | mei_disable_interrupts(dev); |
| @@ -1737,7 +1737,7 @@ static int vmballoon_migratepage(struct balloon_dev_info *b_dev_info, · 1736 unmodified lines | |||
| 1737 | { | 1737 | { |
| 1738 | unsigned long status, flags; | 1738 | unsigned long status, flags; |
| 1739 | struct vmballoon *b; | 1739 | struct vmballoon *b; |
| 1740 | int ret; | 1740 | int ret = 0; |
| 1741 | 1741 | ||
| 1742 | b = container_of(b_dev_info, struct vmballoon, b_dev_info); | 1742 | b = container_of(b_dev_info, struct vmballoon, b_dev_info); |
| 1743 | 1743 | ||
| @@ -1796,17 +1796,15 @@ static int vmballoon_migratepage(struct balloon_dev_info *b_dev_info, · 52 unmodified lines | |||
| 1796 | * A failure happened. While we can deflate the page we just | 1796 | * A failure happened. While we can deflate the page we just |
| 1797 | * inflated, this deflation can also encounter an error. Instead | 1797 | * inflated, this deflation can also encounter an error. Instead |
| 1798 | * we will decrease the size of the balloon to reflect the | 1798 | * we will decrease the size of the balloon to reflect the |
| 1799 | * change and report failure. | 1799 | * change. |
| 1800 | */ | 1800 | */ |
| 1801 | atomic64_dec(&b->size); | 1801 | atomic64_dec(&b->size); |
| 1802 | ret = -EBUSY; | ||
| 1803 | } else { | 1802 | } else { |
| 1804 | /* | 1803 | /* |
| 1805 | * Success. Take a reference for the page, and we will add it to | 1804 | * Success. Take a reference for the page, and we will add it to |
| 1806 | * the list after acquiring the lock. | 1805 | * the list after acquiring the lock. |
| 1807 | */ | 1806 | */ |
| 1808 | get_page(newpage); | 1807 | get_page(newpage); |
| 1809 | ret = 0; | ||
| 1810 | } | 1808 | } |
| 1811 | 1809 | ||
| 1812 | /* Update the balloon list under the @pages_lock */ | 1810 | /* Update the balloon list under the @pages_lock */ |
| @@ -1817,7 +1815,7 @@ static int vmballoon_migratepage(struct balloon_dev_info *b_dev_info, · 4 unmodified lines | |||
| 1817 | * If we succeed just insert it to the list and update the statistics | 1815 | * If we succeed just insert it to the list and update the statistics |
| 1818 | * under the lock. | 1816 | * under the lock. |
| 1819 | */ | 1817 | */ |
| 1820 | if (!ret) { | 1818 | if (status == VMW_BALLOON_SUCCESS) { |
| 1821 | balloon_page_insert(&b->b_dev_info, newpage); | 1819 | balloon_page_insert(&b->b_dev_info, newpage); |
| 1822 | __count_vm_event(BALLOON_MIGRATE); | 1820 | __count_vm_event(BALLOON_MIGRATE); |
| 1823 | } | 1821 | } |
| @@ -929,6 +929,10 @@ static void release_mdev(struct device *dev) · 928 unmodified lines | |||
| 929 | { | 929 | { |
| 930 | struct most_dev *mdev = to_mdev_from_dev(dev); | 930 | struct most_dev *mdev = to_mdev_from_dev(dev); |
| 931 | 931 | ||
| 932 | kfree(mdev->busy_urbs); | ||
| 933 | kfree(mdev->cap); | ||
| 934 | kfree(mdev->conf); | ||
| 935 | kfree(mdev->ep_address); | ||
| 932 | kfree(mdev); | 936 | kfree(mdev); |
| 933 | } | 937 | } |
| 934 | /** | 938 | /** |
| @@ -1093,7 +1097,7 @@ err_free_cap: · 158 unmodified lines | |||
| 1093 | err_free_conf: | 1097 | err_free_conf: |
| 1094 | kfree(mdev->conf); | 1098 | kfree(mdev->conf); |
| 1095 | err_free_mdev: | 1099 | err_free_mdev: |
| 1096 | put_device(&mdev->dev); | 1100 | kfree(mdev); |
| 1097 | return ret; | 1101 | return ret; |
| 1098 | } | 1102 | } |
| 1099 | 1103 | ||
| @@ -1121,13 +1125,6 @@ static void hdm_disconnect(struct usb_interface *interface) · 21 unmodified lines | |||
| 1121 | if (mdev->dci) | 1125 | if (mdev->dci) |
| 1122 | device_unregister(&mdev->dci->dev); | 1126 | device_unregister(&mdev->dci->dev); |
| 1123 | most_deregister_interface(&mdev->iface); | 1127 | most_deregister_interface(&mdev->iface); |
| 1124 | |||
| 1125 | kfree(mdev->busy_urbs); | ||
| 1126 | kfree(mdev->cap); | ||
| 1127 | kfree(mdev->conf); | ||
| 1128 | kfree(mdev->ep_address); | ||
| 1129 | put_device(&mdev->dci->dev); | ||
| 1130 | put_device(&mdev->dev); | ||
| 1131 | } | 1128 | } |
| 1132 | 1129 | ||
| 1133 | static int hdm_suspend(struct usb_interface *interface, pm_message_t message) | 1130 | static int hdm_suspend(struct usb_interface *interface, pm_message_t message) |
| @@ -2287,7 +2287,9 @@ skip_mac_set: · 2286 unmodified lines | |||
| 2287 | unblock_netpoll_tx(); | 2287 | unblock_netpoll_tx(); |
| 2288 | } | 2288 | } |
| 2289 | 2289 | ||
| 2290 | if (bond_mode_can_use_xmit_hash(bond)) | 2290 | /* broadcast mode uses the all_slaves to loop through slaves. */ |
| 2291 | if (bond_mode_can_use_xmit_hash(bond) || | ||
| 2292 | BOND_MODE(bond) == BOND_MODE_BROADCAST) | ||
| 2291 | bond_update_slave_arr(bond, NULL); | 2293 | bond_update_slave_arr(bond, NULL); |
| 2292 | 2294 | ||
| 2293 | if (!slave_dev->netdev_ops->ndo_bpf || | 2295 | if (!slave_dev->netdev_ops->ndo_bpf || |
| @@ -2463,7 +2465,8 @@ static int __bond_release_one(struct net_device *bond_dev, · 169 unmodified lines | |||
| 2463 | 2465 | ||
| 2464 | bond_upper_dev_unlink(bond, slave); | 2466 | bond_upper_dev_unlink(bond, slave); |
| 2465 | 2467 | ||
| 2466 | if (bond_mode_can_use_xmit_hash(bond)) | 2468 | if (bond_mode_can_use_xmit_hash(bond) || |
| 2469 | BOND_MODE(bond) == BOND_MODE_BROADCAST) | ||
| 2467 | bond_update_slave_arr(bond, slave); | 2470 | bond_update_slave_arr(bond, slave); |
| 2468 | 2471 | ||
| 2469 | slave_info(bond_dev, slave_dev, "Releasing %s interface\n", | 2472 | slave_info(bond_dev, slave_dev, "Releasing %s interface\n", |
| @@ -2871,7 +2874,7 @@ static void bond_mii_monitor(struct work_struct *work) · 401 unmodified lines | |||
| 2871 | { | 2874 | { |
| 2872 | struct bonding *bond = container_of(work, struct bonding, | 2875 | struct bonding *bond = container_of(work, struct bonding, |
| 2873 | mii_work.work); | 2876 | mii_work.work); |
| 2874 | bool should_notify_peers = false; | 2877 | bool should_notify_peers; |
| 2875 | bool commit; | 2878 | bool commit; |
| 2876 | unsigned long delay; | 2879 | unsigned long delay; |
| 2877 | struct slave *slave; | 2880 | struct slave *slave; |
| @@ -2883,30 +2886,33 @@ static void bond_mii_monitor(struct work_struct *work) · 5 unmodified lines | |||
| 2883 | goto re_arm; | 2886 | goto re_arm; |
| 2884 | 2887 | ||
| 2885 | rcu_read_lock(); | 2888 | rcu_read_lock(); |
| 2889 | |||
| 2886 | should_notify_peers = bond_should_notify_peers(bond); | 2890 | should_notify_peers = bond_should_notify_peers(bond); |
| 2887 | commit = !!bond_miimon_inspect(bond); | 2891 | commit = !!bond_miimon_inspect(bond); |
| 2888 | if (bond->send_peer_notif) { | ||
| 2889 | rcu_read_unlock(); | ||
| 2890 | if (rtnl_trylock()) { | ||
| 2891 | bond->send_peer_notif--; | ||
| 2892 | rtnl_unlock(); | ||
| 2893 | } | ||
| 2894 | } else { | ||
| 2895 | rcu_read_unlock(); | ||
| 2896 | } | ||
| 2897 | 2892 | ||
| 2898 | if (commit) { | 2893 | rcu_read_unlock(); |
| 2894 | |||
| 2895 | if (commit || bond->send_peer_notif) { | ||
| 2899 | /* Race avoidance with bond_close cancel of workqueue */ | 2896 | /* Race avoidance with bond_close cancel of workqueue */ |
| 2900 | if (!rtnl_trylock()) { | 2897 | if (!rtnl_trylock()) { |
| 2901 | delay = 1; | 2898 | delay = 1; |
| 2902 | should_notify_peers = false; | ||
| 2903 | goto re_arm; | 2899 | goto re_arm; |
| 2904 | } | 2900 | } |
| 2905 | 2901 | ||
| 2906 | bond_for_each_slave(bond, slave, iter) { | 2902 | if (commit) { |
| 2907 | bond_commit_link_state(slave, BOND_SLAVE_NOTIFY_LATER); | 2903 | bond_for_each_slave(bond, slave, iter) { |
| 2904 | bond_commit_link_state(slave, | ||
| 2905 | BOND_SLAVE_NOTIFY_LATER); | ||
| 2906 | } | ||
| 2907 | bond_miimon_commit(bond); | ||
| 2908 | } | ||
| 2909 | |||
| 2910 | if (bond->send_peer_notif) { | ||
| 2911 | bond->send_peer_notif--; | ||
| 2912 | if (should_notify_peers) | ||
| 2913 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | ||
| 2914 | bond->dev); | ||
| 2908 | } | 2915 | } |
| 2909 | bond_miimon_commit(bond); | ||
| 2910 | 2916 | ||
| 2911 | rtnl_unlock(); /* might sleep, hold no other locks */ | 2917 | rtnl_unlock(); /* might sleep, hold no other locks */ |
| 2912 | } | 2918 | } |
| @@ -2914,13 +2920,6 @@ static void bond_mii_monitor(struct work_struct *work) · 1 unmodified line | |||
| 2914 | re_arm: | 2920 | re_arm: |
| 2915 | if (bond->params.miimon) | 2921 | if (bond->params.miimon) |
| 2916 | queue_delayed_work(bond->wq, &bond->mii_work, delay); | 2922 | queue_delayed_work(bond->wq, &bond->mii_work, delay); |
| 2917 | |||
| 2918 | if (should_notify_peers) { | ||
| 2919 | if (!rtnl_trylock()) | ||
| 2920 | return; | ||
| 2921 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); | ||
| 2922 | rtnl_unlock(); | ||
| 2923 | } | ||
| 2924 | } | 2923 | } |
| 2925 | 2924 | ||
| 2926 | static int bond_upper_dev_walk(struct net_device *upper, | 2925 | static int bond_upper_dev_walk(struct net_device *upper, |
| @@ -842,7 +842,7 @@ static netdev_tx_t bxcan_start_xmit(struct sk_buff *skb, · 841 unmodified lines | |||
| 842 | u32 id; | 842 | u32 id; |
| 843 | int i, j; | 843 | int i, j; |
| 844 | 844 | ||
| 845 | if (can_dropped_invalid_skb(ndev, skb)) | 845 | if (can_dev_dropped_skb(ndev, skb)) |
| 846 | return NETDEV_TX_OK; | 846 | return NETDEV_TX_OK; |
| 847 | 847 | ||
| 848 | if (bxcan_tx_busy(priv)) | 848 | if (bxcan_tx_busy(priv)) |
| @@ -452,7 +452,9 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], · 451 unmodified lines | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | if (data[IFLA_CAN_RESTART_MS]) { | 454 | if (data[IFLA_CAN_RESTART_MS]) { |
| 455 | if (!priv->do_set_mode) { | 455 | unsigned int restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); |
| 456 | |||
| 457 | if (restart_ms != 0 && !priv->do_set_mode) { | ||
| 456 | NL_SET_ERR_MSG(extack, | 458 | NL_SET_ERR_MSG(extack, |
| 457 | "Device doesn't support restart from Bus Off"); | 459 | "Device doesn't support restart from Bus Off"); |
| 458 | return -EOPNOTSUPP; | 460 | return -EOPNOTSUPP; |
| @@ -461,7 +463,7 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], · 2 unmodified lines | |||
| 461 | /* Do not allow changing restart delay while running */ | 463 | /* Do not allow changing restart delay while running */ |
| 462 | if (dev->flags & IFF_UP) | 464 | if (dev->flags & IFF_UP) |
| 463 | return -EBUSY; | 465 | return -EBUSY; |
| 464 | priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); | 466 | priv->restart_ms = restart_ms; |
| 465 | } | 467 | } |
| 466 | 468 | ||
| 467 | if (data[IFLA_CAN_RESTART]) { | 469 | if (data[IFLA_CAN_RESTART]) { |
| @@ -254,7 +254,7 @@ netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 253 unmodified lines | |||
| 254 | u32 acc_id; | 254 | u32 acc_id; |
| 255 | u32 acc_dlc; | 255 | u32 acc_dlc; |
| 256 | 256 | ||
| 257 | if (can_dropped_invalid_skb(netdev, skb)) | 257 | if (can_dev_dropped_skb(netdev, skb)) |
| 258 | return NETDEV_TX_OK; | 258 | return NETDEV_TX_OK; |
| 259 | 259 | ||
| 260 | /* Access core->tx_fifo_tail only once because it may be changed | 260 | /* Access core->tx_fifo_tail only once because it may be changed |
| @@ -72,7 +72,7 @@ netdev_tx_t rkcanfd_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 71 unmodified lines | |||
| 72 | int err; | 72 | int err; |
| 73 | u8 i; | 73 | u8 i; |
| 74 | 74 | ||
| 75 | if (can_dropped_invalid_skb(ndev, skb)) | 75 | if (can_dev_dropped_skb(ndev, skb)) |
| 76 | return NETDEV_TX_OK; | 76 | return NETDEV_TX_OK; |
| 77 | 77 | ||
| 78 | if (!netif_subqueue_maybe_stop(priv->ndev, 0, | 78 | if (!netif_subqueue_maybe_stop(priv->ndev, 0, |
| @@ -733,7 +733,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) · 732 unmodified lines | |||
| 733 | u64 tfc_vlan_tag = 0; | 733 | u64 tfc_vlan_tag = 0; |
| 734 | 734 | ||
| 735 | if (np->link_status == 0) { /* Link Down */ | 735 | if (np->link_status == 0) { /* Link Down */ |
| 736 | dev_kfree_skb(skb); | 736 | dev_kfree_skb_any(skb); |
| 737 | return NETDEV_TX_OK; | 737 | return NETDEV_TX_OK; |
| 738 | } | 738 | } |
| 739 | entry = np->cur_tx % TX_RING_SIZE; | 739 | entry = np->cur_tx % TX_RING_SIZE; |
| @@ -1077,8 +1077,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv, · 1076 unmodified lines | |||
| 1077 | dma_addr_t addr; | 1077 | dma_addr_t addr; |
| 1078 | 1078 | ||
| 1079 | buffer_start = skb->data - dpaa2_eth_needed_headroom(skb); | 1079 | buffer_start = skb->data - dpaa2_eth_needed_headroom(skb); |
| 1080 | aligned_start = PTR_ALIGN(buffer_start - DPAA2_ETH_TX_BUF_ALIGN, | 1080 | aligned_start = PTR_ALIGN(buffer_start, DPAA2_ETH_TX_BUF_ALIGN); |
| 1081 | DPAA2_ETH_TX_BUF_ALIGN); | ||
| 1082 | if (aligned_start >= skb->head) | 1081 | if (aligned_start >= skb->head) |
| 1083 | buffer_start = aligned_start; | 1082 | buffer_start = aligned_start; |
| 1084 | else | 1083 | else |
| @@ -1595,6 +1595,8 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, · 1594 unmodified lines | |||
| 1595 | /* next descriptor to process */ | 1595 | /* next descriptor to process */ |
| 1596 | i = rx_ring->next_to_clean; | 1596 | i = rx_ring->next_to_clean; |
| 1597 | 1597 | ||
| 1598 | enetc_lock_mdio(); | ||
| 1599 | |||
| 1598 | while (likely(rx_frm_cnt < work_limit)) { | 1600 | while (likely(rx_frm_cnt < work_limit)) { |
| 1599 | union enetc_rx_bd *rxbd; | 1601 | union enetc_rx_bd *rxbd; |
| 1600 | struct sk_buff *skb; | 1602 | struct sk_buff *skb; |
| @@ -1630,7 +1632,9 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, · 29 unmodified lines | |||
| 1630 | rx_byte_cnt += skb->len + ETH_HLEN; | 1632 | rx_byte_cnt += skb->len + ETH_HLEN; |
| 1631 | rx_frm_cnt++; | 1633 | rx_frm_cnt++; |
| 1632 | 1634 | ||
| 1635 | enetc_unlock_mdio(); | ||
| 1633 | napi_gro_receive(napi, skb); | 1636 | napi_gro_receive(napi, skb); |
| 1637 | enetc_lock_mdio(); | ||
| 1634 | } | 1638 | } |
| 1635 | 1639 | ||
| 1636 | rx_ring->next_to_clean = i; | 1640 | rx_ring->next_to_clean = i; |
| @@ -1638,6 +1642,8 @@ static int enetc_clean_rx_ring(struct enetc_bdr *rx_ring, · 1 unmodified line | |||
| 1638 | rx_ring->stats.packets += rx_frm_cnt; | 1642 | rx_ring->stats.packets += rx_frm_cnt; |
| 1639 | rx_ring->stats.bytes += rx_byte_cnt; | 1643 | rx_ring->stats.bytes += rx_byte_cnt; |
| 1640 | 1644 | ||
| 1645 | enetc_unlock_mdio(); | ||
| 1646 | |||
| 1641 | return rx_frm_cnt; | 1647 | return rx_frm_cnt; |
| 1642 | } | 1648 | } |
| 1643 | 1649 | ||
| @@ -1947,6 +1953,8 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 303 unmodified lines | |||
| 1947 | /* next descriptor to process */ | 1953 | /* next descriptor to process */ |
| 1948 | i = rx_ring->next_to_clean; | 1954 | i = rx_ring->next_to_clean; |
| 1949 | 1955 | ||
| 1956 | enetc_lock_mdio(); | ||
| 1957 | |||
| 1950 | while (likely(rx_frm_cnt < work_limit)) { | 1958 | while (likely(rx_frm_cnt < work_limit)) { |
| 1951 | union enetc_rx_bd *rxbd, *orig_rxbd; | 1959 | union enetc_rx_bd *rxbd, *orig_rxbd; |
| 1952 | struct xdp_buff xdp_buff; | 1960 | struct xdp_buff xdp_buff; |
| @@ -2010,7 +2018,9 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 57 unmodified lines | |||
| 2010 | */ | 2018 | */ |
| 2011 | enetc_bulk_flip_buff(rx_ring, orig_i, i); | 2019 | enetc_bulk_flip_buff(rx_ring, orig_i, i); |
| 2012 | 2020 | ||
| 2021 | enetc_unlock_mdio(); | ||
| 2013 | napi_gro_receive(napi, skb); | 2022 | napi_gro_receive(napi, skb); |
| 2023 | enetc_lock_mdio(); | ||
| 2014 | break; | 2024 | break; |
| 2015 | case XDP_TX: | 2025 | case XDP_TX: |
| 2016 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; | 2026 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; |
| @@ -2045,7 +2055,9 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 28 unmodified lines | |||
| 2045 | } | 2055 | } |
| 2046 | break; | 2056 | break; |
| 2047 | case XDP_REDIRECT: | 2057 | case XDP_REDIRECT: |
| 2058 | enetc_unlock_mdio(); | ||
| 2048 | err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog); | 2059 | err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog); |
| 2060 | enetc_lock_mdio(); | ||
| 2049 | if (unlikely(err)) { | 2061 | if (unlikely(err)) { |
| 2050 | enetc_xdp_drop(rx_ring, orig_i, i); | 2062 | enetc_xdp_drop(rx_ring, orig_i, i); |
| 2051 | rx_ring->stats.xdp_redirect_failures++; | 2063 | rx_ring->stats.xdp_redirect_failures++; |
| @@ -2065,8 +2077,11 @@ out: · 13 unmodified lines | |||
| 2065 | rx_ring->stats.packets += rx_frm_cnt; | 2077 | rx_ring->stats.packets += rx_frm_cnt; |
| 2066 | rx_ring->stats.bytes += rx_byte_cnt; | 2078 | rx_ring->stats.bytes += rx_byte_cnt; |
| 2067 | 2079 | ||
| 2068 | if (xdp_redirect_frm_cnt) | 2080 | if (xdp_redirect_frm_cnt) { |
| 2081 | enetc_unlock_mdio(); | ||
| 2069 | xdp_do_flush(); | 2082 | xdp_do_flush(); |
| 2083 | enetc_lock_mdio(); | ||
| 2084 | } | ||
| 2070 | 2085 | ||
| 2071 | if (xdp_tx_frm_cnt) | 2086 | if (xdp_tx_frm_cnt) |
| 2072 | enetc_update_tx_ring_tail(tx_ring); | 2087 | enetc_update_tx_ring_tail(tx_ring); |
| @@ -2075,6 +2090,8 @@ out: · 2 unmodified lines | |||
| 2075 | enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring) - | 2090 | enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring) - |
| 2076 | rx_ring->xdp.xdp_tx_in_flight); | 2091 | rx_ring->xdp.xdp_tx_in_flight); |
| 2077 | 2092 | ||
| 2093 | enetc_unlock_mdio(); | ||
| 2094 | |||
| 2078 | return rx_frm_cnt; | 2095 | return rx_frm_cnt; |
| 2079 | } | 2096 | } |
| 2080 | 2097 | ||
| @@ -2093,6 +2110,7 @@ static int enetc_poll(struct napi_struct *napi, int budget) · 12 unmodified lines | |||
| 2093 | for (i = 0; i < v->count_tx_rings; i++) | 2110 | for (i = 0; i < v->count_tx_rings; i++) |
| 2094 | if (!enetc_clean_tx_ring(&v->tx_ring[i], budget)) | 2111 | if (!enetc_clean_tx_ring(&v->tx_ring[i], budget)) |
| 2095 | complete = false; | 2112 | complete = false; |
| 2113 | enetc_unlock_mdio(); | ||
| 2096 | 2114 | ||
| 2097 | prog = rx_ring->xdp.prog; | 2115 | prog = rx_ring->xdp.prog; |
| 2098 | if (prog) | 2116 | if (prog) |
| @@ -2104,10 +2122,8 @@ static int enetc_poll(struct napi_struct *napi, int budget) · 5 unmodified lines | |||
| 2104 | if (work_done) | 2122 | if (work_done) |
| 2105 | v->rx_napi_work = true; | 2123 | v->rx_napi_work = true; |
| 2106 | 2124 | ||
| 2107 | if (!complete) { | 2125 | if (!complete) |
| 2108 | enetc_unlock_mdio(); | ||
| 2109 | return budget; | 2126 | return budget; |
| 2110 | } | ||
| 2111 | 2127 | ||
| 2112 | napi_complete_done(napi, work_done); | 2128 | napi_complete_done(napi, work_done); |
| 2113 | 2129 | ||
| @@ -2116,6 +2132,7 @@ static int enetc_poll(struct napi_struct *napi, int budget) · 2 unmodified lines | |||
| 2116 | 2132 | ||
| 2117 | v->rx_napi_work = false; | 2133 | v->rx_napi_work = false; |
| 2118 | 2134 | ||
| 2135 | enetc_lock_mdio(); | ||
| 2119 | /* enable interrupts */ | 2136 | /* enable interrupts */ |
| 2120 | enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE); | 2137 | enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE); |
| 2121 | 2138 | ||
| @@ -76,7 +76,7 @@ struct enetc_lso_t { · 75 unmodified lines | |||
| 76 | #define ENETC_LSO_MAX_DATA_LEN SZ_256K | 76 | #define ENETC_LSO_MAX_DATA_LEN SZ_256K |
| 77 | 77 | ||
| 78 | #define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE | 78 | #define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE |
| 79 | #define ENETC_RXB_TRUESIZE 2048 /* PAGE_SIZE >> 1 */ | 79 | #define ENETC_RXB_TRUESIZE (PAGE_SIZE >> 1) |
| 80 | #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */ | 80 | #define ENETC_RXB_PAD NET_SKB_PAD /* add extra space if needed */ |
| 81 | #define ENETC_RXB_DMA_SIZE \ | 81 | #define ENETC_RXB_DMA_SIZE \ |
| 82 | (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD) | 82 | (SKB_WITH_OVERHEAD(ENETC_RXB_TRUESIZE) - ENETC_RXB_PAD) |
| @@ -148,6 +148,7 @@ config HIBMCGE · 147 unmodified lines | |||
| 148 | tristate "Hisilicon BMC Gigabit Ethernet Device Support" | 148 | tristate "Hisilicon BMC Gigabit Ethernet Device Support" |
| 149 | depends on PCI && PCI_MSI | 149 | depends on PCI && PCI_MSI |
| 150 | select PHYLIB | 150 | select PHYLIB |
| 151 | select FIXED_PHY | ||
| 151 | select MOTORCOMM_PHY | 152 | select MOTORCOMM_PHY |
| 152 | select REALTEK_PHY | 153 | select REALTEK_PHY |
| 153 | help | 154 | help |
| @@ -100,7 +100,7 @@ u8 mlx5e_mpwrq_umr_entry_size(enum mlx5e_mpwrq_umr_mode mode) · 99 unmodified lines | |||
| 100 | return sizeof(struct mlx5_ksm) * 4; | 100 | return sizeof(struct mlx5_ksm) * 4; |
| 101 | } | 101 | } |
| 102 | WARN_ONCE(1, "MPWRQ UMR mode %d is not known\n", mode); | 102 | WARN_ONCE(1, "MPWRQ UMR mode %d is not known\n", mode); |
| 103 | return 0; | 103 | return 1; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | u8 mlx5e_mpwrq_log_wqe_sz(struct mlx5_core_dev *mdev, u8 page_shift, | 106 | u8 mlx5e_mpwrq_log_wqe_sz(struct mlx5_core_dev *mdev, u8 page_shift, |
| @@ -342,6 +342,7 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, · 341 unmodified lines | |||
| 342 | void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv, | 342 | void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv, |
| 343 | struct mlx5e_priv *master_priv); | 343 | struct mlx5e_priv *master_priv); |
| 344 | void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event); | 344 | void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event); |
| 345 | void mlx5e_ipsec_disable_events(struct mlx5e_priv *priv); | ||
| 345 | 346 | ||
| 346 | static inline struct mlx5_core_dev * | 347 | static inline struct mlx5_core_dev * |
| 347 | mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry) | 348 | mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry) |
| @@ -387,6 +388,10 @@ static inline void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *sl · 39 unmodified lines | |||
| 387 | static inline void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event) | 388 | static inline void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event) |
| 388 | { | 389 | { |
| 389 | } | 390 | } |
| 391 | |||
| 392 | static inline void mlx5e_ipsec_disable_events(struct mlx5e_priv *priv) | ||
| 393 | { | ||
| 394 | } | ||
| 390 | #endif | 395 | #endif |
| 391 | 396 | ||
| 392 | #endif /* __MLX5E_IPSEC_H__ */ | 397 | #endif /* __MLX5E_IPSEC_H__ */ |
| @@ -2893,9 +2893,30 @@ void mlx5e_ipsec_handle_mpv_event(int event, struct mlx5e_priv *slave_priv, · 2892 unmodified lines | |||
| 2893 | 2893 | ||
| 2894 | void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event) | 2894 | void mlx5e_ipsec_send_event(struct mlx5e_priv *priv, int event) |
| 2895 | { | 2895 | { |
| 2896 | if (!priv->ipsec) | 2896 | if (!priv->ipsec || mlx5_devcom_comp_get_size(priv->devcom) < 2) |
| 2897 | return; /* IPsec not supported */ | 2897 | return; /* IPsec not supported or no peers */ |
| 2898 | 2898 | ||
| 2899 | mlx5_devcom_send_event(priv->devcom, event, event, priv); | 2899 | mlx5_devcom_send_event(priv->devcom, event, event, priv); |
| 2900 | wait_for_completion(&priv->ipsec->comp); | 2900 | wait_for_completion(&priv->ipsec->comp); |
| 2901 | } | 2901 | } |
| 2902 | |||
| 2903 | void mlx5e_ipsec_disable_events(struct mlx5e_priv *priv) | ||
| 2904 | { | ||
| 2905 | struct mlx5_devcom_comp_dev *tmp = NULL; | ||
| 2906 | struct mlx5e_priv *peer_priv; | ||
| 2907 | |||
| 2908 | if (!priv->devcom) | ||
| 2909 | return; | ||
| 2910 | |||
| 2911 | if (!mlx5_devcom_for_each_peer_begin(priv->devcom)) | ||
| 2912 | goto out; | ||
| 2913 | |||
| 2914 | peer_priv = mlx5_devcom_get_next_peer_data(priv->devcom, &tmp); | ||
| 2915 | if (peer_priv) | ||
| 2916 | complete_all(&peer_priv->ipsec->comp); | ||
| 2917 | |||
| 2918 | mlx5_devcom_for_each_peer_end(priv->devcom); | ||
| 2919 | out: | ||
| 2920 | mlx5_devcom_unregister_component(priv->devcom); | ||
| 2921 | priv->devcom = NULL; | ||
| 2922 | } | ||
| @@ -242,8 +242,8 @@ static int mlx5e_devcom_init_mpv(struct mlx5e_priv *priv, u64 *data) · 241 unmodified lines | |||
| 242 | &attr, | 242 | &attr, |
| 243 | mlx5e_devcom_event_mpv, | 243 | mlx5e_devcom_event_mpv, |
| 244 | priv); | 244 | priv); |
| 245 | if (IS_ERR(priv->devcom)) | 245 | if (!priv->devcom) |
| 246 | return PTR_ERR(priv->devcom); | 246 | return -EINVAL; |
| 247 | 247 | ||
| 248 | if (mlx5_core_is_mp_master(priv->mdev)) { | 248 | if (mlx5_core_is_mp_master(priv->mdev)) { |
| 249 | mlx5_devcom_send_event(priv->devcom, MPV_DEVCOM_MASTER_UP, | 249 | mlx5_devcom_send_event(priv->devcom, MPV_DEVCOM_MASTER_UP, |
| @@ -256,7 +256,7 @@ static int mlx5e_devcom_init_mpv(struct mlx5e_priv *priv, u64 *data) · 6 unmodified lines | |||
| 256 | 256 | ||
| 257 | static void mlx5e_devcom_cleanup_mpv(struct mlx5e_priv *priv) | 257 | static void mlx5e_devcom_cleanup_mpv(struct mlx5e_priv *priv) |
| 258 | { | 258 | { |
| 259 | if (IS_ERR_OR_NULL(priv->devcom)) | 259 | if (!priv->devcom) |
| 260 | return; | 260 | return; |
| 261 | 261 | ||
| 262 | if (mlx5_core_is_mp_master(priv->mdev)) { | 262 | if (mlx5_core_is_mp_master(priv->mdev)) { |
| @@ -266,6 +266,7 @@ static void mlx5e_devcom_cleanup_mpv(struct mlx5e_priv *priv) · 3 unmodified lines | |||
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | mlx5_devcom_unregister_component(priv->devcom); | 268 | mlx5_devcom_unregister_component(priv->devcom); |
| 269 | priv->devcom = NULL; | ||
| 269 | } | 270 | } |
| 270 | 271 | ||
| 271 | static int blocking_event(struct notifier_block *nb, unsigned long event, void *data) | 272 | static int blocking_event(struct notifier_block *nb, unsigned long event, void *data) |
| @@ -6120,6 +6121,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv) · 5848 unmodified lines | |||
| 6120 | if (mlx5e_monitor_counter_supported(priv)) | 6121 | if (mlx5e_monitor_counter_supported(priv)) |
| 6121 | mlx5e_monitor_counter_cleanup(priv); | 6122 | mlx5e_monitor_counter_cleanup(priv); |
| 6122 | 6123 | ||
| 6124 | mlx5e_ipsec_disable_events(priv); | ||
| 6123 | mlx5e_disable_blocking_events(priv); | 6125 | mlx5e_disable_blocking_events(priv); |
| 6124 | mlx5e_disable_async_events(priv); | 6126 | mlx5e_disable_async_events(priv); |
| 6125 | mlx5_lag_remove_netdev(mdev, priv->netdev); | 6127 | mlx5_lag_remove_netdev(mdev, priv->netdev); |
| @@ -1794,14 +1794,27 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi · 1793 unmodified lines | |||
| 1794 | } | 1794 | } |
| 1795 | 1795 | ||
| 1796 | prog = rcu_dereference(rq->xdp_prog); | 1796 | prog = rcu_dereference(rq->xdp_prog); |
| 1797 | if (prog && mlx5e_xdp_handle(rq, prog, mxbuf)) { | 1797 | if (prog) { |
| 1798 | if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) { | 1798 | u8 nr_frags_free, old_nr_frags = sinfo->nr_frags; |
| 1799 | struct mlx5e_wqe_frag_info *pwi; | 1799 | |
| 1800 | if (mlx5e_xdp_handle(rq, prog, mxbuf)) { | ||
| 1801 | if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, | ||
| 1802 | rq->flags)) { | ||
| 1803 | struct mlx5e_wqe_frag_info *pwi; | ||
| 1804 | |||
| 1805 | wi -= old_nr_frags - sinfo->nr_frags; | ||
| 1806 | |||
| 1807 | for (pwi = head_wi; pwi < wi; pwi++) | ||
| 1808 | pwi->frag_page->frags++; | ||
| 1809 | } | ||
| 1810 | return NULL; /* page/packet was consumed by XDP */ | ||
| 1811 | } | ||
| 1800 | 1812 | ||
| 1801 | for (pwi = head_wi; pwi < wi; pwi++) | 1813 | nr_frags_free = old_nr_frags - sinfo->nr_frags; |
| 1802 | pwi->frag_page->frags++; | 1814 | if (unlikely(nr_frags_free)) { |
| 1815 | wi -= nr_frags_free; | ||
| 1816 | truesize -= nr_frags_free * frag_info->frag_stride; | ||
| 1803 | } | 1817 | } |
| 1804 | return NULL; /* page/packet was consumed by XDP */ | ||
| 1805 | } | 1818 | } |
| 1806 | 1819 | ||
| 1807 | skb = mlx5e_build_linear_skb( | 1820 | skb = mlx5e_build_linear_skb( |
| @@ -2027,6 +2040,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w · 219 unmodified lines | |||
| 2027 | u32 byte_cnt = cqe_bcnt; | 2040 | u32 byte_cnt = cqe_bcnt; |
| 2028 | struct skb_shared_info *sinfo; | 2041 | struct skb_shared_info *sinfo; |
| 2029 | unsigned int truesize = 0; | 2042 | unsigned int truesize = 0; |
| 2043 | u32 pg_consumed_bytes; | ||
| 2030 | struct bpf_prog *prog; | 2044 | struct bpf_prog *prog; |
| 2031 | struct sk_buff *skb; | 2045 | struct sk_buff *skb; |
| 2032 | u32 linear_frame_sz; | 2046 | u32 linear_frame_sz; |
| @@ -2080,7 +2094,8 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w · 47 unmodified lines | |||
| 2080 | 2094 | ||
| 2081 | while (byte_cnt) { | 2095 | while (byte_cnt) { |
| 2082 | /* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */ | 2096 | /* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */ |
| 2083 | u32 pg_consumed_bytes = min_t(u32, PAGE_SIZE - frag_offset, byte_cnt); | 2097 | pg_consumed_bytes = |
| 2098 | min_t(u32, PAGE_SIZE - frag_offset, byte_cnt); | ||
| 2084 | 2099 | ||
| 2085 | if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state)) | 2100 | if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state)) |
| 2086 | truesize += pg_consumed_bytes; | 2101 | truesize += pg_consumed_bytes; |
| @@ -2096,10 +2111,15 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w · 9 unmodified lines | |||
| 2096 | } | 2111 | } |
| 2097 | 2112 | ||
| 2098 | if (prog) { | 2113 | if (prog) { |
| 2114 | u8 nr_frags_free, old_nr_frags = sinfo->nr_frags; | ||
| 2115 | u32 len; | ||
| 2116 | |||
| 2099 | if (mlx5e_xdp_handle(rq, prog, mxbuf)) { | 2117 | if (mlx5e_xdp_handle(rq, prog, mxbuf)) { |
| 2100 | if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) { | 2118 | if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) { |
| 2101 | struct mlx5e_frag_page *pfp; | 2119 | struct mlx5e_frag_page *pfp; |
| 2102 | 2120 | ||
| 2121 | frag_page -= old_nr_frags - sinfo->nr_frags; | ||
| 2122 | |||
| 2103 | for (pfp = head_page; pfp < frag_page; pfp++) | 2123 | for (pfp = head_page; pfp < frag_page; pfp++) |
| 2104 | pfp->frags++; | 2124 | pfp->frags++; |
| 2105 | 2125 | ||
| @@ -2110,9 +2130,19 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w · 4 unmodified lines | |||
| 2110 | return NULL; /* page/packet was consumed by XDP */ | 2130 | return NULL; /* page/packet was consumed by XDP */ |
| 2111 | } | 2131 | } |
| 2112 | 2132 | ||
| 2133 | nr_frags_free = old_nr_frags - sinfo->nr_frags; | ||
| 2134 | if (unlikely(nr_frags_free)) { | ||
| 2135 | frag_page -= nr_frags_free; | ||
| 2136 | truesize -= (nr_frags_free - 1) * PAGE_SIZE + | ||
| 2137 | ALIGN(pg_consumed_bytes, | ||
| 2138 | BIT(rq->mpwqe.log_stride_sz)); | ||
| 2139 | } | ||
| 2140 | |||
| 2141 | len = mxbuf->xdp.data_end - mxbuf->xdp.data; | ||
| 2142 | |||
| 2113 | skb = mlx5e_build_linear_skb( | 2143 | skb = mlx5e_build_linear_skb( |
| 2114 | rq, mxbuf->xdp.data_hard_start, linear_frame_sz, | 2144 | rq, mxbuf->xdp.data_hard_start, linear_frame_sz, |
| 2115 | mxbuf->xdp.data - mxbuf->xdp.data_hard_start, 0, | 2145 | mxbuf->xdp.data - mxbuf->xdp.data_hard_start, len, |
| 2116 | mxbuf->xdp.data - mxbuf->xdp.data_meta); | 2146 | mxbuf->xdp.data - mxbuf->xdp.data_meta); |
| 2117 | if (unlikely(!skb)) { | 2147 | if (unlikely(!skb)) { |
| 2118 | mlx5e_page_release_fragmented(rq->page_pool, | 2148 | mlx5e_page_release_fragmented(rq->page_pool, |
| @@ -2137,8 +2167,11 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w · 18 unmodified lines | |||
| 2137 | do | 2167 | do |
| 2138 | pagep->frags++; | 2168 | pagep->frags++; |
| 2139 | while (++pagep < frag_page); | 2169 | while (++pagep < frag_page); |
| 2170 | |||
| 2171 | headlen = min_t(u16, MLX5E_RX_MAX_HEAD - len, | ||
| 2172 | skb->data_len); | ||
| 2173 | __pskb_pull_tail(skb, headlen); | ||
| 2140 | } | 2174 | } |
| 2141 | __pskb_pull_tail(skb, headlen); | ||
| 2142 | } else { | 2175 | } else { |
| 2143 | dma_addr_t addr; | 2176 | dma_addr_t addr; |
| 2144 | 2177 | ||
| @@ -1614,7 +1614,9 @@ void mlx5e_stats_fec_get(struct mlx5e_priv *priv, · 1613 unmodified lines | |||
| 1614 | 1614 | ||
| 1615 | fec_set_corrected_bits_total(priv, fec_stats); | 1615 | fec_set_corrected_bits_total(priv, fec_stats); |
| 1616 | fec_set_block_stats(priv, mode, fec_stats); | 1616 | fec_set_block_stats(priv, mode, fec_stats); |
| 1617 | fec_set_histograms_stats(priv, mode, hist); | 1617 | |
| 1618 | if (MLX5_CAP_PCAM_REG(priv->mdev, pphcr)) | ||
| 1619 | fec_set_histograms_stats(priv, mode, hist); | ||
| 1618 | } | 1620 | } |
| 1619 | 1621 | ||
| 1620 | #define PPORT_ETH_EXT_OFF(c) \ | 1622 | #define PPORT_ETH_EXT_OFF(c) \ |
| @@ -256,7 +256,7 @@ mlx5e_tx_wqe_inline_mode(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 255 unmodified lines | |||
| 256 | u8 mode; | 256 | u8 mode; |
| 257 | 257 | ||
| 258 | #ifdef CONFIG_MLX5_EN_TLS | 258 | #ifdef CONFIG_MLX5_EN_TLS |
| 259 | if (accel && accel->tls.tls_tisn) | 259 | if (accel->tls.tls_tisn) |
| 260 | return MLX5_INLINE_MODE_TCP_UDP; | 260 | return MLX5_INLINE_MODE_TCP_UDP; |
| 261 | #endif | 261 | #endif |
| 262 | 262 | ||
| @@ -982,6 +982,7 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 719 unmodified lines | |||
| 982 | struct mlx5e_tx_attr attr; | 982 | struct mlx5e_tx_attr attr; |
| 983 | struct mlx5i_tx_wqe *wqe; | 983 | struct mlx5i_tx_wqe *wqe; |
| 984 | 984 | ||
| 985 | struct mlx5e_accel_tx_state accel = {}; | ||
| 985 | struct mlx5_wqe_datagram_seg *datagram; | 986 | struct mlx5_wqe_datagram_seg *datagram; |
| 986 | struct mlx5_wqe_ctrl_seg *cseg; | 987 | struct mlx5_wqe_ctrl_seg *cseg; |
| 987 | struct mlx5_wqe_eth_seg *eseg; | 988 | struct mlx5_wqe_eth_seg *eseg; |
| @@ -992,7 +993,7 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 4 unmodified lines | |||
| 992 | int num_dma; | 993 | int num_dma; |
| 993 | u16 pi; | 994 | u16 pi; |
| 994 | 995 | ||
| 995 | mlx5e_sq_xmit_prepare(sq, skb, NULL, &attr); | 996 | mlx5e_sq_xmit_prepare(sq, skb, &accel, &attr); |
| 996 | mlx5i_sq_calc_wqe_attr(skb, &attr, &wqe_attr); | 997 | mlx5i_sq_calc_wqe_attr(skb, &attr, &wqe_attr); |
| 997 | 998 | ||
| 998 | pi = mlx5e_txqsq_get_next_pi(sq, wqe_attr.num_wqebbs); | 999 | pi = mlx5e_txqsq_get_next_pi(sq, wqe_attr.num_wqebbs); |
| @@ -1009,7 +1010,7 @@ void mlx5i_sq_xmit(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 10 unmodified lines | |||
| 1009 | 1010 | ||
| 1010 | mlx5i_txwqe_build_datagram(av, dqpn, dqkey, datagram); | 1011 | mlx5i_txwqe_build_datagram(av, dqpn, dqkey, datagram); |
| 1011 | 1012 | ||
| 1012 | mlx5e_txwqe_build_eseg_csum(sq, skb, NULL, eseg); | 1013 | mlx5e_txwqe_build_eseg_csum(sq, skb, &accel, eseg); |
| 1013 | 1014 | ||
| 1014 | eseg->mss = attr.mss; | 1015 | eseg->mss = attr.mss; |
| 1015 | 1016 | ||
| @@ -3129,7 +3129,7 @@ void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw, · 3128 unmodified lines | |||
| 3129 | attr, | 3129 | attr, |
| 3130 | mlx5_esw_offloads_devcom_event, | 3130 | mlx5_esw_offloads_devcom_event, |
| 3131 | esw); | 3131 | esw); |
| 3132 | if (IS_ERR(esw->devcom)) | 3132 | if (!esw->devcom) |
| 3133 | return; | 3133 | return; |
| 3134 | 3134 | ||
| 3135 | mlx5_devcom_send_event(esw->devcom, | 3135 | mlx5_devcom_send_event(esw->devcom, |
| @@ -3140,7 +3140,7 @@ void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw, · 4 unmodified lines | |||
| 3140 | 3140 | ||
| 3141 | void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw) | 3141 | void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw) |
| 3142 | { | 3142 | { |
| 3143 | if (IS_ERR_OR_NULL(esw->devcom)) | 3143 | if (!esw->devcom) |
| 3144 | return; | 3144 | return; |
| 3145 | 3145 | ||
| 3146 | mlx5_devcom_send_event(esw->devcom, | 3146 | mlx5_devcom_send_event(esw->devcom, |
| @@ -1430,11 +1430,10 @@ static int mlx5_lag_register_hca_devcom_comp(struct mlx5_core_dev *dev) · 1429 unmodified lines | |||
| 1430 | mlx5_devcom_register_component(dev->priv.devc, | 1430 | mlx5_devcom_register_component(dev->priv.devc, |
| 1431 | MLX5_DEVCOM_HCA_PORTS, | 1431 | MLX5_DEVCOM_HCA_PORTS, |
| 1432 | &attr, NULL, dev); | 1432 | &attr, NULL, dev); |
| 1433 | if (IS_ERR(dev->priv.hca_devcom_comp)) { | 1433 | if (!dev->priv.hca_devcom_comp) { |
| 1434 | mlx5_core_err(dev, | 1434 | mlx5_core_err(dev, |
| 1435 | "Failed to register devcom HCA component, err: %ld\n", | 1435 | "Failed to register devcom HCA component."); |
| 1436 | PTR_ERR(dev->priv.hca_devcom_comp)); | 1436 | return -EINVAL; |
| 1437 | return PTR_ERR(dev->priv.hca_devcom_comp); | ||
| 1438 | } | 1437 | } |
| 1439 | 1438 | ||
| 1440 | return 0; | 1439 | return 0; |
| @@ -1444,7 +1444,7 @@ static void mlx5_shared_clock_register(struct mlx5_core_dev *mdev, u64 key) · 1443 unmodified lines | |||
| 1444 | compd = mlx5_devcom_register_component(mdev->priv.devc, | 1444 | compd = mlx5_devcom_register_component(mdev->priv.devc, |
| 1445 | MLX5_DEVCOM_SHARED_CLOCK, | 1445 | MLX5_DEVCOM_SHARED_CLOCK, |
| 1446 | &attr, NULL, mdev); | 1446 | &attr, NULL, mdev); |
| 1447 | if (IS_ERR(compd)) | 1447 | if (!compd) |
| 1448 | return; | 1448 | return; |
| 1449 | 1449 | ||
| 1450 | mdev->clock_state->compdev = compd; | 1450 | mdev->clock_state->compdev = compd; |
| @@ -76,20 +76,18 @@ mlx5_devcom_dev_alloc(struct mlx5_core_dev *dev) · 75 unmodified lines | |||
| 76 | struct mlx5_devcom_dev * | 76 | struct mlx5_devcom_dev * |
| 77 | mlx5_devcom_register_device(struct mlx5_core_dev *dev) | 77 | mlx5_devcom_register_device(struct mlx5_core_dev *dev) |
| 78 | { | 78 | { |
| 79 | struct mlx5_devcom_dev *devc; | 79 | struct mlx5_devcom_dev *devc = NULL; |
| 80 | 80 | ||
| 81 | mutex_lock(&dev_list_lock); | 81 | mutex_lock(&dev_list_lock); |
| 82 | 82 | ||
| 83 | if (devcom_dev_exists(dev)) { | 83 | if (devcom_dev_exists(dev)) { |
| 84 | devc = ERR_PTR(-EEXIST); | 84 | mlx5_core_err(dev, "devcom device already exists"); |
| 85 | goto out; | 85 | goto out; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | devc = mlx5_devcom_dev_alloc(dev); | 88 | devc = mlx5_devcom_dev_alloc(dev); |
| 89 | if (!devc) { | 89 | if (!devc) |
| 90 | devc = ERR_PTR(-ENOMEM); | ||
| 91 | goto out; | 90 | goto out; |
| 92 | } | ||
| 93 | 91 | ||
| 94 | list_add_tail(&devc->list, &devcom_dev_list); | 92 | list_add_tail(&devc->list, &devcom_dev_list); |
| 95 | out: | 93 | out: |
| @@ -110,8 +108,10 @@ mlx5_devcom_dev_release(struct kref *ref) · 14 unmodified lines | |||
| 110 | 108 | ||
| 111 | void mlx5_devcom_unregister_device(struct mlx5_devcom_dev *devc) | 109 | void mlx5_devcom_unregister_device(struct mlx5_devcom_dev *devc) |
| 112 | { | 110 | { |
| 113 | if (!IS_ERR_OR_NULL(devc)) | 111 | if (!devc) |
| 114 | kref_put(&devc->ref, mlx5_devcom_dev_release); | 112 | return; |
| 113 | |||
| 114 | kref_put(&devc->ref, mlx5_devcom_dev_release); | ||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | static struct mlx5_devcom_comp * | 117 | static struct mlx5_devcom_comp * |
| @@ -122,7 +122,7 @@ mlx5_devcom_comp_alloc(u64 id, const struct mlx5_devcom_match_attr *attr, · 4 unmodified lines | |||
| 122 | 122 | ||
| 123 | comp = kzalloc(sizeof(*comp), GFP_KERNEL); | 123 | comp = kzalloc(sizeof(*comp), GFP_KERNEL); |
| 124 | if (!comp) | 124 | if (!comp) |
| 125 | return ERR_PTR(-ENOMEM); | 125 | return NULL; |
| 126 | 126 | ||
| 127 | comp->id = id; | 127 | comp->id = id; |
| 128 | comp->key.key = attr->key; | 128 | comp->key.key = attr->key; |
| @@ -160,7 +160,7 @@ devcom_alloc_comp_dev(struct mlx5_devcom_dev *devc, · 31 unmodified lines | |||
| 160 | 160 | ||
| 161 | devcom = kzalloc(sizeof(*devcom), GFP_KERNEL); | 161 | devcom = kzalloc(sizeof(*devcom), GFP_KERNEL); |
| 162 | if (!devcom) | 162 | if (!devcom) |
| 163 | return ERR_PTR(-ENOMEM); | 163 | return NULL; |
| 164 | 164 | ||
| 165 | kref_get(&devc->ref); | 165 | kref_get(&devc->ref); |
| 166 | devcom->devc = devc; | 166 | devcom->devc = devc; |
| @@ -240,31 +240,28 @@ mlx5_devcom_register_component(struct mlx5_devcom_dev *devc, · 73 unmodified lines | |||
| 240 | mlx5_devcom_event_handler_t handler, | 240 | mlx5_devcom_event_handler_t handler, |
| 241 | void *data) | 241 | void *data) |
| 242 | { | 242 | { |
| 243 | struct mlx5_devcom_comp_dev *devcom; | 243 | struct mlx5_devcom_comp_dev *devcom = NULL; |
| 244 | struct mlx5_devcom_comp *comp; | 244 | struct mlx5_devcom_comp *comp; |
| 245 | 245 | ||
| 246 | if (IS_ERR_OR_NULL(devc)) | 246 | if (!devc) |
| 247 | return ERR_PTR(-EINVAL); | 247 | return NULL; |
| 248 | 248 | ||
| 249 | mutex_lock(&comp_list_lock); | 249 | mutex_lock(&comp_list_lock); |
| 250 | comp = devcom_component_get(devc, id, attr, handler); | 250 | comp = devcom_component_get(devc, id, attr, handler); |
| 251 | if (IS_ERR(comp)) { | 251 | if (IS_ERR(comp)) |
| 252 | devcom = ERR_PTR(-EINVAL); | ||
| 253 | goto out_unlock; | 252 | goto out_unlock; |
| 254 | } | ||
| 255 | 253 | ||
| 256 | if (!comp) { | 254 | if (!comp) { |
| 257 | comp = mlx5_devcom_comp_alloc(id, attr, handler); | 255 | comp = mlx5_devcom_comp_alloc(id, attr, handler); |
| 258 | if (IS_ERR(comp)) { | 256 | if (!comp) |
| 259 | devcom = ERR_CAST(comp); | ||
| 260 | goto out_unlock; | 257 | goto out_unlock; |
| 261 | } | 258 | |
| 262 | list_add_tail(&comp->comp_list, &devcom_comp_list); | 259 | list_add_tail(&comp->comp_list, &devcom_comp_list); |
| 263 | } | 260 | } |
| 264 | mutex_unlock(&comp_list_lock); | 261 | mutex_unlock(&comp_list_lock); |
| 265 | 262 | ||
| 266 | devcom = devcom_alloc_comp_dev(devc, comp, data); | 263 | devcom = devcom_alloc_comp_dev(devc, comp, data); |
| 267 | if (IS_ERR(devcom)) | 264 | if (!devcom) |
| 268 | kref_put(&comp->ref, mlx5_devcom_comp_release); | 265 | kref_put(&comp->ref, mlx5_devcom_comp_release); |
| 269 | 266 | ||
| 270 | return devcom; | 267 | return devcom; |
| @@ -276,8 +273,10 @@ out_unlock: · 5 unmodified lines | |||
| 276 | 273 | ||
| 277 | void mlx5_devcom_unregister_component(struct mlx5_devcom_comp_dev *devcom) | 274 | void mlx5_devcom_unregister_component(struct mlx5_devcom_comp_dev *devcom) |
| 278 | { | 275 | { |
| 279 | if (!IS_ERR_OR_NULL(devcom)) | 276 | if (!devcom) |
| 280 | devcom_free_comp_dev(devcom); | 277 | return; |
| 278 | |||
| 279 | devcom_free_comp_dev(devcom); | ||
| 281 | } | 280 | } |
| 282 | 281 | ||
| 283 | int mlx5_devcom_comp_get_size(struct mlx5_devcom_comp_dev *devcom) | 282 | int mlx5_devcom_comp_get_size(struct mlx5_devcom_comp_dev *devcom) |
| @@ -296,7 +295,7 @@ int mlx5_devcom_send_event(struct mlx5_devcom_comp_dev *devcom, · 12 unmodified lines | |||
| 296 | int err = 0; | 295 | int err = 0; |
| 297 | void *data; | 296 | void *data; |
| 298 | 297 | ||
| 299 | if (IS_ERR_OR_NULL(devcom)) | 298 | if (!devcom) |
| 300 | return -ENODEV; | 299 | return -ENODEV; |
| 301 | 300 | ||
| 302 | comp = devcom->comp; | 301 | comp = devcom->comp; |
| @@ -338,7 +337,7 @@ void mlx5_devcom_comp_set_ready(struct mlx5_devcom_comp_dev *devcom, bool ready) · 35 unmodified lines | |||
| 338 | 337 | ||
| 339 | bool mlx5_devcom_comp_is_ready(struct mlx5_devcom_comp_dev *devcom) | 338 | bool mlx5_devcom_comp_is_ready(struct mlx5_devcom_comp_dev *devcom) |
| 340 | { | 339 | { |
| 341 | if (IS_ERR_OR_NULL(devcom)) | 340 | if (!devcom) |
| 342 | return false; | 341 | return false; |
| 343 | 342 | ||
| 344 | return READ_ONCE(devcom->comp->ready); | 343 | return READ_ONCE(devcom->comp->ready); |
| @@ -348,7 +347,7 @@ bool mlx5_devcom_for_each_peer_begin(struct mlx5_devcom_comp_dev *devcom) · 3 unmodified lines | |||
| 348 | { | 347 | { |
| 349 | struct mlx5_devcom_comp *comp; | 348 | struct mlx5_devcom_comp *comp; |
| 350 | 349 | ||
| 351 | if (IS_ERR_OR_NULL(devcom)) | 350 | if (!devcom) |
| 352 | return false; | 351 | return false; |
| 353 | 352 | ||
| 354 | comp = devcom->comp; | 353 | comp = devcom->comp; |
| @@ -421,21 +420,21 @@ void *mlx5_devcom_get_next_peer_data_rcu(struct mlx5_devcom_comp_dev *devcom, · 66 unmodified lines | |||
| 421 | 420 | ||
| 422 | void mlx5_devcom_comp_lock(struct mlx5_devcom_comp_dev *devcom) | 421 | void mlx5_devcom_comp_lock(struct mlx5_devcom_comp_dev *devcom) |
| 423 | { | 422 | { |
| 424 | if (IS_ERR_OR_NULL(devcom)) | 423 | if (!devcom) |
| 425 | return; | 424 | return; |
| 426 | down_write(&devcom->comp->sem); | 425 | down_write(&devcom->comp->sem); |
| 427 | } | 426 | } |
| 428 | 427 | ||
| 429 | void mlx5_devcom_comp_unlock(struct mlx5_devcom_comp_dev *devcom) | 428 | void mlx5_devcom_comp_unlock(struct mlx5_devcom_comp_dev *devcom) |
| 430 | { | 429 | { |
| 431 | if (IS_ERR_OR_NULL(devcom)) | 430 | if (!devcom) |
| 432 | return; | 431 | return; |
| 433 | up_write(&devcom->comp->sem); | 432 | up_write(&devcom->comp->sem); |
| 434 | } | 433 | } |
| 435 | 434 | ||
| 436 | int mlx5_devcom_comp_trylock(struct mlx5_devcom_comp_dev *devcom) | 435 | int mlx5_devcom_comp_trylock(struct mlx5_devcom_comp_dev *devcom) |
| 437 | { | 436 | { |
| 438 | if (IS_ERR_OR_NULL(devcom)) | 437 | if (!devcom) |
| 439 | return 0; | 438 | return 0; |
| 440 | return down_write_trylock(&devcom->comp->sem); | 439 | return down_write_trylock(&devcom->comp->sem); |
| 441 | } | 440 | } |
| @@ -221,8 +221,8 @@ static int sd_register(struct mlx5_core_dev *dev) · 220 unmodified lines | |||
| 221 | attr.net = mlx5_core_net(dev); | 221 | attr.net = mlx5_core_net(dev); |
| 222 | devcom = mlx5_devcom_register_component(dev->priv.devc, MLX5_DEVCOM_SD_GROUP, | 222 | devcom = mlx5_devcom_register_component(dev->priv.devc, MLX5_DEVCOM_SD_GROUP, |
| 223 | &attr, NULL, dev); | 223 | &attr, NULL, dev); |
| 224 | if (IS_ERR(devcom)) | 224 | if (!devcom) |
| 225 | return PTR_ERR(devcom); | 225 | return -EINVAL; |
| 226 | 226 | ||
| 227 | sd->devcom = devcom; | 227 | sd->devcom = devcom; |
| 228 | 228 | ||
| @@ -978,9 +978,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) · 977 unmodified lines | |||
| 978 | int err; | 978 | int err; |
| 979 | 979 | ||
| 980 | dev->priv.devc = mlx5_devcom_register_device(dev); | 980 | dev->priv.devc = mlx5_devcom_register_device(dev); |
| 981 | if (IS_ERR(dev->priv.devc)) | 981 | if (!dev->priv.devc) |
| 982 | mlx5_core_warn(dev, "failed to register devcom device %pe\n", | 982 | mlx5_core_warn(dev, "failed to register devcom device\n"); |
| 983 | dev->priv.devc); | ||
| 984 | 983 | ||
| 985 | err = mlx5_query_board_id(dev); | 984 | err = mlx5_query_board_id(dev); |
| 986 | if (err) { | 985 | if (err) { |
| @@ -2211,15 +2211,35 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 2210 unmodified lines | |||
| 2211 | 2211 | ||
| 2212 | skb_tx_timestamp(skb); | 2212 | skb_tx_timestamp(skb); |
| 2213 | } | 2213 | } |
| 2214 | /* Descriptor type must be set after all the above writes */ | 2214 | |
| 2215 | dma_wmb(); | ||
| 2216 | if (num_tx_desc > 1) { | 2215 | if (num_tx_desc > 1) { |
| 2217 | desc->die_dt = DT_FEND; | 2216 | desc->die_dt = DT_FEND; |
| 2218 | desc--; | 2217 | desc--; |
| 2218 | /* When using multi-descriptors, DT_FEND needs to get written | ||
| 2219 | * before DT_FSTART, but the compiler may reorder the memory | ||
| 2220 | * writes in an attempt to optimize the code. | ||
| 2221 | * Use a dma_wmb() barrier to make sure DT_FEND and DT_FSTART | ||
| 2222 | * are written exactly in the order shown in the code. | ||
| 2223 | * This is particularly important for cases where the DMA engine | ||
| 2224 | * is already running when we are running this code. If the DMA | ||
| 2225 | * sees DT_FSTART without the corresponding DT_FEND it will enter | ||
| 2226 | * an error condition. | ||
| 2227 | */ | ||
| 2228 | dma_wmb(); | ||
| 2219 | desc->die_dt = DT_FSTART; | 2229 | desc->die_dt = DT_FSTART; |
| 2220 | } else { | 2230 | } else { |
| 2231 | /* Descriptor type must be set after all the above writes */ | ||
| 2232 | dma_wmb(); | ||
| 2221 | desc->die_dt = DT_FSINGLE; | 2233 | desc->die_dt = DT_FSINGLE; |
| 2222 | } | 2234 | } |
| 2235 | |||
| 2236 | /* Before ringing the doorbell we need to make sure that the latest | ||
| 2237 | * writes have been committed to memory, otherwise it could delay | ||
| 2238 | * things until the doorbell is rang again. | ||
| 2239 | * This is in replacement of the read operation mentioned in the HW | ||
| 2240 | * manuals. | ||
| 2241 | */ | ||
| 2242 | dma_wmb(); | ||
| 2223 | ravb_modify(ndev, TCCR, TCCR_TSRQ0 << q, TCCR_TSRQ0 << q); | 2243 | ravb_modify(ndev, TCCR, TCCR_TSRQ0 << q, TCCR_TSRQ0 << q); |
| 2224 | 2244 | ||
| 2225 | priv->cur_tx[q] += num_tx_desc; | 2245 | priv->cur_tx[q] += num_tx_desc; |
| @@ -1446,14 +1446,15 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) · 1445 unmodified lines | |||
| 1446 | } | 1446 | } |
| 1447 | } else { | 1447 | } else { |
| 1448 | if (bsp_priv->clk_enabled) { | 1448 | if (bsp_priv->clk_enabled) { |
| 1449 | if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) { | ||
| 1450 | bsp_priv->ops->set_clock_selection(bsp_priv, | ||
| 1451 | bsp_priv->clock_input, false); | ||
| 1452 | } | ||
| 1453 | |||
| 1449 | clk_bulk_disable_unprepare(bsp_priv->num_clks, | 1454 | clk_bulk_disable_unprepare(bsp_priv->num_clks, |
| 1450 | bsp_priv->clks); | 1455 | bsp_priv->clks); |
| 1451 | clk_disable_unprepare(bsp_priv->clk_phy); | 1456 | clk_disable_unprepare(bsp_priv->clk_phy); |
| 1452 | 1457 | ||
| 1453 | if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) | ||
| 1454 | bsp_priv->ops->set_clock_selection(bsp_priv, | ||
| 1455 | bsp_priv->clock_input, false); | ||
| 1456 | |||
| 1457 | bsp_priv->clk_enabled = false; | 1458 | bsp_priv->clk_enabled = false; |
| 1458 | } | 1459 | } |
| 1459 | } | 1460 | } |
| @@ -163,7 +163,9 @@ struct am65_cpts { · 162 unmodified lines | |||
| 163 | struct device_node *clk_mux_np; | 163 | struct device_node *clk_mux_np; |
| 164 | struct clk *refclk; | 164 | struct clk *refclk; |
| 165 | u32 refclk_freq; | 165 | u32 refclk_freq; |
| 166 | struct list_head events; | 166 | /* separate lists to handle TX and RX timestamp independently */ |
| 167 | struct list_head events_tx; | ||
| 168 | struct list_head events_rx; | ||
| 167 | struct list_head pool; | 169 | struct list_head pool; |
| 168 | struct am65_cpts_event pool_data[AM65_CPTS_MAX_EVENTS]; | 170 | struct am65_cpts_event pool_data[AM65_CPTS_MAX_EVENTS]; |
| 169 | spinlock_t lock; /* protects events lists*/ | 171 | spinlock_t lock; /* protects events lists*/ |
| @@ -227,6 +229,24 @@ static void am65_cpts_disable(struct am65_cpts *cpts) · 57 unmodified lines | |||
| 227 | am65_cpts_write32(cpts, 0, int_enable); | 229 | am65_cpts_write32(cpts, 0, int_enable); |
| 228 | } | 230 | } |
| 229 | 231 | ||
| 232 | static int am65_cpts_purge_event_list(struct am65_cpts *cpts, | ||
| 233 | struct list_head *events) | ||
| 234 | { | ||
| 235 | struct list_head *this, *next; | ||
| 236 | struct am65_cpts_event *event; | ||
| 237 | int removed = 0; | ||
| 238 | |||
| 239 | list_for_each_safe(this, next, events) { | ||
| 240 | event = list_entry(this, struct am65_cpts_event, list); | ||
| 241 | if (time_after(jiffies, event->tmo)) { | ||
| 242 | list_del_init(&event->list); | ||
| 243 | list_add(&event->list, &cpts->pool); | ||
| 244 | ++removed; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | return removed; | ||
| 248 | } | ||
| 249 | |||
| 230 | static int am65_cpts_event_get_port(struct am65_cpts_event *event) | 250 | static int am65_cpts_event_get_port(struct am65_cpts_event *event) |
| 231 | { | 251 | { |
| 232 | return (event->event1 & AM65_CPTS_EVENT_1_PORT_NUMBER_MASK) >> | 252 | return (event->event1 & AM65_CPTS_EVENT_1_PORT_NUMBER_MASK) >> |
| @@ -239,20 +259,12 @@ static int am65_cpts_event_get_type(struct am65_cpts_event *event) · 6 unmodified lines | |||
| 239 | AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT; | 259 | AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT; |
| 240 | } | 260 | } |
| 241 | 261 | ||
| 242 | static int am65_cpts_cpts_purge_events(struct am65_cpts *cpts) | 262 | static int am65_cpts_purge_events(struct am65_cpts *cpts) |
| 243 | { | 263 | { |
| 244 | struct list_head *this, *next; | ||
| 245 | struct am65_cpts_event *event; | ||
| 246 | int removed = 0; | 264 | int removed = 0; |
| 247 | 265 | ||
| 248 | list_for_each_safe(this, next, &cpts->events) { | 266 | removed += am65_cpts_purge_event_list(cpts, &cpts->events_tx); |
| 249 | event = list_entry(this, struct am65_cpts_event, list); | 267 | removed += am65_cpts_purge_event_list(cpts, &cpts->events_rx); |
| 250 | if (time_after(jiffies, event->tmo)) { | ||
| 251 | list_del_init(&event->list); | ||
| 252 | list_add(&event->list, &cpts->pool); | ||
| 253 | ++removed; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | 268 | ||
| 257 | if (removed) | 269 | if (removed) |
| 258 | dev_dbg(cpts->dev, "event pool cleaned up %d\n", removed); | 270 | dev_dbg(cpts->dev, "event pool cleaned up %d\n", removed); |
| @@ -287,7 +299,7 @@ static int __am65_cpts_fifo_read(struct am65_cpts *cpts) · 28 unmodified lines | |||
| 287 | struct am65_cpts_event, list); | 299 | struct am65_cpts_event, list); |
| 288 | 300 | ||
| 289 | if (!event) { | 301 | if (!event) { |
| 290 | if (am65_cpts_cpts_purge_events(cpts)) { | 302 | if (am65_cpts_purge_events(cpts)) { |
| 291 | dev_err(cpts->dev, "cpts: event pool empty\n"); | 303 | dev_err(cpts->dev, "cpts: event pool empty\n"); |
| 292 | ret = -1; | 304 | ret = -1; |
| 293 | goto out; | 305 | goto out; |
| @@ -306,11 +318,21 @@ static int __am65_cpts_fifo_read(struct am65_cpts *cpts) · 12 unmodified lines | |||
| 306 | cpts->timestamp); | 318 | cpts->timestamp); |
| 307 | break; | 319 | break; |
| 308 | case AM65_CPTS_EV_RX: | 320 | case AM65_CPTS_EV_RX: |
| 321 | event->tmo = jiffies + | ||
| 322 | msecs_to_jiffies(AM65_CPTS_EVENT_RX_TX_TIMEOUT); | ||
| 323 | |||
| 324 | list_move_tail(&event->list, &cpts->events_rx); | ||
| 325 | |||
| 326 | dev_dbg(cpts->dev, | ||
| 327 | "AM65_CPTS_EV_RX e1:%08x e2:%08x t:%lld\n", | ||
| 328 | event->event1, event->event2, | ||
| 329 | event->timestamp); | ||
| 330 | break; | ||
| 309 | case AM65_CPTS_EV_TX: | 331 | case AM65_CPTS_EV_TX: |
| 310 | event->tmo = jiffies + | 332 | event->tmo = jiffies + |
| 311 | msecs_to_jiffies(AM65_CPTS_EVENT_RX_TX_TIMEOUT); | 333 | msecs_to_jiffies(AM65_CPTS_EVENT_RX_TX_TIMEOUT); |
| 312 | 334 | ||
| 313 | list_move_tail(&event->list, &cpts->events); | 335 | list_move_tail(&event->list, &cpts->events_tx); |
| 314 | 336 | ||
| 315 | dev_dbg(cpts->dev, | 337 | dev_dbg(cpts->dev, |
| 316 | "AM65_CPTS_EV_TX e1:%08x e2:%08x t:%lld\n", | 338 | "AM65_CPTS_EV_TX e1:%08x e2:%08x t:%lld\n", |
| @@ -828,7 +850,7 @@ static bool am65_cpts_match_tx_ts(struct am65_cpts *cpts, · 511 unmodified lines | |||
| 828 | return found; | 850 | return found; |
| 829 | } | 851 | } |
| 830 | 852 | ||
| 831 | static void am65_cpts_find_ts(struct am65_cpts *cpts) | 853 | static void am65_cpts_find_tx_ts(struct am65_cpts *cpts) |
| 832 | { | 854 | { |
| 833 | struct am65_cpts_event *event; | 855 | struct am65_cpts_event *event; |
| 834 | struct list_head *this, *next; | 856 | struct list_head *this, *next; |
| @@ -837,7 +859,7 @@ static void am65_cpts_find_ts(struct am65_cpts *cpts) · 2 unmodified lines | |||
| 837 | LIST_HEAD(events); | 859 | LIST_HEAD(events); |
| 838 | 860 | ||
| 839 | spin_lock_irqsave(&cpts->lock, flags); | 861 | spin_lock_irqsave(&cpts->lock, flags); |
| 840 | list_splice_init(&cpts->events, &events); | 862 | list_splice_init(&cpts->events_tx, &events); |
| 841 | spin_unlock_irqrestore(&cpts->lock, flags); | 863 | spin_unlock_irqrestore(&cpts->lock, flags); |
| 842 | 864 | ||
| 843 | list_for_each_safe(this, next, &events) { | 865 | list_for_each_safe(this, next, &events) { |
| @@ -850,7 +872,7 @@ static void am65_cpts_find_ts(struct am65_cpts *cpts) · 6 unmodified lines | |||
| 850 | } | 872 | } |
| 851 | 873 | ||
| 852 | spin_lock_irqsave(&cpts->lock, flags); | 874 | spin_lock_irqsave(&cpts->lock, flags); |
| 853 | list_splice_tail(&events, &cpts->events); | 875 | list_splice_tail(&events, &cpts->events_tx); |
| 854 | list_splice_tail(&events_free, &cpts->pool); | 876 | list_splice_tail(&events_free, &cpts->pool); |
| 855 | spin_unlock_irqrestore(&cpts->lock, flags); | 877 | spin_unlock_irqrestore(&cpts->lock, flags); |
| 856 | } | 878 | } |
| @@ -861,7 +883,7 @@ static long am65_cpts_ts_work(struct ptp_clock_info *ptp) · 4 unmodified lines | |||
| 861 | unsigned long flags; | 883 | unsigned long flags; |
| 862 | long delay = -1; | 884 | long delay = -1; |
| 863 | 885 | ||
| 864 | am65_cpts_find_ts(cpts); | 886 | am65_cpts_find_tx_ts(cpts); |
| 865 | 887 | ||
| 866 | spin_lock_irqsave(&cpts->txq.lock, flags); | 888 | spin_lock_irqsave(&cpts->txq.lock, flags); |
| 867 | if (!skb_queue_empty(&cpts->txq)) | 889 | if (!skb_queue_empty(&cpts->txq)) |
| @@ -905,7 +927,7 @@ static u64 am65_cpts_find_rx_ts(struct am65_cpts *cpts, u32 skb_mtype_seqid) · 37 unmodified lines | |||
| 905 | 927 | ||
| 906 | spin_lock_irqsave(&cpts->lock, flags); | 928 | spin_lock_irqsave(&cpts->lock, flags); |
| 907 | __am65_cpts_fifo_read(cpts); | 929 | __am65_cpts_fifo_read(cpts); |
| 908 | list_for_each_safe(this, next, &cpts->events) { | 930 | list_for_each_safe(this, next, &cpts->events_rx) { |
| 909 | event = list_entry(this, struct am65_cpts_event, list); | 931 | event = list_entry(this, struct am65_cpts_event, list); |
| 910 | if (time_after(jiffies, event->tmo)) { | 932 | if (time_after(jiffies, event->tmo)) { |
| 911 | list_move(&event->list, &cpts->pool); | 933 | list_move(&event->list, &cpts->pool); |
| @@ -1155,7 +1177,8 @@ struct am65_cpts *am65_cpts_create(struct device *dev, void __iomem *regs, · 243 unmodified lines | |||
| 1155 | return ERR_PTR(ret); | 1177 | return ERR_PTR(ret); |
| 1156 | 1178 | ||
| 1157 | mutex_init(&cpts->ptp_clk_lock); | 1179 | mutex_init(&cpts->ptp_clk_lock); |
| 1158 | INIT_LIST_HEAD(&cpts->events); | 1180 | INIT_LIST_HEAD(&cpts->events_tx); |
| 1181 | INIT_LIST_HEAD(&cpts->events_rx); | ||
| 1159 | INIT_LIST_HEAD(&cpts->pool); | 1182 | INIT_LIST_HEAD(&cpts->pool); |
| 1160 | spin_lock_init(&cpts->lock); | 1183 | spin_lock_init(&cpts->lock); |
| 1161 | skb_queue_head_init(&cpts->txq); | 1184 | skb_queue_head_init(&cpts->txq); |
| @@ -560,16 +560,34 @@ static void ovpn_tcp_close(struct sock *sk, long timeout) · 559 unmodified lines | |||
| 560 | static __poll_t ovpn_tcp_poll(struct file *file, struct socket *sock, | 560 | static __poll_t ovpn_tcp_poll(struct file *file, struct socket *sock, |
| 561 | poll_table *wait) | 561 | poll_table *wait) |
| 562 | { | 562 | { |
| 563 | __poll_t mask = datagram_poll(file, sock, wait); | 563 | struct sk_buff_head *queue = &sock->sk->sk_receive_queue; |
| 564 | struct ovpn_socket *ovpn_sock; | 564 | struct ovpn_socket *ovpn_sock; |
| 565 | struct ovpn_peer *peer = NULL; | ||
| 566 | __poll_t mask; | ||
| 565 | 567 | ||
| 566 | rcu_read_lock(); | 568 | rcu_read_lock(); |
| 567 | ovpn_sock = rcu_dereference_sk_user_data(sock->sk); | 569 | ovpn_sock = rcu_dereference_sk_user_data(sock->sk); |
| 568 | if (ovpn_sock && ovpn_sock->peer && | 570 | /* if we landed in this callback, we expect to have a |
| 569 | !skb_queue_empty(&ovpn_sock->peer->tcp.user_queue)) | 571 | * meaningful state. The ovpn_socket lifecycle would |
| 570 | mask |= EPOLLIN | EPOLLRDNORM; | 572 | * prevent it otherwise. |
| 573 | */ | ||
| 574 | if (WARN(!ovpn_sock || !ovpn_sock->peer, | ||
| 575 | "ovpn: null state in ovpn_tcp_poll!")) { | ||
| 576 | rcu_read_unlock(); | ||
| 577 | return 0; | ||
| 578 | } | ||
| 579 | |||
| 580 | if (ovpn_peer_hold(ovpn_sock->peer)) { | ||
| 581 | peer = ovpn_sock->peer; | ||
| 582 | queue = &peer->tcp.user_queue; | ||
| 583 | } | ||
| 571 | rcu_read_unlock(); | 584 | rcu_read_unlock(); |
| 572 | 585 | ||
| 586 | mask = datagram_poll_queue(file, sock, wait, queue); | ||
| 587 | |||
| 588 | if (peer) | ||
| 589 | ovpn_peer_put(peer); | ||
| 590 | |||
| 573 | return mask; | 591 | return mask; |
| 574 | } | 592 | } |
| 575 | 593 | ||
| @@ -4262,6 +4262,8 @@ static int __lan8814_ptp_probe_once(struct phy_device *phydev, char *pin_name, · 4261 unmodified lines | |||
| 4262 | { | 4262 | { |
| 4263 | struct lan8814_shared_priv *shared = phy_package_get_priv(phydev); | 4263 | struct lan8814_shared_priv *shared = phy_package_get_priv(phydev); |
| 4264 | 4264 | ||
| 4265 | shared->phydev = phydev; | ||
| 4266 | |||
| 4265 | /* Initialise shared lock for clock*/ | 4267 | /* Initialise shared lock for clock*/ |
| 4266 | mutex_init(&shared->shared_lock); | 4268 | mutex_init(&shared->shared_lock); |
| 4267 | 4269 | ||
| @@ -4317,8 +4319,6 @@ static int __lan8814_ptp_probe_once(struct phy_device *phydev, char *pin_name, · 49 unmodified lines | |||
| 4317 | 4319 | ||
| 4318 | phydev_dbg(phydev, "successfully registered ptp clock\n"); | 4320 | phydev_dbg(phydev, "successfully registered ptp clock\n"); |
| 4319 | 4321 | ||
| 4320 | shared->phydev = phydev; | ||
| 4321 | |||
| 4322 | /* The EP.4 is shared between all the PHYs in the package and also it | 4322 | /* The EP.4 is shared between all the PHYs in the package and also it |
| 4323 | * can be accessed by any of the PHYs | 4323 | * can be accessed by any of the PHYs |
| 4324 | */ | 4324 | */ |
| @@ -154,7 +154,7 @@ · 153 unmodified lines | |||
| 154 | #define RTL_8211FVD_PHYID 0x001cc878 | 154 | #define RTL_8211FVD_PHYID 0x001cc878 |
| 155 | #define RTL_8221B 0x001cc840 | 155 | #define RTL_8221B 0x001cc840 |
| 156 | #define RTL_8221B_VB_CG 0x001cc849 | 156 | #define RTL_8221B_VB_CG 0x001cc849 |
| 157 | #define RTL_8221B_VN_CG 0x001cc84a | 157 | #define RTL_8221B_VM_CG 0x001cc84a |
| 158 | #define RTL_8251B 0x001cc862 | 158 | #define RTL_8251B 0x001cc862 |
| 159 | #define RTL_8261C 0x001cc890 | 159 | #define RTL_8261C 0x001cc890 |
| 160 | 160 | ||
| @@ -1523,16 +1523,16 @@ static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev, · 1362 unmodified lines | |||
| 1523 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); | 1523 | return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true); |
| 1524 | } | 1524 | } |
| 1525 | 1525 | ||
| 1526 | static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev, | 1526 | static int rtl8221b_vm_cg_c22_match_phy_device(struct phy_device *phydev, |
| 1527 | const struct phy_driver *phydrv) | 1527 | const struct phy_driver *phydrv) |
| 1528 | { | 1528 | { |
| 1529 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false); | 1529 | return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, false); |
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev, | 1532 | static int rtl8221b_vm_cg_c45_match_phy_device(struct phy_device *phydev, |
| 1533 | const struct phy_driver *phydrv) | 1533 | const struct phy_driver *phydrv) |
| 1534 | { | 1534 | { |
| 1535 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); | 1535 | return rtlgen_is_c45_match(phydev, RTL_8221B_VM_CG, true); |
| 1536 | } | 1536 | } |
| 1537 | 1537 | ||
| 1538 | static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, | 1538 | static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev, |
| @@ -1879,7 +1879,7 @@ static struct phy_driver realtek_drvs[] = { · 340 unmodified lines | |||
| 1879 | .suspend = genphy_c45_pma_suspend, | 1879 | .suspend = genphy_c45_pma_suspend, |
| 1880 | .resume = rtlgen_c45_resume, | 1880 | .resume = rtlgen_c45_resume, |
| 1881 | }, { | 1881 | }, { |
| 1882 | .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device, | 1882 | .match_phy_device = rtl8221b_vm_cg_c22_match_phy_device, |
| 1883 | .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", | 1883 | .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)", |
| 1884 | .probe = rtl822x_probe, | 1884 | .probe = rtl822x_probe, |
| 1885 | .get_features = rtl822x_get_features, | 1885 | .get_features = rtl822x_get_features, |
| @@ -1892,8 +1892,8 @@ static struct phy_driver realtek_drvs[] = { · 6 unmodified lines | |||
| 1892 | .read_page = rtl821x_read_page, | 1892 | .read_page = rtl821x_read_page, |
| 1893 | .write_page = rtl821x_write_page, | 1893 | .write_page = rtl821x_write_page, |
| 1894 | }, { | 1894 | }, { |
| 1895 | .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device, | 1895 | .match_phy_device = rtl8221b_vm_cg_c45_match_phy_device, |
| 1896 | .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)", | 1896 | .name = "RTL8221B-VM-CG 2.5Gbps PHY (C45)", |
| 1897 | .probe = rtl822x_probe, | 1897 | .probe = rtl822x_probe, |
| 1898 | .config_init = rtl822xb_config_init, | 1898 | .config_init = rtl822xb_config_init, |
| 1899 | .get_rate_matching = rtl822xb_get_rate_matching, | 1899 | .get_rate_matching = rtl822xb_get_rate_matching, |
| @@ -685,9 +685,16 @@ static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb, · 684 unmodified lines | |||
| 685 | rtl8150_t *dev = netdev_priv(netdev); | 685 | rtl8150_t *dev = netdev_priv(netdev); |
| 686 | int count, res; | 686 | int count, res; |
| 687 | 687 | ||
| 688 | /* pad the frame and ensure terminating USB packet, datasheet 9.2.3 */ | ||
| 689 | count = max(skb->len, ETH_ZLEN); | ||
| 690 | if (count % 64 == 0) | ||
| 691 | count++; | ||
| 692 | if (skb_padto(skb, count)) { | ||
| 693 | netdev->stats.tx_dropped++; | ||
| 694 | return NETDEV_TX_OK; | ||
| 695 | } | ||
| 696 | |||
| 688 | netif_stop_queue(netdev); | 697 | netif_stop_queue(netdev); |
| 689 | count = (skb->len < 60) ? 60 : skb->len; | ||
| 690 | count = (count & 0x3f) ? count : count + 1; | ||
| 691 | dev->tx_skb = skb; | 698 | dev->tx_skb = skb; |
| 692 | usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), | 699 | usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), |
| 693 | skb->data, count, write_bulk_callback, dev); | 700 | skb->data, count, write_bulk_callback, dev); |
| @@ -127,6 +127,7 @@ static const struct of_device_id rcar_fuse_match[] = { · 126 unmodified lines | |||
| 127 | { .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m }, | 127 | { .compatible = "renesas,r8a779h0-otp", .data = &rcar_fuse_v4m }, |
| 128 | { /* sentinel */ } | 128 | { /* sentinel */ } |
| 129 | }; | 129 | }; |
| 130 | MODULE_DEVICE_TABLE(of, rcar_fuse_match); | ||
| 130 | 131 | ||
| 131 | static struct platform_driver rcar_fuse_driver = { | 132 | static struct platform_driver rcar_fuse_driver = { |
| 132 | .probe = rcar_fuse_probe, | 133 | .probe = rcar_fuse_probe, |
| @@ -671,6 +671,36 @@ err: · 670 unmodified lines | |||
| 671 | } | 671 | } |
| 672 | } | 672 | } |
| 673 | 673 | ||
| 674 | static int of_check_msi_parent(struct device_node *dev_node, struct device_node **msi_node) | ||
| 675 | { | ||
| 676 | struct of_phandle_args msi_spec; | ||
| 677 | int ret; | ||
| 678 | |||
| 679 | /* | ||
| 680 | * An msi-parent phandle with a missing or == 0 #msi-cells | ||
| 681 | * property identifies a 1:1 ID translation mapping. | ||
| 682 | * | ||
| 683 | * Set the msi controller node if the firmware matches this | ||
| 684 | * condition. | ||
| 685 | */ | ||
| 686 | ret = of_parse_phandle_with_optional_args(dev_node, "msi-parent", "#msi-cells", | ||
| 687 | 0, &msi_spec); | ||
| 688 | if (ret) | ||
| 689 | return ret; | ||
| 690 | |||
| 691 | if ((*msi_node && *msi_node != msi_spec.np) || msi_spec.args_count != 0) | ||
| 692 | ret = -EINVAL; | ||
| 693 | |||
| 694 | if (!ret) { | ||
| 695 | /* Return with a node reference held */ | ||
| 696 | *msi_node = msi_spec.np; | ||
| 697 | return 0; | ||
| 698 | } | ||
| 699 | of_node_put(msi_spec.np); | ||
| 700 | |||
| 701 | return ret; | ||
| 702 | } | ||
| 703 | |||
| 674 | /** | 704 | /** |
| 675 | * of_msi_xlate - map a MSI ID and find relevant MSI controller node | 705 | * of_msi_xlate - map a MSI ID and find relevant MSI controller node |
| 676 | * @dev: device for which the mapping is to be done. | 706 | * @dev: device for which the mapping is to be done. |
| @@ -678,7 +708,7 @@ err: · 1 unmodified line | |||
| 678 | * @id_in: Device ID. | 708 | * @id_in: Device ID. |
| 679 | * | 709 | * |
| 680 | * Walk up the device hierarchy looking for devices with a "msi-map" | 710 | * Walk up the device hierarchy looking for devices with a "msi-map" |
| 681 | * property. If found, apply the mapping to @id_in. | 711 | * or "msi-parent" property. If found, apply the mapping to @id_in. |
| 682 | * If @msi_np points to a non-NULL device node pointer, only entries targeting | 712 | * If @msi_np points to a non-NULL device node pointer, only entries targeting |
| 683 | * that node will be matched; if it points to a NULL value, it will receive the | 713 | * that node will be matched; if it points to a NULL value, it will receive the |
| 684 | * device node of the first matching target phandle, with a reference held. | 714 | * device node of the first matching target phandle, with a reference held. |
| @@ -692,14 +722,18 @@ u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_in) · 7 unmodified lines | |||
| 692 | 722 | ||
| 693 | /* | 723 | /* |
| 694 | * Walk up the device parent links looking for one with a | 724 | * Walk up the device parent links looking for one with a |
| 695 | * "msi-map" property. | 725 | * "msi-map" or an "msi-parent" property. |
| 696 | */ | 726 | */ |
| 697 | for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) | 727 | for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) { |
| 698 | if (!of_map_id(parent_dev->of_node, id_in, "msi-map", | 728 | if (!of_map_id(parent_dev->of_node, id_in, "msi-map", |
| 699 | "msi-map-mask", msi_np, &id_out)) | 729 | "msi-map-mask", msi_np, &id_out)) |
| 700 | break; | 730 | break; |
| 731 | if (!of_check_msi_parent(parent_dev->of_node, msi_np)) | ||
| 732 | break; | ||
| 733 | } | ||
| 701 | return id_out; | 734 | return id_out; |
| 702 | } | 735 | } |
| 736 | EXPORT_SYMBOL_GPL(of_msi_xlate); | ||
| 703 | 737 | ||
| 704 | /** | 738 | /** |
| 705 | * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain | 739 | * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain |
| @@ -741,8 +775,10 @@ struct irq_domain *of_msi_get_domain(struct device *dev, · 35 unmodified lines | |||
| 741 | 775 | ||
| 742 | of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) { | 776 | of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) { |
| 743 | d = irq_find_matching_host(it.node, token); | 777 | d = irq_find_matching_host(it.node, token); |
| 744 | if (d) | 778 | if (d) { |
| 779 | of_node_put(it.node); | ||
| 745 | return d; | 780 | return d; |
| 781 | } | ||
| 746 | } | 782 | } |
| 747 | 783 | ||
| 748 | return NULL; | 784 | return NULL; |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include "pcie-designware.h" | 23 | #include "pcie-designware.h" |
| 24 | 24 | ||
| 25 | static struct pci_ops dw_pcie_ops; | 25 | static struct pci_ops dw_pcie_ops; |
| 26 | static struct pci_ops dw_pcie_ecam_ops; | ||
| 26 | static struct pci_ops dw_child_pcie_ops; | 27 | static struct pci_ops dw_child_pcie_ops; |
| 27 | 28 | ||
| 28 | #define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ | 29 | #define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ |
| @@ -471,9 +472,6 @@ static int dw_pcie_create_ecam_window(struct dw_pcie_rp *pp, struct resource *re · 442 unmodified lines | |||
| 471 | if (IS_ERR(pp->cfg)) | 472 | if (IS_ERR(pp->cfg)) |
| 472 | return PTR_ERR(pp->cfg); | 473 | return PTR_ERR(pp->cfg); |
| 473 | 474 | ||
| 474 | pci->dbi_base = pp->cfg->win; | ||
| 475 | pci->dbi_phys_addr = res->start; | ||
| 476 | |||
| 477 | return 0; | 475 | return 0; |
| 478 | } | 476 | } |
| 479 | 477 | ||
| @@ -529,7 +527,7 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp) · 49 unmodified lines | |||
| 529 | if (ret) | 527 | if (ret) |
| 530 | return ret; | 528 | return ret; |
| 531 | 529 | ||
| 532 | pp->bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops; | 530 | pp->bridge->ops = &dw_pcie_ecam_ops; |
| 533 | pp->bridge->sysdata = pp->cfg; | 531 | pp->bridge->sysdata = pp->cfg; |
| 534 | pp->cfg->priv = pp; | 532 | pp->cfg->priv = pp; |
| 535 | } else { | 533 | } else { |
| @@ -842,12 +840,34 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn, · 306 unmodified lines | |||
| 842 | } | 840 | } |
| 843 | EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus); | 841 | EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus); |
| 844 | 842 | ||
| 843 | static void __iomem *dw_pcie_ecam_conf_map_bus(struct pci_bus *bus, unsigned int devfn, int where) | ||
| 844 | { | ||
| 845 | struct pci_config_window *cfg = bus->sysdata; | ||
| 846 | struct dw_pcie_rp *pp = cfg->priv; | ||
| 847 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 848 | unsigned int busn = bus->number; | ||
| 849 | |||
| 850 | if (busn > 0) | ||
| 851 | return pci_ecam_map_bus(bus, devfn, where); | ||
| 852 | |||
| 853 | if (PCI_SLOT(devfn) > 0) | ||
| 854 | return NULL; | ||
| 855 | |||
| 856 | return pci->dbi_base + where; | ||
| 857 | } | ||
| 858 | |||
| 845 | static struct pci_ops dw_pcie_ops = { | 859 | static struct pci_ops dw_pcie_ops = { |
| 846 | .map_bus = dw_pcie_own_conf_map_bus, | 860 | .map_bus = dw_pcie_own_conf_map_bus, |
| 847 | .read = pci_generic_config_read, | 861 | .read = pci_generic_config_read, |
| 848 | .write = pci_generic_config_write, | 862 | .write = pci_generic_config_write, |
| 849 | }; | 863 | }; |
| 850 | 864 | ||
| 865 | static struct pci_ops dw_pcie_ecam_ops = { | ||
| 866 | .map_bus = dw_pcie_ecam_conf_map_bus, | ||
| 867 | .read = pci_generic_config_read, | ||
| 868 | .write = pci_generic_config_write, | ||
| 869 | }; | ||
| 870 | |||
| 851 | static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp) | 871 | static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp) |
| 852 | { | 872 | { |
| 853 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 873 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| @@ -55,7 +55,6 @@ · 54 unmodified lines | |||
| 55 | #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 | 55 | #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 |
| 56 | #define PARF_Q2A_FLUSH 0x1ac | 56 | #define PARF_Q2A_FLUSH 0x1ac |
| 57 | #define PARF_LTSSM 0x1b0 | 57 | #define PARF_LTSSM 0x1b0 |
| 58 | #define PARF_SLV_DBI_ELBI 0x1b4 | ||
| 59 | #define PARF_INT_ALL_STATUS 0x224 | 58 | #define PARF_INT_ALL_STATUS 0x224 |
| 60 | #define PARF_INT_ALL_CLEAR 0x228 | 59 | #define PARF_INT_ALL_CLEAR 0x228 |
| 61 | #define PARF_INT_ALL_MASK 0x22c | 60 | #define PARF_INT_ALL_MASK 0x22c |
| @@ -65,16 +64,6 @@ · 3 unmodified lines | |||
| 65 | #define PARF_DBI_BASE_ADDR_V2_HI 0x354 | 64 | #define PARF_DBI_BASE_ADDR_V2_HI 0x354 |
| 66 | #define PARF_SLV_ADDR_SPACE_SIZE_V2 0x358 | 65 | #define PARF_SLV_ADDR_SPACE_SIZE_V2 0x358 |
| 67 | #define PARF_SLV_ADDR_SPACE_SIZE_V2_HI 0x35c | 66 | #define PARF_SLV_ADDR_SPACE_SIZE_V2_HI 0x35c |
| 68 | #define PARF_BLOCK_SLV_AXI_WR_BASE 0x360 | ||
| 69 | #define PARF_BLOCK_SLV_AXI_WR_BASE_HI 0x364 | ||
| 70 | #define PARF_BLOCK_SLV_AXI_WR_LIMIT 0x368 | ||
| 71 | #define PARF_BLOCK_SLV_AXI_WR_LIMIT_HI 0x36c | ||
| 72 | #define PARF_BLOCK_SLV_AXI_RD_BASE 0x370 | ||
| 73 | #define PARF_BLOCK_SLV_AXI_RD_BASE_HI 0x374 | ||
| 74 | #define PARF_BLOCK_SLV_AXI_RD_LIMIT 0x378 | ||
| 75 | #define PARF_BLOCK_SLV_AXI_RD_LIMIT_HI 0x37c | ||
| 76 | #define PARF_ECAM_BASE 0x380 | ||
| 77 | #define PARF_ECAM_BASE_HI 0x384 | ||
| 78 | #define PARF_NO_SNOOP_OVERRIDE 0x3d4 | 67 | #define PARF_NO_SNOOP_OVERRIDE 0x3d4 |
| 79 | #define PARF_ATU_BASE_ADDR 0x634 | 68 | #define PARF_ATU_BASE_ADDR 0x634 |
| 80 | #define PARF_ATU_BASE_ADDR_HI 0x638 | 69 | #define PARF_ATU_BASE_ADDR_HI 0x638 |
| @@ -98,7 +87,6 @@ · 17 unmodified lines | |||
| 98 | 87 | ||
| 99 | /* PARF_SYS_CTRL register fields */ | 88 | /* PARF_SYS_CTRL register fields */ |
| 100 | #define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN BIT(29) | 89 | #define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN BIT(29) |
| 101 | #define PCIE_ECAM_BLOCKER_EN BIT(26) | ||
| 102 | #define MST_WAKEUP_EN BIT(13) | 90 | #define MST_WAKEUP_EN BIT(13) |
| 103 | #define SLV_WAKEUP_EN BIT(12) | 91 | #define SLV_WAKEUP_EN BIT(12) |
| 104 | #define MSTR_ACLK_CGC_DIS BIT(10) | 92 | #define MSTR_ACLK_CGC_DIS BIT(10) |
| @@ -146,9 +134,6 @@ · 41 unmodified lines | |||
| 146 | /* PARF_LTSSM register fields */ | 134 | /* PARF_LTSSM register fields */ |
| 147 | #define LTSSM_EN BIT(8) | 135 | #define LTSSM_EN BIT(8) |
| 148 | 136 | ||
| 149 | /* PARF_SLV_DBI_ELBI */ | ||
| 150 | #define SLV_DBI_ELBI_ADDR_BASE GENMASK(11, 0) | ||
| 151 | |||
| 152 | /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */ | 137 | /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */ |
| 153 | #define PARF_INT_ALL_LINK_UP BIT(13) | 138 | #define PARF_INT_ALL_LINK_UP BIT(13) |
| 154 | #define PARF_INT_MSI_DEV_0_7 GENMASK(30, 23) | 139 | #define PARF_INT_MSI_DEV_0_7 GENMASK(30, 23) |
| @@ -326,47 +311,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) · 171 unmodified lines | |||
| 326 | qcom_perst_assert(pcie, false); | 311 | qcom_perst_assert(pcie, false); |
| 327 | } | 312 | } |
| 328 | 313 | ||
| 329 | static void qcom_pci_config_ecam(struct dw_pcie_rp *pp) | ||
| 330 | { | ||
| 331 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 332 | struct qcom_pcie *pcie = to_qcom_pcie(pci); | ||
| 333 | u64 addr, addr_end; | ||
| 334 | u32 val; | ||
| 335 | |||
| 336 | writel_relaxed(lower_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE); | ||
| 337 | writel_relaxed(upper_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE_HI); | ||
| 338 | |||
| 339 | /* | ||
| 340 | * The only device on the root bus is a single Root Port. If we try to | ||
| 341 | * access any devices other than Device/Function 00.0 on Bus 0, the TLP | ||
| 342 | * will go outside of the controller to the PCI bus. But with CFG Shift | ||
| 343 | * Feature (ECAM) enabled in iATU, there is no guarantee that the | ||
| 344 | * response is going to be all F's. Hence, to make sure that the | ||
| 345 | * requester gets all F's response for accesses other than the Root | ||
| 346 | * Port, configure iATU to block the transactions starting from | ||
| 347 | * function 1 of the root bus to the end of the root bus (i.e., from | ||
| 348 | * dbi_base + 4KB to dbi_base + 1MB). | ||
| 349 | */ | ||
| 350 | addr = pci->dbi_phys_addr + SZ_4K; | ||
| 351 | writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE); | ||
| 352 | writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE_HI); | ||
| 353 | |||
| 354 | writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE); | ||
| 355 | writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE_HI); | ||
| 356 | |||
| 357 | addr_end = pci->dbi_phys_addr + SZ_1M - 1; | ||
| 358 | |||
| 359 | writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT); | ||
| 360 | writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT_HI); | ||
| 361 | |||
| 362 | writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT); | ||
| 363 | writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT_HI); | ||
| 364 | |||
| 365 | val = readl_relaxed(pcie->parf + PARF_SYS_CTRL); | ||
| 366 | val |= PCIE_ECAM_BLOCKER_EN; | ||
| 367 | writel_relaxed(val, pcie->parf + PARF_SYS_CTRL); | ||
| 368 | } | ||
| 369 | |||
| 370 | static int qcom_pcie_start_link(struct dw_pcie *pci) | 314 | static int qcom_pcie_start_link(struct dw_pcie *pci) |
| 371 | { | 315 | { |
| 372 | struct qcom_pcie *pcie = to_qcom_pcie(pci); | 316 | struct qcom_pcie *pcie = to_qcom_pcie(pci); |
| @@ -1320,7 +1264,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) · 947 unmodified lines | |||
| 1320 | { | 1264 | { |
| 1321 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 1265 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
| 1322 | struct qcom_pcie *pcie = to_qcom_pcie(pci); | 1266 | struct qcom_pcie *pcie = to_qcom_pcie(pci); |
| 1323 | u16 offset; | ||
| 1324 | int ret; | 1267 | int ret; |
| 1325 | 1268 | ||
| 1326 | qcom_ep_reset_assert(pcie); | 1269 | qcom_ep_reset_assert(pcie); |
| @@ -1329,17 +1272,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp) · 2 unmodified lines | |||
| 1329 | if (ret) | 1272 | if (ret) |
| 1330 | return ret; | 1273 | return ret; |
| 1331 | 1274 | ||
| 1332 | if (pp->ecam_enabled) { | ||
| 1333 | /* | ||
| 1334 | * Override ELBI when ECAM is enabled, as when ECAM is enabled, | ||
| 1335 | * ELBI moves under the 'config' space. | ||
| 1336 | */ | ||
| 1337 | offset = FIELD_GET(SLV_DBI_ELBI_ADDR_BASE, readl(pcie->parf + PARF_SLV_DBI_ELBI)); | ||
| 1338 | pci->elbi_base = pci->dbi_base + offset; | ||
| 1339 | |||
| 1340 | qcom_pci_config_ecam(pp); | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | ret = qcom_pcie_phy_power_on(pcie); | 1275 | ret = qcom_pcie_phy_power_on(pcie); |
| 1344 | if (ret) | 1276 | if (ret) |
| 1345 | goto err_deinit; | 1277 | goto err_deinit; |
| @@ -243,8 +243,7 @@ struct pcie_link_state { · 242 unmodified lines | |||
| 243 | /* Clock PM state */ | 243 | /* Clock PM state */ |
| 244 | u32 clkpm_capable:1; /* Clock PM capable? */ | 244 | u32 clkpm_capable:1; /* Clock PM capable? */ |
| 245 | u32 clkpm_enabled:1; /* Current Clock PM state */ | 245 | u32 clkpm_enabled:1; /* Current Clock PM state */ |
| 246 | u32 clkpm_default:1; /* Default Clock PM state by BIOS or | 246 | u32 clkpm_default:1; /* Default Clock PM state by BIOS */ |
| 247 | override */ | ||
| 248 | u32 clkpm_disable:1; /* Clock PM disabled */ | 247 | u32 clkpm_disable:1; /* Clock PM disabled */ |
| 249 | }; | 248 | }; |
| 250 | 249 | ||
| @@ -376,18 +375,6 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) · 125 unmodified lines | |||
| 376 | pcie_set_clkpm_nocheck(link, enable); | 375 | pcie_set_clkpm_nocheck(link, enable); |
| 377 | } | 376 | } |
| 378 | 377 | ||
| 379 | static void pcie_clkpm_override_default_link_state(struct pcie_link_state *link, | ||
| 380 | int enabled) | ||
| 381 | { | ||
| 382 | struct pci_dev *pdev = link->downstream; | ||
| 383 | |||
| 384 | /* For devicetree platforms, enable ClockPM by default */ | ||
| 385 | if (of_have_populated_dt() && !enabled) { | ||
| 386 | link->clkpm_default = 1; | ||
| 387 | pci_info(pdev, "ASPM: DT platform, enabling ClockPM\n"); | ||
| 388 | } | ||
| 389 | } | ||
| 390 | |||
| 391 | static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | 378 | static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) |
| 392 | { | 379 | { |
| 393 | int capable = 1, enabled = 1; | 380 | int capable = 1, enabled = 1; |
| @@ -410,7 +397,6 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) · 16 unmodified lines | |||
| 410 | } | 397 | } |
| 411 | link->clkpm_enabled = enabled; | 398 | link->clkpm_enabled = enabled; |
| 412 | link->clkpm_default = enabled; | 399 | link->clkpm_default = enabled; |
| 413 | pcie_clkpm_override_default_link_state(link, enabled); | ||
| 414 | link->clkpm_capable = capable; | 400 | link->clkpm_capable = capable; |
| 415 | link->clkpm_disable = blacklist ? 1 : 0; | 401 | link->clkpm_disable = blacklist ? 1 : 0; |
| 416 | } | 402 | } |
| @@ -811,19 +797,17 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link) · 394 unmodified lines | |||
| 811 | struct pci_dev *pdev = link->downstream; | 797 | struct pci_dev *pdev = link->downstream; |
| 812 | u32 override; | 798 | u32 override; |
| 813 | 799 | ||
| 814 | /* For devicetree platforms, enable all ASPM states by default */ | 800 | /* For devicetree platforms, enable L0s and L1 by default */ |
| 815 | if (of_have_populated_dt()) { | 801 | if (of_have_populated_dt()) { |
| 816 | link->aspm_default = PCIE_LINK_STATE_ASPM_ALL; | 802 | if (link->aspm_support & PCIE_LINK_STATE_L0S) |
| 803 | link->aspm_default |= PCIE_LINK_STATE_L0S; | ||
| 804 | if (link->aspm_support & PCIE_LINK_STATE_L1) | ||
| 805 | link->aspm_default |= PCIE_LINK_STATE_L1; | ||
| 817 | override = link->aspm_default & ~link->aspm_enabled; | 806 | override = link->aspm_default & ~link->aspm_enabled; |
| 818 | if (override) | 807 | if (override) |
| 819 | pci_info(pdev, "ASPM: DT platform, enabling%s%s%s%s%s%s%s\n", | 808 | pci_info(pdev, "ASPM: default states%s%s\n", |
| 820 | FLAG(override, L0S_UP, " L0s-up"), | 809 | FLAG(override, L0S, " L0s"), |
| 821 | FLAG(override, L0S_DW, " L0s-dw"), | 810 | FLAG(override, L1, " L1")); |
| 822 | FLAG(override, L1, " L1"), | ||
| 823 | FLAG(override, L1_1, " ASPM-L1.1"), | ||
| 824 | FLAG(override, L1_2, " ASPM-L1.2"), | ||
| 825 | FLAG(override, L1_1_PCIPM, " PCI-PM-L1.1"), | ||
| 826 | FLAG(override, L1_2_PCIPM, " PCI-PM-L1.2")); | ||
| 827 | } | 811 | } |
| 828 | } | 812 | } |
| 829 | 813 | ||
| @@ -2015,6 +2015,7 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, unsigned int blk_ · 2014 unmodified lines | |||
| 2015 | if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) { | 2015 | if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) { |
| 2016 | /* Program crspace counters to count clock cycles using "count_clock" sysfs */ | 2016 | /* Program crspace counters to count clock cycles using "count_clock" sysfs */ |
| 2017 | attr = &pmc->block[blk_num].attr_count_clock; | 2017 | attr = &pmc->block[blk_num].attr_count_clock; |
| 2018 | sysfs_attr_init(&attr->dev_attr.attr); | ||
| 2018 | attr->dev_attr.attr.mode = 0644; | 2019 | attr->dev_attr.attr.mode = 0644; |
| 2019 | attr->dev_attr.show = mlxbf_pmc_count_clock_show; | 2020 | attr->dev_attr.show = mlxbf_pmc_count_clock_show; |
| 2020 | attr->dev_attr.store = mlxbf_pmc_count_clock_store; | 2021 | attr->dev_attr.store = mlxbf_pmc_count_clock_store; |
| @@ -209,6 +209,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { · 208 unmodified lines | |||
| 209 | }, | 209 | }, |
| 210 | .driver_data = &g_series_quirks, | 210 | .driver_data = &g_series_quirks, |
| 211 | }, | 211 | }, |
| 212 | { | ||
| 213 | .ident = "Dell Inc. G15 5530", | ||
| 214 | .matches = { | ||
| 215 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 216 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5530"), | ||
| 217 | }, | ||
| 218 | .driver_data = &g_series_quirks, | ||
| 219 | }, | ||
| 212 | { | 220 | { |
| 213 | .ident = "Dell Inc. G16 7630", | 221 | .ident = "Dell Inc. G16 7630", |
| 214 | .matches = { | 222 | .matches = { |
| @@ -1639,7 +1647,7 @@ static int wmax_wmi_probe(struct wmi_device *wdev, const void *context) · 1424 unmodified lines | |||
| 1639 | 1647 | ||
| 1640 | static int wmax_wmi_suspend(struct device *dev) | 1648 | static int wmax_wmi_suspend(struct device *dev) |
| 1641 | { | 1649 | { |
| 1642 | if (awcc->hwmon) | 1650 | if (awcc && awcc->hwmon) |
| 1643 | awcc_hwmon_suspend(dev); | 1651 | awcc_hwmon_suspend(dev); |
| 1644 | 1652 | ||
| 1645 | return 0; | 1653 | return 0; |
| @@ -1647,7 +1655,7 @@ static int wmax_wmi_suspend(struct device *dev) · 1 unmodified line | |||
| 1647 | 1655 | ||
| 1648 | static int wmax_wmi_resume(struct device *dev) | 1656 | static int wmax_wmi_resume(struct device *dev) |
| 1649 | { | 1657 | { |
| 1650 | if (awcc->hwmon) | 1658 | if (awcc && awcc->hwmon) |
| 1651 | awcc_hwmon_resume(dev); | 1659 | awcc_hwmon_resume(dev); |
| 1652 | 1660 | ||
| 1653 | return 0; | 1661 | return 0; |
| @@ -2548,7 +2548,7 @@ ptp_ocp_sma_fb_init(struct ptp_ocp *bp) · 2547 unmodified lines | |||
| 2548 | for (i = 0; i < OCP_SMA_NUM; i++) { | 2548 | for (i = 0; i < OCP_SMA_NUM; i++) { |
| 2549 | bp->sma[i].fixed_fcn = true; | 2549 | bp->sma[i].fixed_fcn = true; |
| 2550 | bp->sma[i].fixed_dir = true; | 2550 | bp->sma[i].fixed_dir = true; |
| 2551 | bp->sma[1].dpll_prop.capabilities &= | 2551 | bp->sma[i].dpll_prop.capabilities &= |
| 2552 | ~DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE; | 2552 | ~DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE; |
| 2553 | } | 2553 | } |
| 2554 | return; | 2554 | return; |
| @@ -503,7 +503,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) · 502 unmodified lines | |||
| 503 | host_bcode = FC_ERROR; | 503 | host_bcode = FC_ERROR; |
| 504 | goto err; | 504 | goto err; |
| 505 | } | 505 | } |
| 506 | if (offset + len > fsp->data_len) { | 506 | if (size_add(offset, len) > fsp->data_len) { |
| 507 | /* this should never happen */ | 507 | /* this should never happen */ |
| 508 | if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && | 508 | if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && |
| 509 | fc_frame_crc_check(fp)) | 509 | fc_frame_crc_check(fp)) |
| @@ -4104,7 +4104,7 @@ void qla4xxx_srb_compl(struct kref *ref) · 4103 unmodified lines | |||
| 4104 | * The mid-level driver tries to ensure that queuecommand never gets | 4104 | * The mid-level driver tries to ensure that queuecommand never gets |
| 4105 | * invoked concurrently with itself or the interrupt handler (although | 4105 | * invoked concurrently with itself or the interrupt handler (although |
| 4106 | * the interrupt handler may call this routine as part of request- | 4106 | * the interrupt handler may call this routine as part of request- |
| 4107 | * completion handling). Unfortunely, it sometimes calls the scheduler | 4107 | * completion handling). Unfortunately, it sometimes calls the scheduler |
| 4108 | * in interrupt context which is a big NO! NO!. | 4108 | * in interrupt context which is a big NO! NO!. |
| 4109 | **/ | 4109 | **/ |
| 4110 | static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) | 4110 | static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
| @@ -4647,7 +4647,7 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) · 536 unmodified lines | |||
| 4647 | cmd = scsi_host_find_tag(ha->host, index); | 4647 | cmd = scsi_host_find_tag(ha->host, index); |
| 4648 | /* | 4648 | /* |
| 4649 | * We cannot just check if the index is valid, | 4649 | * We cannot just check if the index is valid, |
| 4650 | * becase if we are run from the scsi eh, then | 4650 | * because if we are run from the scsi eh, then |
| 4651 | * the scsi/block layer is going to prevent | 4651 | * the scsi/block layer is going to prevent |
| 4652 | * the tag from being released. | 4652 | * the tag from being released. |
| 4653 | */ | 4653 | */ |
| @@ -4952,7 +4952,7 @@ recover_ha_init_adapter: · 298 unmodified lines | |||
| 4952 | /* Upon successful firmware/chip reset, re-initialize the adapter */ | 4952 | /* Upon successful firmware/chip reset, re-initialize the adapter */ |
| 4953 | if (status == QLA_SUCCESS) { | 4953 | if (status == QLA_SUCCESS) { |
| 4954 | /* For ISP-4xxx, force function 1 to always initialize | 4954 | /* For ISP-4xxx, force function 1 to always initialize |
| 4955 | * before function 3 to prevent both funcions from | 4955 | * before function 3 to prevent both functions from |
| 4956 | * stepping on top of the other */ | 4956 | * stepping on top of the other */ |
| 4957 | if (is_qla40XX(ha) && (ha->mac_index == 3)) | 4957 | if (is_qla40XX(ha) && (ha->mac_index == 3)) |
| 4958 | ssleep(6); | 4958 | ssleep(6); |
| @@ -6914,7 +6914,7 @@ static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha, · 1955 unmodified lines | |||
| 6914 | struct ddb_entry *ddb_entry = NULL; | 6914 | struct ddb_entry *ddb_entry = NULL; |
| 6915 | 6915 | ||
| 6916 | /* Create session object, with INVALID_ENTRY, | 6916 | /* Create session object, with INVALID_ENTRY, |
| 6917 | * the targer_id would get set when we issue the login | 6917 | * the target_id would get set when we issue the login |
| 6918 | */ | 6918 | */ |
| 6919 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, ha->host, | 6919 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, ha->host, |
| 6920 | cmds_max, sizeof(struct ddb_entry), | 6920 | cmds_max, sizeof(struct ddb_entry), |
| @@ -1406,14 +1406,19 @@ static struct vmbus_channel *get_og_chn(struct storvsc_device *stor_device, · 1405 unmodified lines | |||
| 1406 | } | 1406 | } |
| 1407 | 1407 | ||
| 1408 | /* | 1408 | /* |
| 1409 | * Our channel array is sparsley populated and we | 1409 | * Our channel array could be sparsley populated and we |
| 1410 | * initiated I/O on a processor/hw-q that does not | 1410 | * initiated I/O on a processor/hw-q that does not |
| 1411 | * currently have a designated channel. Fix this. | 1411 | * currently have a designated channel. Fix this. |
| 1412 | * The strategy is simple: | 1412 | * The strategy is simple: |
| 1413 | * I. Ensure NUMA locality | 1413 | * I. Prefer the channel associated with the current CPU |
| 1414 | * II. Distribute evenly (best effort) | 1414 | * II. Ensure NUMA locality |
| 1415 | * III. Distribute evenly (best effort) | ||
| 1415 | */ | 1416 | */ |
| 1416 | 1417 | ||
| 1418 | /* Prefer the channel on the I/O issuing processor/hw-q */ | ||
| 1419 | if (cpumask_test_cpu(q_num, &stor_device->alloced_cpus)) | ||
| 1420 | return stor_device->stor_chns[q_num]; | ||
| 1421 | |||
| 1417 | node_mask = cpumask_of_node(cpu_to_node(q_num)); | 1422 | node_mask = cpumask_of_node(cpu_to_node(q_num)); |
| 1418 | 1423 | ||
| 1419 | num_channels = 0; | 1424 | num_channels = 0; |
| @@ -1469,59 +1474,48 @@ static int storvsc_do_io(struct hv_device *device, · 49 unmodified lines | |||
| 1469 | /* See storvsc_change_target_cpu(). */ | 1474 | /* See storvsc_change_target_cpu(). */ |
| 1470 | outgoing_channel = READ_ONCE(stor_device->stor_chns[q_num]); | 1475 | outgoing_channel = READ_ONCE(stor_device->stor_chns[q_num]); |
| 1471 | if (outgoing_channel != NULL) { | 1476 | if (outgoing_channel != NULL) { |
| 1472 | if (outgoing_channel->target_cpu == q_num) { | 1477 | if (hv_get_avail_to_write_percent(&outgoing_channel->outbound) |
| 1473 | /* | 1478 | > ring_avail_percent_lowater) |
| 1474 | * Ideally, we want to pick a different channel if | 1479 | goto found_channel; |
| 1475 | * available on the same NUMA node. | ||
| 1476 | */ | ||
| 1477 | node_mask = cpumask_of_node(cpu_to_node(q_num)); | ||
| 1478 | for_each_cpu_wrap(tgt_cpu, | ||
| 1479 | &stor_device->alloced_cpus, q_num + 1) { | ||
| 1480 | if (!cpumask_test_cpu(tgt_cpu, node_mask)) | ||
| 1481 | continue; | ||
| 1482 | if (tgt_cpu == q_num) | ||
| 1483 | continue; | ||
| 1484 | channel = READ_ONCE( | ||
| 1485 | stor_device->stor_chns[tgt_cpu]); | ||
| 1486 | if (channel == NULL) | ||
| 1487 | continue; | ||
| 1488 | if (hv_get_avail_to_write_percent( | ||
| 1489 | &channel->outbound) | ||
| 1490 | > ring_avail_percent_lowater) { | ||
| 1491 | outgoing_channel = channel; | ||
| 1492 | goto found_channel; | ||
| 1493 | } | ||
| 1494 | } | ||
| 1495 | 1480 | ||
| 1496 | /* | 1481 | /* |
| 1497 | * All the other channels on the same NUMA node are | 1482 | * Channel is busy, try to find a channel on the same NUMA node |
| 1498 | * busy. Try to use the channel on the current CPU | 1483 | */ |
| 1499 | */ | 1484 | node_mask = cpumask_of_node(cpu_to_node(q_num)); |
| 1500 | if (hv_get_avail_to_write_percent( | 1485 | for_each_cpu_wrap(tgt_cpu, &stor_device->alloced_cpus, |
| 1501 | &outgoing_channel->outbound) | 1486 | q_num + 1) { |
| 1502 | > ring_avail_percent_lowater) | 1487 | if (!cpumask_test_cpu(tgt_cpu, node_mask)) |
| 1488 | continue; | ||
| 1489 | channel = READ_ONCE(stor_device->stor_chns[tgt_cpu]); | ||
| 1490 | if (!channel) | ||
| 1491 | continue; | ||
| 1492 | if (hv_get_avail_to_write_percent(&channel->outbound) | ||
| 1493 | > ring_avail_percent_lowater) { | ||
| 1494 | outgoing_channel = channel; | ||
| 1503 | goto found_channel; | 1495 | goto found_channel; |
| 1496 | } | ||
| 1497 | } | ||
| 1504 | 1498 | ||
| 1505 | /* | 1499 | /* |
| 1506 | * If we reach here, all the channels on the current | 1500 | * If we reach here, all the channels on the current |
| 1507 | * NUMA node are busy. Try to find a channel in | 1501 | * NUMA node are busy. Try to find a channel in |
| 1508 | * other NUMA nodes | 1502 | * all NUMA nodes |
| 1509 | */ | 1503 | */ |
| 1510 | for_each_cpu(tgt_cpu, &stor_device->alloced_cpus) { | 1504 | for_each_cpu_wrap(tgt_cpu, &stor_device->alloced_cpus, |
| 1511 | if (cpumask_test_cpu(tgt_cpu, node_mask)) | 1505 | q_num + 1) { |
| 1512 | continue; | 1506 | channel = READ_ONCE(stor_device->stor_chns[tgt_cpu]); |
| 1513 | channel = READ_ONCE( | 1507 | if (!channel) |
| 1514 | stor_device->stor_chns[tgt_cpu]); | 1508 | continue; |
| 1515 | if (channel == NULL) | 1509 | if (hv_get_avail_to_write_percent(&channel->outbound) |
| 1516 | continue; | 1510 | > ring_avail_percent_lowater) { |
| 1517 | if (hv_get_avail_to_write_percent( | 1511 | outgoing_channel = channel; |
| 1518 | &channel->outbound) | 1512 | goto found_channel; |
| 1519 | > ring_avail_percent_lowater) { | ||
| 1520 | outgoing_channel = channel; | ||
| 1521 | goto found_channel; | ||
| 1522 | } | ||
| 1523 | } | 1513 | } |
| 1524 | } | 1514 | } |
| 1515 | /* | ||
| 1516 | * If we reach here, all the channels are busy. Use the | ||
| 1517 | * original channel found. | ||
| 1518 | */ | ||
| 1525 | } else { | 1519 | } else { |
| 1526 | spin_lock_irqsave(&stor_device->lock, flags); | 1520 | spin_lock_irqsave(&stor_device->lock, flags); |
| 1527 | outgoing_channel = stor_device->stor_chns[q_num]; | 1521 | outgoing_channel = stor_device->stor_chns[q_num]; |
| @@ -192,6 +192,14 @@ · 191 unmodified lines | |||
| 192 | #define SPI_NAND_OP_RESET 0xff | 192 | #define SPI_NAND_OP_RESET 0xff |
| 193 | #define SPI_NAND_OP_DIE_SELECT 0xc2 | 193 | #define SPI_NAND_OP_DIE_SELECT 0xc2 |
| 194 | 194 | ||
| 195 | /* SNAND FIFO commands */ | ||
| 196 | #define SNAND_FIFO_TX_BUSWIDTH_SINGLE 0x08 | ||
| 197 | #define SNAND_FIFO_TX_BUSWIDTH_DUAL 0x09 | ||
| 198 | #define SNAND_FIFO_TX_BUSWIDTH_QUAD 0x0a | ||
| 199 | #define SNAND_FIFO_RX_BUSWIDTH_SINGLE 0x0c | ||
| 200 | #define SNAND_FIFO_RX_BUSWIDTH_DUAL 0x0e | ||
| 201 | #define SNAND_FIFO_RX_BUSWIDTH_QUAD 0x0f | ||
| 202 | |||
| 195 | #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) | 203 | #define SPI_NAND_CACHE_SIZE (SZ_4K + SZ_256) |
| 196 | #define SPI_MAX_TRANSFER_SIZE 511 | 204 | #define SPI_MAX_TRANSFER_SIZE 511 |
| 197 | 205 | ||
| @@ -387,10 +395,26 @@ static int airoha_snand_set_mode(struct airoha_snand_ctrl *as_ctrl, · 189 unmodified lines | |||
| 387 | return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); | 395 | return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); |
| 388 | } | 396 | } |
| 389 | 397 | ||
| 390 | static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, | 398 | static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, |
| 391 | const u8 *data, int len) | 399 | const u8 *data, int len, int buswidth) |
| 392 | { | 400 | { |
| 393 | int i, data_len; | 401 | int i, data_len; |
| 402 | u8 cmd; | ||
| 403 | |||
| 404 | switch (buswidth) { | ||
| 405 | case 0: | ||
| 406 | case 1: | ||
| 407 | cmd = SNAND_FIFO_TX_BUSWIDTH_SINGLE; | ||
| 408 | break; | ||
| 409 | case 2: | ||
| 410 | cmd = SNAND_FIFO_TX_BUSWIDTH_DUAL; | ||
| 411 | break; | ||
| 412 | case 4: | ||
| 413 | cmd = SNAND_FIFO_TX_BUSWIDTH_QUAD; | ||
| 414 | break; | ||
| 415 | default: | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 394 | 418 | ||
| 395 | for (i = 0; i < len; i += data_len) { | 419 | for (i = 0; i < len; i += data_len) { |
| 396 | int err; | 420 | int err; |
| @@ -409,16 +433,32 @@ static int airoha_snand_write_data(struct airoha_snand_ctrl *as_ctrl, u8 cmd, · 12 unmodified lines | |||
| 409 | return 0; | 433 | return 0; |
| 410 | } | 434 | } |
| 411 | 435 | ||
| 412 | static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, u8 *data, | 436 | static int airoha_snand_read_data(struct airoha_snand_ctrl *as_ctrl, |
| 413 | int len) | 437 | u8 *data, int len, int buswidth) |
| 414 | { | 438 | { |
| 415 | int i, data_len; | 439 | int i, data_len; |
| 440 | u8 cmd; | ||
| 441 | |||
| 442 | switch (buswidth) { | ||
| 443 | case 0: | ||
| 444 | case 1: | ||
| 445 | cmd = SNAND_FIFO_RX_BUSWIDTH_SINGLE; | ||
| 446 | break; | ||
| 447 | case 2: | ||
| 448 | cmd = SNAND_FIFO_RX_BUSWIDTH_DUAL; | ||
| 449 | break; | ||
| 450 | case 4: | ||
| 451 | cmd = SNAND_FIFO_RX_BUSWIDTH_QUAD; | ||
| 452 | break; | ||
| 453 | default: | ||
| 454 | return -EINVAL; | ||
| 455 | } | ||
| 416 | 456 | ||
| 417 | for (i = 0; i < len; i += data_len) { | 457 | for (i = 0; i < len; i += data_len) { |
| 418 | int err; | 458 | int err; |
| 419 | 459 | ||
| 420 | data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); | 460 | data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); |
| 421 | err = airoha_snand_set_fifo_op(as_ctrl, 0xc, data_len); | 461 | err = airoha_snand_set_fifo_op(as_ctrl, cmd, data_len); |
| 422 | if (err) | 462 | if (err) |
| 423 | return err; | 463 | return err; |
| 424 | 464 | ||
| @@ -618,6 +658,10 @@ static int airoha_snand_dirmap_create(struct spi_mem_dirmap_desc *desc) · 193 unmodified lines | |||
| 618 | if (desc->info.offset + desc->info.length > U32_MAX) | 658 | if (desc->info.offset + desc->info.length > U32_MAX) |
| 619 | return -EINVAL; | 659 | return -EINVAL; |
| 620 | 660 | ||
| 661 | /* continuous reading is not supported */ | ||
| 662 | if (desc->info.length > SPI_NAND_CACHE_SIZE) | ||
| 663 | return -E2BIG; | ||
| 664 | |||
| 621 | if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) | 665 | if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) |
| 622 | return -EOPNOTSUPP; | 666 | return -EOPNOTSUPP; |
| 623 | 667 | ||
| @@ -654,13 +698,13 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, · 30 unmodified lines | |||
| 654 | 698 | ||
| 655 | err = airoha_snand_nfi_config(as_ctrl); | 699 | err = airoha_snand_nfi_config(as_ctrl); |
| 656 | if (err) | 700 | if (err) |
| 657 | return err; | 701 | goto error_dma_mode_off; |
| 658 | 702 | ||
| 659 | dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, | 703 | dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, |
| 660 | DMA_FROM_DEVICE); | 704 | DMA_FROM_DEVICE); |
| 661 | err = dma_mapping_error(as_ctrl->dev, dma_addr); | 705 | err = dma_mapping_error(as_ctrl->dev, dma_addr); |
| 662 | if (err) | 706 | if (err) |
| 663 | return err; | 707 | goto error_dma_mode_off; |
| 664 | 708 | ||
| 665 | /* set dma addr */ | 709 | /* set dma addr */ |
| 666 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, | 710 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, |
| @@ -689,8 +733,9 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, · 22 unmodified lines | |||
| 689 | if (err) | 733 | if (err) |
| 690 | goto error_dma_unmap; | 734 | goto error_dma_unmap; |
| 691 | 735 | ||
| 692 | /* set read addr */ | 736 | /* set read addr: zero page offset + descriptor read offset */ |
| 693 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); | 737 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, |
| 738 | desc->info.offset); | ||
| 694 | if (err) | 739 | if (err) |
| 695 | goto error_dma_unmap; | 740 | goto error_dma_unmap; |
| 696 | 741 | ||
| @@ -760,6 +805,8 @@ static ssize_t airoha_snand_dirmap_read(struct spi_mem_dirmap_desc *desc, · 63 unmodified lines | |||
| 760 | error_dma_unmap: | 805 | error_dma_unmap: |
| 761 | dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, | 806 | dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, |
| 762 | DMA_FROM_DEVICE); | 807 | DMA_FROM_DEVICE); |
| 808 | error_dma_mode_off: | ||
| 809 | airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); | ||
| 763 | return err; | 810 | return err; |
| 764 | } | 811 | } |
| 765 | 812 | ||
| @@ -824,7 +871,9 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, · 58 unmodified lines | |||
| 824 | if (err) | 871 | if (err) |
| 825 | goto error_dma_unmap; | 872 | goto error_dma_unmap; |
| 826 | 873 | ||
| 827 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); | 874 | /* set write addr: zero page offset + descriptor write offset */ |
| 875 | err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, | ||
| 876 | desc->info.offset); | ||
| 828 | if (err) | 877 | if (err) |
| 829 | goto error_dma_unmap; | 878 | goto error_dma_unmap; |
| 830 | 879 | ||
| @@ -892,18 +941,35 @@ static ssize_t airoha_snand_dirmap_write(struct spi_mem_dirmap_desc *desc, · 61 unmodified lines | |||
| 892 | error_dma_unmap: | 941 | error_dma_unmap: |
| 893 | dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, | 942 | dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, |
| 894 | DMA_TO_DEVICE); | 943 | DMA_TO_DEVICE); |
| 944 | airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); | ||
| 895 | return err; | 945 | return err; |
| 896 | } | 946 | } |
| 897 | 947 | ||
| 898 | static int airoha_snand_exec_op(struct spi_mem *mem, | 948 | static int airoha_snand_exec_op(struct spi_mem *mem, |
| 899 | const struct spi_mem_op *op) | 949 | const struct spi_mem_op *op) |
| 900 | { | 950 | { |
| 901 | u8 data[8], cmd, opcode = op->cmd.opcode; | ||
| 902 | struct airoha_snand_ctrl *as_ctrl; | 951 | struct airoha_snand_ctrl *as_ctrl; |
| 952 | int op_len, addr_len, dummy_len; | ||
| 953 | u8 buf[20], *data; | ||
| 903 | int i, err; | 954 | int i, err; |
| 904 | 955 | ||
| 905 | as_ctrl = spi_controller_get_devdata(mem->spi->controller); | 956 | as_ctrl = spi_controller_get_devdata(mem->spi->controller); |
| 906 | 957 | ||
| 958 | op_len = op->cmd.nbytes; | ||
| 959 | addr_len = op->addr.nbytes; | ||
| 960 | dummy_len = op->dummy.nbytes; | ||
| 961 | |||
| 962 | if (op_len + dummy_len + addr_len > sizeof(buf)) | ||
| 963 | return -EIO; | ||
| 964 | |||
| 965 | data = buf; | ||
| 966 | for (i = 0; i < op_len; i++) | ||
| 967 | *data++ = op->cmd.opcode >> (8 * (op_len - i - 1)); | ||
| 968 | for (i = 0; i < addr_len; i++) | ||
| 969 | *data++ = op->addr.val >> (8 * (addr_len - i - 1)); | ||
| 970 | for (i = 0; i < dummy_len; i++) | ||
| 971 | *data++ = 0xff; | ||
| 972 | |||
| 907 | /* switch to manual mode */ | 973 | /* switch to manual mode */ |
| 908 | err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); | 974 | err = airoha_snand_set_mode(as_ctrl, SPI_MODE_MANUAL); |
| 909 | if (err < 0) | 975 | if (err < 0) |
| @@ -914,40 +980,40 @@ static int airoha_snand_exec_op(struct spi_mem *mem, · 4 unmodified lines | |||
| 914 | return err; | 980 | return err; |
| 915 | 981 | ||
| 916 | /* opcode */ | 982 | /* opcode */ |
| 917 | err = airoha_snand_write_data(as_ctrl, 0x8, &opcode, sizeof(opcode)); | 983 | data = buf; |
| 984 | err = airoha_snand_write_data(as_ctrl, data, op_len, | ||
| 985 | op->cmd.buswidth); | ||
| 918 | if (err) | 986 | if (err) |
| 919 | return err; | 987 | return err; |
| 920 | 988 | ||
| 921 | /* addr part */ | 989 | /* addr part */ |
| 922 | cmd = opcode == SPI_NAND_OP_GET_FEATURE ? 0x11 : 0x8; | 990 | data += op_len; |
| 923 | put_unaligned_be64(op->addr.val, data); | 991 | if (addr_len) { |
| 924 | 992 | err = airoha_snand_write_data(as_ctrl, data, addr_len, | |
| 925 | for (i = ARRAY_SIZE(data) - op->addr.nbytes; | 993 | op->addr.buswidth); |
| 926 | i < ARRAY_SIZE(data); i++) { | ||
| 927 | err = airoha_snand_write_data(as_ctrl, cmd, &data[i], | ||
| 928 | sizeof(data[0])); | ||
| 929 | if (err) | 994 | if (err) |
| 930 | return err; | 995 | return err; |
| 931 | } | 996 | } |
| 932 | 997 | ||
| 933 | /* dummy */ | 998 | /* dummy */ |
| 934 | data[0] = 0xff; | 999 | data += addr_len; |
| 935 | for (i = 0; i < op->dummy.nbytes; i++) { | 1000 | if (dummy_len) { |
| 936 | err = airoha_snand_write_data(as_ctrl, 0x8, &data[0], | 1001 | err = airoha_snand_write_data(as_ctrl, data, dummy_len, |
| 937 | sizeof(data[0])); | 1002 | op->dummy.buswidth); |
| 938 | if (err) | 1003 | if (err) |
| 939 | return err; | 1004 | return err; |
| 940 | } | 1005 | } |
| 941 | 1006 | ||
| 942 | /* data */ | 1007 | /* data */ |
| 943 | if (op->data.dir == SPI_MEM_DATA_IN) { | 1008 | if (op->data.nbytes) { |
| 944 | err = airoha_snand_read_data(as_ctrl, op->data.buf.in, | 1009 | if (op->data.dir == SPI_MEM_DATA_IN) |
| 945 | op->data.nbytes); | 1010 | err = airoha_snand_read_data(as_ctrl, op->data.buf.in, |
| 946 | if (err) | 1011 | op->data.nbytes, |
| 947 | return err; | 1012 | op->data.buswidth); |
| 948 | } else { | 1013 | else |
| 949 | err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out, | 1014 | err = airoha_snand_write_data(as_ctrl, op->data.buf.out, |
| 950 | op->data.nbytes); | 1015 | op->data.nbytes, |
| 1016 | op->data.buswidth); | ||
| 951 | if (err) | 1017 | if (err) |
| 952 | return err; | 1018 | return err; |
| 953 | } | 1019 | } |
| @@ -286,7 +286,7 @@ static int aml_sfc_set_bus_width(struct aml_sfc *sfc, u8 buswidth, u32 mask) · 285 unmodified lines | |||
| 286 | 286 | ||
| 287 | for (i = 0; i <= LANE_MAX; i++) { | 287 | for (i = 0; i <= LANE_MAX; i++) { |
| 288 | if (buswidth == 1 << i) { | 288 | if (buswidth == 1 << i) { |
| 289 | conf = i << __bf_shf(mask); | 289 | conf = i << __ffs(mask); |
| 290 | return regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, | 290 | return regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, |
| 291 | mask, conf); | 291 | mask, conf); |
| 292 | } | 292 | } |
| @@ -566,7 +566,7 @@ static int aml_sfc_raw_io_op(struct aml_sfc *sfc, const struct spi_mem_op *op) · 273 unmodified lines | |||
| 566 | if (!op->data.nbytes) | 566 | if (!op->data.nbytes) |
| 567 | goto end_xfer; | 567 | goto end_xfer; |
| 568 | 568 | ||
| 569 | conf = (op->data.nbytes >> RAW_SIZE_BW) << __bf_shf(RAW_EXT_SIZE); | 569 | conf = (op->data.nbytes >> RAW_SIZE_BW) << __ffs(RAW_EXT_SIZE); |
| 570 | ret = regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, RAW_EXT_SIZE, conf); | 570 | ret = regmap_update_bits(sfc->regmap_base, SFC_SPI_CFG, RAW_EXT_SIZE, conf); |
| 571 | if (ret) | 571 | if (ret) |
| 572 | goto err_out; | 572 | goto err_out; |
| @@ -1995,7 +1995,7 @@ static int cqspi_probe(struct platform_device *pdev) · 1994 unmodified lines | |||
| 1995 | if (cqspi->use_direct_mode) { | 1995 | if (cqspi->use_direct_mode) { |
| 1996 | ret = cqspi_request_mmap_dma(cqspi); | 1996 | ret = cqspi_request_mmap_dma(cqspi); |
| 1997 | if (ret == -EPROBE_DEFER) | 1997 | if (ret == -EPROBE_DEFER) |
| 1998 | goto probe_setup_failed; | 1998 | goto probe_dma_failed; |
| 1999 | } | 1999 | } |
| 2000 | 2000 | ||
| 2001 | if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { | 2001 | if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { |
| @@ -2019,9 +2019,10 @@ static int cqspi_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 2019 | 2019 | ||
| 2020 | return 0; | 2020 | return 0; |
| 2021 | probe_setup_failed: | 2021 | probe_setup_failed: |
| 2022 | cqspi_controller_enable(cqspi, 0); | ||
| 2023 | if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) | 2022 | if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) |
| 2024 | pm_runtime_disable(dev); | 2023 | pm_runtime_disable(dev); |
| 2024 | probe_dma_failed: | ||
| 2025 | cqspi_controller_enable(cqspi, 0); | ||
| 2025 | probe_reset_failed: | 2026 | probe_reset_failed: |
| 2026 | if (cqspi->is_jh7110) | 2027 | if (cqspi->is_jh7110) |
| 2027 | cqspi_jh7110_disable_clk(pdev, cqspi); | 2028 | cqspi_jh7110_disable_clk(pdev, cqspi); |
| @@ -358,7 +358,9 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) · 357 unmodified lines | |||
| 358 | if (IS_ERR(dwsmmio->rstc)) | 358 | if (IS_ERR(dwsmmio->rstc)) |
| 359 | return PTR_ERR(dwsmmio->rstc); | 359 | return PTR_ERR(dwsmmio->rstc); |
| 360 | 360 | ||
| 361 | reset_control_deassert(dwsmmio->rstc); | 361 | ret = reset_control_deassert(dwsmmio->rstc); |
| 362 | if (ret) | ||
| 363 | return dev_err_probe(&pdev->dev, ret, "Failed to deassert resets\n"); | ||
| 362 | 364 | ||
| 363 | dws->bus_num = pdev->id; | 365 | dws->bus_num = pdev->id; |
| 364 | 366 | ||
| @@ -75,10 +75,12 @@ static const struct pci_device_id intel_spi_pci_ids[] = { · 74 unmodified lines | |||
| 75 | { PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info }, | 75 | { PCI_VDEVICE(INTEL, 0x38a4), (unsigned long)&bxt_info }, |
| 76 | { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info }, | 76 | { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info }, |
| 77 | { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, | 77 | { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, |
| 78 | { PCI_VDEVICE(INTEL, 0x4d23), (unsigned long)&cnl_info }, | ||
| 78 | { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, | 79 | { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, |
| 79 | { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, | 80 | { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, |
| 80 | { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, | 81 | { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, |
| 81 | { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, | 82 | { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, |
| 83 | { PCI_VDEVICE(INTEL, 0x7723), (unsigned long)&cnl_info }, | ||
| 82 | { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, | 84 | { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, |
| 83 | { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, | 85 | { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, |
| 84 | { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, | 86 | { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, |
| @@ -132,6 +132,7 @@ · 131 unmodified lines | |||
| 132 | #define FLCOMP_C0DEN_16M 0x05 | 132 | #define FLCOMP_C0DEN_16M 0x05 |
| 133 | #define FLCOMP_C0DEN_32M 0x06 | 133 | #define FLCOMP_C0DEN_32M 0x06 |
| 134 | #define FLCOMP_C0DEN_64M 0x07 | 134 | #define FLCOMP_C0DEN_64M 0x07 |
| 135 | #define FLCOMP_C0DEN_128M 0x08 | ||
| 135 | 136 | ||
| 136 | #define INTEL_SPI_TIMEOUT 5000 /* ms */ | 137 | #define INTEL_SPI_TIMEOUT 5000 /* ms */ |
| 137 | #define INTEL_SPI_FIFO_SZ 64 | 138 | #define INTEL_SPI_FIFO_SZ 64 |
| @@ -1347,7 +1348,12 @@ static int intel_spi_read_desc(struct intel_spi *ispi) · 1209 unmodified lines | |||
| 1347 | case FLCOMP_C0DEN_64M: | 1348 | case FLCOMP_C0DEN_64M: |
| 1348 | ispi->chip0_size = SZ_64M; | 1349 | ispi->chip0_size = SZ_64M; |
| 1349 | break; | 1350 | break; |
| 1351 | case FLCOMP_C0DEN_128M: | ||
| 1352 | ispi->chip0_size = SZ_128M; | ||
| 1353 | break; | ||
| 1350 | default: | 1354 | default: |
| 1355 | dev_warn(ispi->dev, "unsupported C0DEN: %#lx\n", | ||
| 1356 | flcomp & FLCOMP_C0DEN_MASK); | ||
| 1351 | return -EINVAL; | 1357 | return -EINVAL; |
| 1352 | } | 1358 | } |
| 1353 | 1359 | ||
| @@ -404,6 +404,10 @@ struct nxp_fspi { · 403 unmodified lines | |||
| 404 | #define FSPI_NEED_INIT BIT(0) | 404 | #define FSPI_NEED_INIT BIT(0) |
| 405 | #define FSPI_DTR_MODE BIT(1) | 405 | #define FSPI_DTR_MODE BIT(1) |
| 406 | int flags; | 406 | int flags; |
| 407 | /* save the previous operation clock rate */ | ||
| 408 | unsigned long pre_op_rate; | ||
| 409 | /* the max clock rate fspi output to device */ | ||
| 410 | unsigned long max_rate; | ||
| 407 | }; | 411 | }; |
| 408 | 412 | ||
| 409 | static inline int needs_ip_only(struct nxp_fspi *f) | 413 | static inline int needs_ip_only(struct nxp_fspi *f) |
| @@ -685,10 +689,13 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f, · 275 unmodified lines | |||
| 685 | * change the mode back to mode 0. | 689 | * change the mode back to mode 0. |
| 686 | */ | 690 | */ |
| 687 | reg = fspi_readl(f, f->iobase + FSPI_MCR0); | 691 | reg = fspi_readl(f, f->iobase + FSPI_MCR0); |
| 688 | if (op_is_dtr) | 692 | if (op_is_dtr) { |
| 689 | reg |= FSPI_MCR0_RXCLKSRC(3); | 693 | reg |= FSPI_MCR0_RXCLKSRC(3); |
| 690 | else /*select mode 0 */ | 694 | f->max_rate = 166000000; |
| 695 | } else { /*select mode 0 */ | ||
| 691 | reg &= ~FSPI_MCR0_RXCLKSRC(3); | 696 | reg &= ~FSPI_MCR0_RXCLKSRC(3); |
| 697 | f->max_rate = 66000000; | ||
| 698 | } | ||
| 692 | fspi_writel(f, reg, f->iobase + FSPI_MCR0); | 699 | fspi_writel(f, reg, f->iobase + FSPI_MCR0); |
| 693 | } | 700 | } |
| 694 | 701 | ||
| @@ -719,6 +726,12 @@ static void nxp_fspi_dll_calibration(struct nxp_fspi *f) · 24 unmodified lines | |||
| 719 | 0, POLL_TOUT, true); | 726 | 0, POLL_TOUT, true); |
| 720 | if (ret) | 727 | if (ret) |
| 721 | dev_warn(f->dev, "DLL lock failed, please fix it!\n"); | 728 | dev_warn(f->dev, "DLL lock failed, please fix it!\n"); |
| 729 | |||
| 730 | /* | ||
| 731 | * For ERR050272, DLL lock status bit is not accurate, | ||
| 732 | * wait for 4us more as a workaround. | ||
| 733 | */ | ||
| 734 | udelay(4); | ||
| 722 | } | 735 | } |
| 723 | 736 | ||
| 724 | /* | 737 | /* |
| @@ -780,11 +793,17 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, · 55 unmodified lines | |||
| 780 | uint64_t size_kb; | 793 | uint64_t size_kb; |
| 781 | 794 | ||
| 782 | /* | 795 | /* |
| 783 | * Return, if previously selected target device is same as current | 796 | * Return when following condition all meet, |
| 784 | * requested target device. Also the DTR or STR mode do not change. | 797 | * 1, if previously selected target device is same as current |
| 798 | * requested target device. | ||
| 799 | * 2, the DTR or STR mode do not change. | ||
| 800 | * 3, previous operation max rate equals current one. | ||
| 801 | * | ||
| 802 | * For other case, need to re-config. | ||
| 785 | */ | 803 | */ |
| 786 | if ((f->selected == spi_get_chipselect(spi, 0)) && | 804 | if ((f->selected == spi_get_chipselect(spi, 0)) && |
| 787 | (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr)) | 805 | (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) && |
| 806 | (f->pre_op_rate == op->max_freq)) | ||
| 788 | return; | 807 | return; |
| 789 | 808 | ||
| 790 | /* Reset FLSHxxCR0 registers */ | 809 | /* Reset FLSHxxCR0 registers */ |
| @@ -802,6 +821,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, · 11 unmodified lines | |||
| 802 | dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); | 821 | dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); |
| 803 | 822 | ||
| 804 | nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); | 823 | nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); |
| 824 | rate = min(f->max_rate, op->max_freq); | ||
| 805 | 825 | ||
| 806 | if (op_is_dtr) { | 826 | if (op_is_dtr) { |
| 807 | f->flags |= FSPI_DTR_MODE; | 827 | f->flags |= FSPI_DTR_MODE; |
| @@ -832,6 +852,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, · 24 unmodified lines | |||
| 832 | else | 852 | else |
| 833 | nxp_fspi_dll_override(f); | 853 | nxp_fspi_dll_override(f); |
| 834 | 854 | ||
| 855 | f->pre_op_rate = op->max_freq; | ||
| 856 | |||
| 835 | f->selected = spi_get_chipselect(spi, 0); | 857 | f->selected = spi_get_chipselect(spi, 0); |
| 836 | } | 858 | } |
| 837 | 859 | ||
| @@ -704,7 +704,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev) · 703 unmodified lines | |||
| 704 | ret = -ENOMEM; | 704 | ret = -ENOMEM; |
| 705 | goto err_dma; | 705 | goto err_dma; |
| 706 | } | 706 | } |
| 707 | sfc->dma_buffer = virt_to_phys(sfc->buffer); | 707 | sfc->dma_buffer = dma_map_single(dev, sfc->buffer, |
| 708 | sfc->max_iosize, DMA_BIDIRECTIONAL); | ||
| 709 | if (dma_mapping_error(dev, sfc->dma_buffer)) { | ||
| 710 | ret = -ENOMEM; | ||
| 711 | goto err_dma_map; | ||
| 712 | } | ||
| 708 | } | 713 | } |
| 709 | 714 | ||
| 710 | ret = devm_spi_register_controller(dev, host); | 715 | ret = devm_spi_register_controller(dev, host); |
| @@ -715,6 +720,9 @@ static int rockchip_sfc_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 715 | 720 | ||
| 716 | return 0; | 721 | return 0; |
| 717 | err_register: | 722 | err_register: |
| 723 | dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize, | ||
| 724 | DMA_BIDIRECTIONAL); | ||
| 725 | err_dma_map: | ||
| 718 | free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); | 726 | free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); |
| 719 | err_dma: | 727 | err_dma: |
| 720 | pm_runtime_get_sync(dev); | 728 | pm_runtime_get_sync(dev); |
| @@ -736,6 +744,8 @@ static void rockchip_sfc_remove(struct platform_device *pdev) · 15 unmodified lines | |||
| 736 | struct spi_controller *host = sfc->host; | 744 | struct spi_controller *host = sfc->host; |
| 737 | 745 | ||
| 738 | spi_unregister_controller(host); | 746 | spi_unregister_controller(host); |
| 747 | dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize, | ||
| 748 | DMA_BIDIRECTIONAL); | ||
| 739 | free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); | 749 | free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); |
| 740 | 750 | ||
| 741 | clk_disable_unprepare(sfc->clk); | 751 | clk_disable_unprepare(sfc->clk); |
| @@ -182,10 +182,12 @@ static int agilent_82350b_accel_write(struct gpib_board *board, u8 *buffer, · 181 unmodified lines | |||
| 182 | return retval; | 182 | return retval; |
| 183 | #endif | 183 | #endif |
| 184 | 184 | ||
| 185 | retval = agilent_82350b_write(board, buffer, 1, 0, &num_bytes); | 185 | if (fifotransferlength > 0) { |
| 186 | *bytes_written += num_bytes; | 186 | retval = agilent_82350b_write(board, buffer, 1, 0, &num_bytes); |
| 187 | if (retval < 0) | 187 | *bytes_written += num_bytes; |
| 188 | return retval; | 188 | if (retval < 0) |
| 189 | return retval; | ||
| 190 | } | ||
| 189 | 191 | ||
| 190 | write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BOIE, IMR0); | 192 | write_byte(tms_priv, tms_priv->imr0_bits & ~HR_BOIE, IMR0); |
| 191 | for (i = 1; i < fifotransferlength;) { | 193 | for (i = 1; i < fifotransferlength;) { |
| @@ -217,7 +219,7 @@ static int agilent_82350b_accel_write(struct gpib_board *board, u8 *buffer, · 25 unmodified lines | |||
| 217 | break; | 219 | break; |
| 218 | } | 220 | } |
| 219 | write_byte(tms_priv, tms_priv->imr0_bits, IMR0); | 221 | write_byte(tms_priv, tms_priv->imr0_bits, IMR0); |
| 220 | if (retval) | 222 | if (retval < 0) |
| 221 | return retval; | 223 | return retval; |
| 222 | 224 | ||
| 223 | if (send_eoi) { | 225 | if (send_eoi) { |
| @@ -1517,6 +1517,11 @@ void fmh_gpib_detach(struct gpib_board *board) · 1516 unmodified lines | |||
| 1517 | resource_size(e_priv->gpib_iomem_res)); | 1517 | resource_size(e_priv->gpib_iomem_res)); |
| 1518 | } | 1518 | } |
| 1519 | fmh_gpib_generic_detach(board); | 1519 | fmh_gpib_generic_detach(board); |
| 1520 | |||
| 1521 | if (board->dev) { | ||
| 1522 | put_device(board->dev); | ||
| 1523 | board->dev = NULL; | ||
| 1524 | } | ||
| 1520 | } | 1525 | } |
| 1521 | 1526 | ||
| 1522 | static int fmh_gpib_pci_attach_impl(struct gpib_board *board, | 1527 | static int fmh_gpib_pci_attach_impl(struct gpib_board *board, |
| @@ -327,7 +327,10 @@ static void ni_usb_soft_update_status(struct gpib_board *board, unsigned int ni_ · 326 unmodified lines | |||
| 327 | board->status &= ~clear_mask; | 327 | board->status &= ~clear_mask; |
| 328 | board->status &= ~ni_usb_ibsta_mask; | 328 | board->status &= ~ni_usb_ibsta_mask; |
| 329 | board->status |= ni_usb_ibsta & ni_usb_ibsta_mask; | 329 | board->status |= ni_usb_ibsta & ni_usb_ibsta_mask; |
| 330 | // FIXME should generate events on DTAS and DCAS | 330 | if (ni_usb_ibsta & DCAS) |
| 331 | push_gpib_event(board, EVENT_DEV_CLR); | ||
| 332 | if (ni_usb_ibsta & DTAS) | ||
| 333 | push_gpib_event(board, EVENT_DEV_TRG); | ||
| 331 | 334 | ||
| 332 | spin_lock_irqsave(&board->spinlock, flags); | 335 | spin_lock_irqsave(&board->spinlock, flags); |
| 333 | /* remove set status bits from monitored set why ?***/ | 336 | /* remove set status bits from monitored set why ?***/ |
| @@ -694,8 +697,12 @@ static int ni_usb_read(struct gpib_board *board, u8 *buffer, size_t length, · 360 unmodified lines | |||
| 694 | */ | 697 | */ |
| 695 | break; | 698 | break; |
| 696 | case NIUSB_ATN_STATE_ERROR: | 699 | case NIUSB_ATN_STATE_ERROR: |
| 697 | retval = -EIO; | 700 | if (status.ibsta & DCAS) { |
| 698 | dev_err(&usb_dev->dev, "read when ATN set\n"); | 701 | retval = -EINTR; |
| 702 | } else { | ||
| 703 | retval = -EIO; | ||
| 704 | dev_dbg(&usb_dev->dev, "read when ATN set stat: 0x%06x\n", status.ibsta); | ||
| 705 | } | ||
| 699 | break; | 706 | break; |
| 700 | case NIUSB_ADDRESSING_ERROR: | 707 | case NIUSB_ADDRESSING_ERROR: |
| 701 | retval = -EIO; | 708 | retval = -EIO; |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | # Qualcomm Trusted Execution Environment Configuration | 2 | # Qualcomm Trusted Execution Environment Configuration |
| 3 | config QCOMTEE | 3 | config QCOMTEE |
| 4 | tristate "Qualcomm TEE Support" | 4 | tristate "Qualcomm TEE Support" |
| 5 | depends on ARCH_QCOM || COMPILE_TEST | ||
| 5 | depends on !CPU_BIG_ENDIAN | 6 | depends on !CPU_BIG_ENDIAN |
| 6 | select QCOM_SCM | 7 | select QCOM_SCM |
| 7 | select QCOM_TZMEM_MODE_SHMBRIDGE | 8 | select QCOM_TZMEM_MODE_SHMBRIDGE |
| @@ -308,7 +308,7 @@ out_failed: · 307 unmodified lines | |||
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | /* Release any IO and OO objects not processed. */ | 310 | /* Release any IO and OO objects not processed. */ |
| 311 | for (; u[i].type && i < num_params; i++) { | 311 | for (; i < num_params && u[i].type; i++) { |
| 312 | if (u[i].type == QCOMTEE_ARG_TYPE_OO || | 312 | if (u[i].type == QCOMTEE_ARG_TYPE_OO || |
| 313 | u[i].type == QCOMTEE_ARG_TYPE_IO) | 313 | u[i].type == QCOMTEE_ARG_TYPE_IO) |
| 314 | qcomtee_object_put(u[i].o); | 314 | qcomtee_object_put(u[i].o); |
| @@ -424,7 +424,7 @@ static int qcomtee_prepare_msg(struct qcomtee_object_invoke_ctx *oic, · 423 unmodified lines | |||
| 424 | if (!(u[i].flags & QCOMTEE_ARG_FLAGS_UADDR)) | 424 | if (!(u[i].flags & QCOMTEE_ARG_FLAGS_UADDR)) |
| 425 | memcpy(msgptr, u[i].b.addr, u[i].b.size); | 425 | memcpy(msgptr, u[i].b.addr, u[i].b.size); |
| 426 | else if (copy_from_user(msgptr, u[i].b.uaddr, u[i].b.size)) | 426 | else if (copy_from_user(msgptr, u[i].b.uaddr, u[i].b.size)) |
| 427 | return -EINVAL; | 427 | return -EFAULT; |
| 428 | 428 | ||
| 429 | offset += qcomtee_msg_offset_align(u[i].b.size); | 429 | offset += qcomtee_msg_offset_align(u[i].b.size); |
| 430 | ib++; | 430 | ib++; |
| @@ -635,7 +635,9 @@ static int dw8250_probe(struct platform_device *pdev) · 634 unmodified lines | |||
| 635 | if (IS_ERR(data->rst)) | 635 | if (IS_ERR(data->rst)) |
| 636 | return PTR_ERR(data->rst); | 636 | return PTR_ERR(data->rst); |
| 637 | 637 | ||
| 638 | reset_control_deassert(data->rst); | 638 | err = reset_control_deassert(data->rst); |
| 639 | if (err) | ||
| 640 | return dev_err_probe(dev, err, "failed to deassert resets\n"); | ||
| 639 | 641 | ||
| 640 | err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); | 642 | err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); |
| 641 | if (err) | 643 | if (err) |
| @@ -40,6 +40,8 @@ · 39 unmodified lines | |||
| 40 | #define PCI_DEVICE_ID_ACCESSIO_COM_4SM 0x10db | 40 | #define PCI_DEVICE_ID_ACCESSIO_COM_4SM 0x10db |
| 41 | #define PCI_DEVICE_ID_ACCESSIO_COM_8SM 0x10ea | 41 | #define PCI_DEVICE_ID_ACCESSIO_COM_8SM 0x10ea |
| 42 | 42 | ||
| 43 | #define PCI_DEVICE_ID_ADVANTECH_XR17V352 0x0018 | ||
| 44 | |||
| 43 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 | 45 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 |
| 44 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 | 46 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 |
| 45 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a | 47 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a |
| @@ -1622,6 +1624,12 @@ static const struct exar8250_board pbn_fastcom35x_8 = { · 1576 unmodified lines | |||
| 1622 | .exit = pci_xr17v35x_exit, | 1624 | .exit = pci_xr17v35x_exit, |
| 1623 | }; | 1625 | }; |
| 1624 | 1626 | ||
| 1627 | static const struct exar8250_board pbn_adv_XR17V352 = { | ||
| 1628 | .num_ports = 2, | ||
| 1629 | .setup = pci_xr17v35x_setup, | ||
| 1630 | .exit = pci_xr17v35x_exit, | ||
| 1631 | }; | ||
| 1632 | |||
| 1625 | static const struct exar8250_board pbn_exar_XR17V4358 = { | 1633 | static const struct exar8250_board pbn_exar_XR17V4358 = { |
| 1626 | .num_ports = 12, | 1634 | .num_ports = 12, |
| 1627 | .setup = pci_xr17v35x_setup, | 1635 | .setup = pci_xr17v35x_setup, |
| @@ -1696,6 +1704,9 @@ static const struct pci_device_id exar_pci_tbl[] = { · 68 unmodified lines | |||
| 1696 | USR_DEVICE(XR17C152, 2980, pbn_exar_XR17C15x), | 1704 | USR_DEVICE(XR17C152, 2980, pbn_exar_XR17C15x), |
| 1697 | USR_DEVICE(XR17C152, 2981, pbn_exar_XR17C15x), | 1705 | USR_DEVICE(XR17C152, 2981, pbn_exar_XR17C15x), |
| 1698 | 1706 | ||
| 1707 | /* ADVANTECH devices */ | ||
| 1708 | EXAR_DEVICE(ADVANTECH, XR17V352, pbn_adv_XR17V352), | ||
| 1709 | |||
| 1699 | /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */ | 1710 | /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */ |
| 1700 | EXAR_DEVICE(EXAR, XR17C152, pbn_exar_XR17C15x), | 1711 | EXAR_DEVICE(EXAR, XR17C152, pbn_exar_XR17C15x), |
| 1701 | EXAR_DEVICE(EXAR, XR17C154, pbn_exar_XR17C15x), | 1712 | EXAR_DEVICE(EXAR, XR17C154, pbn_exar_XR17C15x), |
| @@ -435,6 +435,7 @@ static int __maybe_unused mtk8250_runtime_suspend(struct device *dev) · 434 unmodified lines | |||
| 435 | while | 435 | while |
| 436 | (serial_in(up, MTK_UART_DEBUG0)); | 436 | (serial_in(up, MTK_UART_DEBUG0)); |
| 437 | 437 | ||
| 438 | clk_disable_unprepare(data->uart_clk); | ||
| 438 | clk_disable_unprepare(data->bus_clk); | 439 | clk_disable_unprepare(data->bus_clk); |
| 439 | 440 | ||
| 440 | return 0; | 441 | return 0; |
| @@ -445,6 +446,7 @@ static int __maybe_unused mtk8250_runtime_resume(struct device *dev) · 4 unmodified lines | |||
| 445 | struct mtk8250_data *data = dev_get_drvdata(dev); | 446 | struct mtk8250_data *data = dev_get_drvdata(dev); |
| 446 | 447 | ||
| 447 | clk_prepare_enable(data->bus_clk); | 448 | clk_prepare_enable(data->bus_clk); |
| 449 | clk_prepare_enable(data->uart_clk); | ||
| 448 | 450 | ||
| 449 | return 0; | 451 | return 0; |
| 450 | } | 452 | } |
| @@ -475,13 +477,13 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, · 24 unmodified lines | |||
| 475 | int dmacnt; | 477 | int dmacnt; |
| 476 | #endif | 478 | #endif |
| 477 | 479 | ||
| 478 | data->uart_clk = devm_clk_get(&pdev->dev, "baud"); | 480 | data->uart_clk = devm_clk_get_enabled(&pdev->dev, "baud"); |
| 479 | if (IS_ERR(data->uart_clk)) { | 481 | if (IS_ERR(data->uart_clk)) { |
| 480 | /* | 482 | /* |
| 481 | * For compatibility with older device trees try unnamed | 483 | * For compatibility with older device trees try unnamed |
| 482 | * clk when no baud clk can be found. | 484 | * clk when no baud clk can be found. |
| 483 | */ | 485 | */ |
| 484 | data->uart_clk = devm_clk_get(&pdev->dev, NULL); | 486 | data->uart_clk = devm_clk_get_enabled(&pdev->dev, NULL); |
| 485 | if (IS_ERR(data->uart_clk)) { | 487 | if (IS_ERR(data->uart_clk)) { |
| 486 | dev_warn(&pdev->dev, "Can't get uart clock\n"); | 488 | dev_warn(&pdev->dev, "Can't get uart clock\n"); |
| 487 | return PTR_ERR(data->uart_clk); | 489 | return PTR_ERR(data->uart_clk); |
| @@ -588,13 +588,6 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud) · 587 unmodified lines | |||
| 588 | div /= prescaler; | 588 | div /= prescaler; |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | /* Enable enhanced features */ | ||
| 592 | sc16is7xx_efr_lock(port); | ||
| 593 | sc16is7xx_port_update(port, SC16IS7XX_EFR_REG, | ||
| 594 | SC16IS7XX_EFR_ENABLE_BIT, | ||
| 595 | SC16IS7XX_EFR_ENABLE_BIT); | ||
| 596 | sc16is7xx_efr_unlock(port); | ||
| 597 | |||
| 598 | /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */ | 591 | /* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */ |
| 599 | sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, | 592 | sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, |
| 600 | SC16IS7XX_MCR_CLKSEL_BIT, | 593 | SC16IS7XX_MCR_CLKSEL_BIT, |
| @@ -1014,16 +1014,18 @@ static int sci_handle_fifo_overrun(struct uart_port *port) · 1013 unmodified lines | |||
| 1014 | struct sci_port *s = to_sci_port(port); | 1014 | struct sci_port *s = to_sci_port(port); |
| 1015 | const struct plat_sci_reg *reg; | 1015 | const struct plat_sci_reg *reg; |
| 1016 | int copied = 0; | 1016 | int copied = 0; |
| 1017 | u16 status; | 1017 | u32 status; |
| 1018 | 1018 | ||
| 1019 | reg = sci_getreg(port, s->params->overrun_reg); | 1019 | if (s->type != SCI_PORT_RSCI) { |
| 1020 | if (!reg->size) | 1020 | reg = sci_getreg(port, s->params->overrun_reg); |
| 1021 | return 0; | 1021 | if (!reg->size) |
| 1022 | return 0; | ||
| 1023 | } | ||
| 1022 | 1024 | ||
| 1023 | status = sci_serial_in(port, s->params->overrun_reg); | 1025 | status = s->ops->read_reg(port, s->params->overrun_reg); |
| 1024 | if (status & s->params->overrun_mask) { | 1026 | if (status & s->params->overrun_mask) { |
| 1025 | status &= ~s->params->overrun_mask; | 1027 | status &= ~s->params->overrun_mask; |
| 1026 | sci_serial_out(port, s->params->overrun_reg, status); | 1028 | s->ops->write_reg(port, s->params->overrun_reg, status); |
| 1027 | 1029 | ||
| 1028 | port->icount.overrun++; | 1030 | port->icount.overrun++; |
| 1029 | 1031 | ||
| @@ -467,6 +467,8 @@ static const struct usb_device_id usb_quirk_list[] = { · 466 unmodified lines | |||
| 467 | /* Huawei 4G LTE module */ | 467 | /* Huawei 4G LTE module */ |
| 468 | { USB_DEVICE(0x12d1, 0x15bb), .driver_info = | 468 | { USB_DEVICE(0x12d1, 0x15bb), .driver_info = |
| 469 | USB_QUIRK_DISCONNECT_SUSPEND }, | 469 | USB_QUIRK_DISCONNECT_SUSPEND }, |
| 470 | { USB_DEVICE(0x12d1, 0x15c1), .driver_info = | ||
| 471 | USB_QUIRK_DISCONNECT_SUSPEND }, | ||
| 470 | { USB_DEVICE(0x12d1, 0x15c3), .driver_info = | 472 | { USB_DEVICE(0x12d1, 0x15c3), .driver_info = |
| 471 | USB_QUIRK_DISCONNECT_SUSPEND }, | 473 | USB_QUIRK_DISCONNECT_SUSPEND }, |
| 472 | 474 | ||
| @@ -85,11 +85,8 @@ static int dwc3_generic_probe(struct platform_device *pdev) · 84 unmodified lines | |||
| 85 | static void dwc3_generic_remove(struct platform_device *pdev) | 85 | static void dwc3_generic_remove(struct platform_device *pdev) |
| 86 | { | 86 | { |
| 87 | struct dwc3 *dwc = platform_get_drvdata(pdev); | 87 | struct dwc3 *dwc = platform_get_drvdata(pdev); |
| 88 | struct dwc3_generic *dwc3g = to_dwc3_generic(dwc); | ||
| 89 | 88 | ||
| 90 | dwc3_core_remove(dwc); | 89 | dwc3_core_remove(dwc); |
| 91 | |||
| 92 | clk_bulk_disable_unprepare(dwc3g->num_clocks, dwc3g->clks); | ||
| 93 | } | 90 | } |
| 94 | 91 | ||
| 95 | static int dwc3_generic_suspend(struct device *dev) | 92 | static int dwc3_generic_suspend(struct device *dev) |
| @@ -667,8 +667,6 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, · 666 unmodified lines | |||
| 667 | return ERR_PTR(-EINVAL); | 667 | return ERR_PTR(-EINVAL); |
| 668 | if (!usb_raw_io_flags_valid(io->flags)) | 668 | if (!usb_raw_io_flags_valid(io->flags)) |
| 669 | return ERR_PTR(-EINVAL); | 669 | return ERR_PTR(-EINVAL); |
| 670 | if (io->length > PAGE_SIZE) | ||
| 671 | return ERR_PTR(-EINVAL); | ||
| 672 | if (get_from_user) | 670 | if (get_from_user) |
| 673 | data = memdup_user(ptr + sizeof(*io), io->length); | 671 | data = memdup_user(ptr + sizeof(*io), io->length); |
| 674 | else { | 672 | else { |
| @@ -892,7 +892,8 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc) · 891 unmodified lines | |||
| 892 | dev_info(dbc->dev, "DbC configured\n"); | 892 | dev_info(dbc->dev, "DbC configured\n"); |
| 893 | portsc = readl(&dbc->regs->portsc); | 893 | portsc = readl(&dbc->regs->portsc); |
| 894 | writel(portsc, &dbc->regs->portsc); | 894 | writel(portsc, &dbc->regs->portsc); |
| 895 | return EVT_GSER; | 895 | ret = EVT_GSER; |
| 896 | break; | ||
| 896 | } | 897 | } |
| 897 | 898 | ||
| 898 | return EVT_DONE; | 899 | return EVT_DONE; |
| @@ -954,7 +955,8 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc) · 55 unmodified lines | |||
| 954 | break; | 955 | break; |
| 955 | case TRB_TYPE(TRB_TRANSFER): | 956 | case TRB_TYPE(TRB_TRANSFER): |
| 956 | dbc_handle_xfer_event(dbc, evt); | 957 | dbc_handle_xfer_event(dbc, evt); |
| 957 | ret = EVT_XFER_DONE; | 958 | if (ret != EVT_GSER) |
| 959 | ret = EVT_XFER_DONE; | ||
| 958 | break; | 960 | break; |
| 959 | default: | 961 | default: |
| 960 | break; | 962 | break; |
| @@ -1390,8 +1392,15 @@ int xhci_dbc_suspend(struct xhci_hcd *xhci) · 429 unmodified lines | |||
| 1390 | if (!dbc) | 1392 | if (!dbc) |
| 1391 | return 0; | 1393 | return 0; |
| 1392 | 1394 | ||
| 1393 | if (dbc->state == DS_CONFIGURED) | 1395 | switch (dbc->state) { |
| 1396 | case DS_ENABLED: | ||
| 1397 | case DS_CONNECTED: | ||
| 1398 | case DS_CONFIGURED: | ||
| 1394 | dbc->resume_required = 1; | 1399 | dbc->resume_required = 1; |
| 1400 | break; | ||
| 1401 | default: | ||
| 1402 | break; | ||
| 1403 | } | ||
| 1395 | 1404 | ||
| 1396 | xhci_dbc_stop(dbc); | 1405 | xhci_dbc_stop(dbc); |
| 1397 | 1406 | ||
| @@ -582,6 +582,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) · 581 unmodified lines | |||
| 582 | if (!usb_hcd_is_primary_hcd(hcd)) | 582 | if (!usb_hcd_is_primary_hcd(hcd)) |
| 583 | return 0; | 583 | return 0; |
| 584 | 584 | ||
| 585 | xhci->allow_single_roothub = 1; | ||
| 586 | |||
| 585 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) | 587 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) |
| 586 | xhci_pme_acpi_rtd3_enable(pdev); | 588 | xhci_pme_acpi_rtd3_enable(pdev); |
| 587 | 589 | ||
| @@ -637,7 +639,6 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id) · 49 unmodified lines | |||
| 637 | xhci = hcd_to_xhci(hcd); | 639 | xhci = hcd_to_xhci(hcd); |
| 638 | xhci->reset = reset; | 640 | xhci->reset = reset; |
| 639 | 641 | ||
| 640 | xhci->allow_single_roothub = 1; | ||
| 641 | if (!xhci_has_one_roothub(xhci)) { | 642 | if (!xhci_has_one_roothub(xhci)) { |
| 642 | xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev, | 643 | xhci->shared_hcd = usb_create_shared_hcd(&xhci_pci_hc_driver, &dev->dev, |
| 643 | pci_name(dev), hcd); | 644 | pci_name(dev), hcd); |
| @@ -182,6 +182,7 @@ config USB_LJCA · 181 unmodified lines | |||
| 182 | config USB_USBIO | 182 | config USB_USBIO |
| 183 | tristate "Intel USBIO Bridge support" | 183 | tristate "Intel USBIO Bridge support" |
| 184 | depends on USB && ACPI | 184 | depends on USB && ACPI |
| 185 | depends on X86 || COMPILE_TEST | ||
| 185 | select AUXILIARY_BUS | 186 | select AUXILIARY_BUS |
| 186 | help | 187 | help |
| 187 | This adds support for Intel USBIO drivers. | 188 | This adds support for Intel USBIO drivers. |
| @@ -273,6 +273,7 @@ static void option_instat_callback(struct urb *urb); · 272 unmodified lines | |||
| 273 | #define QUECTEL_PRODUCT_EM05CN 0x0312 | 273 | #define QUECTEL_PRODUCT_EM05CN 0x0312 |
| 274 | #define QUECTEL_PRODUCT_EM05G_GR 0x0313 | 274 | #define QUECTEL_PRODUCT_EM05G_GR 0x0313 |
| 275 | #define QUECTEL_PRODUCT_EM05G_RS 0x0314 | 275 | #define QUECTEL_PRODUCT_EM05G_RS 0x0314 |
| 276 | #define QUECTEL_PRODUCT_RG255C 0x0316 | ||
| 276 | #define QUECTEL_PRODUCT_EM12 0x0512 | 277 | #define QUECTEL_PRODUCT_EM12 0x0512 |
| 277 | #define QUECTEL_PRODUCT_RM500Q 0x0800 | 278 | #define QUECTEL_PRODUCT_RM500Q 0x0800 |
| 278 | #define QUECTEL_PRODUCT_RM520N 0x0801 | 279 | #define QUECTEL_PRODUCT_RM520N 0x0801 |
| @@ -617,6 +618,7 @@ static void option_instat_callback(struct urb *urb); · 338 unmodified lines | |||
| 617 | #define UNISOC_VENDOR_ID 0x1782 | 618 | #define UNISOC_VENDOR_ID 0x1782 |
| 618 | /* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ | 619 | /* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */ |
| 619 | #define TOZED_PRODUCT_LT70C 0x4055 | 620 | #define TOZED_PRODUCT_LT70C 0x4055 |
| 621 | #define UNISOC_PRODUCT_UIS7720 0x4064 | ||
| 620 | /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ | 622 | /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */ |
| 621 | #define LUAT_PRODUCT_AIR720U 0x4e00 | 623 | #define LUAT_PRODUCT_AIR720U 0x4e00 |
| 622 | 624 | ||
| @@ -1270,6 +1272,9 @@ static const struct usb_device_id option_ids[] = { · 647 unmodified lines | |||
| 1270 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, | 1272 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, |
| 1271 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) }, | 1273 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) }, |
| 1272 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) }, | 1274 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) }, |
| 1275 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x30) }, | ||
| 1276 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0, 0) }, | ||
| 1277 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x40) }, | ||
| 1273 | 1278 | ||
| 1274 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 1279 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
| 1275 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, | 1280 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, |
| @@ -1398,10 +1403,14 @@ static const struct usb_device_id option_ids[] = { · 122 unmodified lines | |||
| 1398 | .driver_info = RSVD(0) | NCTRL(3) }, | 1403 | .driver_info = RSVD(0) | NCTRL(3) }, |
| 1399 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ | 1404 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ |
| 1400 | .driver_info = NCTRL(4) }, | 1405 | .driver_info = NCTRL(4) }, |
| 1406 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a3, 0xff), /* Telit FN920C04 (ECM) */ | ||
| 1407 | .driver_info = NCTRL(4) }, | ||
| 1401 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ | 1408 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1402 | .driver_info = RSVD(0) | NCTRL(3) }, | 1409 | .driver_info = RSVD(0) | NCTRL(3) }, |
| 1403 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ | 1410 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ |
| 1404 | .driver_info = NCTRL(4) }, | 1411 | .driver_info = NCTRL(4) }, |
| 1412 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a8, 0xff), /* Telit FN920C04 (ECM) */ | ||
| 1413 | .driver_info = NCTRL(4) }, | ||
| 1405 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ | 1414 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */ |
| 1406 | .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, | 1415 | .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, |
| 1407 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ | 1416 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ |
| @@ -2466,6 +2475,7 @@ static const struct usb_device_id option_ids[] = { · 1058 unmodified lines | |||
| 2466 | { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) }, | 2475 | { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) }, |
| 2467 | { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) }, | 2476 | { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) }, |
| 2468 | { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, | 2477 | { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, |
| 2478 | { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, UNISOC_PRODUCT_UIS7720, 0xff, 0, 0) }, | ||
| 2469 | { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, | 2479 | { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, |
| 2470 | { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ | 2480 | { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */ |
| 2471 | .driver_info = NCTRL(1) }, | 2481 | .driver_info = NCTRL(1) }, |
| @@ -7876,9 +7876,9 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) · 7875 unmodified lines | |||
| 7876 | 7876 | ||
| 7877 | port->partner_desc.identity = &port->partner_ident; | 7877 | port->partner_desc.identity = &port->partner_ident; |
| 7878 | 7878 | ||
| 7879 | port->role_sw = usb_role_switch_get(port->dev); | 7879 | port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode); |
| 7880 | if (!port->role_sw) | 7880 | if (!port->role_sw) |
| 7881 | port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode); | 7881 | port->role_sw = usb_role_switch_get(port->dev); |
| 7882 | if (IS_ERR(port->role_sw)) { | 7882 | if (IS_ERR(port->role_sw)) { |
| 7883 | err = PTR_ERR(port->role_sw); | 7883 | err = PTR_ERR(port->role_sw); |
| 7884 | goto out_destroy_wq; | 7884 | goto out_destroy_wq; |
| @@ -66,7 +66,6 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) · 65 unmodified lines | |||
| 66 | struct p9_fid *fid; | 66 | struct p9_fid *fid; |
| 67 | struct inode *inode; | 67 | struct inode *inode; |
| 68 | struct v9fs_inode *v9inode; | 68 | struct v9fs_inode *v9inode; |
| 69 | unsigned int cached; | ||
| 70 | 69 | ||
| 71 | if (flags & LOOKUP_RCU) | 70 | if (flags & LOOKUP_RCU) |
| 72 | return -ECHILD; | 71 | return -ECHILD; |
| @@ -76,11 +75,7 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) · 3 unmodified lines | |||
| 76 | goto out_valid; | 75 | goto out_valid; |
| 77 | 76 | ||
| 78 | v9inode = V9FS_I(inode); | 77 | v9inode = V9FS_I(inode); |
| 79 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 78 | if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) { |
| 80 | |||
| 81 | cached = v9ses->cache & (CACHE_META | CACHE_LOOSE); | ||
| 82 | |||
| 83 | if (!cached || v9inode->cache_validity & V9FS_INO_INVALID_ATTR) { | ||
| 84 | int retval; | 79 | int retval; |
| 85 | struct v9fs_session_info *v9ses; | 80 | struct v9fs_session_info *v9ses; |
| 86 | 81 | ||
| @@ -114,6 +109,7 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) · 27 unmodified lines | |||
| 114 | p9_debug(P9_DEBUG_VFS, | 109 | p9_debug(P9_DEBUG_VFS, |
| 115 | "refresh inode: dentry = %pd (%p), got error %pe\n", | 110 | "refresh inode: dentry = %pd (%p), got error %pe\n", |
| 116 | dentry, dentry, ERR_PTR(retval)); | 111 | dentry, dentry, ERR_PTR(retval)); |
| 112 | if (retval < 0) | ||
| 117 | return retval; | 113 | return retval; |
| 118 | } | 114 | } |
| 119 | } | 115 | } |
| @@ -150,8 +146,6 @@ const struct dentry_operations v9fs_cached_dentry_operations = { · 30 unmodified lines | |||
| 150 | }; | 146 | }; |
| 151 | 147 | ||
| 152 | const struct dentry_operations v9fs_dentry_operations = { | 148 | const struct dentry_operations v9fs_dentry_operations = { |
| 153 | .d_revalidate = v9fs_lookup_revalidate, | ||
| 154 | .d_weak_revalidate = __v9fs_lookup_revalidate, | ||
| 155 | .d_release = v9fs_dentry_release, | 149 | .d_release = v9fs_dentry_release, |
| 156 | .d_unalias_trylock = v9fs_dentry_unalias_trylock, | 150 | .d_unalias_trylock = v9fs_dentry_unalias_trylock, |
| 157 | .d_unalias_unlock = v9fs_dentry_unalias_unlock, | 151 | .d_unalias_unlock = v9fs_dentry_unalias_unlock, |
| @@ -1339,14 +1339,8 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) · 1338 unmodified lines | |||
| 1339 | * Don't update inode if the file type is different | 1339 | * Don't update inode if the file type is different |
| 1340 | */ | 1340 | */ |
| 1341 | umode = p9mode2unixmode(v9ses, st, &rdev); | 1341 | umode = p9mode2unixmode(v9ses, st, &rdev); |
| 1342 | if (inode_wrong_type(inode, umode)) { | 1342 | if (inode_wrong_type(inode, umode)) |
| 1343 | /* | ||
| 1344 | * Do this as a way of letting the caller know the inode should not | ||
| 1345 | * be reused | ||
| 1346 | */ | ||
| 1347 | v9fs_invalidate_inode_attr(inode); | ||
| 1348 | goto out; | 1343 | goto out; |
| 1349 | } | ||
| 1350 | 1344 | ||
| 1351 | /* | 1345 | /* |
| 1352 | * We don't want to refresh inode->i_size, | 1346 | * We don't want to refresh inode->i_size, |
| @@ -897,14 +897,8 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) · 896 unmodified lines | |||
| 897 | /* | 897 | /* |
| 898 | * Don't update inode if the file type is different | 898 | * Don't update inode if the file type is different |
| 899 | */ | 899 | */ |
| 900 | if (inode_wrong_type(inode, st->st_mode)) { | 900 | if (inode_wrong_type(inode, st->st_mode)) |
| 901 | /* | ||
| 902 | * Do this as a way of letting the caller know the inode should not | ||
| 903 | * be reused | ||
| 904 | */ | ||
| 905 | v9fs_invalidate_inode_attr(inode); | ||
| 906 | goto out; | 901 | goto out; |
| 907 | } | ||
| 908 | 902 | ||
| 909 | /* | 903 | /* |
| 910 | * We don't want to refresh inode->i_size, | 904 | * We don't want to refresh inode->i_size, |
| @@ -2110,9 +2110,9 @@ void btrfs_kill_all_delayed_nodes(struct btrfs_root *root) · 2109 unmodified lines | |||
| 2110 | 2110 | ||
| 2111 | for (int i = 0; i < count; i++) { | 2111 | for (int i = 0; i < count; i++) { |
| 2112 | __btrfs_kill_delayed_node(delayed_nodes[i]); | 2112 | __btrfs_kill_delayed_node(delayed_nodes[i]); |
| 2113 | btrfs_delayed_node_ref_tracker_dir_print(delayed_nodes[i]); | ||
| 2113 | btrfs_release_delayed_node(delayed_nodes[i], | 2114 | btrfs_release_delayed_node(delayed_nodes[i], |
| 2114 | &delayed_node_trackers[i]); | 2115 | &delayed_node_trackers[i]); |
| 2115 | btrfs_delayed_node_ref_tracker_dir_print(delayed_nodes[i]); | ||
| 2116 | } | 2116 | } |
| 2117 | } | 2117 | } |
| 2118 | } | 2118 | } |
| @@ -219,6 +219,13 @@ static inline void btrfs_delayed_node_ref_tracker_dir_print(struct btrfs_delayed · 218 unmodified lines | |||
| 219 | if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER)) | 219 | if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER)) |
| 220 | return; | 220 | return; |
| 221 | 221 | ||
| 222 | /* | ||
| 223 | * Only print if there are leaked references. The caller is | ||
| 224 | * holding one reference, so if refs == 1 there is no leak. | ||
| 225 | */ | ||
| 226 | if (refcount_read(&node->refs) == 1) | ||
| 227 | return; | ||
| 228 | |||
| 222 | ref_tracker_dir_print(&node->ref_dir.dir, | 229 | ref_tracker_dir_print(&node->ref_dir.dir, |
| 223 | BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT); | 230 | BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT); |
| 224 | } | 231 | } |
| @@ -982,7 +982,7 @@ int btrfs_build_ref_tree(struct btrfs_fs_info *fs_info) · 981 unmodified lines | |||
| 982 | 982 | ||
| 983 | extent_root = btrfs_extent_root(fs_info, 0); | 983 | extent_root = btrfs_extent_root(fs_info, 0); |
| 984 | /* If the extent tree is damaged we cannot ignore it (IGNOREBADROOTS). */ | 984 | /* If the extent tree is damaged we cannot ignore it (IGNOREBADROOTS). */ |
| 985 | if (IS_ERR(extent_root)) { | 985 | if (!extent_root) { |
| 986 | btrfs_warn(fs_info, "ref-verify: extent tree not available, disabling"); | 986 | btrfs_warn(fs_info, "ref-verify: extent tree not available, disabling"); |
| 987 | btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); | 987 | btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); |
| 988 | return 0; | 988 | return 0; |
| @@ -4102,6 +4102,48 @@ out: · 4101 unmodified lines | |||
| 4102 | return ret; | 4102 | return ret; |
| 4103 | } | 4103 | } |
| 4104 | 4104 | ||
| 4105 | static int rbtree_check_dir_ref_comp(const void *k, const struct rb_node *node) | ||
| 4106 | { | ||
| 4107 | const struct recorded_ref *data = k; | ||
| 4108 | const struct recorded_ref *ref = rb_entry(node, struct recorded_ref, node); | ||
| 4109 | |||
| 4110 | if (data->dir > ref->dir) | ||
| 4111 | return 1; | ||
| 4112 | if (data->dir < ref->dir) | ||
| 4113 | return -1; | ||
| 4114 | if (data->dir_gen > ref->dir_gen) | ||
| 4115 | return 1; | ||
| 4116 | if (data->dir_gen < ref->dir_gen) | ||
| 4117 | return -1; | ||
| 4118 | return 0; | ||
| 4119 | } | ||
| 4120 | |||
| 4121 | static bool rbtree_check_dir_ref_less(struct rb_node *node, const struct rb_node *parent) | ||
| 4122 | { | ||
| 4123 | const struct recorded_ref *entry = rb_entry(node, struct recorded_ref, node); | ||
| 4124 | |||
| 4125 | return rbtree_check_dir_ref_comp(entry, parent) < 0; | ||
| 4126 | } | ||
| 4127 | |||
| 4128 | static int record_check_dir_ref_in_tree(struct rb_root *root, | ||
| 4129 | struct recorded_ref *ref, struct list_head *list) | ||
| 4130 | { | ||
| 4131 | struct recorded_ref *tmp_ref; | ||
| 4132 | int ret; | ||
| 4133 | |||
| 4134 | if (rb_find(ref, root, rbtree_check_dir_ref_comp)) | ||
| 4135 | return 0; | ||
| 4136 | |||
| 4137 | ret = dup_ref(ref, list); | ||
| 4138 | if (ret < 0) | ||
| 4139 | return ret; | ||
| 4140 | |||
| 4141 | tmp_ref = list_last_entry(list, struct recorded_ref, list); | ||
| 4142 | rb_add(&tmp_ref->node, root, rbtree_check_dir_ref_less); | ||
| 4143 | tmp_ref->root = root; | ||
| 4144 | return 0; | ||
| 4145 | } | ||
| 4146 | |||
| 4105 | static int rename_current_inode(struct send_ctx *sctx, | 4147 | static int rename_current_inode(struct send_ctx *sctx, |
| 4106 | struct fs_path *current_path, | 4148 | struct fs_path *current_path, |
| 4107 | struct fs_path *new_path) | 4149 | struct fs_path *new_path) |
| @@ -4129,11 +4171,11 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 21 unmodified lines | |||
| 4129 | struct recorded_ref *cur; | 4171 | struct recorded_ref *cur; |
| 4130 | struct recorded_ref *cur2; | 4172 | struct recorded_ref *cur2; |
| 4131 | LIST_HEAD(check_dirs); | 4173 | LIST_HEAD(check_dirs); |
| 4174 | struct rb_root rbtree_check_dirs = RB_ROOT; | ||
| 4132 | struct fs_path *valid_path = NULL; | 4175 | struct fs_path *valid_path = NULL; |
| 4133 | u64 ow_inode = 0; | 4176 | u64 ow_inode = 0; |
| 4134 | u64 ow_gen; | 4177 | u64 ow_gen; |
| 4135 | u64 ow_mode; | 4178 | u64 ow_mode; |
| 4136 | u64 last_dir_ino_rm = 0; | ||
| 4137 | bool did_overwrite = false; | 4179 | bool did_overwrite = false; |
| 4138 | bool is_orphan = false; | 4180 | bool is_orphan = false; |
| 4139 | bool can_rename = true; | 4181 | bool can_rename = true; |
| @@ -4437,7 +4479,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 297 unmodified lines | |||
| 4437 | goto out; | 4479 | goto out; |
| 4438 | } | 4480 | } |
| 4439 | } | 4481 | } |
| 4440 | ret = dup_ref(cur, &check_dirs); | 4482 | ret = record_check_dir_ref_in_tree(&rbtree_check_dirs, cur, &check_dirs); |
| 4441 | if (ret < 0) | 4483 | if (ret < 0) |
| 4442 | goto out; | 4484 | goto out; |
| 4443 | } | 4485 | } |
| @@ -4465,7 +4507,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 21 unmodified lines | |||
| 4465 | } | 4507 | } |
| 4466 | 4508 | ||
| 4467 | list_for_each_entry(cur, &sctx->deleted_refs, list) { | 4509 | list_for_each_entry(cur, &sctx->deleted_refs, list) { |
| 4468 | ret = dup_ref(cur, &check_dirs); | 4510 | ret = record_check_dir_ref_in_tree(&rbtree_check_dirs, cur, &check_dirs); |
| 4469 | if (ret < 0) | 4511 | if (ret < 0) |
| 4470 | goto out; | 4512 | goto out; |
| 4471 | } | 4513 | } |
| @@ -4475,7 +4517,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 3 unmodified lines | |||
| 4475 | * We have a moved dir. Add the old parent to check_dirs | 4517 | * We have a moved dir. Add the old parent to check_dirs |
| 4476 | */ | 4518 | */ |
| 4477 | cur = list_first_entry(&sctx->deleted_refs, struct recorded_ref, list); | 4519 | cur = list_first_entry(&sctx->deleted_refs, struct recorded_ref, list); |
| 4478 | ret = dup_ref(cur, &check_dirs); | 4520 | ret = record_check_dir_ref_in_tree(&rbtree_check_dirs, cur, &check_dirs); |
| 4479 | if (ret < 0) | 4521 | if (ret < 0) |
| 4480 | goto out; | 4522 | goto out; |
| 4481 | } else if (!S_ISDIR(sctx->cur_inode_mode)) { | 4523 | } else if (!S_ISDIR(sctx->cur_inode_mode)) { |
| @@ -4509,7 +4551,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 27 unmodified lines | |||
| 4509 | if (is_current_inode_path(sctx, cur->full_path)) | 4551 | if (is_current_inode_path(sctx, cur->full_path)) |
| 4510 | fs_path_reset(&sctx->cur_inode_path); | 4552 | fs_path_reset(&sctx->cur_inode_path); |
| 4511 | } | 4553 | } |
| 4512 | ret = dup_ref(cur, &check_dirs); | 4554 | ret = record_check_dir_ref_in_tree(&rbtree_check_dirs, cur, &check_dirs); |
| 4513 | if (ret < 0) | 4555 | if (ret < 0) |
| 4514 | goto out; | 4556 | goto out; |
| 4515 | } | 4557 | } |
| @@ -4552,8 +4594,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 36 unmodified lines | |||
| 4552 | ret = cache_dir_utimes(sctx, cur->dir, cur->dir_gen); | 4594 | ret = cache_dir_utimes(sctx, cur->dir, cur->dir_gen); |
| 4553 | if (ret < 0) | 4595 | if (ret < 0) |
| 4554 | goto out; | 4596 | goto out; |
| 4555 | } else if (ret == inode_state_did_delete && | 4597 | } else if (ret == inode_state_did_delete) { |
| 4556 | cur->dir != last_dir_ino_rm) { | ||
| 4557 | ret = can_rmdir(sctx, cur->dir, cur->dir_gen); | 4598 | ret = can_rmdir(sctx, cur->dir, cur->dir_gen); |
| 4558 | if (ret < 0) | 4599 | if (ret < 0) |
| 4559 | goto out; | 4600 | goto out; |
| @@ -4565,7 +4606,6 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move) · 5 unmodified lines | |||
| 4565 | ret = send_rmdir(sctx, valid_path); | 4606 | ret = send_rmdir(sctx, valid_path); |
| 4566 | if (ret < 0) | 4607 | if (ret < 0) |
| 4567 | goto out; | 4608 | goto out; |
| 4568 | last_dir_ino_rm = cur->dir; | ||
| 4569 | } | 4609 | } |
| 4570 | } | 4610 | } |
| 4571 | } | 4611 | } |
| @@ -2068,7 +2068,13 @@ static int btrfs_get_tree_subvol(struct fs_context *fc) · 2067 unmodified lines | |||
| 2068 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); | 2068 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); |
| 2069 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); | 2069 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); |
| 2070 | if (!fs_info->super_copy || !fs_info->super_for_commit) { | 2070 | if (!fs_info->super_copy || !fs_info->super_for_commit) { |
| 2071 | btrfs_free_fs_info(fs_info); | 2071 | /* |
| 2072 | * Dont call btrfs_free_fs_info() to free it as it's still | ||
| 2073 | * initialized partially. | ||
| 2074 | */ | ||
| 2075 | kfree(fs_info->super_copy); | ||
| 2076 | kfree(fs_info->super_for_commit); | ||
| 2077 | kvfree(fs_info); | ||
| 2072 | return -ENOMEM; | 2078 | return -ENOMEM; |
| 2073 | } | 2079 | } |
| 2074 | btrfs_init_fs_info(fs_info); | 2080 | btrfs_init_fs_info(fs_info); |
| @@ -55,10 +55,6 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m, · 54 unmodified lines | |||
| 55 | } else { | 55 | } else { |
| 56 | m->partialref = !!(advise & Z_EROFS_LI_PARTIAL_REF); | 56 | m->partialref = !!(advise & Z_EROFS_LI_PARTIAL_REF); |
| 57 | m->clusterofs = le16_to_cpu(di->di_clusterofs); | 57 | m->clusterofs = le16_to_cpu(di->di_clusterofs); |
| 58 | if (m->clusterofs >= 1 << vi->z_lclusterbits) { | ||
| 59 | DBG_BUGON(1); | ||
| 60 | return -EFSCORRUPTED; | ||
| 61 | } | ||
| 62 | m->pblk = le32_to_cpu(di->di_u.blkaddr); | 58 | m->pblk = le32_to_cpu(di->di_u.blkaddr); |
| 63 | } | 59 | } |
| 64 | return 0; | 60 | return 0; |
| @@ -240,21 +236,29 @@ static int z_erofs_load_compact_lcluster(struct z_erofs_maprecorder *m, · 175 unmodified lines | |||
| 240 | static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m, | 236 | static int z_erofs_load_lcluster_from_disk(struct z_erofs_maprecorder *m, |
| 241 | unsigned int lcn, bool lookahead) | 237 | unsigned int lcn, bool lookahead) |
| 242 | { | 238 | { |
| 239 | struct erofs_inode *vi = EROFS_I(m->inode); | ||
| 240 | int err; | ||
| 241 | |||
| 242 | if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT) { | ||
| 243 | err = z_erofs_load_compact_lcluster(m, lcn, lookahead); | ||
| 244 | } else { | ||
| 245 | DBG_BUGON(vi->datalayout != EROFS_INODE_COMPRESSED_FULL); | ||
| 246 | err = z_erofs_load_full_lcluster(m, lcn); | ||
| 247 | } | ||
| 248 | if (err) | ||
| 249 | return err; | ||
| 250 | |||
| 243 | if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) { | 251 | if (m->type >= Z_EROFS_LCLUSTER_TYPE_MAX) { |
| 244 | erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu", | 252 | erofs_err(m->inode->i_sb, "unknown type %u @ lcn %u of nid %llu", |
| 245 | m->type, lcn, EROFS_I(m->inode)->nid); | 253 | m->type, lcn, EROFS_I(m->inode)->nid); |
| 246 | DBG_BUGON(1); | 254 | DBG_BUGON(1); |
| 247 | return -EOPNOTSUPP; | 255 | return -EOPNOTSUPP; |
| 256 | } else if (m->type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && | ||
| 257 | m->clusterofs >= (1 << vi->z_lclusterbits)) { | ||
| 258 | DBG_BUGON(1); | ||
| 259 | return -EFSCORRUPTED; | ||
| 248 | } | 260 | } |
| 249 | 261 | return 0; | |
| 250 | switch (EROFS_I(m->inode)->datalayout) { | ||
| 251 | case EROFS_INODE_COMPRESSED_FULL: | ||
| 252 | return z_erofs_load_full_lcluster(m, lcn); | ||
| 253 | case EROFS_INODE_COMPRESSED_COMPACT: | ||
| 254 | return z_erofs_load_compact_lcluster(m, lcn, lookahead); | ||
| 255 | default: | ||
| 256 | return -EINVAL; | ||
| 257 | } | ||
| 258 | } | 262 | } |
| 259 | 263 | ||
| 260 | static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, | 264 | static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, |
| @@ -268,20 +272,19 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, · 7 unmodified lines | |||
| 268 | unsigned long lcn = m->lcn - lookback_distance; | 272 | unsigned long lcn = m->lcn - lookback_distance; |
| 269 | int err; | 273 | int err; |
| 270 | 274 | ||
| 275 | if (!lookback_distance) | ||
| 276 | break; | ||
| 277 | |||
| 271 | err = z_erofs_load_lcluster_from_disk(m, lcn, false); | 278 | err = z_erofs_load_lcluster_from_disk(m, lcn, false); |
| 272 | if (err) | 279 | if (err) |
| 273 | return err; | 280 | return err; |
| 274 | |||
| 275 | if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { | 281 | if (m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) { |
| 276 | lookback_distance = m->delta[0]; | 282 | lookback_distance = m->delta[0]; |
| 277 | if (!lookback_distance) | ||
| 278 | break; | ||
| 279 | continue; | 283 | continue; |
| 280 | } else { | ||
| 281 | m->headtype = m->type; | ||
| 282 | m->map->m_la = (lcn << lclusterbits) | m->clusterofs; | ||
| 283 | return 0; | ||
| 284 | } | 284 | } |
| 285 | m->headtype = m->type; | ||
| 286 | m->map->m_la = (lcn << lclusterbits) | m->clusterofs; | ||
| 287 | return 0; | ||
| 285 | } | 288 | } |
| 286 | erofs_err(sb, "bogus lookback distance %u @ lcn %lu of nid %llu", | 289 | erofs_err(sb, "bogus lookback distance %u @ lcn %lu of nid %llu", |
| 287 | lookback_distance, m->lcn, vi->nid); | 290 | lookback_distance, m->lcn, vi->nid); |
| @@ -431,13 +434,6 @@ static int z_erofs_map_blocks_fo(struct inode *inode, · 143 unmodified lines | |||
| 431 | end = inode->i_size; | 434 | end = inode->i_size; |
| 432 | } else { | 435 | } else { |
| 433 | if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) { | 436 | if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) { |
| 434 | /* m.lcn should be >= 1 if endoff < m.clusterofs */ | ||
| 435 | if (!m.lcn) { | ||
| 436 | erofs_err(sb, "invalid logical cluster 0 at nid %llu", | ||
| 437 | vi->nid); | ||
| 438 | err = -EFSCORRUPTED; | ||
| 439 | goto unmap_out; | ||
| 440 | } | ||
| 441 | end = (m.lcn << lclusterbits) | m.clusterofs; | 437 | end = (m.lcn << lclusterbits) | m.clusterofs; |
| 442 | map->m_flags |= EROFS_MAP_FULL_MAPPED; | 438 | map->m_flags |= EROFS_MAP_FULL_MAPPED; |
| 443 | m.delta[0] = 1; | 439 | m.delta[0] = 1; |
| @@ -596,7 +592,7 @@ static int z_erofs_map_blocks_ext(struct inode *inode, · 152 unmodified lines | |||
| 596 | vi->z_fragmentoff = map->m_plen; | 592 | vi->z_fragmentoff = map->m_plen; |
| 597 | if (recsz > offsetof(struct z_erofs_extent, pstart_lo)) | 593 | if (recsz > offsetof(struct z_erofs_extent, pstart_lo)) |
| 598 | vi->z_fragmentoff |= map->m_pa << 32; | 594 | vi->z_fragmentoff |= map->m_pa << 32; |
| 599 | } else if (map->m_plen) { | 595 | } else if (map->m_plen & Z_EROFS_EXTENT_PLEN_MASK) { |
| 600 | map->m_flags |= EROFS_MAP_MAPPED | | 596 | map->m_flags |= EROFS_MAP_MAPPED | |
| 601 | EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED; | 597 | EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED; |
| 602 | fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT; | 598 | fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT; |
| @@ -715,6 +711,7 @@ static int z_erofs_map_sanity_check(struct inode *inode, · 112 unmodified lines | |||
| 715 | struct erofs_map_blocks *map) | 711 | struct erofs_map_blocks *map) |
| 716 | { | 712 | { |
| 717 | struct erofs_sb_info *sbi = EROFS_I_SB(inode); | 713 | struct erofs_sb_info *sbi = EROFS_I_SB(inode); |
| 714 | u64 pend; | ||
| 718 | 715 | ||
| 719 | if (!(map->m_flags & EROFS_MAP_ENCODED)) | 716 | if (!(map->m_flags & EROFS_MAP_ENCODED)) |
| 720 | return 0; | 717 | return 0; |
| @@ -732,6 +729,10 @@ static int z_erofs_map_sanity_check(struct inode *inode, · 11 unmodified lines | |||
| 732 | if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE || | 729 | if (unlikely(map->m_plen > Z_EROFS_PCLUSTER_MAX_SIZE || |
| 733 | map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE)) | 730 | map->m_llen > Z_EROFS_PCLUSTER_MAX_DSIZE)) |
| 734 | return -EOPNOTSUPP; | 731 | return -EOPNOTSUPP; |
| 732 | /* Filesystems beyond 48-bit physical block addresses are invalid */ | ||
| 733 | if (unlikely(check_add_overflow(map->m_pa, map->m_plen, &pend) || | ||
| 734 | (pend >> sbi->blkszbits) >= BIT_ULL(48))) | ||
| 735 | return -EFSCORRUPTED; | ||
| 735 | return 0; | 736 | return 0; |
| 736 | } | 737 | } |
| 737 | 738 | ||
| @@ -478,14 +478,6 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end, · 477 unmodified lines | |||
| 478 | if (!hugetlb_vma_trylock_write(vma)) | 478 | if (!hugetlb_vma_trylock_write(vma)) |
| 479 | continue; | 479 | continue; |
| 480 | 480 | ||
| 481 | /* | ||
| 482 | * Skip VMAs without shareable locks. Per the design in commit | ||
| 483 | * 40549ba8f8e0, these will be handled by remove_inode_hugepages() | ||
| 484 | * called after this function with proper locking. | ||
| 485 | */ | ||
| 486 | if (!__vma_shareable_lock(vma)) | ||
| 487 | goto skip; | ||
| 488 | |||
| 489 | v_start = vma_offset_start(vma, start); | 481 | v_start = vma_offset_start(vma, start); |
| 490 | v_end = vma_offset_end(vma, end); | 482 | v_end = vma_offset_end(vma, end); |
| 491 | 483 | ||
| @@ -496,7 +488,6 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end, · 4 unmodified lines | |||
| 496 | * vmas. Therefore, lock is not held when calling | 488 | * vmas. Therefore, lock is not held when calling |
| 497 | * unmap_hugepage_range for private vmas. | 489 | * unmap_hugepage_range for private vmas. |
| 498 | */ | 490 | */ |
| 499 | skip: | ||
| 500 | hugetlb_vma_unlock_write(vma); | 491 | hugetlb_vma_unlock_write(vma); |
| 501 | } | 492 | } |
| 502 | } | 493 | } |
| @@ -76,14 +76,14 @@ struct jfs_inode_info { · 75 unmodified lines | |||
| 76 | struct { | 76 | struct { |
| 77 | unchar _unused[16]; /* 16: */ | 77 | unchar _unused[16]; /* 16: */ |
| 78 | dxd_t _dxd; /* 16: */ | 78 | dxd_t _dxd; /* 16: */ |
| 79 | /* _inline may overflow into _inline_ea when needed */ | 79 | /* _inline_sym may overflow into _inline_ea when needed */ |
| 80 | /* _inline_ea may overlay the last part of | 80 | /* _inline_ea may overlay the last part of |
| 81 | * file._xtroot if maxentry = XTROOTINITSLOT | 81 | * file._xtroot if maxentry = XTROOTINITSLOT |
| 82 | */ | 82 | */ |
| 83 | union { | 83 | union { |
| 84 | struct { | 84 | struct { |
| 85 | /* 128: inline symlink */ | 85 | /* 128: inline symlink */ |
| 86 | unchar _inline[128]; | 86 | unchar _inline_sym[128]; |
| 87 | /* 128: inline extended attr */ | 87 | /* 128: inline extended attr */ |
| 88 | unchar _inline_ea[128]; | 88 | unchar _inline_ea[128]; |
| 89 | }; | 89 | }; |
| @@ -101,7 +101,7 @@ struct jfs_inode_info { · 11 unmodified lines | |||
| 101 | #define i_imap u.file._imap | 101 | #define i_imap u.file._imap |
| 102 | #define i_dirtable u.dir._table | 102 | #define i_dirtable u.dir._table |
| 103 | #define i_dtroot u.dir._dtroot | 103 | #define i_dtroot u.dir._dtroot |
| 104 | #define i_inline u.link._inline | 104 | #define i_inline u.link._inline_sym |
| 105 | #define i_inline_ea u.link._inline_ea | 105 | #define i_inline_ea u.link._inline_ea |
| 106 | #define i_inline_all u.link._inline_all | 106 | #define i_inline_all u.link._inline_all |
| 107 | 107 | ||
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include "fanotify/fanotify.h" | 17 | #include "fanotify/fanotify.h" |
| 18 | #include "fdinfo.h" | 18 | #include "fdinfo.h" |
| 19 | #include "fsnotify.h" | 19 | #include "fsnotify.h" |
| 20 | #include "../internal.h" | ||
| 20 | 21 | ||
| 21 | #if defined(CONFIG_PROC_FS) | 22 | #if defined(CONFIG_PROC_FS) |
| 22 | 23 | ||
| @@ -46,7 +47,12 @@ static void show_mark_fhandle(struct seq_file *m, struct inode *inode) · 23 unmodified lines | |||
| 46 | 47 | ||
| 47 | size = f->handle_bytes >> 2; | 48 | size = f->handle_bytes >> 2; |
| 48 | 49 | ||
| 50 | if (!super_trylock_shared(inode->i_sb)) | ||
| 51 | return; | ||
| 52 | |||
| 49 | ret = exportfs_encode_fid(inode, (struct fid *)f->f_handle, &size); | 53 | ret = exportfs_encode_fid(inode, (struct fid *)f->f_handle, &size); |
| 54 | up_read(&inode->i_sb->s_umount); | ||
| 55 | |||
| 50 | if ((ret == FILEID_INVALID) || (ret < 0)) | 56 | if ((ret == FILEID_INVALID) || (ret < 0)) |
| 51 | return; | 57 | return; |
| 52 | 58 | ||
| @@ -867,6 +867,11 @@ static int __ocfs2_move_extents_range(struct buffer_head *di_bh, · 866 unmodified lines | |||
| 867 | mlog_errno(ret); | 867 | mlog_errno(ret); |
| 868 | goto out; | 868 | goto out; |
| 869 | } | 869 | } |
| 870 | /* | ||
| 871 | * Invalidate extent cache after moving/defragging to prevent | ||
| 872 | * stale cached data with outdated extent flags. | ||
| 873 | */ | ||
| 874 | ocfs2_extent_map_trunc(inode, cpos); | ||
| 870 | 875 | ||
| 871 | context->clusters_moved += alloc_size; | 876 | context->clusters_moved += alloc_size; |
| 872 | next: | 877 | next: |
| @@ -1782,15 +1782,13 @@ int resctrl_mon_resource_init(void) · 1781 unmodified lines | |||
| 1782 | mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID; | 1782 | mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID; |
| 1783 | 1783 | ||
| 1784 | if (r->mon.mbm_cntr_assignable) { | 1784 | if (r->mon.mbm_cntr_assignable) { |
| 1785 | if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID)) | 1785 | if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID)) |
| 1786 | resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID); | 1786 | mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask; |
| 1787 | if (!resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID)) | 1787 | if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID)) |
| 1788 | resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID); | 1788 | mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask & |
| 1789 | mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask; | 1789 | (READS_TO_LOCAL_MEM | |
| 1790 | mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask & | 1790 | READS_TO_LOCAL_S_MEM | |
| 1791 | (READS_TO_LOCAL_MEM | | 1791 | NON_TEMP_WRITE_TO_LOCAL_MEM); |
| 1792 | READS_TO_LOCAL_S_MEM | | ||
| 1793 | NON_TEMP_WRITE_TO_LOCAL_MEM); | ||
| 1794 | r->mon.mbm_assign_on_mkdir = true; | 1792 | r->mon.mbm_assign_on_mkdir = true; |
| 1795 | resctrl_file_fflags_init("num_mbm_cntrs", | 1793 | resctrl_file_fflags_init("num_mbm_cntrs", |
| 1796 | RFTYPE_MON_INFO | RFTYPE_RES_CACHE); | 1794 | RFTYPE_MON_INFO | RFTYPE_RES_CACHE); |
| @@ -534,8 +534,6 @@ struct smb_version_operations { · 533 unmodified lines | |||
| 534 | void (*new_lease_key)(struct cifs_fid *); | 534 | void (*new_lease_key)(struct cifs_fid *); |
| 535 | int (*generate_signingkey)(struct cifs_ses *ses, | 535 | int (*generate_signingkey)(struct cifs_ses *ses, |
| 536 | struct TCP_Server_Info *server); | 536 | struct TCP_Server_Info *server); |
| 537 | int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *, | ||
| 538 | bool allocate_crypto); | ||
| 539 | int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, | 537 | int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, |
| 540 | struct cifsFileInfo *src_file); | 538 | struct cifsFileInfo *src_file); |
| 541 | int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon, | 539 | int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon, |
| @@ -732,7 +730,7 @@ struct TCP_Server_Info { · 190 unmodified lines | |||
| 732 | bool nosharesock; | 730 | bool nosharesock; |
| 733 | bool tcp_nodelay; | 731 | bool tcp_nodelay; |
| 734 | bool terminate; | 732 | bool terminate; |
| 735 | unsigned int credits; /* send no more requests at once */ | 733 | int credits; /* send no more requests at once */ |
| 736 | unsigned int max_credits; /* can override large 32000 default at mnt */ | 734 | unsigned int max_credits; /* can override large 32000 default at mnt */ |
| 737 | unsigned int in_flight; /* number of requests on the wire to server */ | 735 | unsigned int in_flight; /* number of requests on the wire to server */ |
| 738 | unsigned int max_in_flight; /* max number of requests that were on wire */ | 736 | unsigned int max_in_flight; /* max number of requests that were on wire */ |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #define _CIFSPROTO_H | 9 | #define _CIFSPROTO_H |
| 10 | #include <linux/nls.h> | 10 | #include <linux/nls.h> |
| 11 | #include <linux/ctype.h> | 11 | #include <linux/ctype.h> |
| 12 | #include "cifsglob.h" | ||
| 12 | #include "trace.h" | 13 | #include "trace.h" |
| 13 | #ifdef CONFIG_CIFS_DFS_UPCALL | 14 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 14 | #include "dfs_cache.h" | 15 | #include "dfs_cache.h" |
| @@ -1311,6 +1311,8 @@ cifs_readv_callback(struct mid_q_entry *mid) · 1310 unmodified lines | |||
| 1311 | .rreq_debug_id = rdata->rreq->debug_id, | 1311 | .rreq_debug_id = rdata->rreq->debug_id, |
| 1312 | .rreq_debug_index = rdata->subreq.debug_index, | 1312 | .rreq_debug_index = rdata->subreq.debug_index, |
| 1313 | }; | 1313 | }; |
| 1314 | unsigned int rreq_debug_id = rdata->rreq->debug_id; | ||
| 1315 | unsigned int subreq_debug_index = rdata->subreq.debug_index; | ||
| 1314 | 1316 | ||
| 1315 | cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", | 1317 | cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", |
| 1316 | __func__, mid->mid, mid->mid_state, rdata->result, | 1318 | __func__, mid->mid, mid->mid_state, rdata->result, |
| @@ -1374,6 +1376,9 @@ do_retry: · 57 unmodified lines | |||
| 1374 | __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); | 1376 | __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); |
| 1375 | } | 1377 | } |
| 1376 | 1378 | ||
| 1379 | trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, | ||
| 1380 | server->credits, server->in_flight, | ||
| 1381 | 0, cifs_trace_rw_credits_read_response_clear); | ||
| 1377 | rdata->credits.value = 0; | 1382 | rdata->credits.value = 0; |
| 1378 | rdata->subreq.error = rdata->result; | 1383 | rdata->subreq.error = rdata->result; |
| 1379 | rdata->subreq.transferred += rdata->got_bytes; | 1384 | rdata->subreq.transferred += rdata->got_bytes; |
| @@ -1381,6 +1386,9 @@ do_retry: · 1 unmodified line | |||
| 1381 | netfs_read_subreq_terminated(&rdata->subreq); | 1386 | netfs_read_subreq_terminated(&rdata->subreq); |
| 1382 | release_mid(mid); | 1387 | release_mid(mid); |
| 1383 | add_credits(server, &credits, 0); | 1388 | add_credits(server, &credits, 0); |
| 1389 | trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, | ||
| 1390 | server->credits, server->in_flight, | ||
| 1391 | credits.value, cifs_trace_rw_credits_read_response_add); | ||
| 1384 | } | 1392 | } |
| 1385 | 1393 | ||
| 1386 | /* cifs_async_readv - send an async write, and set up mid to handle result */ | 1394 | /* cifs_async_readv - send an async write, and set up mid to handle result */ |
| @@ -2484,11 +2484,8 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, · 2483 unmodified lines | |||
| 2484 | } | 2484 | } |
| 2485 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ | 2485 | #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ |
| 2486 | do_rename_exit: | 2486 | do_rename_exit: |
| 2487 | if (rc == 0) { | 2487 | if (rc == 0) |
| 2488 | d_move(from_dentry, to_dentry); | 2488 | d_move(from_dentry, to_dentry); |
| 2489 | /* Force a new lookup */ | ||
| 2490 | d_drop(from_dentry); | ||
| 2491 | } | ||
| 2492 | cifs_put_tlink(tlink); | 2489 | cifs_put_tlink(tlink); |
| 2493 | return rc; | 2490 | return rc; |
| 2494 | } | 2491 | } |
| @@ -5446,7 +5446,6 @@ struct smb_version_operations smb20_operations = { · 5445 unmodified lines | |||
| 5446 | .get_lease_key = smb2_get_lease_key, | 5446 | .get_lease_key = smb2_get_lease_key, |
| 5447 | .set_lease_key = smb2_set_lease_key, | 5447 | .set_lease_key = smb2_set_lease_key, |
| 5448 | .new_lease_key = smb2_new_lease_key, | 5448 | .new_lease_key = smb2_new_lease_key, |
| 5449 | .calc_signature = smb2_calc_signature, | ||
| 5450 | .is_read_op = smb2_is_read_op, | 5449 | .is_read_op = smb2_is_read_op, |
| 5451 | .set_oplock_level = smb2_set_oplock_level, | 5450 | .set_oplock_level = smb2_set_oplock_level, |
| 5452 | .create_lease_buf = smb2_create_lease_buf, | 5451 | .create_lease_buf = smb2_create_lease_buf, |
| @@ -5550,7 +5549,6 @@ struct smb_version_operations smb21_operations = { · 97 unmodified lines | |||
| 5550 | .get_lease_key = smb2_get_lease_key, | 5549 | .get_lease_key = smb2_get_lease_key, |
| 5551 | .set_lease_key = smb2_set_lease_key, | 5550 | .set_lease_key = smb2_set_lease_key, |
| 5552 | .new_lease_key = smb2_new_lease_key, | 5551 | .new_lease_key = smb2_new_lease_key, |
| 5553 | .calc_signature = smb2_calc_signature, | ||
| 5554 | .is_read_op = smb21_is_read_op, | 5552 | .is_read_op = smb21_is_read_op, |
| 5555 | .set_oplock_level = smb21_set_oplock_level, | 5553 | .set_oplock_level = smb21_set_oplock_level, |
| 5556 | .create_lease_buf = smb2_create_lease_buf, | 5554 | .create_lease_buf = smb2_create_lease_buf, |
| @@ -5660,7 +5658,6 @@ struct smb_version_operations smb30_operations = { · 103 unmodified lines | |||
| 5660 | .set_lease_key = smb2_set_lease_key, | 5658 | .set_lease_key = smb2_set_lease_key, |
| 5661 | .new_lease_key = smb2_new_lease_key, | 5659 | .new_lease_key = smb2_new_lease_key, |
| 5662 | .generate_signingkey = generate_smb30signingkey, | 5660 | .generate_signingkey = generate_smb30signingkey, |
| 5663 | .calc_signature = smb3_calc_signature, | ||
| 5664 | .set_integrity = smb3_set_integrity, | 5661 | .set_integrity = smb3_set_integrity, |
| 5665 | .is_read_op = smb21_is_read_op, | 5662 | .is_read_op = smb21_is_read_op, |
| 5666 | .set_oplock_level = smb3_set_oplock_level, | 5663 | .set_oplock_level = smb3_set_oplock_level, |
| @@ -5777,7 +5774,6 @@ struct smb_version_operations smb311_operations = { · 110 unmodified lines | |||
| 5777 | .set_lease_key = smb2_set_lease_key, | 5774 | .set_lease_key = smb2_set_lease_key, |
| 5778 | .new_lease_key = smb2_new_lease_key, | 5775 | .new_lease_key = smb2_new_lease_key, |
| 5779 | .generate_signingkey = generate_smb311signingkey, | 5776 | .generate_signingkey = generate_smb311signingkey, |
| 5780 | .calc_signature = smb3_calc_signature, | ||
| 5781 | .set_integrity = smb3_set_integrity, | 5777 | .set_integrity = smb3_set_integrity, |
| 5782 | .is_read_op = smb21_is_read_op, | 5778 | .is_read_op = smb21_is_read_op, |
| 5783 | .set_oplock_level = smb3_set_oplock_level, | 5779 | .set_oplock_level = smb3_set_oplock_level, |
| @@ -39,12 +39,6 @@ extern struct mid_q_entry *smb2_setup_async_request( · 38 unmodified lines | |||
| 39 | struct TCP_Server_Info *server, struct smb_rqst *rqst); | 39 | struct TCP_Server_Info *server, struct smb_rqst *rqst); |
| 40 | extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, | 40 | extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, |
| 41 | __u64 ses_id, __u32 tid); | 41 | __u64 ses_id, __u32 tid); |
| 42 | extern int smb2_calc_signature(struct smb_rqst *rqst, | ||
| 43 | struct TCP_Server_Info *server, | ||
| 44 | bool allocate_crypto); | ||
| 45 | extern int smb3_calc_signature(struct smb_rqst *rqst, | ||
| 46 | struct TCP_Server_Info *server, | ||
| 47 | bool allocate_crypto); | ||
| 48 | extern void smb2_echo_request(struct work_struct *work); | 42 | extern void smb2_echo_request(struct work_struct *work); |
| 49 | extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode); | 43 | extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode); |
| 50 | extern bool smb2_is_valid_oplock_break(char *buffer, | 44 | extern bool smb2_is_valid_oplock_break(char *buffer, |
| @@ -209,9 +209,9 @@ smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) · 208 unmodified lines | |||
| 209 | return tcon; | 209 | return tcon; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | int | 212 | static int |
| 213 | smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, | 213 | smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, |
| 214 | bool allocate_crypto) | 214 | bool allocate_crypto) |
| 215 | { | 215 | { |
| 216 | int rc; | 216 | int rc; |
| 217 | unsigned char smb2_signature[SMB2_HMACSHA256_SIZE]; | 217 | unsigned char smb2_signature[SMB2_HMACSHA256_SIZE]; |
| @@ -465,9 +465,9 @@ generate_smb311signingkey(struct cifs_ses *ses, · 247 unmodified lines | |||
| 465 | return generate_smb3signingkey(ses, server, &triplet); | 465 | return generate_smb3signingkey(ses, server, &triplet); |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | int | 468 | static int |
| 469 | smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, | 469 | smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, |
| 470 | bool allocate_crypto) | 470 | bool allocate_crypto) |
| 471 | { | 471 | { |
| 472 | int rc; | 472 | int rc; |
| 473 | unsigned char smb3_signature[SMB2_CMACAES_SIZE]; | 473 | unsigned char smb3_signature[SMB2_CMACAES_SIZE]; |
| @@ -477,6 +477,9 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, · 3 unmodified lines | |||
| 477 | struct smb_rqst drqst; | 477 | struct smb_rqst drqst; |
| 478 | u8 key[SMB3_SIGN_KEY_SIZE]; | 478 | u8 key[SMB3_SIGN_KEY_SIZE]; |
| 479 | 479 | ||
| 480 | if (server->vals->protocol_id <= SMB21_PROT_ID) | ||
| 481 | return smb2_calc_signature(rqst, server, allocate_crypto); | ||
| 482 | |||
| 480 | rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); | 483 | rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); |
| 481 | if (unlikely(rc)) { | 484 | if (unlikely(rc)) { |
| 482 | cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__); | 485 | cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__); |
| @@ -547,7 +550,6 @@ out: · 64 unmodified lines | |||
| 547 | static int | 550 | static int |
| 548 | smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) | 551 | smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
| 549 | { | 552 | { |
| 550 | int rc = 0; | ||
| 551 | struct smb2_hdr *shdr; | 553 | struct smb2_hdr *shdr; |
| 552 | struct smb2_sess_setup_req *ssr; | 554 | struct smb2_sess_setup_req *ssr; |
| 553 | bool is_binding; | 555 | bool is_binding; |
| @@ -574,9 +576,7 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 20 unmodified lines | |||
| 574 | return 0; | 576 | return 0; |
| 575 | } | 577 | } |
| 576 | 578 | ||
| 577 | rc = server->ops->calc_signature(rqst, server, false); | 579 | return smb3_calc_signature(rqst, server, false); |
| 578 | |||
| 579 | return rc; | ||
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | int | 582 | int |
| @@ -612,7 +612,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 29 unmodified lines | |||
| 612 | 612 | ||
| 613 | memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE); | 613 | memset(shdr->Signature, 0, SMB2_SIGNATURE_SIZE); |
| 614 | 614 | ||
| 615 | rc = server->ops->calc_signature(rqst, server, true); | 615 | rc = smb3_calc_signature(rqst, server, true); |
| 616 | 616 | ||
| 617 | if (rc) | 617 | if (rc) |
| 618 | return rc; | 618 | return rc; |
| @@ -172,6 +172,7 @@ static void smbd_disconnect_wake_up_all(struct smbdirect_socket *sc) · 171 unmodified lines | |||
| 172 | * in order to notice the broken connection. | 172 | * in order to notice the broken connection. |
| 173 | */ | 173 | */ |
| 174 | wake_up_all(&sc->status_wait); | 174 | wake_up_all(&sc->status_wait); |
| 175 | wake_up_all(&sc->send_io.lcredits.wait_queue); | ||
| 175 | wake_up_all(&sc->send_io.credits.wait_queue); | 176 | wake_up_all(&sc->send_io.credits.wait_queue); |
| 176 | wake_up_all(&sc->send_io.pending.dec_wait_queue); | 177 | wake_up_all(&sc->send_io.pending.dec_wait_queue); |
| 177 | wake_up_all(&sc->send_io.pending.zero_wait_queue); | 178 | wake_up_all(&sc->send_io.pending.zero_wait_queue); |
| @@ -495,6 +496,7 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) · 317 unmodified lines | |||
| 495 | struct smbdirect_send_io *request = | 496 | struct smbdirect_send_io *request = |
| 496 | container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); | 497 | container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); |
| 497 | struct smbdirect_socket *sc = request->socket; | 498 | struct smbdirect_socket *sc = request->socket; |
| 499 | int lcredits = 0; | ||
| 498 | 500 | ||
| 499 | log_rdma_send(INFO, "smbdirect_send_io 0x%p completed wc->status=%s\n", | 501 | log_rdma_send(INFO, "smbdirect_send_io 0x%p completed wc->status=%s\n", |
| 500 | request, ib_wc_status_msg(wc->status)); | 502 | request, ib_wc_status_msg(wc->status)); |
| @@ -504,22 +506,24 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) · 3 unmodified lines | |||
| 504 | request->sge[i].addr, | 506 | request->sge[i].addr, |
| 505 | request->sge[i].length, | 507 | request->sge[i].length, |
| 506 | DMA_TO_DEVICE); | 508 | DMA_TO_DEVICE); |
| 509 | mempool_free(request, sc->send_io.mem.pool); | ||
| 510 | lcredits += 1; | ||
| 507 | 511 | ||
| 508 | if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { | 512 | if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { |
| 509 | if (wc->status != IB_WC_WR_FLUSH_ERR) | 513 | if (wc->status != IB_WC_WR_FLUSH_ERR) |
| 510 | log_rdma_send(ERR, "wc->status=%s wc->opcode=%d\n", | 514 | log_rdma_send(ERR, "wc->status=%s wc->opcode=%d\n", |
| 511 | ib_wc_status_msg(wc->status), wc->opcode); | 515 | ib_wc_status_msg(wc->status), wc->opcode); |
| 512 | mempool_free(request, sc->send_io.mem.pool); | ||
| 513 | smbd_disconnect_rdma_connection(sc); | 516 | smbd_disconnect_rdma_connection(sc); |
| 514 | return; | 517 | return; |
| 515 | } | 518 | } |
| 516 | 519 | ||
| 520 | atomic_add(lcredits, &sc->send_io.lcredits.count); | ||
| 521 | wake_up(&sc->send_io.lcredits.wait_queue); | ||
| 522 | |||
| 517 | if (atomic_dec_and_test(&sc->send_io.pending.count)) | 523 | if (atomic_dec_and_test(&sc->send_io.pending.count)) |
| 518 | wake_up(&sc->send_io.pending.zero_wait_queue); | 524 | wake_up(&sc->send_io.pending.zero_wait_queue); |
| 519 | 525 | ||
| 520 | wake_up(&sc->send_io.pending.dec_wait_queue); | 526 | wake_up(&sc->send_io.pending.dec_wait_queue); |
| 521 | |||
| 522 | mempool_free(request, sc->send_io.mem.pool); | ||
| 523 | } | 527 | } |
| 524 | 528 | ||
| 525 | static void dump_smbdirect_negotiate_resp(struct smbdirect_negotiate_resp *resp) | 529 | static void dump_smbdirect_negotiate_resp(struct smbdirect_negotiate_resp *resp) |
| @@ -567,6 +571,7 @@ static bool process_negotiation_response( · 41 unmodified lines | |||
| 567 | log_rdma_event(ERR, "error: credits_granted==0\n"); | 571 | log_rdma_event(ERR, "error: credits_granted==0\n"); |
| 568 | return false; | 572 | return false; |
| 569 | } | 573 | } |
| 574 | atomic_set(&sc->send_io.lcredits.count, sp->send_credit_target); | ||
| 570 | atomic_set(&sc->send_io.credits.count, le16_to_cpu(packet->credits_granted)); | 575 | atomic_set(&sc->send_io.credits.count, le16_to_cpu(packet->credits_granted)); |
| 571 | 576 | ||
| 572 | if (le32_to_cpu(packet->preferred_send_size) > sp->max_recv_size) { | 577 | if (le32_to_cpu(packet->preferred_send_size) > sp->max_recv_size) { |
| @@ -1114,6 +1119,24 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc, · 541 unmodified lines | |||
| 1114 | struct smbdirect_data_transfer *packet; | 1119 | struct smbdirect_data_transfer *packet; |
| 1115 | int new_credits = 0; | 1120 | int new_credits = 0; |
| 1116 | 1121 | ||
| 1122 | wait_lcredit: | ||
| 1123 | /* Wait for local send credits */ | ||
| 1124 | rc = wait_event_interruptible(sc->send_io.lcredits.wait_queue, | ||
| 1125 | atomic_read(&sc->send_io.lcredits.count) > 0 || | ||
| 1126 | sc->status != SMBDIRECT_SOCKET_CONNECTED); | ||
| 1127 | if (rc) | ||
| 1128 | goto err_wait_lcredit; | ||
| 1129 | |||
| 1130 | if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { | ||
| 1131 | log_outgoing(ERR, "disconnected not sending on wait_credit\n"); | ||
| 1132 | rc = -EAGAIN; | ||
| 1133 | goto err_wait_lcredit; | ||
| 1134 | } | ||
| 1135 | if (unlikely(atomic_dec_return(&sc->send_io.lcredits.count) < 0)) { | ||
| 1136 | atomic_inc(&sc->send_io.lcredits.count); | ||
| 1137 | goto wait_lcredit; | ||
| 1138 | } | ||
| 1139 | |||
| 1117 | wait_credit: | 1140 | wait_credit: |
| 1118 | /* Wait for send credits. A SMBD packet needs one credit */ | 1141 | /* Wait for send credits. A SMBD packet needs one credit */ |
| 1119 | rc = wait_event_interruptible(sc->send_io.credits.wait_queue, | 1142 | rc = wait_event_interruptible(sc->send_io.credits.wait_queue, |
| @@ -1132,23 +1155,6 @@ wait_credit: · 12 unmodified lines | |||
| 1132 | goto wait_credit; | 1155 | goto wait_credit; |
| 1133 | } | 1156 | } |
| 1134 | 1157 | ||
| 1135 | wait_send_queue: | ||
| 1136 | wait_event(sc->send_io.pending.dec_wait_queue, | ||
| 1137 | atomic_read(&sc->send_io.pending.count) < sp->send_credit_target || | ||
| 1138 | sc->status != SMBDIRECT_SOCKET_CONNECTED); | ||
| 1139 | |||
| 1140 | if (sc->status != SMBDIRECT_SOCKET_CONNECTED) { | ||
| 1141 | log_outgoing(ERR, "disconnected not sending on wait_send_queue\n"); | ||
| 1142 | rc = -EAGAIN; | ||
| 1143 | goto err_wait_send_queue; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | if (unlikely(atomic_inc_return(&sc->send_io.pending.count) > | ||
| 1147 | sp->send_credit_target)) { | ||
| 1148 | atomic_dec(&sc->send_io.pending.count); | ||
| 1149 | goto wait_send_queue; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | request = mempool_alloc(sc->send_io.mem.pool, GFP_KERNEL); | 1158 | request = mempool_alloc(sc->send_io.mem.pool, GFP_KERNEL); |
| 1153 | if (!request) { | 1159 | if (!request) { |
| 1154 | rc = -ENOMEM; | 1160 | rc = -ENOMEM; |
| @@ -1229,10 +1235,21 @@ wait_send_queue: · 74 unmodified lines | |||
| 1229 | le32_to_cpu(packet->data_length), | 1235 | le32_to_cpu(packet->data_length), |
| 1230 | le32_to_cpu(packet->remaining_data_length)); | 1236 | le32_to_cpu(packet->remaining_data_length)); |
| 1231 | 1237 | ||
| 1238 | /* | ||
| 1239 | * Now that we got a local and a remote credit | ||
| 1240 | * we add us as pending | ||
| 1241 | */ | ||
| 1242 | atomic_inc(&sc->send_io.pending.count); | ||
| 1243 | |||
| 1232 | rc = smbd_post_send(sc, request); | 1244 | rc = smbd_post_send(sc, request); |
| 1233 | if (!rc) | 1245 | if (!rc) |
| 1234 | return 0; | 1246 | return 0; |
| 1235 | 1247 | ||
| 1248 | if (atomic_dec_and_test(&sc->send_io.pending.count)) | ||
| 1249 | wake_up(&sc->send_io.pending.zero_wait_queue); | ||
| 1250 | |||
| 1251 | wake_up(&sc->send_io.pending.dec_wait_queue); | ||
| 1252 | |||
| 1236 | err_dma: | 1253 | err_dma: |
| 1237 | for (i = 0; i < request->num_sge; i++) | 1254 | for (i = 0; i < request->num_sge; i++) |
| 1238 | if (request->sge[i].addr) | 1255 | if (request->sge[i].addr) |
| @@ -1246,14 +1263,14 @@ err_dma: · 7 unmodified lines | |||
| 1246 | atomic_sub(new_credits, &sc->recv_io.credits.count); | 1263 | atomic_sub(new_credits, &sc->recv_io.credits.count); |
| 1247 | 1264 | ||
| 1248 | err_alloc: | 1265 | err_alloc: |
| 1249 | if (atomic_dec_and_test(&sc->send_io.pending.count)) | ||
| 1250 | wake_up(&sc->send_io.pending.zero_wait_queue); | ||
| 1251 | |||
| 1252 | err_wait_send_queue: | ||
| 1253 | /* roll back send credits and pending */ | ||
| 1254 | atomic_inc(&sc->send_io.credits.count); | 1266 | atomic_inc(&sc->send_io.credits.count); |
| 1267 | wake_up(&sc->send_io.credits.wait_queue); | ||
| 1255 | 1268 | ||
| 1256 | err_wait_credit: | 1269 | err_wait_credit: |
| 1270 | atomic_inc(&sc->send_io.lcredits.count); | ||
| 1271 | wake_up(&sc->send_io.lcredits.wait_queue); | ||
| 1272 | |||
| 1273 | err_wait_lcredit: | ||
| 1257 | return rc; | 1274 | return rc; |
| 1258 | } | 1275 | } |
| 1259 | 1276 | ||
| @@ -1767,6 +1784,7 @@ static struct smbd_connection *_smbd_get_connection( · 507 unmodified lines | |||
| 1767 | struct smbdirect_socket *sc; | 1784 | struct smbdirect_socket *sc; |
| 1768 | struct smbdirect_socket_parameters *sp; | 1785 | struct smbdirect_socket_parameters *sp; |
| 1769 | struct rdma_conn_param conn_param; | 1786 | struct rdma_conn_param conn_param; |
| 1787 | struct ib_qp_cap qp_cap; | ||
| 1770 | struct ib_qp_init_attr qp_attr; | 1788 | struct ib_qp_init_attr qp_attr; |
| 1771 | struct sockaddr_in *addr_in = (struct sockaddr_in *) dstaddr; | 1789 | struct sockaddr_in *addr_in = (struct sockaddr_in *) dstaddr; |
| 1772 | struct ib_port_immutable port_immutable; | 1790 | struct ib_port_immutable port_immutable; |
| @@ -1838,6 +1856,25 @@ static struct smbd_connection *_smbd_get_connection( · 65 unmodified lines | |||
| 1838 | goto config_failed; | 1856 | goto config_failed; |
| 1839 | } | 1857 | } |
| 1840 | 1858 | ||
| 1859 | sp->responder_resources = | ||
| 1860 | min_t(u8, sp->responder_resources, | ||
| 1861 | sc->ib.dev->attrs.max_qp_rd_atom); | ||
| 1862 | log_rdma_mr(INFO, "responder_resources=%d\n", | ||
| 1863 | sp->responder_resources); | ||
| 1864 | |||
| 1865 | /* | ||
| 1866 | * We use allocate sp->responder_resources * 2 MRs | ||
| 1867 | * and each MR needs WRs for REG and INV, so | ||
| 1868 | * we use '* 4'. | ||
| 1869 | * | ||
| 1870 | * +1 for ib_drain_qp() | ||
| 1871 | */ | ||
| 1872 | memset(&qp_cap, 0, sizeof(qp_cap)); | ||
| 1873 | qp_cap.max_send_wr = sp->send_credit_target + sp->responder_resources * 4 + 1; | ||
| 1874 | qp_cap.max_recv_wr = sp->recv_credit_max + 1; | ||
| 1875 | qp_cap.max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; | ||
| 1876 | qp_cap.max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; | ||
| 1877 | |||
| 1841 | sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0); | 1878 | sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0); |
| 1842 | if (IS_ERR(sc->ib.pd)) { | 1879 | if (IS_ERR(sc->ib.pd)) { |
| 1843 | rc = PTR_ERR(sc->ib.pd); | 1880 | rc = PTR_ERR(sc->ib.pd); |
| @@ -1848,7 +1885,7 @@ static struct smbd_connection *_smbd_get_connection( · 4 unmodified lines | |||
| 1848 | 1885 | ||
| 1849 | sc->ib.send_cq = | 1886 | sc->ib.send_cq = |
| 1850 | ib_alloc_cq_any(sc->ib.dev, sc, | 1887 | ib_alloc_cq_any(sc->ib.dev, sc, |
| 1851 | sp->send_credit_target, IB_POLL_SOFTIRQ); | 1888 | qp_cap.max_send_wr, IB_POLL_SOFTIRQ); |
| 1852 | if (IS_ERR(sc->ib.send_cq)) { | 1889 | if (IS_ERR(sc->ib.send_cq)) { |
| 1853 | sc->ib.send_cq = NULL; | 1890 | sc->ib.send_cq = NULL; |
| 1854 | goto alloc_cq_failed; | 1891 | goto alloc_cq_failed; |
| @@ -1856,7 +1893,7 @@ static struct smbd_connection *_smbd_get_connection( · 1 unmodified line | |||
| 1856 | 1893 | ||
| 1857 | sc->ib.recv_cq = | 1894 | sc->ib.recv_cq = |
| 1858 | ib_alloc_cq_any(sc->ib.dev, sc, | 1895 | ib_alloc_cq_any(sc->ib.dev, sc, |
| 1859 | sp->recv_credit_max, IB_POLL_SOFTIRQ); | 1896 | qp_cap.max_recv_wr, IB_POLL_SOFTIRQ); |
| 1860 | if (IS_ERR(sc->ib.recv_cq)) { | 1897 | if (IS_ERR(sc->ib.recv_cq)) { |
| 1861 | sc->ib.recv_cq = NULL; | 1898 | sc->ib.recv_cq = NULL; |
| 1862 | goto alloc_cq_failed; | 1899 | goto alloc_cq_failed; |
| @@ -1865,11 +1902,7 @@ static struct smbd_connection *_smbd_get_connection( · 2 unmodified lines | |||
| 1865 | memset(&qp_attr, 0, sizeof(qp_attr)); | 1902 | memset(&qp_attr, 0, sizeof(qp_attr)); |
| 1866 | qp_attr.event_handler = smbd_qp_async_error_upcall; | 1903 | qp_attr.event_handler = smbd_qp_async_error_upcall; |
| 1867 | qp_attr.qp_context = sc; | 1904 | qp_attr.qp_context = sc; |
| 1868 | qp_attr.cap.max_send_wr = sp->send_credit_target; | 1905 | qp_attr.cap = qp_cap; |
| 1869 | qp_attr.cap.max_recv_wr = sp->recv_credit_max; | ||
| 1870 | qp_attr.cap.max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; | ||
| 1871 | qp_attr.cap.max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; | ||
| 1872 | qp_attr.cap.max_inline_data = 0; | ||
| 1873 | qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 1906 | qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
| 1874 | qp_attr.qp_type = IB_QPT_RC; | 1907 | qp_attr.qp_type = IB_QPT_RC; |
| 1875 | qp_attr.send_cq = sc->ib.send_cq; | 1908 | qp_attr.send_cq = sc->ib.send_cq; |
| @@ -1883,12 +1916,6 @@ static struct smbd_connection *_smbd_get_connection( · 7 unmodified lines | |||
| 1883 | } | 1916 | } |
| 1884 | sc->ib.qp = sc->rdma.cm_id->qp; | 1917 | sc->ib.qp = sc->rdma.cm_id->qp; |
| 1885 | 1918 | ||
| 1886 | sp->responder_resources = | ||
| 1887 | min_t(u8, sp->responder_resources, | ||
| 1888 | sc->ib.dev->attrs.max_qp_rd_atom); | ||
| 1889 | log_rdma_mr(INFO, "responder_resources=%d\n", | ||
| 1890 | sp->responder_resources); | ||
| 1891 | |||
| 1892 | memset(&conn_param, 0, sizeof(conn_param)); | 1919 | memset(&conn_param, 0, sizeof(conn_param)); |
| 1893 | conn_param.initiator_depth = sp->initiator_depth; | 1920 | conn_param.initiator_depth = sp->initiator_depth; |
| 1894 | conn_param.responder_resources = sp->responder_resources; | 1921 | conn_param.responder_resources = sp->responder_resources; |
| @@ -4,5 +4,6 @@ · 3 unmodified lines | |||
| 4 | * | 4 | * |
| 5 | * Author(s): Steve French <stfrench@microsoft.com> | 5 | * Author(s): Steve French <stfrench@microsoft.com> |
| 6 | */ | 6 | */ |
| 7 | #include "cifsglob.h" | ||
| 7 | #define CREATE_TRACE_POINTS | 8 | #define CREATE_TRACE_POINTS |
| 8 | #include "trace.h" | 9 | #include "trace.h" |
| @@ -142,7 +142,15 @@ struct smbdirect_socket { · 141 unmodified lines | |||
| 142 | } mem; | 142 | } mem; |
| 143 | 143 | ||
| 144 | /* | 144 | /* |
| 145 | * The credit state for the send side | 145 | * The local credit state for ib_post_send() |
| 146 | */ | ||
| 147 | struct { | ||
| 148 | atomic_t count; | ||
| 149 | wait_queue_head_t wait_queue; | ||
| 150 | } lcredits; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * The remote credit state for the send side | ||
| 146 | */ | 154 | */ |
| 147 | struct { | 155 | struct { |
| 148 | atomic_t count; | 156 | atomic_t count; |
| @@ -337,6 +345,9 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc) · 188 unmodified lines | |||
| 337 | INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work); | 345 | INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work); |
| 338 | disable_delayed_work_sync(&sc->idle.timer_work); | 346 | disable_delayed_work_sync(&sc->idle.timer_work); |
| 339 | 347 | ||
| 348 | atomic_set(&sc->send_io.lcredits.count, 0); | ||
| 349 | init_waitqueue_head(&sc->send_io.lcredits.wait_queue); | ||
| 350 | |||
| 340 | atomic_set(&sc->send_io.credits.count, 0); | 351 | atomic_set(&sc->send_io.credits.count, 0); |
| 341 | init_waitqueue_head(&sc->send_io.credits.wait_queue); | 352 | init_waitqueue_head(&sc->send_io.credits.wait_queue); |
| 342 | 353 | ||
| @@ -219,6 +219,7 @@ static void smb_direct_disconnect_wake_up_all(struct smbdirect_socket *sc) · 218 unmodified lines | |||
| 219 | * in order to notice the broken connection. | 219 | * in order to notice the broken connection. |
| 220 | */ | 220 | */ |
| 221 | wake_up_all(&sc->status_wait); | 221 | wake_up_all(&sc->status_wait); |
| 222 | wake_up_all(&sc->send_io.lcredits.wait_queue); | ||
| 222 | wake_up_all(&sc->send_io.credits.wait_queue); | 223 | wake_up_all(&sc->send_io.credits.wait_queue); |
| 223 | wake_up_all(&sc->send_io.pending.zero_wait_queue); | 224 | wake_up_all(&sc->send_io.pending.zero_wait_queue); |
| 224 | wake_up_all(&sc->recv_io.reassembly.wait_queue); | 225 | wake_up_all(&sc->recv_io.reassembly.wait_queue); |
| @@ -450,11 +451,10 @@ static void free_transport(struct smb_direct_transport *t) · 225 unmodified lines | |||
| 450 | struct smbdirect_recv_io *recvmsg; | 451 | struct smbdirect_recv_io *recvmsg; |
| 451 | 452 | ||
| 452 | disable_work_sync(&sc->disconnect_work); | 453 | disable_work_sync(&sc->disconnect_work); |
| 453 | if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) { | 454 | if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING) |
| 454 | smb_direct_disconnect_rdma_work(&sc->disconnect_work); | 455 | smb_direct_disconnect_rdma_work(&sc->disconnect_work); |
| 455 | wait_event_interruptible(sc->status_wait, | 456 | if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) |
| 456 | sc->status == SMBDIRECT_SOCKET_DISCONNECTED); | 457 | wait_event(sc->status_wait, sc->status == SMBDIRECT_SOCKET_DISCONNECTED); |
| 457 | } | ||
| 458 | 458 | ||
| 459 | /* | 459 | /* |
| 460 | * Wake up all waiters in all wait queues | 460 | * Wake up all waiters in all wait queues |
| @@ -471,7 +471,6 @@ static void free_transport(struct smb_direct_transport *t) · 10 unmodified lines | |||
| 471 | 471 | ||
| 472 | if (sc->ib.qp) { | 472 | if (sc->ib.qp) { |
| 473 | ib_drain_qp(sc->ib.qp); | 473 | ib_drain_qp(sc->ib.qp); |
| 474 | ib_mr_pool_destroy(sc->ib.qp, &sc->ib.qp->rdma_mrs); | ||
| 475 | sc->ib.qp = NULL; | 474 | sc->ib.qp = NULL; |
| 476 | rdma_destroy_qp(sc->rdma.cm_id); | 475 | rdma_destroy_qp(sc->rdma.cm_id); |
| 477 | } | 476 | } |
| @@ -524,6 +523,12 @@ static void smb_direct_free_sendmsg(struct smbdirect_socket *sc, · 46 unmodified lines | |||
| 524 | { | 523 | { |
| 525 | int i; | 524 | int i; |
| 526 | 525 | ||
| 526 | /* | ||
| 527 | * The list needs to be empty! | ||
| 528 | * The caller should take care of it. | ||
| 529 | */ | ||
| 530 | WARN_ON_ONCE(!list_empty(&msg->sibling_list)); | ||
| 531 | |||
| 527 | if (msg->num_sge > 0) { | 532 | if (msg->num_sge > 0) { |
| 528 | ib_dma_unmap_single(sc->ib.dev, | 533 | ib_dma_unmap_single(sc->ib.dev, |
| 529 | msg->sge[0].addr, msg->sge[0].length, | 534 | msg->sge[0].addr, msg->sge[0].length, |
| @@ -909,9 +914,9 @@ static void smb_direct_post_recv_credits(struct work_struct *work) · 379 unmodified lines | |||
| 909 | 914 | ||
| 910 | static void send_done(struct ib_cq *cq, struct ib_wc *wc) | 915 | static void send_done(struct ib_cq *cq, struct ib_wc *wc) |
| 911 | { | 916 | { |
| 912 | struct smbdirect_send_io *sendmsg, *sibling; | 917 | struct smbdirect_send_io *sendmsg, *sibling, *next; |
| 913 | struct smbdirect_socket *sc; | 918 | struct smbdirect_socket *sc; |
| 914 | struct list_head *pos, *prev, *end; | 919 | int lcredits = 0; |
| 915 | 920 | ||
| 916 | sendmsg = container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); | 921 | sendmsg = container_of(wc->wr_cqe, struct smbdirect_send_io, cqe); |
| 917 | sc = sendmsg->socket; | 922 | sc = sendmsg->socket; |
| @@ -920,27 +925,31 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc) · 2 unmodified lines | |||
| 920 | ib_wc_status_msg(wc->status), wc->status, | 925 | ib_wc_status_msg(wc->status), wc->status, |
| 921 | wc->opcode); | 926 | wc->opcode); |
| 922 | 927 | ||
| 928 | /* | ||
| 929 | * Free possible siblings and then the main send_io | ||
| 930 | */ | ||
| 931 | list_for_each_entry_safe(sibling, next, &sendmsg->sibling_list, sibling_list) { | ||
| 932 | list_del_init(&sibling->sibling_list); | ||
| 933 | smb_direct_free_sendmsg(sc, sibling); | ||
| 934 | lcredits += 1; | ||
| 935 | } | ||
| 936 | /* Note this frees wc->wr_cqe, but not wc */ | ||
| 937 | smb_direct_free_sendmsg(sc, sendmsg); | ||
| 938 | lcredits += 1; | ||
| 939 | |||
| 923 | if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { | 940 | if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_SEND) { |
| 924 | pr_err("Send error. status='%s (%d)', opcode=%d\n", | 941 | pr_err("Send error. status='%s (%d)', opcode=%d\n", |
| 925 | ib_wc_status_msg(wc->status), wc->status, | 942 | ib_wc_status_msg(wc->status), wc->status, |
| 926 | wc->opcode); | 943 | wc->opcode); |
| 927 | smb_direct_disconnect_rdma_connection(sc); | 944 | smb_direct_disconnect_rdma_connection(sc); |
| 945 | return; | ||
| 928 | } | 946 | } |
| 929 | 947 | ||
| 948 | atomic_add(lcredits, &sc->send_io.lcredits.count); | ||
| 949 | wake_up(&sc->send_io.lcredits.wait_queue); | ||
| 950 | |||
| 930 | if (atomic_dec_and_test(&sc->send_io.pending.count)) | 951 | if (atomic_dec_and_test(&sc->send_io.pending.count)) |
| 931 | wake_up(&sc->send_io.pending.zero_wait_queue); | 952 | wake_up(&sc->send_io.pending.zero_wait_queue); |
| 932 | |||
| 933 | /* iterate and free the list of messages in reverse. the list's head | ||
| 934 | * is invalid. | ||
| 935 | */ | ||
| 936 | for (pos = &sendmsg->sibling_list, prev = pos->prev, end = sendmsg->sibling_list.next; | ||
| 937 | prev != end; pos = prev, prev = prev->prev) { | ||
| 938 | sibling = container_of(pos, struct smbdirect_send_io, sibling_list); | ||
| 939 | smb_direct_free_sendmsg(sc, sibling); | ||
| 940 | } | ||
| 941 | |||
| 942 | sibling = container_of(pos, struct smbdirect_send_io, sibling_list); | ||
| 943 | smb_direct_free_sendmsg(sc, sibling); | ||
| 944 | } | 953 | } |
| 945 | 954 | ||
| 946 | static int manage_credits_prior_sending(struct smbdirect_socket *sc) | 955 | static int manage_credits_prior_sending(struct smbdirect_socket *sc) |
| @@ -988,8 +997,6 @@ static int smb_direct_post_send(struct smbdirect_socket *sc, · 41 unmodified lines | |||
| 988 | ret = ib_post_send(sc->ib.qp, wr, NULL); | 997 | ret = ib_post_send(sc->ib.qp, wr, NULL); |
| 989 | if (ret) { | 998 | if (ret) { |
| 990 | pr_err("failed to post send: %d\n", ret); | 999 | pr_err("failed to post send: %d\n", ret); |
| 991 | if (atomic_dec_and_test(&sc->send_io.pending.count)) | ||
| 992 | wake_up(&sc->send_io.pending.zero_wait_queue); | ||
| 993 | smb_direct_disconnect_rdma_connection(sc); | 1000 | smb_direct_disconnect_rdma_connection(sc); |
| 994 | } | 1001 | } |
| 995 | return ret; | 1002 | return ret; |
| @@ -1032,19 +1039,29 @@ static int smb_direct_flush_send_list(struct smbdirect_socket *sc, · 36 unmodified lines | |||
| 1032 | last->wr.send_flags = IB_SEND_SIGNALED; | 1039 | last->wr.send_flags = IB_SEND_SIGNALED; |
| 1033 | last->wr.wr_cqe = &last->cqe; | 1040 | last->wr.wr_cqe = &last->cqe; |
| 1034 | 1041 | ||
| 1042 | /* | ||
| 1043 | * Remove last from send_ctx->msg_list | ||
| 1044 | * and splice the rest of send_ctx->msg_list | ||
| 1045 | * to last->sibling_list. | ||
| 1046 | * | ||
| 1047 | * send_ctx->msg_list is a valid empty list | ||
| 1048 | * at the end. | ||
| 1049 | */ | ||
| 1050 | list_del_init(&last->sibling_list); | ||
| 1051 | list_splice_tail_init(&send_ctx->msg_list, &last->sibling_list); | ||
| 1052 | send_ctx->wr_cnt = 0; | ||
| 1053 | |||
| 1035 | ret = smb_direct_post_send(sc, &first->wr); | 1054 | ret = smb_direct_post_send(sc, &first->wr); |
| 1036 | if (!ret) { | 1055 | if (ret) { |
| 1037 | smb_direct_send_ctx_init(send_ctx, | 1056 | struct smbdirect_send_io *sibling, *next; |
| 1038 | send_ctx->need_invalidate_rkey, | 1057 | |
| 1039 | send_ctx->remote_key); | 1058 | list_for_each_entry_safe(sibling, next, &last->sibling_list, sibling_list) { |
| 1040 | } else { | 1059 | list_del_init(&sibling->sibling_list); |
| 1041 | atomic_add(send_ctx->wr_cnt, &sc->send_io.credits.count); | 1060 | smb_direct_free_sendmsg(sc, sibling); |
| 1042 | wake_up(&sc->send_io.credits.wait_queue); | ||
| 1043 | list_for_each_entry_safe(first, last, &send_ctx->msg_list, | ||
| 1044 | sibling_list) { | ||
| 1045 | smb_direct_free_sendmsg(sc, first); | ||
| 1046 | } | 1061 | } |
| 1062 | smb_direct_free_sendmsg(sc, last); | ||
| 1047 | } | 1063 | } |
| 1064 | |||
| 1048 | return ret; | 1065 | return ret; |
| 1049 | } | 1066 | } |
| 1050 | 1067 | ||
| @@ -1070,6 +1087,23 @@ static int wait_for_credits(struct smbdirect_socket *sc, · 19 unmodified lines | |||
| 1070 | } while (true); | 1087 | } while (true); |
| 1071 | } | 1088 | } |
| 1072 | 1089 | ||
| 1090 | static int wait_for_send_lcredit(struct smbdirect_socket *sc, | ||
| 1091 | struct smbdirect_send_batch *send_ctx) | ||
| 1092 | { | ||
| 1093 | if (send_ctx && (atomic_read(&sc->send_io.lcredits.count) <= 1)) { | ||
| 1094 | int ret; | ||
| 1095 | |||
| 1096 | ret = smb_direct_flush_send_list(sc, send_ctx, false); | ||
| 1097 | if (ret) | ||
| 1098 | return ret; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | return wait_for_credits(sc, | ||
| 1102 | &sc->send_io.lcredits.wait_queue, | ||
| 1103 | &sc->send_io.lcredits.count, | ||
| 1104 | 1); | ||
| 1105 | } | ||
| 1106 | |||
| 1073 | static int wait_for_send_credits(struct smbdirect_socket *sc, | 1107 | static int wait_for_send_credits(struct smbdirect_socket *sc, |
| 1074 | struct smbdirect_send_batch *send_ctx) | 1108 | struct smbdirect_send_batch *send_ctx) |
| 1075 | { | 1109 | { |
| @@ -1257,9 +1291,13 @@ static int smb_direct_post_send_data(struct smbdirect_socket *sc, · 181 unmodified lines | |||
| 1257 | int data_length; | 1291 | int data_length; |
| 1258 | struct scatterlist sg[SMBDIRECT_SEND_IO_MAX_SGE - 1]; | 1292 | struct scatterlist sg[SMBDIRECT_SEND_IO_MAX_SGE - 1]; |
| 1259 | 1293 | ||
| 1294 | ret = wait_for_send_lcredit(sc, send_ctx); | ||
| 1295 | if (ret) | ||
| 1296 | goto lcredit_failed; | ||
| 1297 | |||
| 1260 | ret = wait_for_send_credits(sc, send_ctx); | 1298 | ret = wait_for_send_credits(sc, send_ctx); |
| 1261 | if (ret) | 1299 | if (ret) |
| 1262 | return ret; | 1300 | goto credit_failed; |
| 1263 | 1301 | ||
| 1264 | data_length = 0; | 1302 | data_length = 0; |
| 1265 | for (i = 0; i < niov; i++) | 1303 | for (i = 0; i < niov; i++) |
| @@ -1267,10 +1305,8 @@ static int smb_direct_post_send_data(struct smbdirect_socket *sc, · 1 unmodified line | |||
| 1267 | 1305 | ||
| 1268 | ret = smb_direct_create_header(sc, data_length, remaining_data_length, | 1306 | ret = smb_direct_create_header(sc, data_length, remaining_data_length, |
| 1269 | &msg); | 1307 | &msg); |
| 1270 | if (ret) { | 1308 | if (ret) |
| 1271 | atomic_inc(&sc->send_io.credits.count); | 1309 | goto header_failed; |
| 1272 | return ret; | ||
| 1273 | } | ||
| 1274 | 1310 | ||
| 1275 | for (i = 0; i < niov; i++) { | 1311 | for (i = 0; i < niov; i++) { |
| 1276 | struct ib_sge *sge; | 1312 | struct ib_sge *sge; |
| @@ -1308,7 +1344,11 @@ static int smb_direct_post_send_data(struct smbdirect_socket *sc, · 31 unmodified lines | |||
| 1308 | return 0; | 1344 | return 0; |
| 1309 | err: | 1345 | err: |
| 1310 | smb_direct_free_sendmsg(sc, msg); | 1346 | smb_direct_free_sendmsg(sc, msg); |
| 1347 | header_failed: | ||
| 1311 | atomic_inc(&sc->send_io.credits.count); | 1348 | atomic_inc(&sc->send_io.credits.count); |
| 1349 | credit_failed: | ||
| 1350 | atomic_inc(&sc->send_io.lcredits.count); | ||
| 1351 | lcredit_failed: | ||
| 1312 | return ret; | 1352 | return ret; |
| 1313 | } | 1353 | } |
| 1314 | 1354 | ||
| @@ -1871,20 +1911,11 @@ out_err: · 556 unmodified lines | |||
| 1871 | return ret; | 1911 | return ret; |
| 1872 | } | 1912 | } |
| 1873 | 1913 | ||
| 1874 | static unsigned int smb_direct_get_max_fr_pages(struct smbdirect_socket *sc) | 1914 | static int smb_direct_init_params(struct smbdirect_socket *sc) |
| 1875 | { | ||
| 1876 | return min_t(unsigned int, | ||
| 1877 | sc->ib.dev->attrs.max_fast_reg_page_list_len, | ||
| 1878 | 256); | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | static int smb_direct_init_params(struct smbdirect_socket *sc, | ||
| 1882 | struct ib_qp_cap *cap) | ||
| 1883 | { | 1915 | { |
| 1884 | struct smbdirect_socket_parameters *sp = &sc->parameters; | 1916 | struct smbdirect_socket_parameters *sp = &sc->parameters; |
| 1885 | struct ib_device *device = sc->ib.dev; | 1917 | int max_send_sges; |
| 1886 | int max_send_sges, max_rw_wrs, max_send_wrs; | 1918 | unsigned int maxpages; |
| 1887 | unsigned int max_sge_per_wr, wrs_per_credit; | ||
| 1888 | 1919 | ||
| 1889 | /* need 3 more sge. because a SMB_DIRECT header, SMB2 header, | 1920 | /* need 3 more sge. because a SMB_DIRECT header, SMB2 header, |
| 1890 | * SMB2 response could be mapped. | 1921 | * SMB2 response could be mapped. |
| @@ -1895,67 +1926,20 @@ static int smb_direct_init_params(struct smbdirect_socket *sc, · 4 unmodified lines | |||
| 1895 | return -EINVAL; | 1926 | return -EINVAL; |
| 1896 | } | 1927 | } |
| 1897 | 1928 | ||
| 1898 | /* Calculate the number of work requests for RDMA R/W. | 1929 | atomic_set(&sc->send_io.lcredits.count, sp->send_credit_target); |
| 1899 | * The maximum number of pages which can be registered | ||
| 1900 | * with one Memory region can be transferred with one | ||
| 1901 | * R/W credit. And at least 4 work requests for each credit | ||
| 1902 | * are needed for MR registration, RDMA R/W, local & remote | ||
| 1903 | * MR invalidation. | ||
| 1904 | */ | ||
| 1905 | sc->rw_io.credits.num_pages = smb_direct_get_max_fr_pages(sc); | ||
| 1906 | sc->rw_io.credits.max = DIV_ROUND_UP(sp->max_read_write_size, | ||
| 1907 | (sc->rw_io.credits.num_pages - 1) * | ||
| 1908 | PAGE_SIZE); | ||
| 1909 | |||
| 1910 | max_sge_per_wr = min_t(unsigned int, device->attrs.max_send_sge, | ||
| 1911 | device->attrs.max_sge_rd); | ||
| 1912 | max_sge_per_wr = max_t(unsigned int, max_sge_per_wr, | ||
| 1913 | max_send_sges); | ||
| 1914 | wrs_per_credit = max_t(unsigned int, 4, | ||
| 1915 | DIV_ROUND_UP(sc->rw_io.credits.num_pages, | ||
| 1916 | max_sge_per_wr) + 1); | ||
| 1917 | max_rw_wrs = sc->rw_io.credits.max * wrs_per_credit; | ||
| 1918 | |||
| 1919 | max_send_wrs = sp->send_credit_target + max_rw_wrs; | ||
| 1920 | if (max_send_wrs > device->attrs.max_cqe || | ||
| 1921 | max_send_wrs > device->attrs.max_qp_wr) { | ||
| 1922 | pr_err("consider lowering send_credit_target = %d\n", | ||
| 1923 | sp->send_credit_target); | ||
| 1924 | pr_err("Possible CQE overrun, device reporting max_cqe %d max_qp_wr %d\n", | ||
| 1925 | device->attrs.max_cqe, device->attrs.max_qp_wr); | ||
| 1926 | return -EINVAL; | ||
| 1927 | } | ||
| 1928 | 1930 | ||
| 1929 | if (sp->recv_credit_max > device->attrs.max_cqe || | 1931 | maxpages = DIV_ROUND_UP(sp->max_read_write_size, PAGE_SIZE); |
| 1930 | sp->recv_credit_max > device->attrs.max_qp_wr) { | 1932 | sc->rw_io.credits.max = rdma_rw_mr_factor(sc->ib.dev, |
| 1931 | pr_err("consider lowering receive_credit_max = %d\n", | 1933 | sc->rdma.cm_id->port_num, |
| 1932 | sp->recv_credit_max); | 1934 | maxpages); |
| 1933 | pr_err("Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n", | 1935 | sc->rw_io.credits.num_pages = DIV_ROUND_UP(maxpages, sc->rw_io.credits.max); |
| 1934 | device->attrs.max_cqe, device->attrs.max_qp_wr); | 1936 | /* add one extra in order to handle unaligned pages */ |
| 1935 | return -EINVAL; | 1937 | sc->rw_io.credits.max += 1; |
| 1936 | } | ||
| 1937 | |||
| 1938 | if (device->attrs.max_send_sge < SMBDIRECT_SEND_IO_MAX_SGE) { | ||
| 1939 | pr_err("warning: device max_send_sge = %d too small\n", | ||
| 1940 | device->attrs.max_send_sge); | ||
| 1941 | return -EINVAL; | ||
| 1942 | } | ||
| 1943 | if (device->attrs.max_recv_sge < SMBDIRECT_RECV_IO_MAX_SGE) { | ||
| 1944 | pr_err("warning: device max_recv_sge = %d too small\n", | ||
| 1945 | device->attrs.max_recv_sge); | ||
| 1946 | return -EINVAL; | ||
| 1947 | } | ||
| 1948 | 1938 | ||
| 1949 | sc->recv_io.credits.target = 1; | 1939 | sc->recv_io.credits.target = 1; |
| 1950 | 1940 | ||
| 1951 | atomic_set(&sc->rw_io.credits.count, sc->rw_io.credits.max); | 1941 | atomic_set(&sc->rw_io.credits.count, sc->rw_io.credits.max); |
| 1952 | 1942 | ||
| 1953 | cap->max_send_wr = max_send_wrs; | ||
| 1954 | cap->max_recv_wr = sp->recv_credit_max; | ||
| 1955 | cap->max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; | ||
| 1956 | cap->max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; | ||
| 1957 | cap->max_inline_data = 0; | ||
| 1958 | cap->max_rdma_ctxs = sc->rw_io.credits.max; | ||
| 1959 | return 0; | 1943 | return 0; |
| 1960 | } | 1944 | } |
| 1961 | 1945 | ||
| @@ -2029,13 +2013,129 @@ err: · 67 unmodified lines | |||
| 2029 | return -ENOMEM; | 2013 | return -ENOMEM; |
| 2030 | } | 2014 | } |
| 2031 | 2015 | ||
| 2032 | static int smb_direct_create_qpair(struct smbdirect_socket *sc, | 2016 | static u32 smb_direct_rdma_rw_send_wrs(struct ib_device *dev, const struct ib_qp_init_attr *attr) |
| 2033 | struct ib_qp_cap *cap) | 2017 | { |
| 2018 | /* | ||
| 2019 | * This could be split out of rdma_rw_init_qp() | ||
| 2020 | * and be a helper function next to rdma_rw_mr_factor() | ||
| 2021 | * | ||
| 2022 | * We can't check unlikely(rdma_rw_force_mr) here, | ||
| 2023 | * but that is most likely 0 anyway. | ||
| 2024 | */ | ||
| 2025 | u32 factor; | ||
| 2026 | |||
| 2027 | WARN_ON_ONCE(attr->port_num == 0); | ||
| 2028 | |||
| 2029 | /* | ||
| 2030 | * Each context needs at least one RDMA READ or WRITE WR. | ||
| 2031 | * | ||
| 2032 | * For some hardware we might need more, eventually we should ask the | ||
| 2033 | * HCA driver for a multiplier here. | ||
| 2034 | */ | ||
| 2035 | factor = 1; | ||
| 2036 | |||
| 2037 | /* | ||
| 2038 | * If the device needs MRs to perform RDMA READ or WRITE operations, | ||
| 2039 | * we'll need two additional MRs for the registrations and the | ||
| 2040 | * invalidation. | ||
| 2041 | */ | ||
| 2042 | if (rdma_protocol_iwarp(dev, attr->port_num) || dev->attrs.max_sgl_rd) | ||
| 2043 | factor += 2; /* inv + reg */ | ||
| 2044 | |||
| 2045 | return factor * attr->cap.max_rdma_ctxs; | ||
| 2046 | } | ||
| 2047 | |||
| 2048 | static int smb_direct_create_qpair(struct smbdirect_socket *sc) | ||
| 2034 | { | 2049 | { |
| 2035 | struct smbdirect_socket_parameters *sp = &sc->parameters; | 2050 | struct smbdirect_socket_parameters *sp = &sc->parameters; |
| 2036 | int ret; | 2051 | int ret; |
| 2052 | struct ib_qp_cap qp_cap; | ||
| 2037 | struct ib_qp_init_attr qp_attr; | 2053 | struct ib_qp_init_attr qp_attr; |
| 2038 | int pages_per_rw; | 2054 | u32 max_send_wr; |
| 2055 | u32 rdma_send_wr; | ||
| 2056 | |||
| 2057 | /* | ||
| 2058 | * Note that {rdma,ib}_create_qp() will call | ||
| 2059 | * rdma_rw_init_qp() if cap->max_rdma_ctxs is not 0. | ||
| 2060 | * It will adjust cap->max_send_wr to the required | ||
| 2061 | * number of additional WRs for the RDMA RW operations. | ||
| 2062 | * It will cap cap->max_send_wr to the device limit. | ||
| 2063 | * | ||
| 2064 | * +1 for ib_drain_qp | ||
| 2065 | */ | ||
| 2066 | qp_cap.max_send_wr = sp->send_credit_target + 1; | ||
| 2067 | qp_cap.max_recv_wr = sp->recv_credit_max + 1; | ||
| 2068 | qp_cap.max_send_sge = SMBDIRECT_SEND_IO_MAX_SGE; | ||
| 2069 | qp_cap.max_recv_sge = SMBDIRECT_RECV_IO_MAX_SGE; | ||
| 2070 | qp_cap.max_inline_data = 0; | ||
| 2071 | qp_cap.max_rdma_ctxs = sc->rw_io.credits.max; | ||
| 2072 | |||
| 2073 | /* | ||
| 2074 | * Find out the number of max_send_wr | ||
| 2075 | * after rdma_rw_init_qp() adjusted it. | ||
| 2076 | * | ||
| 2077 | * We only do it on a temporary variable, | ||
| 2078 | * as rdma_create_qp() will trigger | ||
| 2079 | * rdma_rw_init_qp() again. | ||
| 2080 | */ | ||
| 2081 | memset(&qp_attr, 0, sizeof(qp_attr)); | ||
| 2082 | qp_attr.cap = qp_cap; | ||
| 2083 | qp_attr.port_num = sc->rdma.cm_id->port_num; | ||
| 2084 | rdma_send_wr = smb_direct_rdma_rw_send_wrs(sc->ib.dev, &qp_attr); | ||
| 2085 | max_send_wr = qp_cap.max_send_wr + rdma_send_wr; | ||
| 2086 | |||
| 2087 | if (qp_cap.max_send_wr > sc->ib.dev->attrs.max_cqe || | ||
| 2088 | qp_cap.max_send_wr > sc->ib.dev->attrs.max_qp_wr) { | ||
| 2089 | pr_err("Possible CQE overrun: max_send_wr %d\n", | ||
| 2090 | qp_cap.max_send_wr); | ||
| 2091 | pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", | ||
| 2092 | IB_DEVICE_NAME_MAX, | ||
| 2093 | sc->ib.dev->name, | ||
| 2094 | sc->ib.dev->attrs.max_cqe, | ||
| 2095 | sc->ib.dev->attrs.max_qp_wr); | ||
| 2096 | pr_err("consider lowering send_credit_target = %d\n", | ||
| 2097 | sp->send_credit_target); | ||
| 2098 | return -EINVAL; | ||
| 2099 | } | ||
| 2100 | |||
| 2101 | if (qp_cap.max_rdma_ctxs && | ||
| 2102 | (max_send_wr >= sc->ib.dev->attrs.max_cqe || | ||
| 2103 | max_send_wr >= sc->ib.dev->attrs.max_qp_wr)) { | ||
| 2104 | pr_err("Possible CQE overrun: rdma_send_wr %d + max_send_wr %d = %d\n", | ||
| 2105 | rdma_send_wr, qp_cap.max_send_wr, max_send_wr); | ||
| 2106 | pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", | ||
| 2107 | IB_DEVICE_NAME_MAX, | ||
| 2108 | sc->ib.dev->name, | ||
| 2109 | sc->ib.dev->attrs.max_cqe, | ||
| 2110 | sc->ib.dev->attrs.max_qp_wr); | ||
| 2111 | pr_err("consider lowering send_credit_target = %d, max_rdma_ctxs = %d\n", | ||
| 2112 | sp->send_credit_target, qp_cap.max_rdma_ctxs); | ||
| 2113 | return -EINVAL; | ||
| 2114 | } | ||
| 2115 | |||
| 2116 | if (qp_cap.max_recv_wr > sc->ib.dev->attrs.max_cqe || | ||
| 2117 | qp_cap.max_recv_wr > sc->ib.dev->attrs.max_qp_wr) { | ||
| 2118 | pr_err("Possible CQE overrun: max_recv_wr %d\n", | ||
| 2119 | qp_cap.max_recv_wr); | ||
| 2120 | pr_err("device %.*s reporting max_cqe %d max_qp_wr %d\n", | ||
| 2121 | IB_DEVICE_NAME_MAX, | ||
| 2122 | sc->ib.dev->name, | ||
| 2123 | sc->ib.dev->attrs.max_cqe, | ||
| 2124 | sc->ib.dev->attrs.max_qp_wr); | ||
| 2125 | pr_err("consider lowering receive_credit_max = %d\n", | ||
| 2126 | sp->recv_credit_max); | ||
| 2127 | return -EINVAL; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | if (qp_cap.max_send_sge > sc->ib.dev->attrs.max_send_sge || | ||
| 2131 | qp_cap.max_recv_sge > sc->ib.dev->attrs.max_recv_sge) { | ||
| 2132 | pr_err("device %.*s max_send_sge/max_recv_sge = %d/%d too small\n", | ||
| 2133 | IB_DEVICE_NAME_MAX, | ||
| 2134 | sc->ib.dev->name, | ||
| 2135 | sc->ib.dev->attrs.max_send_sge, | ||
| 2136 | sc->ib.dev->attrs.max_recv_sge); | ||
| 2137 | return -EINVAL; | ||
| 2138 | } | ||
| 2039 | 2139 | ||
| 2040 | sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0); | 2140 | sc->ib.pd = ib_alloc_pd(sc->ib.dev, 0); |
| 2041 | if (IS_ERR(sc->ib.pd)) { | 2141 | if (IS_ERR(sc->ib.pd)) { |
| @@ -2046,8 +2146,7 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc, · 4 unmodified lines | |||
| 2046 | } | 2146 | } |
| 2047 | 2147 | ||
| 2048 | sc->ib.send_cq = ib_alloc_cq_any(sc->ib.dev, sc, | 2148 | sc->ib.send_cq = ib_alloc_cq_any(sc->ib.dev, sc, |
| 2049 | sp->send_credit_target + | 2149 | max_send_wr, |
| 2050 | cap->max_rdma_ctxs, | ||
| 2051 | IB_POLL_WORKQUEUE); | 2150 | IB_POLL_WORKQUEUE); |
| 2052 | if (IS_ERR(sc->ib.send_cq)) { | 2151 | if (IS_ERR(sc->ib.send_cq)) { |
| 2053 | pr_err("Can't create RDMA send CQ\n"); | 2152 | pr_err("Can't create RDMA send CQ\n"); |
| @@ -2057,7 +2156,7 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc, · 3 unmodified lines | |||
| 2057 | } | 2156 | } |
| 2058 | 2157 | ||
| 2059 | sc->ib.recv_cq = ib_alloc_cq_any(sc->ib.dev, sc, | 2158 | sc->ib.recv_cq = ib_alloc_cq_any(sc->ib.dev, sc, |
| 2060 | sp->recv_credit_max, | 2159 | qp_cap.max_recv_wr, |
| 2061 | IB_POLL_WORKQUEUE); | 2160 | IB_POLL_WORKQUEUE); |
| 2062 | if (IS_ERR(sc->ib.recv_cq)) { | 2161 | if (IS_ERR(sc->ib.recv_cq)) { |
| 2063 | pr_err("Can't create RDMA recv CQ\n"); | 2162 | pr_err("Can't create RDMA recv CQ\n"); |
| @@ -2066,10 +2165,18 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc, · 2 unmodified lines | |||
| 2066 | goto err; | 2165 | goto err; |
| 2067 | } | 2166 | } |
| 2068 | 2167 | ||
| 2168 | /* | ||
| 2169 | * We reset completely here! | ||
| 2170 | * As the above use was just temporary | ||
| 2171 | * to calc max_send_wr and rdma_send_wr. | ||
| 2172 | * | ||
| 2173 | * rdma_create_qp() will trigger rdma_rw_init_qp() | ||
| 2174 | * again if max_rdma_ctxs is not 0. | ||
| 2175 | */ | ||
| 2069 | memset(&qp_attr, 0, sizeof(qp_attr)); | 2176 | memset(&qp_attr, 0, sizeof(qp_attr)); |
| 2070 | qp_attr.event_handler = smb_direct_qpair_handler; | 2177 | qp_attr.event_handler = smb_direct_qpair_handler; |
| 2071 | qp_attr.qp_context = sc; | 2178 | qp_attr.qp_context = sc; |
| 2072 | qp_attr.cap = *cap; | 2179 | qp_attr.cap = qp_cap; |
| 2073 | qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 2180 | qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
| 2074 | qp_attr.qp_type = IB_QPT_RC; | 2181 | qp_attr.qp_type = IB_QPT_RC; |
| 2075 | qp_attr.send_cq = sc->ib.send_cq; | 2182 | qp_attr.send_cq = sc->ib.send_cq; |
| @@ -2085,18 +2192,6 @@ static int smb_direct_create_qpair(struct smbdirect_socket *sc, · 9 unmodified lines | |||
| 2085 | sc->ib.qp = sc->rdma.cm_id->qp; | 2192 | sc->ib.qp = sc->rdma.cm_id->qp; |
| 2086 | sc->rdma.cm_id->event_handler = smb_direct_cm_handler; | 2193 | sc->rdma.cm_id->event_handler = smb_direct_cm_handler; |
| 2087 | 2194 | ||
| 2088 | pages_per_rw = DIV_ROUND_UP(sp->max_read_write_size, PAGE_SIZE) + 1; | ||
| 2089 | if (pages_per_rw > sc->ib.dev->attrs.max_sgl_rd) { | ||
| 2090 | ret = ib_mr_pool_init(sc->ib.qp, &sc->ib.qp->rdma_mrs, | ||
| 2091 | sc->rw_io.credits.max, IB_MR_TYPE_MEM_REG, | ||
| 2092 | sc->rw_io.credits.num_pages, 0); | ||
| 2093 | if (ret) { | ||
| 2094 | pr_err("failed to init mr pool count %zu pages %zu\n", | ||
| 2095 | sc->rw_io.credits.max, sc->rw_io.credits.num_pages); | ||
| 2096 | goto err; | ||
| 2097 | } | ||
| 2098 | } | ||
| 2099 | |||
| 2100 | return 0; | 2195 | return 0; |
| 2101 | err: | 2196 | err: |
| 2102 | if (sc->ib.qp) { | 2197 | if (sc->ib.qp) { |
| @@ -2183,10 +2278,9 @@ out: · 80 unmodified lines | |||
| 2183 | 2278 | ||
| 2184 | static int smb_direct_connect(struct smbdirect_socket *sc) | 2279 | static int smb_direct_connect(struct smbdirect_socket *sc) |
| 2185 | { | 2280 | { |
| 2186 | struct ib_qp_cap qp_cap; | ||
| 2187 | int ret; | 2281 | int ret; |
| 2188 | 2282 | ||
| 2189 | ret = smb_direct_init_params(sc, &qp_cap); | 2283 | ret = smb_direct_init_params(sc); |
| 2190 | if (ret) { | 2284 | if (ret) { |
| 2191 | pr_err("Can't configure RDMA parameters\n"); | 2285 | pr_err("Can't configure RDMA parameters\n"); |
| 2192 | return ret; | 2286 | return ret; |
| @@ -2198,7 +2292,7 @@ static int smb_direct_connect(struct smbdirect_socket *sc) · 5 unmodified lines | |||
| 2198 | return ret; | 2292 | return ret; |
| 2199 | } | 2293 | } |
| 2200 | 2294 | ||
| 2201 | ret = smb_direct_create_qpair(sc, &qp_cap); | 2295 | ret = smb_direct_create_qpair(sc); |
| 2202 | if (ret) { | 2296 | if (ret) { |
| 2203 | pr_err("Can't accept RDMA client: %d\n", ret); | 2297 | pr_err("Can't accept RDMA client: %d\n", ret); |
| 2204 | return ret; | 2298 | return ret; |
| @@ -498,17 +498,26 @@ int compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj, · 497 unmodified lines | |||
| 498 | } | 498 | } |
| 499 | EXPORT_SYMBOL_GPL(compat_only_sysfs_link_entry_to_kobj); | 499 | EXPORT_SYMBOL_GPL(compat_only_sysfs_link_entry_to_kobj); |
| 500 | 500 | ||
| 501 | static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn, | 501 | static int sysfs_group_attrs_change_owner(struct kobject *kobj, |
| 502 | struct kernfs_node *grp_kn, | ||
| 502 | const struct attribute_group *grp, | 503 | const struct attribute_group *grp, |
| 503 | struct iattr *newattrs) | 504 | struct iattr *newattrs) |
| 504 | { | 505 | { |
| 505 | struct kernfs_node *kn; | 506 | struct kernfs_node *kn; |
| 506 | int error; | 507 | int error, i; |
| 508 | umode_t mode; | ||
| 507 | 509 | ||
| 508 | if (grp->attrs) { | 510 | if (grp->attrs) { |
| 509 | struct attribute *const *attr; | 511 | struct attribute *const *attr; |
| 510 | 512 | ||
| 511 | for (attr = grp->attrs; *attr; attr++) { | 513 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) { |
| 514 | if (grp->is_visible) { | ||
| 515 | mode = grp->is_visible(kobj, *attr, i); | ||
| 516 | if (mode & SYSFS_GROUP_INVISIBLE) | ||
| 517 | break; | ||
| 518 | if (!mode) | ||
| 519 | continue; | ||
| 520 | } | ||
| 512 | kn = kernfs_find_and_get(grp_kn, (*attr)->name); | 521 | kn = kernfs_find_and_get(grp_kn, (*attr)->name); |
| 513 | if (!kn) | 522 | if (!kn) |
| 514 | return -ENOENT; | 523 | return -ENOENT; |
| @@ -523,7 +532,14 @@ static int sysfs_group_attrs_change_owner(struct kernfs_node *grp_kn, · 8 unmodified lines | |||
| 523 | if (grp->bin_attrs) { | 532 | if (grp->bin_attrs) { |
| 524 | const struct bin_attribute *const *bin_attr; | 533 | const struct bin_attribute *const *bin_attr; |
| 525 | 534 | ||
| 526 | for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { | 535 | for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) { |
| 536 | if (grp->is_bin_visible) { | ||
| 537 | mode = grp->is_bin_visible(kobj, *bin_attr, i); | ||
| 538 | if (mode & SYSFS_GROUP_INVISIBLE) | ||
| 539 | break; | ||
| 540 | if (!mode) | ||
| 541 | continue; | ||
| 542 | } | ||
| 527 | kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name); | 543 | kn = kernfs_find_and_get(grp_kn, (*bin_attr)->attr.name); |
| 528 | if (!kn) | 544 | if (!kn) |
| 529 | return -ENOENT; | 545 | return -ENOENT; |
| @@ -573,7 +589,7 @@ int sysfs_group_change_owner(struct kobject *kobj, · 43 unmodified lines | |||
| 573 | 589 | ||
| 574 | error = kernfs_setattr(grp_kn, &newattrs); | 590 | error = kernfs_setattr(grp_kn, &newattrs); |
| 575 | if (!error) | 591 | if (!error) |
| 576 | error = sysfs_group_attrs_change_owner(grp_kn, grp, &newattrs); | 592 | error = sysfs_group_attrs_change_owner(kobj, grp_kn, grp, &newattrs); |
| 577 | 593 | ||
| 578 | kernfs_put(grp_kn); | 594 | kernfs_put(grp_kn); |
| 579 | 595 | ||
| @@ -119,6 +119,15 @@ config XFS_RT · 118 unmodified lines | |||
| 119 | 119 | ||
| 120 | See the xfs man page in section 5 for additional information. | 120 | See the xfs man page in section 5 for additional information. |
| 121 | 121 | ||
| 122 | This option is mandatory to support zoned block devices. For these | ||
| 123 | devices, the realtime subvolume must be backed by a zoned block | ||
| 124 | device and a regular block device used as the main device (for | ||
| 125 | metadata). If the zoned block device is a host-managed SMR hard-disk | ||
| 126 | containing conventional zones at the beginning of its address space, | ||
| 127 | XFS will use the disk conventional zones as the main device and the | ||
| 128 | remaining sequential write required zones as the backing storage for | ||
| 129 | the realtime subvolume. | ||
| 130 | |||
| 122 | If unsure, say N. | 131 | If unsure, say N. |
| 123 | 132 | ||
| 124 | config XFS_DRAIN_INTENTS | 133 | config XFS_DRAIN_INTENTS |
| @@ -156,7 +165,7 @@ config XFS_ONLINE_SCRUB_STATS · 31 unmodified lines | |||
| 156 | bool "XFS online metadata check usage data collection" | 165 | bool "XFS online metadata check usage data collection" |
| 157 | default y | 166 | default y |
| 158 | depends on XFS_ONLINE_SCRUB | 167 | depends on XFS_ONLINE_SCRUB |
| 159 | select DEBUG_FS | 168 | depends on DEBUG_FS |
| 160 | help | 169 | help |
| 161 | If you say Y here, the kernel will gather usage data about | 170 | If you say Y here, the kernel will gather usage data about |
| 162 | the online metadata check subsystem. This includes the number | 171 | the online metadata check subsystem. This includes the number |
| @@ -376,6 +376,36 @@ out_incomplete: · 375 unmodified lines | |||
| 376 | return error; | 376 | return error; |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | static uint | ||
| 380 | xchk_nlinks_ilock_dir( | ||
| 381 | struct xfs_inode *ip) | ||
| 382 | { | ||
| 383 | uint lock_mode = XFS_ILOCK_SHARED; | ||
| 384 | |||
| 385 | /* | ||
| 386 | * We're going to scan the directory entries, so we must be ready to | ||
| 387 | * pull the data fork mappings into memory if they aren't already. | ||
| 388 | */ | ||
| 389 | if (xfs_need_iread_extents(&ip->i_df)) | ||
| 390 | lock_mode = XFS_ILOCK_EXCL; | ||
| 391 | |||
| 392 | /* | ||
| 393 | * We're going to scan the parent pointers, so we must be ready to | ||
| 394 | * pull the attr fork mappings into memory if they aren't already. | ||
| 395 | */ | ||
| 396 | if (xfs_has_parent(ip->i_mount) && xfs_inode_has_attr_fork(ip) && | ||
| 397 | xfs_need_iread_extents(&ip->i_af)) | ||
| 398 | lock_mode = XFS_ILOCK_EXCL; | ||
| 399 | |||
| 400 | /* | ||
| 401 | * Take the IOLOCK so that other threads cannot start a directory | ||
| 402 | * update while we're scanning. | ||
| 403 | */ | ||
| 404 | lock_mode |= XFS_IOLOCK_SHARED; | ||
| 405 | xfs_ilock(ip, lock_mode); | ||
| 406 | return lock_mode; | ||
| 407 | } | ||
| 408 | |||
| 379 | /* Walk a directory to bump the observed link counts of the children. */ | 409 | /* Walk a directory to bump the observed link counts of the children. */ |
| 380 | STATIC int | 410 | STATIC int |
| 381 | xchk_nlinks_collect_dir( | 411 | xchk_nlinks_collect_dir( |
| @@ -394,8 +424,7 @@ xchk_nlinks_collect_dir( · 12 unmodified lines | |||
| 394 | return 0; | 424 | return 0; |
| 395 | 425 | ||
| 396 | /* Prevent anyone from changing this directory while we walk it. */ | 426 | /* Prevent anyone from changing this directory while we walk it. */ |
| 397 | xfs_ilock(dp, XFS_IOLOCK_SHARED); | 427 | lock_mode = xchk_nlinks_ilock_dir(dp); |
| 398 | lock_mode = xfs_ilock_data_map_shared(dp); | ||
| 399 | 428 | ||
| 400 | /* | 429 | /* |
| 401 | * The dotdot entry of an unlinked directory still points to the last | 430 | * The dotdot entry of an unlinked directory still points to the last |
| @@ -452,7 +481,6 @@ out_abort: · 50 unmodified lines | |||
| 452 | xchk_iscan_abort(&xnc->collect_iscan); | 481 | xchk_iscan_abort(&xnc->collect_iscan); |
| 453 | out_unlock: | 482 | out_unlock: |
| 454 | xfs_iunlock(dp, lock_mode); | 483 | xfs_iunlock(dp, lock_mode); |
| 455 | xfs_iunlock(dp, XFS_IOLOCK_SHARED); | ||
| 456 | return error; | 484 | return error; |
| 457 | } | 485 | } |
| 458 | 486 | ||
| @@ -1751,7 +1751,7 @@ xfs_init_buftarg( · 1750 unmodified lines | |||
| 1751 | const char *descr) | 1751 | const char *descr) |
| 1752 | { | 1752 | { |
| 1753 | /* The maximum size of the buftarg is only known once the sb is read. */ | 1753 | /* The maximum size of the buftarg is only known once the sb is read. */ |
| 1754 | btp->bt_nr_sectors = (xfs_daddr_t)-1; | 1754 | btp->bt_nr_sectors = XFS_BUF_DADDR_MAX; |
| 1755 | 1755 | ||
| 1756 | /* Set up device logical sector size mask */ | 1756 | /* Set up device logical sector size mask */ |
| 1757 | btp->bt_logical_sectorsize = logical_sectorsize; | 1757 | btp->bt_logical_sectorsize = logical_sectorsize; |
| @@ -22,6 +22,7 @@ extern struct kmem_cache *xfs_buf_cache; · 21 unmodified lines | |||
| 22 | */ | 22 | */ |
| 23 | struct xfs_buf; | 23 | struct xfs_buf; |
| 24 | 24 | ||
| 25 | #define XFS_BUF_DADDR_MAX ((xfs_daddr_t) S64_MAX) | ||
| 25 | #define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) | 26 | #define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) |
| 26 | 27 | ||
| 27 | #define XBF_READ (1u << 0) /* buffer intended for reading from device */ | 28 | #define XBF_READ (1u << 0) /* buffer intended for reading from device */ |
| @@ -236,7 +236,6 @@ typedef struct xfs_mount { · 235 unmodified lines | |||
| 236 | bool m_update_sb; /* sb needs update in mount */ | 236 | bool m_update_sb; /* sb needs update in mount */ |
| 237 | unsigned int m_max_open_zones; | 237 | unsigned int m_max_open_zones; |
| 238 | unsigned int m_zonegc_low_space; | 238 | unsigned int m_zonegc_low_space; |
| 239 | struct xfs_mru_cache *m_zone_cache; /* Inode to open zone cache */ | ||
| 240 | 239 | ||
| 241 | /* max_atomic_write mount option value */ | 240 | /* max_atomic_write mount option value */ |
| 242 | unsigned long long m_awu_max_bytes; | 241 | unsigned long long m_awu_max_bytes; |
| @@ -102,7 +102,7 @@ static const struct constant_table dax_param_enums[] = { · 101 unmodified lines | |||
| 102 | * Table driven mount option parser. | 102 | * Table driven mount option parser. |
| 103 | */ | 103 | */ |
| 104 | enum { | 104 | enum { |
| 105 | Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, | 105 | Op_deprecated, Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, |
| 106 | Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, | 106 | Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, |
| 107 | Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, | 107 | Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, |
| 108 | Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, | 108 | Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, |
| @@ -114,7 +114,21 @@ enum { · 5 unmodified lines | |||
| 114 | Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write, | 114 | Opt_lifetime, Opt_nolifetime, Opt_max_atomic_write, |
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | #define fsparam_dead(NAME) \ | ||
| 118 | __fsparam(NULL, (NAME), Op_deprecated, fs_param_deprecated, NULL) | ||
| 119 | |||
| 117 | static const struct fs_parameter_spec xfs_fs_parameters[] = { | 120 | static const struct fs_parameter_spec xfs_fs_parameters[] = { |
| 121 | /* | ||
| 122 | * These mount options were supposed to be deprecated in September 2025 | ||
| 123 | * but the deprecation warning was buggy, so not all users were | ||
| 124 | * notified. The deprecation is now obnoxiously loud and postponed to | ||
| 125 | * September 2030. | ||
| 126 | */ | ||
| 127 | fsparam_dead("attr2"), | ||
| 128 | fsparam_dead("noattr2"), | ||
| 129 | fsparam_dead("ikeep"), | ||
| 130 | fsparam_dead("noikeep"), | ||
| 131 | |||
| 118 | fsparam_u32("logbufs", Opt_logbufs), | 132 | fsparam_u32("logbufs", Opt_logbufs), |
| 119 | fsparam_string("logbsize", Opt_logbsize), | 133 | fsparam_string("logbsize", Opt_logbsize), |
| 120 | fsparam_string("logdev", Opt_logdev), | 134 | fsparam_string("logdev", Opt_logdev), |
| @@ -786,6 +800,12 @@ xfs_fs_evict_inode( · 665 unmodified lines | |||
| 786 | 800 | ||
| 787 | truncate_inode_pages_final(&inode->i_data); | 801 | truncate_inode_pages_final(&inode->i_data); |
| 788 | clear_inode(inode); | 802 | clear_inode(inode); |
| 803 | |||
| 804 | if (IS_ENABLED(CONFIG_XFS_RT) && | ||
| 805 | S_ISREG(inode->i_mode) && inode->i_private) { | ||
| 806 | xfs_open_zone_put(inode->i_private); | ||
| 807 | inode->i_private = NULL; | ||
| 808 | } | ||
| 789 | } | 809 | } |
| 790 | 810 | ||
| 791 | static void | 811 | static void |
| @@ -1373,16 +1393,25 @@ suffix_kstrtoull( · 581 unmodified lines | |||
| 1373 | static inline void | 1393 | static inline void |
| 1374 | xfs_fs_warn_deprecated( | 1394 | xfs_fs_warn_deprecated( |
| 1375 | struct fs_context *fc, | 1395 | struct fs_context *fc, |
| 1376 | struct fs_parameter *param, | 1396 | struct fs_parameter *param) |
| 1377 | uint64_t flag, | ||
| 1378 | bool value) | ||
| 1379 | { | 1397 | { |
| 1380 | /* Don't print the warning if reconfiguring and current mount point | 1398 | /* |
| 1381 | * already had the flag set | 1399 | * Always warn about someone passing in a deprecated mount option. |
| 1400 | * Previously we wouldn't print the warning if we were reconfiguring | ||
| 1401 | * and current mount point already had the flag set, but that was not | ||
| 1402 | * the right thing to do. | ||
| 1403 | * | ||
| 1404 | * Many distributions mount the root filesystem with no options in the | ||
| 1405 | * initramfs and rely on mount -a to remount the root fs with the | ||
| 1406 | * options in fstab. However, the old behavior meant that there would | ||
| 1407 | * never be a warning about deprecated mount options for the root fs in | ||
| 1408 | * /etc/fstab. On a single-fs system, that means no warning at all. | ||
| 1409 | * | ||
| 1410 | * Compounding this problem are distribution scripts that copy | ||
| 1411 | * /proc/mounts to fstab, which means that we can't remove mount | ||
| 1412 | * options unless we're 100% sure they have only ever been advertised | ||
| 1413 | * in /proc/mounts in response to explicitly provided mount options. | ||
| 1382 | */ | 1414 | */ |
| 1383 | if ((fc->purpose & FS_CONTEXT_FOR_RECONFIGURE) && | ||
| 1384 | !!(XFS_M(fc->root->d_sb)->m_features & flag) == value) | ||
| 1385 | return; | ||
| 1386 | xfs_warn(fc->s_fs_info, "%s mount option is deprecated.", param->key); | 1415 | xfs_warn(fc->s_fs_info, "%s mount option is deprecated.", param->key); |
| 1387 | } | 1416 | } |
| 1388 | 1417 | ||
| @@ -1408,6 +1437,9 @@ xfs_fs_parse_param( · 19 unmodified lines | |||
| 1408 | return opt; | 1437 | return opt; |
| 1409 | 1438 | ||
| 1410 | switch (opt) { | 1439 | switch (opt) { |
| 1440 | case Op_deprecated: | ||
| 1441 | xfs_fs_warn_deprecated(fc, param); | ||
| 1442 | return 0; | ||
| 1411 | case Opt_logbufs: | 1443 | case Opt_logbufs: |
| 1412 | parsing_mp->m_logbufs = result.uint_32; | 1444 | parsing_mp->m_logbufs = result.uint_32; |
| 1413 | return 0; | 1445 | return 0; |
| @@ -1528,7 +1560,6 @@ xfs_fs_parse_param( · 114 unmodified lines | |||
| 1528 | xfs_mount_set_dax_mode(parsing_mp, result.uint_32); | 1560 | xfs_mount_set_dax_mode(parsing_mp, result.uint_32); |
| 1529 | return 0; | 1561 | return 0; |
| 1530 | #endif | 1562 | #endif |
| 1531 | /* Following mount options will be removed in September 2025 */ | ||
| 1532 | case Opt_max_open_zones: | 1563 | case Opt_max_open_zones: |
| 1533 | parsing_mp->m_max_open_zones = result.uint_32; | 1564 | parsing_mp->m_max_open_zones = result.uint_32; |
| 1534 | return 0; | 1565 | return 0; |
| @@ -2221,7 +2252,7 @@ xfs_init_fs_context( · 686 unmodified lines | |||
| 2221 | struct xfs_mount *mp; | 2252 | struct xfs_mount *mp; |
| 2222 | int i; | 2253 | int i; |
| 2223 | 2254 | ||
| 2224 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL | __GFP_NOFAIL); | 2255 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
| 2225 | if (!mp) | 2256 | if (!mp) |
| 2226 | return -ENOMEM; | 2257 | return -ENOMEM; |
| 2227 | 2258 | ||
| @@ -26,14 +26,22 @@ · 25 unmodified lines | |||
| 26 | #include "xfs_trace.h" | 26 | #include "xfs_trace.h" |
| 27 | #include "xfs_mru_cache.h" | 27 | #include "xfs_mru_cache.h" |
| 28 | 28 | ||
| 29 | static void | ||
| 30 | xfs_open_zone_free_rcu( | ||
| 31 | struct callback_head *cb) | ||
| 32 | { | ||
| 33 | struct xfs_open_zone *oz = container_of(cb, typeof(*oz), oz_rcu); | ||
| 34 | |||
| 35 | xfs_rtgroup_rele(oz->oz_rtg); | ||
| 36 | kfree(oz); | ||
| 37 | } | ||
| 38 | |||
| 29 | void | 39 | void |
| 30 | xfs_open_zone_put( | 40 | xfs_open_zone_put( |
| 31 | struct xfs_open_zone *oz) | 41 | struct xfs_open_zone *oz) |
| 32 | { | 42 | { |
| 33 | if (atomic_dec_and_test(&oz->oz_ref)) { | 43 | if (atomic_dec_and_test(&oz->oz_ref)) |
| 34 | xfs_rtgroup_rele(oz->oz_rtg); | 44 | call_rcu(&oz->oz_rcu, xfs_open_zone_free_rcu); |
| 35 | kfree(oz); | ||
| 36 | } | ||
| 37 | } | 45 | } |
| 38 | 46 | ||
| 39 | static inline uint32_t | 47 | static inline uint32_t |
| @@ -614,14 +622,25 @@ static inline enum rw_hint xfs_inode_write_hint(struct xfs_inode *ip) · 574 unmodified lines | |||
| 614 | } | 622 | } |
| 615 | 623 | ||
| 616 | /* | 624 | /* |
| 617 | * Try to pack inodes that are written back after they were closed tight instead | 625 | * Try to tightly pack small files that are written back after they were closed |
| 618 | * of trying to open new zones for them or spread them to the least recently | 626 | * instead of trying to open new zones for them or spread them to the least |
| 619 | * used zone. This optimizes the data layout for workloads that untar or copy | 627 | * recently used zone. This optimizes the data layout for workloads that untar |
| 620 | * a lot of small files. Right now this does not separate multiple such | 628 | * or copy a lot of small files. Right now this does not separate multiple such |
| 621 | * streams. | 629 | * streams. |
| 622 | */ | 630 | */ |
| 623 | static inline bool xfs_zoned_pack_tight(struct xfs_inode *ip) | 631 | static inline bool xfs_zoned_pack_tight(struct xfs_inode *ip) |
| 624 | { | 632 | { |
| 633 | struct xfs_mount *mp = ip->i_mount; | ||
| 634 | size_t zone_capacity = | ||
| 635 | XFS_FSB_TO_B(mp, mp->m_groups[XG_TYPE_RTG].blocks); | ||
| 636 | |||
| 637 | /* | ||
| 638 | * Do not pack write files that are already using a full zone to avoid | ||
| 639 | * fragmentation. | ||
| 640 | */ | ||
| 641 | if (i_size_read(VFS_I(ip)) >= zone_capacity) | ||
| 642 | return false; | ||
| 643 | |||
| 625 | return !inode_is_open_for_write(VFS_I(ip)) && | 644 | return !inode_is_open_for_write(VFS_I(ip)) && |
| 626 | !(ip->i_diflags & XFS_DIFLAG_APPEND); | 645 | !(ip->i_diflags & XFS_DIFLAG_APPEND); |
| 627 | } | 646 | } |
| @@ -745,98 +764,55 @@ xfs_mark_rtg_boundary( · 117 unmodified lines | |||
| 745 | ioend->io_flags |= IOMAP_IOEND_BOUNDARY; | 764 | ioend->io_flags |= IOMAP_IOEND_BOUNDARY; |
| 746 | } | 765 | } |
| 747 | 766 | ||
| 748 | /* | ||
| 749 | * Cache the last zone written to for an inode so that it is considered first | ||
| 750 | * for subsequent writes. | ||
| 751 | */ | ||
| 752 | struct xfs_zone_cache_item { | ||
| 753 | struct xfs_mru_cache_elem mru; | ||
| 754 | struct xfs_open_zone *oz; | ||
| 755 | }; | ||
| 756 | |||
| 757 | static inline struct xfs_zone_cache_item * | ||
| 758 | xfs_zone_cache_item(struct xfs_mru_cache_elem *mru) | ||
| 759 | { | ||
| 760 | return container_of(mru, struct xfs_zone_cache_item, mru); | ||
| 761 | } | ||
| 762 | |||
| 763 | static void | ||
| 764 | xfs_zone_cache_free_func( | ||
| 765 | void *data, | ||
| 766 | struct xfs_mru_cache_elem *mru) | ||
| 767 | { | ||
| 768 | struct xfs_zone_cache_item *item = xfs_zone_cache_item(mru); | ||
| 769 | |||
| 770 | xfs_open_zone_put(item->oz); | ||
| 771 | kfree(item); | ||
| 772 | } | ||
| 773 | |||
| 774 | /* | 767 | /* |
| 775 | * Check if we have a cached last open zone available for the inode and | 768 | * Check if we have a cached last open zone available for the inode and |
| 776 | * if yes return a reference to it. | 769 | * if yes return a reference to it. |
| 777 | */ | 770 | */ |
| 778 | static struct xfs_open_zone * | 771 | static struct xfs_open_zone * |
| 779 | xfs_cached_zone( | 772 | xfs_get_cached_zone( |
| 780 | struct xfs_mount *mp, | 773 | struct xfs_inode *ip) |
| 781 | struct xfs_inode *ip) | ||
| 782 | { | 774 | { |
| 783 | struct xfs_mru_cache_elem *mru; | 775 | struct xfs_open_zone *oz; |
| 784 | struct xfs_open_zone *oz; | ||
| 785 | 776 | ||
| 786 | mru = xfs_mru_cache_lookup(mp->m_zone_cache, ip->i_ino); | 777 | rcu_read_lock(); |
| 787 | if (!mru) | 778 | oz = VFS_I(ip)->i_private; |
| 788 | return NULL; | ||
| 789 | oz = xfs_zone_cache_item(mru)->oz; | ||
| 790 | if (oz) { | 779 | if (oz) { |
| 791 | /* | 780 | /* |
| 792 | * GC only steals open zones at mount time, so no GC zones | 781 | * GC only steals open zones at mount time, so no GC zones |
| 793 | * should end up in the cache. | 782 | * should end up in the cache. |
| 794 | */ | 783 | */ |
| 795 | ASSERT(!oz->oz_is_gc); | 784 | ASSERT(!oz->oz_is_gc); |
| 796 | ASSERT(atomic_read(&oz->oz_ref) > 0); | 785 | if (!atomic_inc_not_zero(&oz->oz_ref)) |
| 797 | atomic_inc(&oz->oz_ref); | 786 | oz = NULL; |
| 798 | } | 787 | } |
| 799 | xfs_mru_cache_done(mp->m_zone_cache); | 788 | rcu_read_unlock(); |
| 789 | |||
| 800 | return oz; | 790 | return oz; |
| 801 | } | 791 | } |
| 802 | 792 | ||
| 803 | /* | 793 | /* |
| 804 | * Update the last used zone cache for a given inode. | 794 | * Stash our zone in the inode so that is is reused for future allocations. |
| 805 | * | 795 | * |
| 806 | * The caller must have a reference on the open zone. | 796 | * The open_zone structure will be pinned until either the inode is freed or |
| 797 | * until the cached open zone is replaced with a different one because the | ||
| 798 | * current one was full when we tried to use it. This means we keep any | ||
| 799 | * open zone around forever as long as any inode that used it for the last | ||
| 800 | * write is cached, which slightly increases the memory use of cached inodes | ||
| 801 | * that were every written to, but significantly simplifies the cached zone | ||
| 802 | * lookup. Because the open_zone is clearly marked as full when all data | ||
| 803 | * in the underlying RTG was written, the caching is always safe. | ||
| 807 | */ | 804 | */ |
| 808 | static void | 805 | static void |
| 809 | xfs_zone_cache_create_association( | 806 | xfs_set_cached_zone( |
| 810 | struct xfs_inode *ip, | 807 | struct xfs_inode *ip, |
| 811 | struct xfs_open_zone *oz) | 808 | struct xfs_open_zone *oz) |
| 812 | { | 809 | { |
| 813 | struct xfs_mount *mp = ip->i_mount; | 810 | struct xfs_open_zone *old_oz; |
| 814 | struct xfs_zone_cache_item *item = NULL; | ||
| 815 | struct xfs_mru_cache_elem *mru; | ||
| 816 | 811 | ||
| 817 | ASSERT(atomic_read(&oz->oz_ref) > 0); | ||
| 818 | atomic_inc(&oz->oz_ref); | 812 | atomic_inc(&oz->oz_ref); |
| 819 | 813 | old_oz = xchg(&VFS_I(ip)->i_private, oz); | |
| 820 | mru = xfs_mru_cache_lookup(mp->m_zone_cache, ip->i_ino); | 814 | if (old_oz) |
| 821 | if (mru) { | 815 | xfs_open_zone_put(old_oz); |
| 822 | /* | ||
| 823 | * If we have an association already, update it to point to the | ||
| 824 | * new zone. | ||
| 825 | */ | ||
| 826 | item = xfs_zone_cache_item(mru); | ||
| 827 | xfs_open_zone_put(item->oz); | ||
| 828 | item->oz = oz; | ||
| 829 | xfs_mru_cache_done(mp->m_zone_cache); | ||
| 830 | return; | ||
| 831 | } | ||
| 832 | |||
| 833 | item = kmalloc(sizeof(*item), GFP_KERNEL); | ||
| 834 | if (!item) { | ||
| 835 | xfs_open_zone_put(oz); | ||
| 836 | return; | ||
| 837 | } | ||
| 838 | item->oz = oz; | ||
| 839 | xfs_mru_cache_insert(mp->m_zone_cache, ip->i_ino, &item->mru); | ||
| 840 | } | 816 | } |
| 841 | 817 | ||
| 842 | static void | 818 | static void |
| @@ -880,15 +856,14 @@ xfs_zone_alloc_and_submit( · 37 unmodified lines | |||
| 880 | * the inode is still associated with a zone and use that if so. | 856 | * the inode is still associated with a zone and use that if so. |
| 881 | */ | 857 | */ |
| 882 | if (!*oz) | 858 | if (!*oz) |
| 883 | *oz = xfs_cached_zone(mp, ip); | 859 | *oz = xfs_get_cached_zone(ip); |
| 884 | 860 | ||
| 885 | if (!*oz) { | 861 | if (!*oz) { |
| 886 | select_zone: | 862 | select_zone: |
| 887 | *oz = xfs_select_zone(mp, write_hint, pack_tight); | 863 | *oz = xfs_select_zone(mp, write_hint, pack_tight); |
| 888 | if (!*oz) | 864 | if (!*oz) |
| 889 | goto out_error; | 865 | goto out_error; |
| 890 | 866 | xfs_set_cached_zone(ip, *oz); | |
| 891 | xfs_zone_cache_create_association(ip, *oz); | ||
| 892 | } | 867 | } |
| 893 | 868 | ||
| 894 | alloc_len = xfs_zone_alloc_blocks(*oz, XFS_B_TO_FSB(mp, ioend->io_size), | 869 | alloc_len = xfs_zone_alloc_blocks(*oz, XFS_B_TO_FSB(mp, ioend->io_size), |
| @@ -966,6 +941,12 @@ xfs_free_open_zones( · 71 unmodified lines | |||
| 966 | xfs_open_zone_put(oz); | 941 | xfs_open_zone_put(oz); |
| 967 | } | 942 | } |
| 968 | spin_unlock(&zi->zi_open_zones_lock); | 943 | spin_unlock(&zi->zi_open_zones_lock); |
| 944 | |||
| 945 | /* | ||
| 946 | * Wait for all open zones to be freed so that they drop the group | ||
| 947 | * references: | ||
| 948 | */ | ||
| 949 | rcu_barrier(); | ||
| 969 | } | 950 | } |
| 970 | 951 | ||
| 971 | struct xfs_init_zones { | 952 | struct xfs_init_zones { |
| @@ -1279,14 +1260,6 @@ xfs_mount_zones( · 307 unmodified lines | |||
| 1279 | error = xfs_zone_gc_mount(mp); | 1260 | error = xfs_zone_gc_mount(mp); |
| 1280 | if (error) | 1261 | if (error) |
| 1281 | goto out_free_zone_info; | 1262 | goto out_free_zone_info; |
| 1282 | |||
| 1283 | /* | ||
| 1284 | * Set up a mru cache to track inode to open zone for data placement | ||
| 1285 | * purposes. The magic values for group count and life time is the | ||
| 1286 | * same as the defaults for file streams, which seems sane enough. | ||
| 1287 | */ | ||
| 1288 | xfs_mru_cache_create(&mp->m_zone_cache, mp, | ||
| 1289 | 5000, 10, xfs_zone_cache_free_func); | ||
| 1290 | return 0; | 1263 | return 0; |
| 1291 | 1264 | ||
| 1292 | out_free_zone_info: | 1265 | out_free_zone_info: |
| @@ -1300,5 +1273,4 @@ xfs_unmount_zones( · 7 unmodified lines | |||
| 1300 | { | 1273 | { |
| 1301 | xfs_zone_gc_unmount(mp); | 1274 | xfs_zone_gc_unmount(mp); |
| 1302 | xfs_free_zone_info(mp->m_zone_info); | 1275 | xfs_free_zone_info(mp->m_zone_info); |
| 1303 | xfs_mru_cache_destroy(mp->m_zone_cache); | ||
| 1304 | } | 1276 | } |
| @@ -491,21 +491,6 @@ xfs_zone_gc_select_victim( · 490 unmodified lines | |||
| 491 | struct xfs_rtgroup *victim_rtg = NULL; | 491 | struct xfs_rtgroup *victim_rtg = NULL; |
| 492 | unsigned int bucket; | 492 | unsigned int bucket; |
| 493 | 493 | ||
| 494 | if (xfs_is_shutdown(mp)) | ||
| 495 | return false; | ||
| 496 | |||
| 497 | if (iter->victim_rtg) | ||
| 498 | return true; | ||
| 499 | |||
| 500 | /* | ||
| 501 | * Don't start new work if we are asked to stop or park. | ||
| 502 | */ | ||
| 503 | if (kthread_should_stop() || kthread_should_park()) | ||
| 504 | return false; | ||
| 505 | |||
| 506 | if (!xfs_zoned_need_gc(mp)) | ||
| 507 | return false; | ||
| 508 | |||
| 509 | spin_lock(&zi->zi_used_buckets_lock); | 494 | spin_lock(&zi->zi_used_buckets_lock); |
| 510 | for (bucket = 0; bucket < XFS_ZONE_USED_BUCKETS; bucket++) { | 495 | for (bucket = 0; bucket < XFS_ZONE_USED_BUCKETS; bucket++) { |
| 511 | victim_rtg = xfs_zone_gc_pick_victim_from(mp, bucket); | 496 | victim_rtg = xfs_zone_gc_pick_victim_from(mp, bucket); |
| @@ -975,6 +960,27 @@ xfs_zone_gc_reset_zones( · 463 unmodified lines | |||
| 975 | } while (next); | 960 | } while (next); |
| 976 | } | 961 | } |
| 977 | 962 | ||
| 963 | static bool | ||
| 964 | xfs_zone_gc_should_start_new_work( | ||
| 965 | struct xfs_zone_gc_data *data) | ||
| 966 | { | ||
| 967 | if (xfs_is_shutdown(data->mp)) | ||
| 968 | return false; | ||
| 969 | if (!xfs_zone_gc_space_available(data)) | ||
| 970 | return false; | ||
| 971 | |||
| 972 | if (!data->iter.victim_rtg) { | ||
| 973 | if (kthread_should_stop() || kthread_should_park()) | ||
| 974 | return false; | ||
| 975 | if (!xfs_zoned_need_gc(data->mp)) | ||
| 976 | return false; | ||
| 977 | if (!xfs_zone_gc_select_victim(data)) | ||
| 978 | return false; | ||
| 979 | } | ||
| 980 | |||
| 981 | return true; | ||
| 982 | } | ||
| 983 | |||
| 978 | /* | 984 | /* |
| 979 | * Handle the work to read and write data for GC and to reset the zones, | 985 | * Handle the work to read and write data for GC and to reset the zones, |
| 980 | * including handling all completions. | 986 | * including handling all completions. |
| @@ -982,7 +988,7 @@ xfs_zone_gc_reset_zones( · 1 unmodified line | |||
| 982 | * Note that the order of the chunks is preserved so that we don't undo the | 988 | * Note that the order of the chunks is preserved so that we don't undo the |
| 983 | * optimal order established by xfs_zone_gc_query(). | 989 | * optimal order established by xfs_zone_gc_query(). |
| 984 | */ | 990 | */ |
| 985 | static bool | 991 | static void |
| 986 | xfs_zone_gc_handle_work( | 992 | xfs_zone_gc_handle_work( |
| 987 | struct xfs_zone_gc_data *data) | 993 | struct xfs_zone_gc_data *data) |
| 988 | { | 994 | { |
| @@ -996,30 +1002,22 @@ xfs_zone_gc_handle_work( · 7 unmodified lines | |||
| 996 | zi->zi_reset_list = NULL; | 1002 | zi->zi_reset_list = NULL; |
| 997 | spin_unlock(&zi->zi_reset_list_lock); | 1003 | spin_unlock(&zi->zi_reset_list_lock); |
| 998 | 1004 | ||
| 999 | if (!xfs_zone_gc_select_victim(data) || | 1005 | if (reset_list) { |
| 1000 | !xfs_zone_gc_space_available(data)) { | 1006 | set_current_state(TASK_RUNNING); |
| 1001 | if (list_empty(&data->reading) && | ||
| 1002 | list_empty(&data->writing) && | ||
| 1003 | list_empty(&data->resetting) && | ||
| 1004 | !reset_list) | ||
| 1005 | return false; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | __set_current_state(TASK_RUNNING); | ||
| 1009 | try_to_freeze(); | ||
| 1010 | |||
| 1011 | if (reset_list) | ||
| 1012 | xfs_zone_gc_reset_zones(data, reset_list); | 1007 | xfs_zone_gc_reset_zones(data, reset_list); |
| 1008 | } | ||
| 1013 | 1009 | ||
| 1014 | list_for_each_entry_safe(chunk, next, &data->resetting, entry) { | 1010 | list_for_each_entry_safe(chunk, next, &data->resetting, entry) { |
| 1015 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) | 1011 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) |
| 1016 | break; | 1012 | break; |
| 1013 | set_current_state(TASK_RUNNING); | ||
| 1017 | xfs_zone_gc_finish_reset(chunk); | 1014 | xfs_zone_gc_finish_reset(chunk); |
| 1018 | } | 1015 | } |
| 1019 | 1016 | ||
| 1020 | list_for_each_entry_safe(chunk, next, &data->writing, entry) { | 1017 | list_for_each_entry_safe(chunk, next, &data->writing, entry) { |
| 1021 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) | 1018 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) |
| 1022 | break; | 1019 | break; |
| 1020 | set_current_state(TASK_RUNNING); | ||
| 1023 | xfs_zone_gc_finish_chunk(chunk); | 1021 | xfs_zone_gc_finish_chunk(chunk); |
| 1024 | } | 1022 | } |
| 1025 | 1023 | ||
| @@ -1027,15 +1025,18 @@ xfs_zone_gc_handle_work( · 1 unmodified line | |||
| 1027 | list_for_each_entry_safe(chunk, next, &data->reading, entry) { | 1025 | list_for_each_entry_safe(chunk, next, &data->reading, entry) { |
| 1028 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) | 1026 | if (READ_ONCE(chunk->state) != XFS_GC_BIO_DONE) |
| 1029 | break; | 1027 | break; |
| 1028 | set_current_state(TASK_RUNNING); | ||
| 1030 | xfs_zone_gc_write_chunk(chunk); | 1029 | xfs_zone_gc_write_chunk(chunk); |
| 1031 | } | 1030 | } |
| 1032 | blk_finish_plug(&plug); | 1031 | blk_finish_plug(&plug); |
| 1033 | 1032 | ||
| 1034 | blk_start_plug(&plug); | 1033 | if (xfs_zone_gc_should_start_new_work(data)) { |
| 1035 | while (xfs_zone_gc_start_chunk(data)) | 1034 | set_current_state(TASK_RUNNING); |
| 1036 | ; | 1035 | blk_start_plug(&plug); |
| 1037 | blk_finish_plug(&plug); | 1036 | while (xfs_zone_gc_start_chunk(data)) |
| 1038 | return true; | 1037 | ; |
| 1038 | blk_finish_plug(&plug); | ||
| 1039 | } | ||
| 1039 | } | 1040 | } |
| 1040 | 1041 | ||
| 1041 | /* | 1042 | /* |
| @@ -1059,8 +1060,18 @@ xfs_zoned_gcd( · 17 unmodified lines | |||
| 1059 | for (;;) { | 1060 | for (;;) { |
| 1060 | set_current_state(TASK_INTERRUPTIBLE | TASK_FREEZABLE); | 1061 | set_current_state(TASK_INTERRUPTIBLE | TASK_FREEZABLE); |
| 1061 | xfs_set_zonegc_running(mp); | 1062 | xfs_set_zonegc_running(mp); |
| 1062 | if (xfs_zone_gc_handle_work(data)) | 1063 | |
| 1064 | xfs_zone_gc_handle_work(data); | ||
| 1065 | |||
| 1066 | /* | ||
| 1067 | * Only sleep if nothing set the state to running. Else check for | ||
| 1068 | * work again as someone might have queued up more work and woken | ||
| 1069 | * us in the meantime. | ||
| 1070 | */ | ||
| 1071 | if (get_current_state() == TASK_RUNNING) { | ||
| 1072 | try_to_freeze(); | ||
| 1063 | continue; | 1073 | continue; |
| 1074 | } | ||
| 1064 | 1075 | ||
| 1065 | if (list_empty(&data->reading) && | 1076 | if (list_empty(&data->reading) && |
| 1066 | list_empty(&data->writing) && | 1077 | list_empty(&data->writing) && |
| @@ -44,6 +44,8 @@ struct xfs_open_zone { · 43 unmodified lines | |||
| 44 | * the life time of an open zone. | 44 | * the life time of an open zone. |
| 45 | */ | 45 | */ |
| 46 | struct xfs_rtgroup *oz_rtg; | 46 | struct xfs_rtgroup *oz_rtg; |
| 47 | |||
| 48 | struct rcu_head oz_rcu; | ||
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | /* | 51 | /* |
| @@ -338,6 +338,7 @@ struct ffa_mem_region_attributes { · 337 unmodified lines | |||
| 338 | * an `struct ffa_mem_region_addr_range`. | 338 | * an `struct ffa_mem_region_addr_range`. |
| 339 | */ | 339 | */ |
| 340 | u32 composite_off; | 340 | u32 composite_off; |
| 341 | u8 impdef_val[16]; | ||
| 341 | u64 reserved; | 342 | u64 reserved; |
| 342 | }; | 343 | }; |
| 343 | 344 | ||
| @@ -417,15 +418,31 @@ struct ffa_mem_region { · 73 unmodified lines | |||
| 417 | #define CONSTITUENTS_OFFSET(x) \ | 418 | #define CONSTITUENTS_OFFSET(x) \ |
| 418 | (offsetof(struct ffa_composite_mem_region, constituents[x])) | 419 | (offsetof(struct ffa_composite_mem_region, constituents[x])) |
| 419 | 420 | ||
| 421 | #define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2) | ||
| 422 | #define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0) | ||
| 423 | |||
| 424 | static inline u32 ffa_emad_size_get(u32 ffa_version) | ||
| 425 | { | ||
| 426 | u32 sz; | ||
| 427 | struct ffa_mem_region_attributes *ep_mem_access; | ||
| 428 | |||
| 429 | if (FFA_EMAD_HAS_IMPDEF_FIELD(ffa_version)) | ||
| 430 | sz = sizeof(*ep_mem_access); | ||
| 431 | else | ||
| 432 | sz = sizeof(*ep_mem_access) - sizeof(ep_mem_access->impdef_val); | ||
| 433 | |||
| 434 | return sz; | ||
| 435 | } | ||
| 436 | |||
| 420 | static inline u32 | 437 | static inline u32 |
| 421 | ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version) | 438 | ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version) |
| 422 | { | 439 | { |
| 423 | u32 offset = count * sizeof(struct ffa_mem_region_attributes); | 440 | u32 offset = count * ffa_emad_size_get(ffa_version); |
| 424 | /* | 441 | /* |
| 425 | * Earlier to v1.1, the endpoint memory descriptor array started at | 442 | * Earlier to v1.1, the endpoint memory descriptor array started at |
| 426 | * offset 32(i.e. offset of ep_mem_offset in the current structure) | 443 | * offset 32(i.e. offset of ep_mem_offset in the current structure) |
| 427 | */ | 444 | */ |
| 428 | if (ffa_version <= FFA_VERSION_1_0) | 445 | if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version)) |
| 429 | offset += offsetof(struct ffa_mem_region, ep_mem_offset); | 446 | offset += offsetof(struct ffa_mem_region, ep_mem_offset); |
| 430 | else | 447 | else |
| 431 | offset += sizeof(struct ffa_mem_region); | 448 | offset += sizeof(struct ffa_mem_region); |
| @@ -452,7 +452,7 @@ struct cgroup_freezer_state { · 451 unmodified lines | |||
| 452 | int nr_frozen_tasks; | 452 | int nr_frozen_tasks; |
| 453 | 453 | ||
| 454 | /* Freeze time data consistency protection */ | 454 | /* Freeze time data consistency protection */ |
| 455 | seqcount_t freeze_seq; | 455 | seqcount_spinlock_t freeze_seq; |
| 456 | 456 | ||
| 457 | /* | 457 | /* |
| 458 | * Most recent time the cgroup was requested to freeze. | 458 | * Most recent time the cgroup was requested to freeze. |
| @@ -320,9 +320,6 @@ static inline bool exportfs_can_decode_fh(const struct export_operations *nop) · 319 unmodified lines | |||
| 320 | static inline bool exportfs_can_encode_fh(const struct export_operations *nop, | 320 | static inline bool exportfs_can_encode_fh(const struct export_operations *nop, |
| 321 | int fh_flags) | 321 | int fh_flags) |
| 322 | { | 322 | { |
| 323 | if (!nop) | ||
| 324 | return false; | ||
| 325 | |||
| 326 | /* | 323 | /* |
| 327 | * If a non-decodeable file handle was requested, we only need to make | 324 | * If a non-decodeable file handle was requested, we only need to make |
| 328 | * sure that filesystem did not opt-out of encoding fid. | 325 | * sure that filesystem did not opt-out of encoding fid. |
| @@ -330,6 +327,10 @@ static inline bool exportfs_can_encode_fh(const struct export_operations *nop, · 1 unmodified line | |||
| 330 | if (fh_flags & EXPORT_FH_FID) | 327 | if (fh_flags & EXPORT_FH_FID) |
| 331 | return exportfs_can_encode_fid(nop); | 328 | return exportfs_can_encode_fid(nop); |
| 332 | 329 | ||
| 330 | /* Normal file handles cannot be created without export ops */ | ||
| 331 | if (!nop) | ||
| 332 | return false; | ||
| 333 | |||
| 333 | /* | 334 | /* |
| 334 | * If a connectable file handle was requested, we need to make sure that | 335 | * If a connectable file handle was requested, we need to make sure that |
| 335 | * filesystem can also decode connected file handles. | 336 | * filesystem can also decode connected file handles. |
| @@ -38,6 +38,10 @@ struct regmap; · 37 unmodified lines | |||
| 38 | * offset to a register/bitmask pair. If not | 38 | * offset to a register/bitmask pair. If not |
| 39 | * given the default gpio_regmap_simple_xlate() | 39 | * given the default gpio_regmap_simple_xlate() |
| 40 | * is used. | 40 | * is used. |
| 41 | * @fixed_direction_output: | ||
| 42 | * (Optional) Bitmap representing the fixed direction of | ||
| 43 | * the GPIO lines. Useful when there are GPIO lines with a | ||
| 44 | * fixed direction mixed together in the same register. | ||
| 41 | * @drvdata: (Optional) Pointer to driver specific data which is | 45 | * @drvdata: (Optional) Pointer to driver specific data which is |
| 42 | * not used by gpio-remap but is provided "as is" to the | 46 | * not used by gpio-remap but is provided "as is" to the |
| 43 | * driver callback(s). | 47 | * driver callback(s). |
| @@ -85,6 +89,7 @@ struct gpio_regmap_config { · 41 unmodified lines | |||
| 85 | int reg_stride; | 89 | int reg_stride; |
| 86 | int ngpio_per_reg; | 90 | int ngpio_per_reg; |
| 87 | struct irq_domain *irq_domain; | 91 | struct irq_domain *irq_domain; |
| 92 | unsigned long *fixed_direction_output; | ||
| 88 | 93 | ||
| 89 | #ifdef CONFIG_REGMAP_IRQ | 94 | #ifdef CONFIG_REGMAP_IRQ |
| 90 | struct regmap_irq_chip *regmap_irq_chip; | 95 | struct regmap_irq_chip *regmap_irq_chip; |
| @@ -20,6 +20,10 @@ · 19 unmodified lines | |||
| 20 | * always zero. So we can use these bits to encode the specific blocking | 20 | * always zero. So we can use these bits to encode the specific blocking |
| 21 | * type. | 21 | * type. |
| 22 | * | 22 | * |
| 23 | * Note that on architectures where this is not guaranteed, or for any | ||
| 24 | * unaligned lock, this tracking mechanism is silently skipped for that | ||
| 25 | * lock. | ||
| 26 | * | ||
| 23 | * Type encoding: | 27 | * Type encoding: |
| 24 | * 00 - Blocked on mutex (BLOCKER_TYPE_MUTEX) | 28 | * 00 - Blocked on mutex (BLOCKER_TYPE_MUTEX) |
| 25 | * 01 - Blocked on semaphore (BLOCKER_TYPE_SEM) | 29 | * 01 - Blocked on semaphore (BLOCKER_TYPE_SEM) |
| @@ -45,7 +49,7 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type) · 19 unmodified lines | |||
| 45 | * If the lock pointer matches the BLOCKER_TYPE_MASK, return | 49 | * If the lock pointer matches the BLOCKER_TYPE_MASK, return |
| 46 | * without writing anything. | 50 | * without writing anything. |
| 47 | */ | 51 | */ |
| 48 | if (WARN_ON_ONCE(lock_ptr & BLOCKER_TYPE_MASK)) | 52 | if (lock_ptr & BLOCKER_TYPE_MASK) |
| 49 | return; | 53 | return; |
| 50 | 54 | ||
| 51 | WRITE_ONCE(current->blocker, lock_ptr | type); | 55 | WRITE_ONCE(current->blocker, lock_ptr | type); |
| @@ -53,8 +57,6 @@ static inline void hung_task_set_blocker(void *lock, unsigned long type) · 1 unmodified line | |||
| 53 | 57 | ||
| 54 | static inline void hung_task_clear_blocker(void) | 58 | static inline void hung_task_clear_blocker(void) |
| 55 | { | 59 | { |
| 56 | WARN_ON_ONCE(!READ_ONCE(current->blocker)); | ||
| 57 | |||
| 58 | WRITE_ONCE(current->blocker, 0UL); | 60 | WRITE_ONCE(current->blocker, 0UL); |
| 59 | } | 61 | } |
| 60 | 62 | ||
| @@ -19,7 +19,7 @@ enum misc_res_type { · 18 unmodified lines | |||
| 19 | MISC_CG_RES_SEV_ES, | 19 | MISC_CG_RES_SEV_ES, |
| 20 | #endif | 20 | #endif |
| 21 | #ifdef CONFIG_INTEL_TDX_HOST | 21 | #ifdef CONFIG_INTEL_TDX_HOST |
| 22 | /* Intel TDX HKIDs resource */ | 22 | /** @MISC_CG_RES_TDX: Intel TDX HKIDs resource */ |
| 23 | MISC_CG_RES_TDX, | 23 | MISC_CG_RES_TDX, |
| 24 | #endif | 24 | #endif |
| 25 | /** @MISC_CG_RES_TYPES: count of enum misc_res_type constants */ | 25 | /** @MISC_CG_RES_TYPES: count of enum misc_res_type constants */ |
| @@ -10833,7 +10833,9 @@ struct mlx5_ifc_pcam_regs_5000_to_507f_bits { · 10832 unmodified lines | |||
| 10833 | u8 port_access_reg_cap_mask_127_to_96[0x20]; | 10833 | u8 port_access_reg_cap_mask_127_to_96[0x20]; |
| 10834 | u8 port_access_reg_cap_mask_95_to_64[0x20]; | 10834 | u8 port_access_reg_cap_mask_95_to_64[0x20]; |
| 10835 | 10835 | ||
| 10836 | u8 port_access_reg_cap_mask_63_to_36[0x1c]; | 10836 | u8 port_access_reg_cap_mask_63[0x1]; |
| 10837 | u8 pphcr[0x1]; | ||
| 10838 | u8 port_access_reg_cap_mask_61_to_36[0x1a]; | ||
| 10837 | u8 pplm[0x1]; | 10839 | u8 pplm[0x1]; |
| 10838 | u8 port_access_reg_cap_mask_34_to_32[0x3]; | 10840 | u8 port_access_reg_cap_mask_34_to_32[0x3]; |
| 10839 | 10841 | ||
| @@ -629,13 +629,13 @@ DEFINE_GUARD(pm_runtime_active_auto, struct device *, · 628 unmodified lines | |||
| 629 | * device. | 629 | * device. |
| 630 | */ | 630 | */ |
| 631 | DEFINE_GUARD_COND(pm_runtime_active, _try, | 631 | DEFINE_GUARD_COND(pm_runtime_active, _try, |
| 632 | pm_runtime_get_active(_T, RPM_TRANSPARENT)) | 632 | pm_runtime_get_active(_T, RPM_TRANSPARENT), _RET == 0) |
| 633 | DEFINE_GUARD_COND(pm_runtime_active, _try_enabled, | 633 | DEFINE_GUARD_COND(pm_runtime_active, _try_enabled, |
| 634 | pm_runtime_resume_and_get(_T)) | 634 | pm_runtime_resume_and_get(_T), _RET == 0) |
| 635 | DEFINE_GUARD_COND(pm_runtime_active_auto, _try, | 635 | DEFINE_GUARD_COND(pm_runtime_active_auto, _try, |
| 636 | pm_runtime_get_active(_T, RPM_TRANSPARENT)) | 636 | pm_runtime_get_active(_T, RPM_TRANSPARENT), _RET == 0) |
| 637 | DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled, | 637 | DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enabled, |
| 638 | pm_runtime_resume_and_get(_T)) | 638 | pm_runtime_resume_and_get(_T), _RET == 0) |
| 639 | 639 | ||
| 640 | /** | 640 | /** |
| 641 | * pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0. | 641 | * pm_runtime_put_sync - Drop device usage counter and run "idle check" if 0. |
| @@ -4204,6 +4204,9 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, · 4203 unmodified lines | |||
| 4204 | struct sk_buff_head *sk_queue, | 4204 | struct sk_buff_head *sk_queue, |
| 4205 | unsigned int flags, int *off, int *err); | 4205 | unsigned int flags, int *off, int *err); |
| 4206 | struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, int *err); | 4206 | struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned int flags, int *err); |
| 4207 | __poll_t datagram_poll_queue(struct file *file, struct socket *sock, | ||
| 4208 | struct poll_table_struct *wait, | ||
| 4209 | struct sk_buff_head *rcv_queue); | ||
| 4207 | __poll_t datagram_poll(struct file *file, struct socket *sock, | 4210 | __poll_t datagram_poll(struct file *file, struct socket *sock, |
| 4208 | struct poll_table_struct *wait); | 4211 | struct poll_table_struct *wait); |
| 4209 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, | 4212 | int skb_copy_datagram_iter(const struct sk_buff *from, int offset, |
| @@ -401,6 +401,10 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb, · 400 unmodified lines | |||
| 401 | if (!tnl_hdr_negotiated) | 401 | if (!tnl_hdr_negotiated) |
| 402 | return -EINVAL; | 402 | return -EINVAL; |
| 403 | 403 | ||
| 404 | vhdr->hash_hdr.hash_value = 0; | ||
| 405 | vhdr->hash_hdr.hash_report = 0; | ||
| 406 | vhdr->hash_hdr.padding = 0; | ||
| 407 | |||
| 404 | /* Let the basic parsing deal with plain GSO features. */ | 408 | /* Let the basic parsing deal with plain GSO features. */ |
| 405 | skb_shinfo(skb)->gso_type &= ~tnl_gso_type; | 409 | skb_shinfo(skb)->gso_type &= ~tnl_gso_type; |
| 406 | ret = virtio_net_hdr_from_skb(skb, hdr, true, false, vlan_hlen); | 410 | ret = virtio_net_hdr_from_skb(skb, hdr, true, false, vlan_hlen); |
| @@ -1013,6 +1013,20 @@ struct drm_xe_vm_destroy { · 1012 unmodified lines | |||
| 1013 | * valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address | 1013 | * valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address |
| 1014 | * mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO | 1014 | * mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO |
| 1015 | * handle MBZ, and the BO offset MBZ. | 1015 | * handle MBZ, and the BO offset MBZ. |
| 1016 | * - %DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET - Can be used in combination with | ||
| 1017 | * %DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR to reset madvises when the underlying | ||
| 1018 | * CPU address space range is unmapped (typically with munmap(2) or brk(2)). | ||
| 1019 | * The madvise values set with &DRM_IOCTL_XE_MADVISE are reset to the values | ||
| 1020 | * that were present immediately after the &DRM_IOCTL_XE_VM_BIND. | ||
| 1021 | * The reset GPU virtual address range is the intersection of the range bound | ||
| 1022 | * using &DRM_IOCTL_XE_VM_BIND and the virtual CPU address space range | ||
| 1023 | * unmapped. | ||
| 1024 | * This functionality is present to mimic the behaviour of CPU address space | ||
| 1025 | * madvises set using madvise(2), which are typically reset on unmap. | ||
| 1026 | * Note: free(3) may or may not call munmap(2) and/or brk(2), and may thus | ||
| 1027 | * not invoke autoreset. Neither will stack variables going out of scope. | ||
| 1028 | * Therefore it's recommended to always explicitly reset the madvises when | ||
| 1029 | * freeing the memory backing a region used in a &DRM_IOCTL_XE_MADVISE call. | ||
| 1016 | * | 1030 | * |
| 1017 | * The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be: | 1031 | * The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be: |
| 1018 | * - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in | 1032 | * - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in |
| @@ -1119,6 +1133,7 @@ struct drm_xe_vm_bind_op { · 100 unmodified lines | |||
| 1119 | #define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3) | 1133 | #define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3) |
| 1120 | #define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4) | 1134 | #define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4) |
| 1121 | #define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5) | 1135 | #define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5) |
| 1136 | #define DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET (1 << 6) | ||
| 1122 | /** @flags: Bind flags */ | 1137 | /** @flags: Bind flags */ |
| 1123 | __u32 flags; | 1138 | __u32 flags; |
| 1124 | 1139 | ||
| @@ -59,7 +59,6 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) · 58 unmodified lines | |||
| 59 | { | 59 | { |
| 60 | struct io_overflow_cqe *ocqe; | 60 | struct io_overflow_cqe *ocqe; |
| 61 | struct io_rings *r = ctx->rings; | 61 | struct io_rings *r = ctx->rings; |
| 62 | struct rusage sq_usage; | ||
| 63 | unsigned int sq_mask = ctx->sq_entries - 1, cq_mask = ctx->cq_entries - 1; | 62 | unsigned int sq_mask = ctx->sq_entries - 1, cq_mask = ctx->cq_entries - 1; |
| 64 | unsigned int sq_head = READ_ONCE(r->sq.head); | 63 | unsigned int sq_head = READ_ONCE(r->sq.head); |
| 65 | unsigned int sq_tail = READ_ONCE(r->sq.tail); | 64 | unsigned int sq_tail = READ_ONCE(r->sq.tail); |
| @@ -152,14 +151,15 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m) · 86 unmodified lines | |||
| 152 | * thread termination. | 151 | * thread termination. |
| 153 | */ | 152 | */ |
| 154 | if (tsk) { | 153 | if (tsk) { |
| 154 | u64 usec; | ||
| 155 | |||
| 155 | get_task_struct(tsk); | 156 | get_task_struct(tsk); |
| 156 | rcu_read_unlock(); | 157 | rcu_read_unlock(); |
| 157 | getrusage(tsk, RUSAGE_SELF, &sq_usage); | 158 | usec = io_sq_cpu_usec(tsk); |
| 158 | put_task_struct(tsk); | 159 | put_task_struct(tsk); |
| 159 | sq_pid = sq->task_pid; | 160 | sq_pid = sq->task_pid; |
| 160 | sq_cpu = sq->sq_cpu; | 161 | sq_cpu = sq->sq_cpu; |
| 161 | sq_total_time = (sq_usage.ru_stime.tv_sec * 1000000 | 162 | sq_total_time = usec; |
| 162 | + sq_usage.ru_stime.tv_usec); | ||
| 163 | sq_work_time = sq->work_time; | 163 | sq_work_time = sq->work_time; |
| 164 | } else { | 164 | } else { |
| 165 | rcu_read_unlock(); | 165 | rcu_read_unlock(); |
| @@ -57,7 +57,7 @@ void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table) · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, | 58 | static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file, |
| 59 | u32 slot_index) | 59 | u32 slot_index) |
| 60 | __must_hold(&req->ctx->uring_lock) | 60 | __must_hold(&ctx->uring_lock) |
| 61 | { | 61 | { |
| 62 | struct io_rsrc_node *node; | 62 | struct io_rsrc_node *node; |
| 63 | 63 | ||
| @@ -879,7 +879,7 @@ static inline struct io_cqe io_init_cqe(u64 user_data, s32 res, u32 cflags) · 878 unmodified lines | |||
| 879 | } | 879 | } |
| 880 | 880 | ||
| 881 | static __cold void io_cqe_overflow(struct io_ring_ctx *ctx, struct io_cqe *cqe, | 881 | static __cold void io_cqe_overflow(struct io_ring_ctx *ctx, struct io_cqe *cqe, |
| 882 | struct io_big_cqe *big_cqe) | 882 | struct io_big_cqe *big_cqe) |
| 883 | { | 883 | { |
| 884 | struct io_overflow_cqe *ocqe; | 884 | struct io_overflow_cqe *ocqe; |
| 885 | 885 | ||
| @@ -155,6 +155,27 @@ static int io_provided_buffers_select(struct io_kiocb *req, size_t *len, · 154 unmodified lines | |||
| 155 | return 1; | 155 | return 1; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static bool io_should_commit(struct io_kiocb *req, unsigned int issue_flags) | ||
| 159 | { | ||
| 160 | /* | ||
| 161 | * If we came in unlocked, we have no choice but to consume the | ||
| 162 | * buffer here, otherwise nothing ensures that the buffer won't | ||
| 163 | * get used by others. This does mean it'll be pinned until the | ||
| 164 | * IO completes, coming in unlocked means we're being called from | ||
| 165 | * io-wq context and there may be further retries in async hybrid | ||
| 166 | * mode. For the locked case, the caller must call commit when | ||
| 167 | * the transfer completes (or if we get -EAGAIN and must poll of | ||
| 168 | * retry). | ||
| 169 | */ | ||
| 170 | if (issue_flags & IO_URING_F_UNLOCKED) | ||
| 171 | return true; | ||
| 172 | |||
| 173 | /* uring_cmd commits kbuf upfront, no need to auto-commit */ | ||
| 174 | if (!io_file_can_poll(req) && req->opcode != IORING_OP_URING_CMD) | ||
| 175 | return true; | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | |||
| 158 | static struct io_br_sel io_ring_buffer_select(struct io_kiocb *req, size_t *len, | 179 | static struct io_br_sel io_ring_buffer_select(struct io_kiocb *req, size_t *len, |
| 159 | struct io_buffer_list *bl, | 180 | struct io_buffer_list *bl, |
| 160 | unsigned int issue_flags) | 181 | unsigned int issue_flags) |
| @@ -181,17 +202,7 @@ static struct io_br_sel io_ring_buffer_select(struct io_kiocb *req, size_t *len, · 20 unmodified lines | |||
| 181 | sel.buf_list = bl; | 202 | sel.buf_list = bl; |
| 182 | sel.addr = u64_to_user_ptr(buf->addr); | 203 | sel.addr = u64_to_user_ptr(buf->addr); |
| 183 | 204 | ||
| 184 | if (issue_flags & IO_URING_F_UNLOCKED || !io_file_can_poll(req)) { | 205 | if (io_should_commit(req, issue_flags)) { |
| 185 | /* | ||
| 186 | * If we came in unlocked, we have no choice but to consume the | ||
| 187 | * buffer here, otherwise nothing ensures that the buffer won't | ||
| 188 | * get used by others. This does mean it'll be pinned until the | ||
| 189 | * IO completes, coming in unlocked means we're being called from | ||
| 190 | * io-wq context and there may be further retries in async hybrid | ||
| 191 | * mode. For the locked case, the caller must call commit when | ||
| 192 | * the transfer completes (or if we get -EAGAIN and must poll of | ||
| 193 | * retry). | ||
| 194 | */ | ||
| 195 | io_kbuf_commit(req, sel.buf_list, *len, 1); | 206 | io_kbuf_commit(req, sel.buf_list, *len, 1); |
| 196 | sel.buf_list = NULL; | 207 | sel.buf_list = NULL; |
| 197 | } | 208 | } |
| @@ -383,7 +383,7 @@ static int io_send_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 382 unmodified lines | |||
| 383 | return 0; | 383 | return 0; |
| 384 | 384 | ||
| 385 | if (sr->flags & IORING_SEND_VECTORIZED) | 385 | if (sr->flags & IORING_SEND_VECTORIZED) |
| 386 | return io_net_import_vec(req, kmsg, sr->buf, sr->len, ITER_SOURCE); | 386 | return io_net_import_vec(req, kmsg, sr->buf, sr->len, ITER_SOURCE); |
| 387 | 387 | ||
| 388 | return import_ubuf(ITER_SOURCE, sr->buf, sr->len, &kmsg->msg.msg_iter); | 388 | return import_ubuf(ITER_SOURCE, sr->buf, sr->len, &kmsg->msg.msg_iter); |
| 389 | } | 389 | } |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/audit.h> | 11 | #include <linux/audit.h> |
| 12 | #include <linux/security.h> | 12 | #include <linux/security.h> |
| 13 | #include <linux/cpuset.h> | 13 | #include <linux/cpuset.h> |
| 14 | #include <linux/sched/cputime.h> | ||
| 14 | #include <linux/io_uring.h> | 15 | #include <linux/io_uring.h> |
| 15 | 16 | ||
| 16 | #include <uapi/linux/io_uring.h> | 17 | #include <uapi/linux/io_uring.h> |
| @@ -169,7 +170,38 @@ static inline bool io_sqd_events_pending(struct io_sq_data *sqd) · 152 unmodified lines | |||
| 169 | return READ_ONCE(sqd->state); | 170 | return READ_ONCE(sqd->state); |
| 170 | } | 171 | } |
| 171 | 172 | ||
| 172 | static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries) | 173 | struct io_sq_time { |
| 174 | bool started; | ||
| 175 | u64 usec; | ||
| 176 | }; | ||
| 177 | |||
| 178 | u64 io_sq_cpu_usec(struct task_struct *tsk) | ||
| 179 | { | ||
| 180 | u64 utime, stime; | ||
| 181 | |||
| 182 | task_cputime_adjusted(tsk, &utime, &stime); | ||
| 183 | do_div(stime, 1000); | ||
| 184 | return stime; | ||
| 185 | } | ||
| 186 | |||
| 187 | static void io_sq_update_worktime(struct io_sq_data *sqd, struct io_sq_time *ist) | ||
| 188 | { | ||
| 189 | if (!ist->started) | ||
| 190 | return; | ||
| 191 | ist->started = false; | ||
| 192 | sqd->work_time += io_sq_cpu_usec(current) - ist->usec; | ||
| 193 | } | ||
| 194 | |||
| 195 | static void io_sq_start_worktime(struct io_sq_time *ist) | ||
| 196 | { | ||
| 197 | if (ist->started) | ||
| 198 | return; | ||
| 199 | ist->started = true; | ||
| 200 | ist->usec = io_sq_cpu_usec(current); | ||
| 201 | } | ||
| 202 | |||
| 203 | static int __io_sq_thread(struct io_ring_ctx *ctx, struct io_sq_data *sqd, | ||
| 204 | bool cap_entries, struct io_sq_time *ist) | ||
| 173 | { | 205 | { |
| 174 | unsigned int to_submit; | 206 | unsigned int to_submit; |
| 175 | int ret = 0; | 207 | int ret = 0; |
| @@ -182,6 +214,8 @@ static int __io_sq_thread(struct io_ring_ctx *ctx, bool cap_entries) · 6 unmodified lines | |||
| 182 | if (to_submit || !wq_list_empty(&ctx->iopoll_list)) { | 214 | if (to_submit || !wq_list_empty(&ctx->iopoll_list)) { |
| 183 | const struct cred *creds = NULL; | 215 | const struct cred *creds = NULL; |
| 184 | 216 | ||
| 217 | io_sq_start_worktime(ist); | ||
| 218 | |||
| 185 | if (ctx->sq_creds != current_cred()) | 219 | if (ctx->sq_creds != current_cred()) |
| 186 | creds = override_creds(ctx->sq_creds); | 220 | creds = override_creds(ctx->sq_creds); |
| 187 | 221 | ||
| @@ -255,23 +289,11 @@ static bool io_sq_tw_pending(struct llist_node *retry_list) · 67 unmodified lines | |||
| 255 | return retry_list || !llist_empty(&tctx->task_list); | 289 | return retry_list || !llist_empty(&tctx->task_list); |
| 256 | } | 290 | } |
| 257 | 291 | ||
| 258 | static void io_sq_update_worktime(struct io_sq_data *sqd, struct rusage *start) | ||
| 259 | { | ||
| 260 | struct rusage end; | ||
| 261 | |||
| 262 | getrusage(current, RUSAGE_SELF, &end); | ||
| 263 | end.ru_stime.tv_sec -= start->ru_stime.tv_sec; | ||
| 264 | end.ru_stime.tv_usec -= start->ru_stime.tv_usec; | ||
| 265 | |||
| 266 | sqd->work_time += end.ru_stime.tv_usec + end.ru_stime.tv_sec * 1000000; | ||
| 267 | } | ||
| 268 | |||
| 269 | static int io_sq_thread(void *data) | 292 | static int io_sq_thread(void *data) |
| 270 | { | 293 | { |
| 271 | struct llist_node *retry_list = NULL; | 294 | struct llist_node *retry_list = NULL; |
| 272 | struct io_sq_data *sqd = data; | 295 | struct io_sq_data *sqd = data; |
| 273 | struct io_ring_ctx *ctx; | 296 | struct io_ring_ctx *ctx; |
| 274 | struct rusage start; | ||
| 275 | unsigned long timeout = 0; | 297 | unsigned long timeout = 0; |
| 276 | char buf[TASK_COMM_LEN] = {}; | 298 | char buf[TASK_COMM_LEN] = {}; |
| 277 | DEFINE_WAIT(wait); | 299 | DEFINE_WAIT(wait); |
| @@ -309,6 +331,7 @@ static int io_sq_thread(void *data) · 31 unmodified lines | |||
| 309 | mutex_lock(&sqd->lock); | 331 | mutex_lock(&sqd->lock); |
| 310 | while (1) { | 332 | while (1) { |
| 311 | bool cap_entries, sqt_spin = false; | 333 | bool cap_entries, sqt_spin = false; |
| 334 | struct io_sq_time ist = { }; | ||
| 312 | 335 | ||
| 313 | if (io_sqd_events_pending(sqd) || signal_pending(current)) { | 336 | if (io_sqd_events_pending(sqd) || signal_pending(current)) { |
| 314 | if (io_sqd_handle_event(sqd)) | 337 | if (io_sqd_handle_event(sqd)) |
| @@ -317,9 +340,8 @@ static int io_sq_thread(void *data) · 2 unmodified lines | |||
| 317 | } | 340 | } |
| 318 | 341 | ||
| 319 | cap_entries = !list_is_singular(&sqd->ctx_list); | 342 | cap_entries = !list_is_singular(&sqd->ctx_list); |
| 320 | getrusage(current, RUSAGE_SELF, &start); | ||
| 321 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { | 343 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { |
| 322 | int ret = __io_sq_thread(ctx, cap_entries); | 344 | int ret = __io_sq_thread(ctx, sqd, cap_entries, &ist); |
| 323 | 345 | ||
| 324 | if (!sqt_spin && (ret > 0 || !wq_list_empty(&ctx->iopoll_list))) | 346 | if (!sqt_spin && (ret > 0 || !wq_list_empty(&ctx->iopoll_list))) |
| 325 | sqt_spin = true; | 347 | sqt_spin = true; |
| @@ -327,15 +349,18 @@ static int io_sq_thread(void *data) · 1 unmodified line | |||
| 327 | if (io_sq_tw(&retry_list, IORING_TW_CAP_ENTRIES_VALUE)) | 349 | if (io_sq_tw(&retry_list, IORING_TW_CAP_ENTRIES_VALUE)) |
| 328 | sqt_spin = true; | 350 | sqt_spin = true; |
| 329 | 351 | ||
| 330 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) | 352 | list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) { |
| 331 | if (io_napi(ctx)) | 353 | if (io_napi(ctx)) { |
| 354 | io_sq_start_worktime(&ist); | ||
| 332 | io_napi_sqpoll_busy_poll(ctx); | 355 | io_napi_sqpoll_busy_poll(ctx); |
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | io_sq_update_worktime(sqd, &ist); | ||
| 333 | 360 | ||
| 334 | if (sqt_spin || !time_after(jiffies, timeout)) { | 361 | if (sqt_spin || !time_after(jiffies, timeout)) { |
| 335 | if (sqt_spin) { | 362 | if (sqt_spin) |
| 336 | io_sq_update_worktime(sqd, &start); | ||
| 337 | timeout = jiffies + sqd->sq_thread_idle; | 363 | timeout = jiffies + sqd->sq_thread_idle; |
| 338 | } | ||
| 339 | if (unlikely(need_resched())) { | 364 | if (unlikely(need_resched())) { |
| 340 | mutex_unlock(&sqd->lock); | 365 | mutex_unlock(&sqd->lock); |
| 341 | cond_resched(); | 366 | cond_resched(); |
| @@ -29,6 +29,7 @@ void io_sq_thread_unpark(struct io_sq_data *sqd); · 28 unmodified lines | |||
| 29 | void io_put_sq_data(struct io_sq_data *sqd); | 29 | void io_put_sq_data(struct io_sq_data *sqd); |
| 30 | void io_sqpoll_wait_sq(struct io_ring_ctx *ctx); | 30 | void io_sqpoll_wait_sq(struct io_ring_ctx *ctx); |
| 31 | int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, cpumask_var_t mask); | 31 | int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, cpumask_var_t mask); |
| 32 | u64 io_sq_cpu_usec(struct task_struct *tsk); | ||
| 32 | 33 | ||
| 33 | static inline struct task_struct *sqpoll_task_locked(struct io_sq_data *sqd) | 34 | static inline struct task_struct *sqpoll_task_locked(struct io_sq_data *sqd) |
| 34 | { | 35 | { |
| @@ -250,7 +250,7 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 249 unmodified lines | |||
| 250 | return -EINVAL; | 250 | return -EINVAL; |
| 251 | 251 | ||
| 252 | iwa = io_uring_alloc_async_data(NULL, req); | 252 | iwa = io_uring_alloc_async_data(NULL, req); |
| 253 | if (!unlikely(iwa)) | 253 | if (unlikely(!iwa)) |
| 254 | return -ENOMEM; | 254 | return -ENOMEM; |
| 255 | iwa->req = req; | 255 | iwa->req = req; |
| 256 | 256 | ||
| @@ -5889,7 +5889,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, · 5888 unmodified lines | |||
| 5889 | * if the parent has to be frozen, the child has too. | 5889 | * if the parent has to be frozen, the child has too. |
| 5890 | */ | 5890 | */ |
| 5891 | cgrp->freezer.e_freeze = parent->freezer.e_freeze; | 5891 | cgrp->freezer.e_freeze = parent->freezer.e_freeze; |
| 5892 | seqcount_init(&cgrp->freezer.freeze_seq); | 5892 | seqcount_spinlock_init(&cgrp->freezer.freeze_seq, &css_set_lock); |
| 5893 | if (cgrp->freezer.e_freeze) { | 5893 | if (cgrp->freezer.e_freeze) { |
| 5894 | /* | 5894 | /* |
| 5895 | * Set the CGRP_FREEZE flag, so when a process will be | 5895 | * Set the CGRP_FREEZE flag, so when a process will be |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/swiotlb.h> | ||
| 26 | #include <asm/sections.h> | 27 | #include <asm/sections.h> |
| 27 | #include "debug.h" | 28 | #include "debug.h" |
| 28 | 29 | ||
| @@ -594,7 +595,9 @@ static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs) · 565 unmodified lines | |||
| 594 | if (rc == -ENOMEM) { | 595 | if (rc == -ENOMEM) { |
| 595 | pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n"); | 596 | pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n"); |
| 596 | global_disable = true; | 597 | global_disable = true; |
| 597 | } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { | 598 | } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) && |
| 599 | !(IS_ENABLED(CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC) && | ||
| 600 | is_swiotlb_active(entry->dev))) { | ||
| 598 | err_printk(entry->dev, entry, | 601 | err_printk(entry->dev, entry, |
| 599 | "cacheline tracking EEXIST, overlapping mappings aren't supported\n"); | 602 | "cacheline tracking EEXIST, overlapping mappings aren't supported\n"); |
| 600 | } | 603 | } |
| @@ -1030,7 +1030,7 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle, · 1029 unmodified lines | |||
| 1030 | void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | 1030 | void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, |
| 1031 | const char *name) | 1031 | const char *name) |
| 1032 | { | 1032 | { |
| 1033 | scoped_irqdesc_get_and_lock(irq, 0) | 1033 | scoped_irqdesc_get_and_buslock(irq, 0) |
| 1034 | __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name); | 1034 | __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name); |
| 1035 | } | 1035 | } |
| 1036 | EXPORT_SYMBOL_GPL(__irq_set_handler); | 1036 | EXPORT_SYMBOL_GPL(__irq_set_handler); |
| @@ -659,7 +659,7 @@ void __disable_irq(struct irq_desc *desc) · 658 unmodified lines | |||
| 659 | 659 | ||
| 660 | static int __disable_irq_nosync(unsigned int irq) | 660 | static int __disable_irq_nosync(unsigned int irq) |
| 661 | { | 661 | { |
| 662 | scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) { | 662 | scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) { |
| 663 | __disable_irq(scoped_irqdesc); | 663 | __disable_irq(scoped_irqdesc); |
| 664 | return 0; | 664 | return 0; |
| 665 | } | 665 | } |
| @@ -789,7 +789,7 @@ void __enable_irq(struct irq_desc *desc) · 123 unmodified lines | |||
| 789 | */ | 789 | */ |
| 790 | void enable_irq(unsigned int irq) | 790 | void enable_irq(unsigned int irq) |
| 791 | { | 791 | { |
| 792 | scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) { | 792 | scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) { |
| 793 | struct irq_desc *desc = scoped_irqdesc; | 793 | struct irq_desc *desc = scoped_irqdesc; |
| 794 | 794 | ||
| 795 | if (WARN(!desc->irq_data.chip, "enable_irq before setup/request_irq: irq %u\n", irq)) | 795 | if (WARN(!desc->irq_data.chip, "enable_irq before setup/request_irq: irq %u\n", irq)) |
| @@ -6437,6 +6437,16 @@ static void sync_throttle(struct task_group *tg, int cpu) · 6436 unmodified lines | |||
| 6437 | 6437 | ||
| 6438 | cfs_rq->throttle_count = pcfs_rq->throttle_count; | 6438 | cfs_rq->throttle_count = pcfs_rq->throttle_count; |
| 6439 | cfs_rq->throttled_clock_pelt = rq_clock_pelt(cpu_rq(cpu)); | 6439 | cfs_rq->throttled_clock_pelt = rq_clock_pelt(cpu_rq(cpu)); |
| 6440 | |||
| 6441 | /* | ||
| 6442 | * It is not enough to sync the "pelt_clock_throttled" indicator | ||
| 6443 | * with the parent cfs_rq when the hierarchy is not queued. | ||
| 6444 | * Always join a throttled hierarchy with PELT clock throttled | ||
| 6445 | * and leaf it to the first enqueue, or distribution to | ||
| 6446 | * unthrottle the PELT clock. | ||
| 6447 | */ | ||
| 6448 | if (cfs_rq->throttle_count) | ||
| 6449 | cfs_rq->pelt_clock_throttled = 1; | ||
| 6440 | } | 6450 | } |
| 6441 | 6451 | ||
| 6442 | /* conditionally throttle active cfs_rq's from put_prev_entity() */ | 6452 | /* conditionally throttle active cfs_rq's from put_prev_entity() */ |
| @@ -13187,6 +13197,8 @@ static void propagate_entity_cfs_rq(struct sched_entity *se) · 6744 unmodified lines | |||
| 13187 | if (!cfs_rq_pelt_clock_throttled(cfs_rq)) | 13197 | if (!cfs_rq_pelt_clock_throttled(cfs_rq)) |
| 13188 | list_add_leaf_cfs_rq(cfs_rq); | 13198 | list_add_leaf_cfs_rq(cfs_rq); |
| 13189 | } | 13199 | } |
| 13200 | |||
| 13201 | assert_list_leaf_cfs_rq(rq_of(cfs_rq)); | ||
| 13190 | } | 13202 | } |
| 13191 | #else /* !CONFIG_FAIR_GROUP_SCHED: */ | 13203 | #else /* !CONFIG_FAIR_GROUP_SCHED: */ |
| 13192 | static void propagate_entity_cfs_rq(struct sched_entity *se) { } | 13204 | static void propagate_entity_cfs_rq(struct sched_entity *se) { } |
| @@ -3740,11 +3740,9 @@ static inline int mm_cid_get(struct rq *rq, struct task_struct *t, · 3739 unmodified lines | |||
| 3740 | struct mm_struct *mm) | 3740 | struct mm_struct *mm) |
| 3741 | { | 3741 | { |
| 3742 | struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; | 3742 | struct mm_cid __percpu *pcpu_cid = mm->pcpu_cid; |
| 3743 | struct cpumask *cpumask; | ||
| 3744 | int cid; | 3743 | int cid; |
| 3745 | 3744 | ||
| 3746 | lockdep_assert_rq_held(rq); | 3745 | lockdep_assert_rq_held(rq); |
| 3747 | cpumask = mm_cidmask(mm); | ||
| 3748 | cid = __this_cpu_read(pcpu_cid->cid); | 3746 | cid = __this_cpu_read(pcpu_cid->cid); |
| 3749 | if (mm_cid_is_valid(cid)) { | 3747 | if (mm_cid_is_valid(cid)) { |
| 3750 | mm_cid_snapshot_time(rq, mm); | 3748 | mm_cid_snapshot_time(rq, mm); |
| @@ -3070,7 +3070,7 @@ static int __init tk_aux_sysfs_init(void) · 3069 unmodified lines | |||
| 3070 | return -ENOMEM; | 3070 | return -ENOMEM; |
| 3071 | } | 3071 | } |
| 3072 | 3072 | ||
| 3073 | for (int i = 0; i <= MAX_AUX_CLOCKS; i++) { | 3073 | for (int i = 0; i < MAX_AUX_CLOCKS; i++) { |
| 3074 | char id[2] = { [0] = '0' + i, }; | 3074 | char id[2] = { [0] = '0' + i, }; |
| 3075 | struct kobject *clk = kobject_create_and_add(id, auxo); | 3075 | struct kobject *clk = kobject_create_and_add(id, auxo); |
| 3076 | 3076 | ||
| @@ -5,6 +5,7 @@ config RV_MON_PAGEFAULT · 4 unmodified lines | |||
| 5 | select RV_LTL_MONITOR | 5 | select RV_LTL_MONITOR |
| 6 | depends on RV_MON_RTAPP | 6 | depends on RV_MON_RTAPP |
| 7 | depends on X86 || RISCV | 7 | depends on X86 || RISCV |
| 8 | depends on MMU | ||
| 8 | default y | 9 | default y |
| 9 | select LTL_MON_EVENTS_ID | 10 | select LTL_MON_EVENTS_ID |
| 10 | bool "pagefault monitor" | 11 | bool "pagefault monitor" |
| @@ -501,7 +501,7 @@ static void *enabled_monitors_next(struct seq_file *m, void *p, loff_t *pos) · 500 unmodified lines | |||
| 501 | 501 | ||
| 502 | list_for_each_entry_continue(mon, &rv_monitors_list, list) { | 502 | list_for_each_entry_continue(mon, &rv_monitors_list, list) { |
| 503 | if (mon->enabled) | 503 | if (mon->enabled) |
| 504 | return mon; | 504 | return &mon->list; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | return NULL; | 507 | return NULL; |
| @@ -509,7 +509,7 @@ static void *enabled_monitors_next(struct seq_file *m, void *p, loff_t *pos) · 1 unmodified line | |||
| 509 | 509 | ||
| 510 | static void *enabled_monitors_start(struct seq_file *m, loff_t *pos) | 510 | static void *enabled_monitors_start(struct seq_file *m, loff_t *pos) |
| 511 | { | 511 | { |
| 512 | struct rv_monitor *mon; | 512 | struct list_head *head; |
| 513 | loff_t l; | 513 | loff_t l; |
| 514 | 514 | ||
| 515 | mutex_lock(&rv_interface_lock); | 515 | mutex_lock(&rv_interface_lock); |
| @@ -517,15 +517,15 @@ static void *enabled_monitors_start(struct seq_file *m, loff_t *pos) · 1 unmodified line | |||
| 517 | if (list_empty(&rv_monitors_list)) | 517 | if (list_empty(&rv_monitors_list)) |
| 518 | return NULL; | 518 | return NULL; |
| 519 | 519 | ||
| 520 | mon = list_entry(&rv_monitors_list, struct rv_monitor, list); | 520 | head = &rv_monitors_list; |
| 521 | 521 | ||
| 522 | for (l = 0; l <= *pos; ) { | 522 | for (l = 0; l <= *pos; ) { |
| 523 | mon = enabled_monitors_next(m, mon, &l); | 523 | head = enabled_monitors_next(m, head, &l); |
| 524 | if (!mon) | 524 | if (!head) |
| 525 | break; | 525 | break; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | return mon; | 528 | return head; |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | /* | 531 | /* |
| @@ -97,7 +97,7 @@ config CRYPTO_LIB_POLY1305 · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | config CRYPTO_LIB_POLY1305_ARCH | 98 | config CRYPTO_LIB_POLY1305_ARCH |
| 99 | bool | 99 | bool |
| 100 | depends on CRYPTO_LIB_POLY1305 && !UML | 100 | depends on CRYPTO_LIB_POLY1305 && !UML && !KMSAN |
| 101 | default y if ARM | 101 | default y if ARM |
| 102 | default y if ARM64 && KERNEL_MODE_NEON | 102 | default y if ARM64 && KERNEL_MODE_NEON |
| 103 | default y if MIPS | 103 | default y if MIPS |
| @@ -452,6 +452,9 @@ void damon_destroy_scheme(struct damos *s) · 451 unmodified lines | |||
| 452 | damos_for_each_filter_safe(f, next, s) | 452 | damos_for_each_filter_safe(f, next, s) |
| 453 | damos_destroy_filter(f); | 453 | damos_destroy_filter(f); |
| 454 | 454 | ||
| 455 | damos_for_each_ops_filter_safe(f, next, s) | ||
| 456 | damos_destroy_filter(f); | ||
| 457 | |||
| 455 | kfree(s->migrate_dests.node_id_arr); | 458 | kfree(s->migrate_dests.node_id_arr); |
| 456 | kfree(s->migrate_dests.weight_arr); | 459 | kfree(s->migrate_dests.weight_arr); |
| 457 | damon_del_scheme(s); | 460 | damon_del_scheme(s); |
| @@ -832,7 +835,7 @@ int damos_commit_quota_goals(struct damos_quota *dst, struct damos_quota *src) · 374 unmodified lines | |||
| 832 | src_goal->metric, src_goal->target_value); | 835 | src_goal->metric, src_goal->target_value); |
| 833 | if (!new_goal) | 836 | if (!new_goal) |
| 834 | return -ENOMEM; | 837 | return -ENOMEM; |
| 835 | damos_commit_quota_goal_union(new_goal, src_goal); | 838 | damos_commit_quota_goal(new_goal, src_goal); |
| 836 | damos_add_quota_goal(dst, new_goal); | 839 | damos_add_quota_goal(dst, new_goal); |
| 837 | } | 840 | } |
| 838 | return 0; | 841 | return 0; |
| @@ -1450,7 +1453,7 @@ int damon_call(struct damon_ctx *ctx, struct damon_call_control *control) · 611 unmodified lines | |||
| 1450 | INIT_LIST_HEAD(&control->list); | 1453 | INIT_LIST_HEAD(&control->list); |
| 1451 | 1454 | ||
| 1452 | mutex_lock(&ctx->call_controls_lock); | 1455 | mutex_lock(&ctx->call_controls_lock); |
| 1453 | list_add_tail(&ctx->call_controls, &control->list); | 1456 | list_add_tail(&control->list, &ctx->call_controls); |
| 1454 | mutex_unlock(&ctx->call_controls_lock); | 1457 | mutex_unlock(&ctx->call_controls_lock); |
| 1455 | if (!damon_is_running(ctx)) | 1458 | if (!damon_is_running(ctx)) |
| 1456 | return -EINVAL; | 1459 | return -EINVAL; |
| @@ -1473,13 +1473,14 @@ static int damon_sysfs_commit_input(void *data) · 1472 unmodified lines | |||
| 1473 | if (IS_ERR(param_ctx)) | 1473 | if (IS_ERR(param_ctx)) |
| 1474 | return PTR_ERR(param_ctx); | 1474 | return PTR_ERR(param_ctx); |
| 1475 | test_ctx = damon_new_ctx(); | 1475 | test_ctx = damon_new_ctx(); |
| 1476 | if (!test_ctx) | ||
| 1477 | return -ENOMEM; | ||
| 1476 | err = damon_commit_ctx(test_ctx, param_ctx); | 1478 | err = damon_commit_ctx(test_ctx, param_ctx); |
| 1477 | if (err) { | 1479 | if (err) |
| 1478 | damon_destroy_ctx(test_ctx); | ||
| 1479 | goto out; | 1480 | goto out; |
| 1480 | } | ||
| 1481 | err = damon_commit_ctx(kdamond->damon_ctx, param_ctx); | 1481 | err = damon_commit_ctx(kdamond->damon_ctx, param_ctx); |
| 1482 | out: | 1482 | out: |
| 1483 | damon_destroy_ctx(test_ctx); | ||
| 1483 | damon_destroy_ctx(param_ctx); | 1484 | damon_destroy_ctx(param_ctx); |
| 1484 | return err; | 1485 | return err; |
| 1485 | } | 1486 | } |
| @@ -4109,6 +4109,9 @@ static bool thp_underused(struct folio *folio) · 4108 unmodified lines | |||
| 4109 | if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1) | 4109 | if (khugepaged_max_ptes_none == HPAGE_PMD_NR - 1) |
| 4110 | return false; | 4110 | return false; |
| 4111 | 4111 | ||
| 4112 | if (folio_contain_hwpoisoned_page(folio)) | ||
| 4113 | return false; | ||
| 4114 | |||
| 4112 | for (i = 0; i < folio_nr_pages(folio); i++) { | 4115 | for (i = 0; i < folio_nr_pages(folio); i++) { |
| 4113 | if (pages_identical(folio_page(folio, i), ZERO_PAGE(0))) { | 4116 | if (pages_identical(folio_page(folio, i), ZERO_PAGE(0))) { |
| 4114 | if (++num_zero_pages > khugepaged_max_ptes_none) | 4117 | if (++num_zero_pages > khugepaged_max_ptes_none) |
| @@ -7614,13 +7614,12 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, · 7613 unmodified lines | |||
| 7614 | p4d_t *p4d = p4d_offset(pgd, addr); | 7614 | p4d_t *p4d = p4d_offset(pgd, addr); |
| 7615 | pud_t *pud = pud_offset(p4d, addr); | 7615 | pud_t *pud = pud_offset(p4d, addr); |
| 7616 | 7616 | ||
| 7617 | i_mmap_assert_write_locked(vma->vm_file->f_mapping); | ||
| 7618 | hugetlb_vma_assert_locked(vma); | ||
| 7619 | if (sz != PMD_SIZE) | 7617 | if (sz != PMD_SIZE) |
| 7620 | return 0; | 7618 | return 0; |
| 7621 | if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep))) | 7619 | if (!ptdesc_pmd_is_shared(virt_to_ptdesc(ptep))) |
| 7622 | return 0; | 7620 | return 0; |
| 7623 | 7621 | i_mmap_assert_write_locked(vma->vm_file->f_mapping); | |
| 7622 | hugetlb_vma_assert_locked(vma); | ||
| 7624 | pud_clear(pud); | 7623 | pud_clear(pud); |
| 7625 | /* | 7624 | /* |
| 7626 | * Once our caller drops the rmap lock, some other process might be | 7625 | * Once our caller drops the rmap lock, some other process might be |
| @@ -301,8 +301,9 @@ static bool try_to_map_unused_to_zeropage(struct page_vma_mapped_walk *pvmw, · 300 unmodified lines | |||
| 301 | struct page *page = folio_page(folio, idx); | 301 | struct page *page = folio_page(folio, idx); |
| 302 | pte_t newpte; | 302 | pte_t newpte; |
| 303 | 303 | ||
| 304 | if (PageCompound(page)) | 304 | if (PageCompound(page) || PageHWPoison(page)) |
| 305 | return false; | 305 | return false; |
| 306 | |||
| 306 | VM_BUG_ON_PAGE(!PageAnon(page), page); | 307 | VM_BUG_ON_PAGE(!PageAnon(page), page); |
| 307 | VM_BUG_ON_PAGE(!PageLocked(page), page); | 308 | VM_BUG_ON_PAGE(!PageLocked(page), page); |
| 308 | VM_BUG_ON_PAGE(pte_present(old_pte), page); | 309 | VM_BUG_ON_PAGE(pte_present(old_pte), page); |
| @@ -1237,10 +1237,10 @@ static int copy_vma_and_data(struct vma_remap_struct *vrm, · 1236 unmodified lines | |||
| 1237 | } | 1237 | } |
| 1238 | 1238 | ||
| 1239 | /* | 1239 | /* |
| 1240 | * Perform final tasks for MADV_DONTUNMAP operation, clearing mlock() and | 1240 | * Perform final tasks for MADV_DONTUNMAP operation, clearing mlock() flag on |
| 1241 | * account flags on remaining VMA by convention (it cannot be mlock()'d any | 1241 | * remaining VMA by convention (it cannot be mlock()'d any longer, as pages in |
| 1242 | * longer, as pages in range are no longer mapped), and removing anon_vma_chain | 1242 | * range are no longer mapped), and removing anon_vma_chain links from it if the |
| 1243 | * links from it (if the entire VMA was copied over). | 1243 | * entire VMA was copied over. |
| 1244 | */ | 1244 | */ |
| 1245 | static void dontunmap_complete(struct vma_remap_struct *vrm, | 1245 | static void dontunmap_complete(struct vma_remap_struct *vrm, |
| 1246 | struct vm_area_struct *new_vma) | 1246 | struct vm_area_struct *new_vma) |
| @@ -1250,11 +1250,8 @@ static void dontunmap_complete(struct vma_remap_struct *vrm, · 3 unmodified lines | |||
| 1250 | unsigned long old_start = vrm->vma->vm_start; | 1250 | unsigned long old_start = vrm->vma->vm_start; |
| 1251 | unsigned long old_end = vrm->vma->vm_end; | 1251 | unsigned long old_end = vrm->vma->vm_end; |
| 1252 | 1252 | ||
| 1253 | /* | 1253 | /* We always clear VM_LOCKED[ONFAULT] on the old VMA. */ |
| 1254 | * We always clear VM_LOCKED[ONFAULT] | VM_ACCOUNT on the old | 1254 | vm_flags_clear(vrm->vma, VM_LOCKED_MASK); |
| 1255 | * vma. | ||
| 1256 | */ | ||
| 1257 | vm_flags_clear(vrm->vma, VM_LOCKED_MASK | VM_ACCOUNT); | ||
| 1258 | 1255 | ||
| 1259 | /* | 1256 | /* |
| 1260 | * anon_vma links of the old vma is no longer needed after its page | 1257 | * anon_vma links of the old vma is no longer needed after its page |
| @@ -168,6 +168,9 @@ static void add_stack_record_to_list(struct stack_record *stack_record, · 167 unmodified lines | |||
| 168 | unsigned long flags; | 168 | unsigned long flags; |
| 169 | struct stack *stack; | 169 | struct stack *stack; |
| 170 | 170 | ||
| 171 | if (!gfpflags_allow_spinning(gfp_mask)) | ||
| 172 | return; | ||
| 173 | |||
| 171 | set_current_in_page_owner(); | 174 | set_current_in_page_owner(); |
| 172 | stack = kmalloc(sizeof(*stack), gfp_nested_mask(gfp_mask)); | 175 | stack = kmalloc(sizeof(*stack), gfp_nested_mask(gfp_mask)); |
| 173 | if (!stack) { | 176 | if (!stack) { |
| @@ -2052,9 +2052,9 @@ static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) · 2051 unmodified lines | |||
| 2052 | } | 2052 | } |
| 2053 | } | 2053 | } |
| 2054 | 2054 | ||
| 2055 | static inline void mark_failed_objexts_alloc(struct slab *slab) | 2055 | static inline bool mark_failed_objexts_alloc(struct slab *slab) |
| 2056 | { | 2056 | { |
| 2057 | slab->obj_exts = OBJEXTS_ALLOC_FAIL; | 2057 | return cmpxchg(&slab->obj_exts, 0, OBJEXTS_ALLOC_FAIL) == 0; |
| 2058 | } | 2058 | } |
| 2059 | 2059 | ||
| 2060 | static inline void handle_failed_objexts_alloc(unsigned long obj_exts, | 2060 | static inline void handle_failed_objexts_alloc(unsigned long obj_exts, |
| @@ -2076,7 +2076,7 @@ static inline void handle_failed_objexts_alloc(unsigned long obj_exts, · 15 unmodified lines | |||
| 2076 | #else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */ | 2076 | #else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */ |
| 2077 | 2077 | ||
| 2078 | static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) {} | 2078 | static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) {} |
| 2079 | static inline void mark_failed_objexts_alloc(struct slab *slab) {} | 2079 | static inline bool mark_failed_objexts_alloc(struct slab *slab) { return false; } |
| 2080 | static inline void handle_failed_objexts_alloc(unsigned long obj_exts, | 2080 | static inline void handle_failed_objexts_alloc(unsigned long obj_exts, |
| 2081 | struct slabobj_ext *vec, unsigned int objects) {} | 2081 | struct slabobj_ext *vec, unsigned int objects) {} |
| 2082 | 2082 | ||
| @@ -2124,8 +2124,14 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, · 41 unmodified lines | |||
| 2124 | slab_nid(slab)); | 2124 | slab_nid(slab)); |
| 2125 | } | 2125 | } |
| 2126 | if (!vec) { | 2126 | if (!vec) { |
| 2127 | /* Mark vectors which failed to allocate */ | 2127 | /* |
| 2128 | mark_failed_objexts_alloc(slab); | 2128 | * Try to mark vectors which failed to allocate. |
| 2129 | * If this operation fails, there may be a racing process | ||
| 2130 | * that has already completed the allocation. | ||
| 2131 | */ | ||
| 2132 | if (!mark_failed_objexts_alloc(slab) && | ||
| 2133 | slab_obj_exts(slab)) | ||
| 2134 | return 0; | ||
| 2129 | 2135 | ||
| 2130 | return -ENOMEM; | 2136 | return -ENOMEM; |
| 2131 | } | 2137 | } |
| @@ -2136,6 +2142,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, · 4 unmodified lines | |||
| 2136 | #ifdef CONFIG_MEMCG | 2142 | #ifdef CONFIG_MEMCG |
| 2137 | new_exts |= MEMCG_DATA_OBJEXTS; | 2143 | new_exts |= MEMCG_DATA_OBJEXTS; |
| 2138 | #endif | 2144 | #endif |
| 2145 | retry: | ||
| 2139 | old_exts = READ_ONCE(slab->obj_exts); | 2146 | old_exts = READ_ONCE(slab->obj_exts); |
| 2140 | handle_failed_objexts_alloc(old_exts, vec, objects); | 2147 | handle_failed_objexts_alloc(old_exts, vec, objects); |
| 2141 | if (new_slab) { | 2148 | if (new_slab) { |
| @@ -2145,8 +2152,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, · 3 unmodified lines | |||
| 2145 | * be simply assigned. | 2152 | * be simply assigned. |
| 2146 | */ | 2153 | */ |
| 2147 | slab->obj_exts = new_exts; | 2154 | slab->obj_exts = new_exts; |
| 2148 | } else if ((old_exts & ~OBJEXTS_FLAGS_MASK) || | 2155 | } else if (old_exts & ~OBJEXTS_FLAGS_MASK) { |
| 2149 | cmpxchg(&slab->obj_exts, old_exts, new_exts) != old_exts) { | ||
| 2150 | /* | 2156 | /* |
| 2151 | * If the slab is already in use, somebody can allocate and | 2157 | * If the slab is already in use, somebody can allocate and |
| 2152 | * assign slabobj_exts in parallel. In this case the existing | 2158 | * assign slabobj_exts in parallel. In this case the existing |
| @@ -2158,6 +2164,9 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, · 5 unmodified lines | |||
| 2158 | else | 2164 | else |
| 2159 | kfree(vec); | 2165 | kfree(vec); |
| 2160 | return 0; | 2166 | return 0; |
| 2167 | } else if (cmpxchg(&slab->obj_exts, old_exts, new_exts) != old_exts) { | ||
| 2168 | /* Retry if a racing thread changed slab->obj_exts from under us. */ | ||
| 2169 | goto retry; | ||
| 2161 | } | 2170 | } |
| 2162 | 2171 | ||
| 2163 | if (allow_spin) | 2172 | if (allow_spin) |
| @@ -3419,7 +3428,6 @@ static void *alloc_single_from_new_slab(struct kmem_cache *s, struct slab *slab, · 1255 unmodified lines | |||
| 3419 | 3428 | ||
| 3420 | if (!allow_spin && !spin_trylock_irqsave(&n->list_lock, flags)) { | 3429 | if (!allow_spin && !spin_trylock_irqsave(&n->list_lock, flags)) { |
| 3421 | /* Unlucky, discard newly allocated slab */ | 3430 | /* Unlucky, discard newly allocated slab */ |
| 3422 | slab->frozen = 1; | ||
| 3423 | defer_deactivate_slab(slab, NULL); | 3431 | defer_deactivate_slab(slab, NULL); |
| 3424 | return NULL; | 3432 | return NULL; |
| 3425 | } | 3433 | } |
| @@ -6468,9 +6476,12 @@ static void free_deferred_objects(struct irq_work *work) · 3042 unmodified lines | |||
| 6468 | struct slab *slab = container_of(pos, struct slab, llnode); | 6476 | struct slab *slab = container_of(pos, struct slab, llnode); |
| 6469 | 6477 | ||
| 6470 | #ifdef CONFIG_SLUB_TINY | 6478 | #ifdef CONFIG_SLUB_TINY |
| 6471 | discard_slab(slab->slab_cache, slab); | 6479 | free_slab(slab->slab_cache, slab); |
| 6472 | #else | 6480 | #else |
| 6473 | deactivate_slab(slab->slab_cache, slab, slab->flush_freelist); | 6481 | if (slab->frozen) |
| 6482 | deactivate_slab(slab->slab_cache, slab, slab->flush_freelist); | ||
| 6483 | else | ||
| 6484 | free_slab(slab->slab_cache, slab); | ||
| 6474 | #endif | 6485 | #endif |
| 6475 | } | 6486 | } |
| 6476 | } | 6487 | } |
| @@ -920,21 +920,22 @@ fault: · 919 unmodified lines | |||
| 920 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg); | 920 | EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg); |
| 921 | 921 | ||
| 922 | /** | 922 | /** |
| 923 | * datagram_poll - generic datagram poll | 923 | * datagram_poll_queue - same as datagram_poll, but on a specific receive |
| 924 | * queue | ||
| 924 | * @file: file struct | 925 | * @file: file struct |
| 925 | * @sock: socket | 926 | * @sock: socket |
| 926 | * @wait: poll table | 927 | * @wait: poll table |
| 928 | * @rcv_queue: receive queue to poll | ||
| 927 | * | 929 | * |
| 928 | * Datagram poll: Again totally generic. This also handles | 930 | * Performs polling on the given receive queue, handling shutdown, error, |
| 929 | * sequenced packet sockets providing the socket receive queue | 931 | * and connection state. This is useful for protocols that deliver |
| 930 | * is only ever holding data ready to receive. | 932 | * userspace-bound packets through a custom queue instead of |
| 933 | * sk->sk_receive_queue. | ||
| 931 | * | 934 | * |
| 932 | * Note: when you *don't* use this routine for this protocol, | 935 | * Return: poll bitmask indicating the socket's current state |
| 933 | * and you use a different write policy from sock_writeable() | ||
| 934 | * then please supply your own write_space callback. | ||
| 935 | */ | 936 | */ |
| 936 | __poll_t datagram_poll(struct file *file, struct socket *sock, | 937 | __poll_t datagram_poll_queue(struct file *file, struct socket *sock, |
| 937 | poll_table *wait) | 938 | poll_table *wait, struct sk_buff_head *rcv_queue) |
| 938 | { | 939 | { |
| 939 | struct sock *sk = sock->sk; | 940 | struct sock *sk = sock->sk; |
| 940 | __poll_t mask; | 941 | __poll_t mask; |
| @@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, · 15 unmodified lines | |||
| 956 | mask |= EPOLLHUP; | 957 | mask |= EPOLLHUP; |
| 957 | 958 | ||
| 958 | /* readable? */ | 959 | /* readable? */ |
| 959 | if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) | 960 | if (!skb_queue_empty_lockless(rcv_queue)) |
| 960 | mask |= EPOLLIN | EPOLLRDNORM; | 961 | mask |= EPOLLIN | EPOLLRDNORM; |
| 961 | 962 | ||
| 962 | /* Connection-based need to check for termination and startup */ | 963 | /* Connection-based need to check for termination and startup */ |
| @@ -978,4 +979,27 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, · 15 unmodified lines | |||
| 978 | 979 | ||
| 979 | return mask; | 980 | return mask; |
| 980 | } | 981 | } |
| 982 | EXPORT_SYMBOL(datagram_poll_queue); | ||
| 983 | |||
| 984 | /** | ||
| 985 | * datagram_poll - generic datagram poll | ||
| 986 | * @file: file struct | ||
| 987 | * @sock: socket | ||
| 988 | * @wait: poll table | ||
| 989 | * | ||
| 990 | * Datagram poll: Again totally generic. This also handles | ||
| 991 | * sequenced packet sockets providing the socket receive queue | ||
| 992 | * is only ever holding data ready to receive. | ||
| 993 | * | ||
| 994 | * Note: when you *don't* use this routine for this protocol, | ||
| 995 | * and you use a different write policy from sock_writeable() | ||
| 996 | * then please supply your own write_space callback. | ||
| 997 | * | ||
| 998 | * Return: poll bitmask indicating the socket's current state | ||
| 999 | */ | ||
| 1000 | __poll_t datagram_poll(struct file *file, struct socket *sock, poll_table *wait) | ||
| 1001 | { | ||
| 1002 | return datagram_poll_queue(file, sock, wait, | ||
| 1003 | &sock->sk->sk_receive_queue); | ||
| 1004 | } | ||
| 981 | EXPORT_SYMBOL(datagram_poll); | 1005 | EXPORT_SYMBOL(datagram_poll); |
| @@ -639,6 +639,8 @@ EXPORT_SYMBOL(gro_receive_skb); · 638 unmodified lines | |||
| 639 | 639 | ||
| 640 | static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | 640 | static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) |
| 641 | { | 641 | { |
| 642 | struct skb_shared_info *shinfo; | ||
| 643 | |||
| 642 | if (unlikely(skb->pfmemalloc)) { | 644 | if (unlikely(skb->pfmemalloc)) { |
| 643 | consume_skb(skb); | 645 | consume_skb(skb); |
| 644 | return; | 646 | return; |
| @@ -655,8 +657,12 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) · 10 unmodified lines | |||
| 655 | 657 | ||
| 656 | skb->encapsulation = 0; | 658 | skb->encapsulation = 0; |
| 657 | skb->ip_summed = CHECKSUM_NONE; | 659 | skb->ip_summed = CHECKSUM_NONE; |
| 658 | skb_shinfo(skb)->gso_type = 0; | 660 | |
| 659 | skb_shinfo(skb)->gso_size = 0; | 661 | shinfo = skb_shinfo(skb); |
| 662 | shinfo->gso_type = 0; | ||
| 663 | shinfo->gso_size = 0; | ||
| 664 | shinfo->hwtstamps.hwtstamp = 0; | ||
| 665 | |||
| 660 | if (unlikely(skb->slow_gro)) { | 666 | if (unlikely(skb->slow_gro)) { |
| 661 | skb_orphan(skb); | 667 | skb_orphan(skb); |
| 662 | skb_ext_reset(skb); | 668 | skb_ext_reset(skb); |
| @@ -43,12 +43,11 @@ drop: · 42 unmodified lines | |||
| 43 | if (skb_queue_len(&cell->napi_skbs) == 1) | 43 | if (skb_queue_len(&cell->napi_skbs) == 1) |
| 44 | napi_schedule(&cell->napi); | 44 | napi_schedule(&cell->napi); |
| 45 | 45 | ||
| 46 | if (have_bh_lock) | ||
| 47 | local_unlock_nested_bh(&gcells->cells->bh_lock); | ||
| 48 | |||
| 49 | res = NET_RX_SUCCESS; | 46 | res = NET_RX_SUCCESS; |
| 50 | 47 | ||
| 51 | unlock: | 48 | unlock: |
| 49 | if (have_bh_lock) | ||
| 50 | local_unlock_nested_bh(&gcells->cells->bh_lock); | ||
| 52 | rcu_read_unlock(); | 51 | rcu_read_unlock(); |
| 53 | return res; | 52 | return res; |
| 54 | } | 53 | } |
| @@ -4715,9 +4715,6 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, · 4714 unmodified lines | |||
| 4715 | int err; | 4715 | int err; |
| 4716 | u16 vid; | 4716 | u16 vid; |
| 4717 | 4717 | ||
| 4718 | if (!netlink_capable(skb, CAP_NET_ADMIN)) | ||
| 4719 | return -EPERM; | ||
| 4720 | |||
| 4721 | if (!del_bulk) { | 4718 | if (!del_bulk) { |
| 4722 | err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, | 4719 | err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, |
| 4723 | NULL, extack); | 4720 | NULL, extack); |
| @@ -34,12 +34,18 @@ static int hsr_newlink(struct net_device *dev, · 33 unmodified lines | |||
| 34 | struct netlink_ext_ack *extack) | 34 | struct netlink_ext_ack *extack) |
| 35 | { | 35 | { |
| 36 | struct net *link_net = rtnl_newlink_link_net(params); | 36 | struct net *link_net = rtnl_newlink_link_net(params); |
| 37 | struct net_device *link[2], *interlink = NULL; | ||
| 37 | struct nlattr **data = params->data; | 38 | struct nlattr **data = params->data; |
| 38 | enum hsr_version proto_version; | 39 | enum hsr_version proto_version; |
| 39 | unsigned char multicast_spec; | 40 | unsigned char multicast_spec; |
| 40 | u8 proto = HSR_PROTOCOL_HSR; | 41 | u8 proto = HSR_PROTOCOL_HSR; |
| 41 | 42 | ||
| 42 | struct net_device *link[2], *interlink = NULL; | 43 | if (!net_eq(link_net, dev_net(dev))) { |
| 44 | NL_SET_ERR_MSG_MOD(extack, | ||
| 45 | "HSR slaves/interlink must be on the same net namespace than HSR link"); | ||
| 46 | return -EINVAL; | ||
| 47 | } | ||
| 48 | |||
| 43 | if (!data) { | 49 | if (!data) { |
| 44 | NL_SET_ERR_MSG_MOD(extack, "No slave devices specified"); | 50 | NL_SET_ERR_MSG_MOD(extack, "No slave devices specified"); |
| 45 | return -EINVAL; | 51 | return -EINVAL; |
| @@ -370,6 +370,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) · 369 unmodified lines | |||
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | subflow: | 372 | subflow: |
| 373 | /* No need to try establishing subflows to remote id0 if not allowed */ | ||
| 374 | if (mptcp_pm_add_addr_c_flag_case(msk)) | ||
| 375 | goto exit; | ||
| 376 | |||
| 373 | /* check if should create a new subflow */ | 377 | /* check if should create a new subflow */ |
| 374 | while (msk->pm.local_addr_used < endp_subflow_max && | 378 | while (msk->pm.local_addr_used < endp_subflow_max && |
| 375 | msk->pm.extra_subflows < limit_extra_subflows) { | 379 | msk->pm.extra_subflows < limit_extra_subflows) { |
| @@ -401,6 +405,8 @@ subflow: · 25 unmodified lines | |||
| 401 | __mptcp_subflow_connect(sk, &local, &addrs[i]); | 405 | __mptcp_subflow_connect(sk, &local, &addrs[i]); |
| 402 | spin_lock_bh(&msk->pm.lock); | 406 | spin_lock_bh(&msk->pm.lock); |
| 403 | } | 407 | } |
| 408 | |||
| 409 | exit: | ||
| 404 | mptcp_pm_nl_check_work_pending(msk); | 410 | mptcp_pm_nl_check_work_pending(msk); |
| 405 | } | 411 | } |
| 406 | 412 | ||
| @@ -169,13 +169,14 @@ next_chunk: · 168 unmodified lines | |||
| 169 | chunk->head_skb = chunk->skb; | 169 | chunk->head_skb = chunk->skb; |
| 170 | 170 | ||
| 171 | /* skbs with "cover letter" */ | 171 | /* skbs with "cover letter" */ |
| 172 | if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len) | 172 | if (chunk->head_skb && chunk->skb->data_len == chunk->skb->len) { |
| 173 | if (WARN_ON(!skb_shinfo(chunk->skb)->frag_list)) { | ||
| 174 | __SCTP_INC_STATS(dev_net(chunk->skb->dev), | ||
| 175 | SCTP_MIB_IN_PKT_DISCARDS); | ||
| 176 | sctp_chunk_free(chunk); | ||
| 177 | goto next_chunk; | ||
| 178 | } | ||
| 173 | chunk->skb = skb_shinfo(chunk->skb)->frag_list; | 179 | chunk->skb = skb_shinfo(chunk->skb)->frag_list; |
| 174 | |||
| 175 | if (WARN_ON(!chunk->skb)) { | ||
| 176 | __SCTP_INC_STATS(dev_net(chunk->skb->dev), SCTP_MIB_IN_PKT_DISCARDS); | ||
| 177 | sctp_chunk_free(chunk); | ||
| 178 | goto next_chunk; | ||
| 179 | } | 180 | } |
| 180 | } | 181 | } |
| 181 | 182 | ||
| @@ -56,7 +56,6 @@ static struct inet_protosw smc_inet_protosw = { · 55 unmodified lines | |||
| 56 | .protocol = IPPROTO_SMC, | 56 | .protocol = IPPROTO_SMC, |
| 57 | .prot = &smc_inet_prot, | 57 | .prot = &smc_inet_prot, |
| 58 | .ops = &smc_inet_stream_ops, | 58 | .ops = &smc_inet_stream_ops, |
| 59 | .flags = INET_PROTOSW_ICSK, | ||
| 60 | }; | 59 | }; |
| 61 | 60 | ||
| 62 | #if IS_ENABLED(CONFIG_IPV6) | 61 | #if IS_ENABLED(CONFIG_IPV6) |
| @@ -104,27 +103,15 @@ static struct inet_protosw smc_inet6_protosw = { · 41 unmodified lines | |||
| 104 | .protocol = IPPROTO_SMC, | 103 | .protocol = IPPROTO_SMC, |
| 105 | .prot = &smc_inet6_prot, | 104 | .prot = &smc_inet6_prot, |
| 106 | .ops = &smc_inet6_stream_ops, | 105 | .ops = &smc_inet6_stream_ops, |
| 107 | .flags = INET_PROTOSW_ICSK, | ||
| 108 | }; | 106 | }; |
| 109 | #endif /* CONFIG_IPV6 */ | 107 | #endif /* CONFIG_IPV6 */ |
| 110 | 108 | ||
| 111 | static unsigned int smc_sync_mss(struct sock *sk, u32 pmtu) | ||
| 112 | { | ||
| 113 | /* No need pass it through to clcsock, mss can always be set by | ||
| 114 | * sock_create_kern or smc_setsockopt. | ||
| 115 | */ | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int smc_inet_init_sock(struct sock *sk) | 109 | static int smc_inet_init_sock(struct sock *sk) |
| 120 | { | 110 | { |
| 121 | struct net *net = sock_net(sk); | 111 | struct net *net = sock_net(sk); |
| 122 | 112 | ||
| 123 | /* init common smc sock */ | 113 | /* init common smc sock */ |
| 124 | smc_sk_init(net, sk, IPPROTO_SMC); | 114 | smc_sk_init(net, sk, IPPROTO_SMC); |
| 125 | |||
| 126 | inet_csk(sk)->icsk_sync_mss = smc_sync_mss; | ||
| 127 | |||
| 128 | /* create clcsock */ | 115 | /* create clcsock */ |
| 129 | return smc_create_clcsk(net, sk, sk->sk_family); | 116 | return smc_create_clcsk(net, sk, sk->sk_family); |
| 130 | } | 117 | } |
| @@ -487,12 +487,26 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) · 486 unmodified lines | |||
| 487 | goto err; | 487 | goto err; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | if (vsk->transport) { | 490 | if (vsk->transport && vsk->transport == new_transport) { |
| 491 | if (vsk->transport == new_transport) { | 491 | ret = 0; |
| 492 | ret = 0; | 492 | goto err; |
| 493 | goto err; | 493 | } |
| 494 | } | ||
| 495 | 494 | ||
| 495 | /* We increase the module refcnt to prevent the transport unloading | ||
| 496 | * while there are open sockets assigned to it. | ||
| 497 | */ | ||
| 498 | if (!new_transport || !try_module_get(new_transport->module)) { | ||
| 499 | ret = -ENODEV; | ||
| 500 | goto err; | ||
| 501 | } | ||
| 502 | |||
| 503 | /* It's safe to release the mutex after a successful try_module_get(). | ||
| 504 | * Whichever transport `new_transport` points at, it won't go away until | ||
| 505 | * the last module_put() below or in vsock_deassign_transport(). | ||
| 506 | */ | ||
| 507 | mutex_unlock(&vsock_register_mutex); | ||
| 508 | |||
| 509 | if (vsk->transport) { | ||
| 496 | /* transport->release() must be called with sock lock acquired. | 510 | /* transport->release() must be called with sock lock acquired. |
| 497 | * This path can only be taken during vsock_connect(), where we | 511 | * This path can only be taken during vsock_connect(), where we |
| 498 | * have already held the sock lock. In the other cases, this | 512 | * have already held the sock lock. In the other cases, this |
| @@ -512,20 +526,6 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) · 13 unmodified lines | |||
| 512 | vsk->peer_shutdown = 0; | 526 | vsk->peer_shutdown = 0; |
| 513 | } | 527 | } |
| 514 | 528 | ||
| 515 | /* We increase the module refcnt to prevent the transport unloading | ||
| 516 | * while there are open sockets assigned to it. | ||
| 517 | */ | ||
| 518 | if (!new_transport || !try_module_get(new_transport->module)) { | ||
| 519 | ret = -ENODEV; | ||
| 520 | goto err; | ||
| 521 | } | ||
| 522 | |||
| 523 | /* It's safe to release the mutex after a successful try_module_get(). | ||
| 524 | * Whichever transport `new_transport` points at, it won't go away until | ||
| 525 | * the last module_put() below or in vsock_deassign_transport(). | ||
| 526 | */ | ||
| 527 | mutex_unlock(&vsock_register_mutex); | ||
| 528 | |||
| 529 | if (sk->sk_type == SOCK_SEQPACKET) { | 529 | if (sk->sk_type == SOCK_SEQPACKET) { |
| 530 | if (!new_transport->seqpacket_allow || | 530 | if (!new_transport->seqpacket_allow || |
| 531 | !new_transport->seqpacket_allow(remote_cid)) { | 531 | !new_transport->seqpacket_allow(remote_cid)) { |
| @@ -555,14 +555,10 @@ static void espintcp_close(struct sock *sk, long timeout) · 554 unmodified lines | |||
| 555 | static __poll_t espintcp_poll(struct file *file, struct socket *sock, | 555 | static __poll_t espintcp_poll(struct file *file, struct socket *sock, |
| 556 | poll_table *wait) | 556 | poll_table *wait) |
| 557 | { | 557 | { |
| 558 | __poll_t mask = datagram_poll(file, sock, wait); | ||
| 559 | struct sock *sk = sock->sk; | 558 | struct sock *sk = sock->sk; |
| 560 | struct espintcp_ctx *ctx = espintcp_getctx(sk); | 559 | struct espintcp_ctx *ctx = espintcp_getctx(sk); |
| 561 | 560 | ||
| 562 | if (!skb_queue_empty(&ctx->ike_queue)) | 561 | return datagram_poll_queue(file, sock, wait, &ctx->ike_queue); |
| 563 | mask |= EPOLLIN | EPOLLRDNORM; | ||
| 564 | |||
| 565 | return mask; | ||
| 566 | } | 562 | } |
| 567 | 563 | ||
| 568 | static void build_protos(struct proto *espintcp_prot, | 564 | static void build_protos(struct proto *espintcp_prot, |
| @@ -217,13 +217,7 @@ impl<Ctx: device::DeviceContext> Device<Ctx> { · 216 unmodified lines | |||
| 217 | 217 | ||
| 218 | /// Returns a reference to the parent [`device::Device`], if any. | 218 | /// Returns a reference to the parent [`device::Device`], if any. |
| 219 | pub fn parent(&self) -> Option<&device::Device> { | 219 | pub fn parent(&self) -> Option<&device::Device> { |
| 220 | let ptr: *const Self = self; | 220 | self.as_ref().parent() |
| 221 | // CAST: `Device<Ctx: DeviceContext>` types are transparent to each other. | ||
| 222 | let ptr: *const Device = ptr.cast(); | ||
| 223 | // SAFETY: `ptr` was derived from `&self`. | ||
| 224 | let this = unsafe { &*ptr }; | ||
| 225 | |||
| 226 | this.as_ref().parent() | ||
| 227 | } | 221 | } |
| 228 | } | 222 | } |
| 229 | 223 | ||
| @@ -251,7 +251,7 @@ impl<Ctx: DeviceContext> Device<Ctx> { · 250 unmodified lines | |||
| 251 | 251 | ||
| 252 | /// Returns a reference to the parent device, if any. | 252 | /// Returns a reference to the parent device, if any. |
| 253 | #[cfg_attr(not(CONFIG_AUXILIARY_BUS), expect(dead_code))] | 253 | #[cfg_attr(not(CONFIG_AUXILIARY_BUS), expect(dead_code))] |
| 254 | pub(crate) fn parent(&self) -> Option<&Self> { | 254 | pub(crate) fn parent(&self) -> Option<&Device> { |
| 255 | // SAFETY: | 255 | // SAFETY: |
| 256 | // - By the type invariant `self.as_raw()` is always valid. | 256 | // - By the type invariant `self.as_raw()` is always valid. |
| 257 | // - The parent device is only ever set at device creation. | 257 | // - The parent device is only ever set at device creation. |
| @@ -264,7 +264,7 @@ impl<Ctx: DeviceContext> Device<Ctx> { · 6 unmodified lines | |||
| 264 | // - Since `parent` is not NULL, it must be a valid pointer to a `struct device`. | 264 | // - Since `parent` is not NULL, it must be a valid pointer to a `struct device`. |
| 265 | // - `parent` is valid for the lifetime of `self`, since a `struct device` holds a | 265 | // - `parent` is valid for the lifetime of `self`, since a `struct device` holds a |
| 266 | // reference count of its parent. | 266 | // reference count of its parent. |
| 267 | Some(unsafe { Self::from_raw(parent) }) | 267 | Some(unsafe { Device::from_raw(parent) }) |
| 268 | } | 268 | } |
| 269 | } | 269 | } |
| 270 | 270 | ||
| @@ -28,8 +28,10 @@ endif · 27 unmodified lines | |||
| 28 | KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds | 28 | KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds |
| 29 | 29 | ||
| 30 | ifdef CONFIG_CC_IS_CLANG | 30 | ifdef CONFIG_CC_IS_CLANG |
| 31 | # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. | 31 | # The kernel builds with '-std=gnu11' and '-fms-extensions' so use of GNU and |
| 32 | # Microsoft extensions is acceptable. | ||
| 32 | KBUILD_CFLAGS += -Wno-gnu | 33 | KBUILD_CFLAGS += -Wno-gnu |
| 34 | KBUILD_CFLAGS += -Wno-microsoft-anon-tag | ||
| 33 | 35 | ||
| 34 | # Clang checks for overflow/truncation with '%p', while GCC does not: | 36 | # Clang checks for overflow/truncation with '%p', while GCC does not: |
| 35 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219 | 37 | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111219 |
| @@ -217,6 +217,7 @@ static bool is_rust_noreturn(const struct symbol *func) · 216 unmodified lines | |||
| 217 | * these come from the Rust standard library). | 217 | * these come from the Rust standard library). |
| 218 | */ | 218 | */ |
| 219 | return str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || | 219 | return str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || |
| 220 | str_ends_with(func->name, "_4core6option13expect_failed") || | ||
| 220 | str_ends_with(func->name, "_4core6option13unwrap_failed") || | 221 | str_ends_with(func->name, "_4core6option13unwrap_failed") || |
| 221 | str_ends_with(func->name, "_4core6result13unwrap_failed") || | 222 | str_ends_with(func->name, "_4core6result13unwrap_failed") || |
| 222 | str_ends_with(func->name, "_4core9panicking5panic") || | 223 | str_ends_with(func->name, "_4core9panicking5panic") || |
| @@ -4710,8 +4711,8 @@ static int check_abs_references(struct objtool_file *file) · 4487 unmodified lines | |||
| 4710 | 4711 | ||
| 4711 | for_each_reloc(sec->rsec, reloc) { | 4712 | for_each_reloc(sec->rsec, reloc) { |
| 4712 | if (arch_absolute_reloc(file->elf, reloc)) { | 4713 | if (arch_absolute_reloc(file->elf, reloc)) { |
| 4713 | WARN("section %s has absolute relocation at offset 0x%lx", | 4714 | WARN("section %s has absolute relocation at offset 0x%llx", |
| 4714 | sec->name, reloc_offset(reloc)); | 4715 | sec->name, (unsigned long long)reloc_offset(reloc)); |
| 4715 | ret++; | 4716 | ret++; |
| 4716 | } | 4717 | } |
| 4717 | } | 4718 | } |
| @@ -25,6 +25,26 @@ static inline int values_close(long a, long b, int err) · 24 unmodified lines | |||
| 25 | return labs(a - b) <= (a + b) / 100 * err; | 25 | return labs(a - b) <= (a + b) / 100 * err; |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | /* | ||
| 29 | * Checks if two given values differ by less than err% of their sum and assert | ||
| 30 | * with detailed debug info if not. | ||
| 31 | */ | ||
| 32 | static inline int values_close_report(long a, long b, int err) | ||
| 33 | { | ||
| 34 | long diff = labs(a - b); | ||
| 35 | long limit = (a + b) / 100 * err; | ||
| 36 | double actual_err = (a + b) ? (100.0 * diff / (a + b)) : 0.0; | ||
| 37 | int close = diff <= limit; | ||
| 38 | |||
| 39 | if (!close) | ||
| 40 | fprintf(stderr, | ||
| 41 | "[FAIL] actual=%ld expected=%ld | diff=%ld | limit=%ld | " | ||
| 42 | "tolerance=%d%% | actual_error=%.2f%%\n", | ||
| 43 | a, b, diff, limit, err, actual_err); | ||
| 44 | |||
| 45 | return close; | ||
| 46 | } | ||
| 47 | |||
| 28 | extern ssize_t read_text(const char *path, char *buf, size_t max_len); | 48 | extern ssize_t read_text(const char *path, char *buf, size_t max_len); |
| 29 | extern ssize_t write_text(const char *path, char *buf, ssize_t len); | 49 | extern ssize_t write_text(const char *path, char *buf, ssize_t len); |
| 30 | 50 | ||
| @@ -219,7 +219,7 @@ static int test_cpucg_stats(const char *root) · 218 unmodified lines | |||
| 219 | if (user_usec <= 0) | 219 | if (user_usec <= 0) |
| 220 | goto cleanup; | 220 | goto cleanup; |
| 221 | 221 | ||
| 222 | if (!values_close(usage_usec, expected_usage_usec, 1)) | 222 | if (!values_close_report(usage_usec, expected_usage_usec, 1)) |
| 223 | goto cleanup; | 223 | goto cleanup; |
| 224 | 224 | ||
| 225 | ret = KSFT_PASS; | 225 | ret = KSFT_PASS; |
| @@ -291,7 +291,7 @@ static int test_cpucg_nice(const char *root) · 65 unmodified lines | |||
| 291 | 291 | ||
| 292 | user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec"); | 292 | user_usec = cg_read_key_long(cpucg, "cpu.stat", "user_usec"); |
| 293 | nice_usec = cg_read_key_long(cpucg, "cpu.stat", "nice_usec"); | 293 | nice_usec = cg_read_key_long(cpucg, "cpu.stat", "nice_usec"); |
| 294 | if (!values_close(nice_usec, expected_nice_usec, 1)) | 294 | if (!values_close_report(nice_usec, expected_nice_usec, 1)) |
| 295 | goto cleanup; | 295 | goto cleanup; |
| 296 | 296 | ||
| 297 | ret = KSFT_PASS; | 297 | ret = KSFT_PASS; |
| @@ -404,7 +404,7 @@ overprovision_validate(const struct cpu_hogger *children, int num_children) · 106 unmodified lines | |||
| 404 | goto cleanup; | 404 | goto cleanup; |
| 405 | 405 | ||
| 406 | delta = children[i + 1].usage - children[i].usage; | 406 | delta = children[i + 1].usage - children[i].usage; |
| 407 | if (!values_close(delta, children[0].usage, 35)) | 407 | if (!values_close_report(delta, children[0].usage, 35)) |
| 408 | goto cleanup; | 408 | goto cleanup; |
| 409 | } | 409 | } |
| 410 | 410 | ||
| @@ -444,7 +444,7 @@ underprovision_validate(const struct cpu_hogger *children, int num_children) · 33 unmodified lines | |||
| 444 | int ret = KSFT_FAIL, i; | 444 | int ret = KSFT_FAIL, i; |
| 445 | 445 | ||
| 446 | for (i = 0; i < num_children - 1; i++) { | 446 | for (i = 0; i < num_children - 1; i++) { |
| 447 | if (!values_close(children[i + 1].usage, children[0].usage, 15)) | 447 | if (!values_close_report(children[i + 1].usage, children[0].usage, 15)) |
| 448 | goto cleanup; | 448 | goto cleanup; |
| 449 | } | 449 | } |
| 450 | 450 | ||
| @@ -573,16 +573,16 @@ run_cpucg_nested_weight_test(const char *root, bool overprovisioned) · 122 unmodified lines | |||
| 573 | 573 | ||
| 574 | nested_leaf_usage = leaf[1].usage + leaf[2].usage; | 574 | nested_leaf_usage = leaf[1].usage + leaf[2].usage; |
| 575 | if (overprovisioned) { | 575 | if (overprovisioned) { |
| 576 | if (!values_close(leaf[0].usage, nested_leaf_usage, 15)) | 576 | if (!values_close_report(leaf[0].usage, nested_leaf_usage, 15)) |
| 577 | goto cleanup; | 577 | goto cleanup; |
| 578 | } else if (!values_close(leaf[0].usage * 2, nested_leaf_usage, 15)) | 578 | } else if (!values_close_report(leaf[0].usage * 2, nested_leaf_usage, 15)) |
| 579 | goto cleanup; | 579 | goto cleanup; |
| 580 | 580 | ||
| 581 | 581 | ||
| 582 | child_usage = cg_read_key_long(child, "cpu.stat", "usage_usec"); | 582 | child_usage = cg_read_key_long(child, "cpu.stat", "usage_usec"); |
| 583 | if (child_usage <= 0) | 583 | if (child_usage <= 0) |
| 584 | goto cleanup; | 584 | goto cleanup; |
| 585 | if (!values_close(child_usage, nested_leaf_usage, 1)) | 585 | if (!values_close_report(child_usage, nested_leaf_usage, 1)) |
| 586 | goto cleanup; | 586 | goto cleanup; |
| 587 | 587 | ||
| 588 | ret = KSFT_PASS; | 588 | ret = KSFT_PASS; |
| @@ -691,7 +691,7 @@ static int test_cpucg_max(const char *root) · 102 unmodified lines | |||
| 691 | expected_usage_usec | 691 | expected_usage_usec |
| 692 | = n_periods * quota_usec + MIN(remainder_usec, quota_usec); | 692 | = n_periods * quota_usec + MIN(remainder_usec, quota_usec); |
| 693 | 693 | ||
| 694 | if (!values_close(usage_usec, expected_usage_usec, 10)) | 694 | if (!values_close_report(usage_usec, expected_usage_usec, 10)) |
| 695 | goto cleanup; | 695 | goto cleanup; |
| 696 | 696 | ||
| 697 | ret = KSFT_PASS; | 697 | ret = KSFT_PASS; |
| @@ -762,7 +762,7 @@ static int test_cpucg_max_nested(const char *root) · 64 unmodified lines | |||
| 762 | expected_usage_usec | 762 | expected_usage_usec |
| 763 | = n_periods * quota_usec + MIN(remainder_usec, quota_usec); | 763 | = n_periods * quota_usec + MIN(remainder_usec, quota_usec); |
| 764 | 764 | ||
| 765 | if (!values_close(usage_usec, expected_usage_usec, 10)) | 765 | if (!values_close_report(usage_usec, expected_usage_usec, 10)) |
| 766 | goto cleanup; | 766 | goto cleanup; |
| 767 | 767 | ||
| 768 | ret = KSFT_PASS; | 768 | ret = KSFT_PASS; |
| @@ -2324,7 +2324,7 @@ laminar_endp_tests() · 2323 unmodified lines | |||
| 2324 | { | 2324 | { |
| 2325 | # no laminar endpoints: routing rules are used | 2325 | # no laminar endpoints: routing rules are used |
| 2326 | if reset_with_tcp_filter "without a laminar endpoint" ns1 10.0.2.2 REJECT && | 2326 | if reset_with_tcp_filter "without a laminar endpoint" ns1 10.0.2.2 REJECT && |
| 2327 | mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then | 2327 | continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then |
| 2328 | pm_nl_set_limits $ns1 0 2 | 2328 | pm_nl_set_limits $ns1 0 2 |
| 2329 | pm_nl_set_limits $ns2 2 2 | 2329 | pm_nl_set_limits $ns2 2 2 |
| 2330 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 2330 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -2336,7 +2336,7 @@ laminar_endp_tests() · 5 unmodified lines | |||
| 2336 | 2336 | ||
| 2337 | # laminar endpoints: this endpoint is used | 2337 | # laminar endpoints: this endpoint is used |
| 2338 | if reset_with_tcp_filter "with a laminar endpoint" ns1 10.0.2.2 REJECT && | 2338 | if reset_with_tcp_filter "with a laminar endpoint" ns1 10.0.2.2 REJECT && |
| 2339 | mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then | 2339 | continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then |
| 2340 | pm_nl_set_limits $ns1 0 2 | 2340 | pm_nl_set_limits $ns1 0 2 |
| 2341 | pm_nl_set_limits $ns2 2 2 | 2341 | pm_nl_set_limits $ns2 2 2 |
| 2342 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 2342 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -2348,7 +2348,7 @@ laminar_endp_tests() · 5 unmodified lines | |||
| 2348 | 2348 | ||
| 2349 | # laminar endpoints: these endpoints are used | 2349 | # laminar endpoints: these endpoints are used |
| 2350 | if reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT && | 2350 | if reset_with_tcp_filter "with multiple laminar endpoints" ns1 10.0.2.2 REJECT && |
| 2351 | mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then | 2351 | continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then |
| 2352 | pm_nl_set_limits $ns1 0 2 | 2352 | pm_nl_set_limits $ns1 0 2 |
| 2353 | pm_nl_set_limits $ns2 2 2 | 2353 | pm_nl_set_limits $ns2 2 2 |
| 2354 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 2354 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -2363,7 +2363,7 @@ laminar_endp_tests() · 8 unmodified lines | |||
| 2363 | 2363 | ||
| 2364 | # laminar endpoints: only one endpoint is used | 2364 | # laminar endpoints: only one endpoint is used |
| 2365 | if reset_with_tcp_filter "single laminar endpoint" ns1 10.0.2.2 REJECT && | 2365 | if reset_with_tcp_filter "single laminar endpoint" ns1 10.0.2.2 REJECT && |
| 2366 | mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then | 2366 | continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then |
| 2367 | pm_nl_set_limits $ns1 0 2 | 2367 | pm_nl_set_limits $ns1 0 2 |
| 2368 | pm_nl_set_limits $ns2 2 2 | 2368 | pm_nl_set_limits $ns2 2 2 |
| 2369 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 2369 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -2376,7 +2376,7 @@ laminar_endp_tests() · 6 unmodified lines | |||
| 2376 | 2376 | ||
| 2377 | # laminar endpoints: subflow and laminar flags | 2377 | # laminar endpoints: subflow and laminar flags |
| 2378 | if reset_with_tcp_filter "sublow + laminar endpoints" ns1 10.0.2.2 REJECT && | 2378 | if reset_with_tcp_filter "sublow + laminar endpoints" ns1 10.0.2.2 REJECT && |
| 2379 | mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then | 2379 | continue_if mptcp_lib_kallsyms_has "mptcp_pm_get_endp_laminar_max$"; then |
| 2380 | pm_nl_set_limits $ns1 0 4 | 2380 | pm_nl_set_limits $ns1 0 4 |
| 2381 | pm_nl_set_limits $ns2 2 4 | 2381 | pm_nl_set_limits $ns2 2 4 |
| 2382 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 2382 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -3939,7 +3939,7 @@ endpoint_tests() · 1556 unmodified lines | |||
| 3939 | # subflow_rebuild_header is needed to support the implicit flag | 3939 | # subflow_rebuild_header is needed to support the implicit flag |
| 3940 | # userspace pm type prevents add_addr | 3940 | # userspace pm type prevents add_addr |
| 3941 | if reset "implicit EP" && | 3941 | if reset "implicit EP" && |
| 3942 | mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then | 3942 | continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then |
| 3943 | pm_nl_set_limits $ns1 2 2 | 3943 | pm_nl_set_limits $ns1 2 2 |
| 3944 | pm_nl_set_limits $ns2 2 2 | 3944 | pm_nl_set_limits $ns2 2 2 |
| 3945 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal | 3945 | pm_nl_add_endpoint $ns1 10.0.2.1 flags signal |
| @@ -3964,7 +3964,7 @@ endpoint_tests() · 18 unmodified lines | |||
| 3964 | fi | 3964 | fi |
| 3965 | 3965 | ||
| 3966 | if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT && | 3966 | if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT && |
| 3967 | mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then | 3967 | continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then |
| 3968 | start_events | 3968 | start_events |
| 3969 | pm_nl_set_limits $ns1 0 3 | 3969 | pm_nl_set_limits $ns1 0 3 |
| 3970 | pm_nl_set_limits $ns2 0 3 | 3970 | pm_nl_set_limits $ns2 0 3 |
| @@ -4040,7 +4040,7 @@ endpoint_tests() · 69 unmodified lines | |||
| 4040 | 4040 | ||
| 4041 | # remove and re-add | 4041 | # remove and re-add |
| 4042 | if reset_with_events "delete re-add signal" && | 4042 | if reset_with_events "delete re-add signal" && |
| 4043 | mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then | 4043 | continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then |
| 4044 | ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=0 | 4044 | ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=0 |
| 4045 | pm_nl_set_limits $ns1 0 3 | 4045 | pm_nl_set_limits $ns1 0 3 |
| 4046 | pm_nl_set_limits $ns2 3 3 | 4046 | pm_nl_set_limits $ns2 3 3 |
| @@ -4115,7 +4115,7 @@ endpoint_tests() · 68 unmodified lines | |||
| 4115 | 4115 | ||
| 4116 | # flush and re-add | 4116 | # flush and re-add |
| 4117 | if reset_with_tcp_filter "flush re-add" ns2 10.0.3.2 REJECT OUTPUT && | 4117 | if reset_with_tcp_filter "flush re-add" ns2 10.0.3.2 REJECT OUTPUT && |
| 4118 | mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then | 4118 | continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then |
| 4119 | pm_nl_set_limits $ns1 0 2 | 4119 | pm_nl_set_limits $ns1 0 2 |
| 4120 | pm_nl_set_limits $ns2 1 2 | 4120 | pm_nl_set_limits $ns2 1 2 |
| 4121 | # broadcast IP: no packet for this address will be received on ns1 | 4121 | # broadcast IP: no packet for this address will be received on ns1 |
| @@ -29,7 +29,6 @@ static void set_addr(struct sockaddr_storage *ss, char *ip, char *port, int *len · 28 unmodified lines | |||
| 29 | static int do_client(int argc, char *argv[]) | 29 | static int do_client(int argc, char *argv[]) |
| 30 | { | 30 | { |
| 31 | struct sockaddr_storage ss; | 31 | struct sockaddr_storage ss; |
| 32 | char buf[] = "hello"; | ||
| 33 | int csk, ret, len; | 32 | int csk, ret, len; |
| 34 | 33 | ||
| 35 | if (argc < 5) { | 34 | if (argc < 5) { |
| @@ -56,16 +55,10 @@ static int do_client(int argc, char *argv[]) · 20 unmodified lines | |||
| 56 | 55 | ||
| 57 | set_addr(&ss, argv[3], argv[4], &len); | 56 | set_addr(&ss, argv[3], argv[4], &len); |
| 58 | ret = connect(csk, (struct sockaddr *)&ss, len); | 57 | ret = connect(csk, (struct sockaddr *)&ss, len); |
| 59 | if (ret < 0) { | 58 | if (ret < 0) |
| 60 | printf("failed to connect to peer\n"); | ||
| 61 | return -1; | 59 | return -1; |
| 62 | } | ||
| 63 | 60 | ||
| 64 | ret = send(csk, buf, strlen(buf) + 1, 0); | 61 | recv(csk, NULL, 0, 0); |
| 65 | if (ret < 0) { | ||
| 66 | printf("failed to send msg %d\n", ret); | ||
| 67 | return -1; | ||
| 68 | } | ||
| 69 | close(csk); | 62 | close(csk); |
| 70 | 63 | ||
| 71 | return 0; | 64 | return 0; |
| @@ -75,7 +68,6 @@ int main(int argc, char *argv[]) · 3 unmodified lines | |||
| 75 | { | 68 | { |
| 76 | struct sockaddr_storage ss; | 69 | struct sockaddr_storage ss; |
| 77 | int lsk, csk, ret, len; | 70 | int lsk, csk, ret, len; |
| 78 | char buf[20]; | ||
| 79 | 71 | ||
| 80 | if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { | 72 | if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { |
| 81 | printf("%s server|client ...\n", argv[0]); | 73 | printf("%s server|client ...\n", argv[0]); |
| @@ -125,11 +117,6 @@ int main(int argc, char *argv[]) · 43 unmodified lines | |||
| 125 | return -1; | 117 | return -1; |
| 126 | } | 118 | } |
| 127 | 119 | ||
| 128 | ret = recv(csk, buf, sizeof(buf), 0); | ||
| 129 | if (ret <= 0) { | ||
| 130 | printf("failed to recv msg %d\n", ret); | ||
| 131 | return -1; | ||
| 132 | } | ||
| 133 | close(csk); | 120 | close(csk); |
| 134 | close(lsk); | 121 | close(lsk); |
| 135 | 122 | ||
| @@ -20,9 +20,9 @@ setup() { · 19 unmodified lines | |||
| 20 | modprobe sctp_diag | 20 | modprobe sctp_diag |
| 21 | setup_ns CLIENT_NS1 CLIENT_NS2 SERVER_NS | 21 | setup_ns CLIENT_NS1 CLIENT_NS2 SERVER_NS |
| 22 | 22 | ||
| 23 | ip net exec $CLIENT_NS1 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null | 23 | ip net exec $CLIENT_NS1 sysctl -wq net.ipv6.conf.default.accept_dad=0 |
| 24 | ip net exec $CLIENT_NS2 sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null | 24 | ip net exec $CLIENT_NS2 sysctl -wq net.ipv6.conf.default.accept_dad=0 |
| 25 | ip net exec $SERVER_NS sysctl -w net.ipv6.conf.default.accept_dad=0 2>&1 >/dev/null | 25 | ip net exec $SERVER_NS sysctl -wq net.ipv6.conf.default.accept_dad=0 |
| 26 | 26 | ||
| 27 | ip -n $SERVER_NS link add veth1 type veth peer name veth1 netns $CLIENT_NS1 | 27 | ip -n $SERVER_NS link add veth1 type veth peer name veth1 netns $CLIENT_NS1 |
| 28 | ip -n $SERVER_NS link add veth2 type veth peer name veth1 netns $CLIENT_NS2 | 28 | ip -n $SERVER_NS link add veth2 type veth peer name veth1 netns $CLIENT_NS2 |
| @@ -62,17 +62,40 @@ setup() { · 33 unmodified lines | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | cleanup() { | 64 | cleanup() { |
| 65 | ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null | 65 | wait_client $CLIENT_NS1 |
| 66 | wait_client $CLIENT_NS2 | ||
| 67 | stop_server | ||
| 66 | cleanup_ns $CLIENT_NS1 $CLIENT_NS2 $SERVER_NS | 68 | cleanup_ns $CLIENT_NS1 $CLIENT_NS2 $SERVER_NS |
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | wait_server() { | 71 | start_server() { |
| 70 | local IFACE=$1 | 72 | local IFACE=$1 |
| 71 | local CNT=0 | 73 | local CNT=0 |
| 72 | 74 | ||
| 73 | until ip netns exec $SERVER_NS ss -lS src $SERVER_IP:$SERVER_PORT | \ | 75 | ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP $SERVER_PORT $IFACE & |
| 74 | grep LISTEN | grep "$IFACE" 2>&1 >/dev/null; do | 76 | disown |
| 75 | [ $((CNT++)) = "20" ] && { RET=3; return $RET; } | 77 | until ip netns exec $SERVER_NS ss -SlH | grep -q "$IFACE"; do |
| 78 | [ $((CNT++)) -eq 30 ] && { RET=3; return $RET; } | ||
| 79 | sleep 0.1 | ||
| 80 | done | ||
| 81 | } | ||
| 82 | |||
| 83 | stop_server() { | ||
| 84 | local CNT=0 | ||
| 85 | |||
| 86 | ip netns exec $SERVER_NS pkill sctp_hello | ||
| 87 | while ip netns exec $SERVER_NS ss -SaH | grep -q .; do | ||
| 88 | [ $((CNT++)) -eq 30 ] && break | ||
| 89 | sleep 0.1 | ||
| 90 | done | ||
| 91 | } | ||
| 92 | |||
| 93 | wait_client() { | ||
| 94 | local CLIENT_NS=$1 | ||
| 95 | local CNT=0 | ||
| 96 | |||
| 97 | while ip netns exec $CLIENT_NS ss -SaH | grep -q .; do | ||
| 98 | [ $((CNT++)) -eq 30 ] && break | ||
| 76 | sleep 0.1 | 99 | sleep 0.1 |
| 77 | done | 100 | done |
| 78 | } | 101 | } |
| @@ -81,14 +104,12 @@ do_test() { · 2 unmodified lines | |||
| 81 | local CLIENT_NS=$1 | 104 | local CLIENT_NS=$1 |
| 82 | local IFACE=$2 | 105 | local IFACE=$2 |
| 83 | 106 | ||
| 84 | ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null | 107 | start_server $IFACE || return $RET |
| 85 | ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ | ||
| 86 | $SERVER_PORT $IFACE 2>&1 >/dev/null & | ||
| 87 | disown | ||
| 88 | wait_server $IFACE || return $RET | ||
| 89 | timeout 3 ip netns exec $CLIENT_NS ./sctp_hello client $AF \ | 108 | timeout 3 ip netns exec $CLIENT_NS ./sctp_hello client $AF \ |
| 90 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null | 109 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT |
| 91 | RET=$? | 110 | RET=$? |
| 111 | wait_client $CLIENT_NS | ||
| 112 | stop_server | ||
| 92 | return $RET | 113 | return $RET |
| 93 | } | 114 | } |
| 94 | 115 | ||
| @@ -96,25 +117,21 @@ do_testx() { · 1 unmodified line | |||
| 96 | local IFACE1=$1 | 117 | local IFACE1=$1 |
| 97 | local IFACE2=$2 | 118 | local IFACE2=$2 |
| 98 | 119 | ||
| 99 | ip netns exec $SERVER_NS pkill sctp_hello 2>&1 >/dev/null | 120 | start_server $IFACE1 || return $RET |
| 100 | ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ | 121 | start_server $IFACE2 || return $RET |
| 101 | $SERVER_PORT $IFACE1 2>&1 >/dev/null & | ||
| 102 | disown | ||
| 103 | wait_server $IFACE1 || return $RET | ||
| 104 | ip netns exec $SERVER_NS ./sctp_hello server $AF $SERVER_IP \ | ||
| 105 | $SERVER_PORT $IFACE2 2>&1 >/dev/null & | ||
| 106 | disown | ||
| 107 | wait_server $IFACE2 || return $RET | ||
| 108 | timeout 3 ip netns exec $CLIENT_NS1 ./sctp_hello client $AF \ | 122 | timeout 3 ip netns exec $CLIENT_NS1 ./sctp_hello client $AF \ |
| 109 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null && \ | 123 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT && \ |
| 110 | timeout 3 ip netns exec $CLIENT_NS2 ./sctp_hello client $AF \ | 124 | timeout 3 ip netns exec $CLIENT_NS2 ./sctp_hello client $AF \ |
| 111 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT 2>&1 >/dev/null | 125 | $SERVER_IP $SERVER_PORT $CLIENT_IP $CLIENT_PORT |
| 112 | RET=$? | 126 | RET=$? |
| 127 | wait_client $CLIENT_NS1 | ||
| 128 | wait_client $CLIENT_NS2 | ||
| 129 | stop_server | ||
| 113 | return $RET | 130 | return $RET |
| 114 | } | 131 | } |
| 115 | 132 | ||
| 116 | testup() { | 133 | testup() { |
| 117 | ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=1 2>&1 >/dev/null | 134 | ip netns exec $SERVER_NS sysctl -wq net.sctp.l3mdev_accept=1 |
| 118 | echo -n "TEST 01: nobind, connect from client 1, l3mdev_accept=1, Y " | 135 | echo -n "TEST 01: nobind, connect from client 1, l3mdev_accept=1, Y " |
| 119 | do_test $CLIENT_NS1 || { echo "[FAIL]"; return $RET; } | 136 | do_test $CLIENT_NS1 || { echo "[FAIL]"; return $RET; } |
| 120 | echo "[PASS]" | 137 | echo "[PASS]" |
| @@ -123,7 +140,7 @@ testup() { · 2 unmodified lines | |||
| 123 | do_test $CLIENT_NS2 && { echo "[FAIL]"; return $RET; } | 140 | do_test $CLIENT_NS2 && { echo "[FAIL]"; return $RET; } |
| 124 | echo "[PASS]" | 141 | echo "[PASS]" |
| 125 | 142 | ||
| 126 | ip netns exec $SERVER_NS sysctl -w net.sctp.l3mdev_accept=0 2>&1 >/dev/null | 143 | ip netns exec $SERVER_NS sysctl -wq net.sctp.l3mdev_accept=0 |
| 127 | echo -n "TEST 03: nobind, connect from client 1, l3mdev_accept=0, N " | 144 | echo -n "TEST 03: nobind, connect from client 1, l3mdev_accept=0, N " |
| 128 | do_test $CLIENT_NS1 && { echo "[FAIL]"; return $RET; } | 145 | do_test $CLIENT_NS1 && { echo "[FAIL]"; return $RET; } |
| 129 | echo "[PASS]" | 146 | echo "[PASS]" |
| @@ -160,7 +177,7 @@ testup() { · 30 unmodified lines | |||
| 160 | do_testx vrf-1 vrf-2 || { echo "[FAIL]"; return $RET; } | 177 | do_testx vrf-1 vrf-2 || { echo "[FAIL]"; return $RET; } |
| 161 | echo "[PASS]" | 178 | echo "[PASS]" |
| 162 | 179 | ||
| 163 | echo -n "TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, N " | 180 | echo -n "TEST 12: bind vrf-2 & 1 in server, connect from client 1 & 2, Y " |
| 164 | do_testx vrf-2 vrf-1 || { echo "[FAIL]"; return $RET; } | 181 | do_testx vrf-2 vrf-1 || { echo "[FAIL]"; return $RET; } |
| 165 | echo "[PASS]" | 182 | echo "[PASS]" |
| 166 | } | 183 | } |