Merge conflict of mlx5 resolved using instructions in merge commit 9566e650bf7fdf58384bb06df634f7531ca3a97e.
Unified · Split
| @@ -39,7 +39,6 @@ Table : Subdirectories in /proc/sys/net · 38 unmodified lines | ||
| 39 | 39 | 802 E802 protocol ax25 AX25 |
| 40 | 40 | ethernet Ethernet protocol rose X.25 PLP layer |
| 41 | 41 | ipv4 IP version 4 x25 X.25 protocol |
| 42 | − ipx IPX token-ring IBM token ring | |
| 43 | 42 | bridge Bridging decnet DEC net |
| 44 | 43 | ipv6 IP version 6 tipc TIPC |
| 45 | 44 | ========= =================== = ========== ================== |
| @@ -401,33 +400,7 @@ interface. · 355 unmodified lines | ||
| 401 | 400 | (network) that the route leads to, the router (may be directly connected), the |
| 402 | 401 | route flags, and the device the route is using. |
| 403 | 402 | |
| 404 | − | |
| 405 | −5. IPX | |
| 406 | −------ | |
| 407 | − | |
| 408 | −The IPX protocol has no tunable values in proc/sys/net. | |
| 409 | − | |
| 410 | −The IPX protocol does, however, provide proc/net/ipx. This lists each IPX | |
| 411 | −socket giving the local and remote addresses in Novell format (that is | |
| 412 | −network:node:port). In accordance with the strange Novell tradition, | |
| 413 | −everything but the port is in hex. Not_Connected is displayed for sockets that | |
| 414 | −are not tied to a specific remote address. The Tx and Rx queue sizes indicate | |
| 415 | −the number of bytes pending for transmission and reception. The state | |
| 416 | −indicates the state the socket is in and the uid is the owning uid of the | |
| 417 | −socket. | |
| 418 | − | |
| 419 | −The /proc/net/ipx_interface file lists all IPX interfaces. For each interface | |
| 420 | −it gives the network number, the node number, and indicates if the network is | |
| 421 | −the primary network. It also indicates which device it is bound to (or | |
| 422 | −Internal for internal networks) and the Frame Type if appropriate. Linux | |
| 423 | −supports 802.3, 802.2, 802.2 SNAP and DIX (Blue Book) ethernet framing for | |
| 424 | −IPX. | |
| 425 | − | |
| 426 | −The /proc/net/ipx_route table holds a list of IPX routes. For each route it | |
| 427 | −gives the destination network, the router node (or Directly) and the network | |
| 428 | −address of the router (or Connected) for internal networks. | |
| 429 | − | |
| 430 | −6. TIPC | |
| 403 | +5. TIPC | |
| 431 | 404 | ------- |
| 432 | 405 | |
| 433 | 406 | tipc_rmem |
| @@ -19,7 +19,9 @@ quiet_cmd_mk_schema = SCHEMA $@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | DT_DOCS = $(shell \ |
| 21 | 21 | cd $(srctree)/$(src) && \ |
| 22 | − find * \( -name '*.yaml' ! -name $(DT_TMP_SCHEMA) \) \ | |
| 22 | + find * \( -name '*.yaml' ! \ | |
| 23 | + -name $(DT_TMP_SCHEMA) ! \ | |
| 24 | + -name '*.example.dt.yaml' \) \ | |
| 23 | 25 | ) |
| 24 | 26 | |
| 25 | 27 | DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS)) |
| @@ -7,18 +7,6 @@ Required properties: · 6 unmodified lines | ||
| 7 | 7 | - phy-mode : See ethernet.txt file in the same directory |
| 8 | 8 | |
| 9 | 9 | Optional properties: |
| 10 | −- phy-reset-gpios : Should specify the gpio for phy reset | |
| 11 | −- phy-reset-duration : Reset duration in milliseconds. Should present | |
| 12 | − only if property "phy-reset-gpios" is available. Missing the property | |
| 13 | − will have the duration be 1 millisecond. Numbers greater than 1000 are | |
| 14 | − invalid and 1 millisecond will be used instead. | |
| 15 | −- phy-reset-active-high : If present then the reset sequence using the GPIO | |
| 16 | − specified in the "phy-reset-gpios" property is reversed (H=reset state, | |
| 17 | − L=operation state). | |
| 18 | −- phy-reset-post-delay : Post reset delay in milliseconds. If present then | |
| 19 | − a delay of phy-reset-post-delay milliseconds will be observed after the | |
| 20 | − phy-reset-gpios has been toggled. Can be omitted thus no delay is | |
| 21 | − observed. Delay is in range of 1ms to 1000ms. Other delays are invalid. | |
| 22 | 10 | - phy-supply : regulator that powers the Ethernet PHY. |
| 23 | 11 | - phy-handle : phandle to the PHY device connected to this device. |
| 24 | 12 | - fixed-link : Assume a fixed link. See fixed-link.txt in the same directory. |
| @@ -47,11 +35,27 @@ Optional properties: · 22 unmodified lines | ||
| 47 | 35 | For imx6sx, "int0" handles all 3 queues and ENET_MII. "pps" is for the pulse |
| 48 | 36 | per second interrupt associated with 1588 precision time protocol(PTP). |
| 49 | 37 | |
| 50 | − | |
| 51 | 38 | Optional subnodes: |
| 52 | 39 | - mdio : specifies the mdio bus in the FEC, used as a container for phy nodes |
| 53 | 40 | according to phy.txt in the same directory |
| 54 | 41 | |
| 42 | +Deprecated optional properties: | |
| 43 | + To avoid these, create a phy node according to phy.txt in the same | |
| 44 | + directory, and point the fec's "phy-handle" property to it. Then use | |
| 45 | + the phy's reset binding, again described by phy.txt. | |
| 46 | +- phy-reset-gpios : Should specify the gpio for phy reset | |
| 47 | +- phy-reset-duration : Reset duration in milliseconds. Should present | |
| 48 | + only if property "phy-reset-gpios" is available. Missing the property | |
| 49 | + will have the duration be 1 millisecond. Numbers greater than 1000 are | |
| 50 | + invalid and 1 millisecond will be used instead. | |
| 51 | +- phy-reset-active-high : If present then the reset sequence using the GPIO | |
| 52 | + specified in the "phy-reset-gpios" property is reversed (H=reset state, | |
| 53 | + L=operation state). | |
| 54 | +- phy-reset-post-delay : Post reset delay in milliseconds. If present then | |
| 55 | + a delay of phy-reset-post-delay milliseconds will be observed after the | |
| 56 | + phy-reset-gpios has been toggled. Can be omitted thus no delay is | |
| 57 | + observed. Delay is in range of 1ms to 1000ms. Other delays are invalid. | |
| 58 | + | |
| 55 | 59 | Example: |
| 56 | 60 | |
| 57 | 61 | ethernet@83fec000 { |
| @@ -37,7 +37,8 @@ properties: · 36 unmodified lines | ||
| 37 | 37 | hwlocks: true |
| 38 | 38 | |
| 39 | 39 | st,syscfg: |
| 40 | − $ref: "/schemas/types.yaml#/definitions/phandle-array" | |
| 40 | + allOf: | |
| 41 | + - $ref: "/schemas/types.yaml#/definitions/phandle-array" | |
| 41 | 42 | description: Should be phandle/offset/mask |
| 42 | 43 | items: |
| 43 | 44 | - description: Phandle to the syscon node which includes IRQ mux selection. |
| @@ -1,162 +0,0 @@ | ||
| 1 | −=================== | |
| 2 | −RISC-V CPU Bindings | |
| 3 | −=================== | |
| 4 | − | |
| 5 | −The device tree allows to describe the layout of CPUs in a system through | |
| 6 | −the "cpus" node, which in turn contains a number of subnodes (ie "cpu") | |
| 7 | −defining properties for every cpu. | |
| 8 | − | |
| 9 | −Bindings for CPU nodes follow the Devicetree Specification, available from: | |
| 10 | − | |
| 11 | −https://www.devicetree.org/specifications/ | |
| 12 | − | |
| 13 | −with updates for 32-bit and 64-bit RISC-V systems provided in this document. | |
| 14 | − | |
| 15 | −=========== | |
| 16 | −Terminology | |
| 17 | −=========== | |
| 18 | − | |
| 19 | −This document uses some terminology common to the RISC-V community that is not | |
| 20 | −widely used, the definitions of which are listed here: | |
| 21 | − | |
| 22 | −* hart: A hardware execution context, which contains all the state mandated by | |
| 23 | − the RISC-V ISA: a PC and some registers. This terminology is designed to | |
| 24 | − disambiguate software's view of execution contexts from any particular | |
| 25 | − microarchitectural implementation strategy. For example, my Intel laptop is | |
| 26 | − described as having one socket with two cores, each of which has two hyper | |
| 27 | − threads. Therefore this system has four harts. | |
| 28 | − | |
| 29 | −===================================== | |
| 30 | −cpus and cpu node bindings definition | |
| 31 | −===================================== | |
| 32 | − | |
| 33 | −The RISC-V architecture, in accordance with the Devicetree Specification, | |
| 34 | −requires the cpus and cpu nodes to be present and contain the properties | |
| 35 | −described below. | |
| 36 | − | |
| 37 | −- cpus node | |
| 38 | − | |
| 39 | − Description: Container of cpu nodes | |
| 40 | − | |
| 41 | − The node name must be "cpus". | |
| 42 | − | |
| 43 | − A cpus node must define the following properties: | |
| 44 | − | |
| 45 | − - #address-cells | |
| 46 | − Usage: required | |
| 47 | − Value type: <u32> | |
| 48 | − Definition: must be set to 1 | |
| 49 | − - #size-cells | |
| 50 | − Usage: required | |
| 51 | − Value type: <u32> | |
| 52 | − Definition: must be set to 0 | |
| 53 | − | |
| 54 | −- cpu node | |
| 55 | − | |
| 56 | − Description: Describes a hart context | |
| 57 | − | |
| 58 | − PROPERTIES | |
| 59 | − | |
| 60 | − - device_type | |
| 61 | − Usage: required | |
| 62 | − Value type: <string> | |
| 63 | − Definition: must be "cpu" | |
| 64 | − - reg | |
| 65 | − Usage: required | |
| 66 | − Value type: <u32> | |
| 67 | − Definition: The hart ID of this CPU node | |
| 68 | − - compatible: | |
| 69 | − Usage: required | |
| 70 | − Value type: <stringlist> | |
| 71 | − Definition: must contain "riscv", may contain one of | |
| 72 | − "sifive,rocket0" | |
| 73 | − - mmu-type: | |
| 74 | − Usage: optional | |
| 75 | − Value type: <string> | |
| 76 | − Definition: Specifies the CPU's MMU type. Possible values are | |
| 77 | − "riscv,sv32" | |
| 78 | − "riscv,sv39" | |
| 79 | − "riscv,sv48" | |
| 80 | − - riscv,isa: | |
| 81 | − Usage: required | |
| 82 | − Value type: <string> | |
| 83 | − Definition: Contains the RISC-V ISA string of this hart. These | |
| 84 | − ISA strings are defined by the RISC-V ISA manual. | |
| 85 | − | |
| 86 | −Example: SiFive Freedom U540G Development Kit | |
| 87 | −--------------------------------------------- | |
| 88 | − | |
| 89 | −This system contains two harts: a hart marked as disabled that's used for | |
| 90 | −low-level system tasks and should be ignored by Linux, and a second hart that | |
| 91 | −Linux is allowed to run on. | |
| 92 | − | |
| 93 | − cpus { | |
| 94 | − #address-cells = <1>; | |
| 95 | − #size-cells = <0>; | |
| 96 | − timebase-frequency = <1000000>; | |
| 97 | − cpu@0 { | |
| 98 | − clock-frequency = <1600000000>; | |
| 99 | − compatible = "sifive,rocket0", "riscv"; | |
| 100 | − device_type = "cpu"; | |
| 101 | − i-cache-block-size = <64>; | |
| 102 | − i-cache-sets = <128>; | |
| 103 | − i-cache-size = <16384>; | |
| 104 | − next-level-cache = <&L15 &L0>; | |
| 105 | − reg = <0>; | |
| 106 | − riscv,isa = "rv64imac"; | |
| 107 | − status = "disabled"; | |
| 108 | − L10: interrupt-controller { | |
| 109 | − #interrupt-cells = <1>; | |
| 110 | − compatible = "riscv,cpu-intc"; | |
| 111 | − interrupt-controller; | |
| 112 | − }; | |
| 113 | − }; | |
| 114 | − cpu@1 { | |
| 115 | − clock-frequency = <1600000000>; | |
| 116 | − compatible = "sifive,rocket0", "riscv"; | |
| 117 | − d-cache-block-size = <64>; | |
| 118 | − d-cache-sets = <64>; | |
| 119 | − d-cache-size = <32768>; | |
| 120 | − d-tlb-sets = <1>; | |
| 121 | − d-tlb-size = <32>; | |
| 122 | − device_type = "cpu"; | |
| 123 | − i-cache-block-size = <64>; | |
| 124 | − i-cache-sets = <64>; | |
| 125 | − i-cache-size = <32768>; | |
| 126 | − i-tlb-sets = <1>; | |
| 127 | − i-tlb-size = <32>; | |
| 128 | − mmu-type = "riscv,sv39"; | |
| 129 | − next-level-cache = <&L15 &L0>; | |
| 130 | − reg = <1>; | |
| 131 | − riscv,isa = "rv64imafdc"; | |
| 132 | − status = "okay"; | |
| 133 | − tlb-split; | |
| 134 | − L13: interrupt-controller { | |
| 135 | − #interrupt-cells = <1>; | |
| 136 | − compatible = "riscv,cpu-intc"; | |
| 137 | − interrupt-controller; | |
| 138 | − }; | |
| 139 | − }; | |
| 140 | − }; | |
| 141 | − | |
| 142 | −Example: Spike ISA Simulator with 1 Hart | |
| 143 | −---------------------------------------- | |
| 144 | − | |
| 145 | −This device tree matches the Spike ISA golden model as run with `spike -p1`. | |
| 146 | − | |
| 147 | − cpus { | |
| 148 | − cpu@0 { | |
| 149 | − device_type = "cpu"; | |
| 150 | − reg = <0x00000000>; | |
| 151 | − status = "okay"; | |
| 152 | − compatible = "riscv"; | |
| 153 | − riscv,isa = "rv64imafdc"; | |
| 154 | − mmu-type = "riscv,sv48"; | |
| 155 | − clock-frequency = <0x3b9aca00>; | |
| 156 | − interrupt-controller { | |
| 157 | − #interrupt-cells = <0x00000001>; | |
| 158 | − interrupt-controller; | |
| 159 | − compatible = "riscv,cpu-intc"; | |
| 160 | − } | |
| 161 | − } | |
| 162 | − } | |
| @@ -10,6 +10,18 @@ maintainers: · 9 unmodified lines | ||
| 10 | 10 | - Paul Walmsley <paul.walmsley@sifive.com> |
| 11 | 11 | - Palmer Dabbelt <palmer@sifive.com> |
| 12 | 12 | |
| 13 | +description: | | |
| 14 | + This document uses some terminology common to the RISC-V community | |
| 15 | + that is not widely used, the definitions of which are listed here: | |
| 16 | + | |
| 17 | + hart: A hardware execution context, which contains all the state | |
| 18 | + mandated by the RISC-V ISA: a PC and some registers. This | |
| 19 | + terminology is designed to disambiguate software's view of execution | |
| 20 | + contexts from any particular microarchitectural implementation | |
| 21 | + strategy. For example, an Intel laptop containing one socket with | |
| 22 | + two cores, each of which has two hyperthreads, could be described as | |
| 23 | + having four harts. | |
| 24 | + | |
| 13 | 25 | properties: |
| 14 | 26 | compatible: |
| 15 | 27 | items: |
| @@ -50,6 +62,10 @@ properties: · 34 unmodified lines | ||
| 50 | 62 | User-Level ISA document, available from |
| 51 | 63 | https://riscv.org/specifications/ |
| 52 | 64 | |
| 65 | + While the isa strings in ISA specification are case | |
| 66 | + insensitive, letters in the riscv,isa string must be all | |
| 67 | + lowercase to simplify parsing. | |
| 68 | + | |
| 53 | 69 | timebase-frequency: |
| 54 | 70 | type: integer |
| 55 | 71 | minimum: 1 |
| @@ -19,7 +19,7 @@ properties: · 18 unmodified lines | ||
| 19 | 19 | compatible: |
| 20 | 20 | items: |
| 21 | 21 | - enum: |
| 22 | − - sifive,freedom-unleashed-a00 | |
| 22 | + - sifive,hifive-unleashed-a00 | |
| 23 | 23 | - const: sifive,fu540-c000 |
| 24 | 24 | - const: sifive,fu540 |
| 25 | 25 | ... |
| @@ -13,7 +13,8 @@ a) SMB3 (and SMB3.1.1) missing optional features: · 12 unmodified lines | ||
| 13 | 13 | - T10 copy offload ie "ODX" (copy chunk, and "Duplicate Extents" ioctl |
| 14 | 14 | currently the only two server side copy mechanisms supported) |
| 15 | 15 | |
| 16 | −b) improved sparse file support | |
| 16 | +b) improved sparse file support (fiemap and SEEK_HOLE are implemented | |
| 17 | +but additional features would be supportable by the protocol). | |
| 17 | 18 | |
| 18 | 19 | c) Directory entry caching relies on a 1 second timer, rather than |
| 19 | 20 | using Directory Leases, currently only the root file handle is cached longer |
| @@ -21,9 +22,13 @@ using Directory Leases, currently only the root file handle is cached longer · 1 unmodified line | ||
| 21 | 22 | d) quota support (needs minor kernel change since quota calls |
| 22 | 23 | to make it to network filesystems or deviceless filesystems) |
| 23 | 24 | |
| 24 | −e) Additional use cases where we use "compoounding" (e.g. open/query/close | |
| 25 | −and open/setinfo/close) to reduce the number of roundtrips, and also | |
| 26 | −open to reduce redundant opens (using deferred close and reference counts more). | |
| 25 | +e) Additional use cases can be optimized to use "compounding" | |
| 26 | +(e.g. open/query/close and open/setinfo/close) to reduce the number | |
| 27 | +of roundtrips to the server and improve performance. Various cases | |
| 28 | +(stat, statfs, create, unlink, mkdir) already have been improved by | |
| 29 | +using compounding but more can be done. In addition we could significantly | |
| 30 | +reduce redundant opens by using deferred close (with handle caching leases) | |
| 31 | +and better using reference counters on file handles. | |
| 27 | 32 | |
| 28 | 33 | f) Finish inotify support so kde and gnome file list windows |
| 29 | 34 | will autorefresh (partially complete by Asser). Needs minor kernel |
| @@ -43,18 +48,17 @@ mount or a per server basis to client UIDs or nobody if no mapping · 13 unmodified lines | ||
| 43 | 48 | exists. Also better integration with winbind for resolving SID owners |
| 44 | 49 | |
| 45 | 50 | k) Add tools to take advantage of more smb3 specific ioctls and features |
| 46 | −(passthrough ioctl/fsctl for sending various SMB3 fsctls to the server | |
| 47 | −is in progress, and a passthrough query_info call is already implemented | |
| 48 | −in cifs.ko to allow smb3 info levels queries to be sent from userspace) | |
| 51 | +(passthrough ioctl/fsctl is now implemented in cifs.ko to allow sending | |
| 52 | +various SMB3 fsctls and query info and set info calls directly from user space) | |
| 53 | +Add tools to make setting various non-POSIX metadata attributes easier | |
| 54 | +from tools (e.g. extending what was done in smb-info tool). | |
| 49 | 55 | |
| 50 | 56 | l) encrypted file support |
| 51 | 57 | |
| 52 | 58 | m) improved stats gathering tools (perhaps integration with nfsometer?) |
| 53 | 59 | to extend and make easier to use what is currently in /proc/fs/cifs/Stats |
| 54 | 60 | |
| 55 | −n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed | |
| 56 | −file attribute via chflags) and improve user space tools for managing and | |
| 57 | −viewing them. | |
| 61 | +n) Add support for claims based ACLs ("DAC") | |
| 58 | 62 | |
| 59 | 63 | o) mount helper GUI (to simplify the various configuration options on mount) |
| 60 | 64 | |
| @@ -82,6 +86,8 @@ so far). · 21 unmodified lines | ||
| 82 | 86 | w) Add support for additional strong encryption types, and additional spnego |
| 83 | 87 | authentication mechanisms (see MS-SMB2) |
| 84 | 88 | |
| 89 | +x) Finish support for SMB3.1.1 compression | |
| 90 | + | |
| 85 | 91 | KNOWN BUGS |
| 86 | 92 | ==================================== |
| 87 | 93 | See http://bugzilla.samba.org - search on product "CifsVFS" for |
| @@ -506,21 +506,3 @@ Drivers should ignore the changes to TLS the device feature flags. · 505 unmodified lines | ||
| 506 | 506 | These flags will be acted upon accordingly by the core ``ktls`` code. |
| 507 | 507 | TLS device feature flags only control adding of new TLS connection |
| 508 | 508 | offloads, old connections will remain active after flags are cleared. |
| 509 | − | |
| 510 | −Known bugs | |
| 511 | −========== | |
| 512 | − | |
| 513 | −skb_orphan() leaks clear text | |
| 514 | −----------------------------- | |
| 515 | − | |
| 516 | −Currently drivers depend on the :c:member:`sk` member of | |
| 517 | −:c:type:`struct sk_buff <sk_buff>` to identify segments requiring | |
| 518 | −encryption. Any operation which removes or does not preserve the socket | |
| 519 | −association such as :c:func:`skb_orphan` or :c:func:`skb_clone` | |
| 520 | −will cause the driver to miss the packets and lead to clear text leaks. | |
| 521 | − | |
| 522 | −Redirects leak clear text | |
| 523 | −------------------------- | |
| 524 | − | |
| 525 | −In the RX direction, if segment has already been decrypted by the device | |
| 526 | −and it gets redirected or mirrored - clear text will be transmitted out. | |
| @@ -204,8 +204,8 @@ Ethernet device, which instead of receiving packets from a physical · 203 unmodified lines | ||
| 204 | 204 | media, receives them from user space program and instead of sending |
| 205 | 205 | packets via physical media sends them to the user space program. |
| 206 | 206 | |
| 207 | −Let's say that you configured IPX on the tap0, then whenever | |
| 208 | −the kernel sends an IPX packet to tap0, it is passed to the application | |
| 207 | +Let's say that you configured IPv6 on the tap0, then whenever | |
| 208 | +the kernel sends an IPv6 packet to tap0, it is passed to the application | |
| 209 | 209 | (VTun for example). The application encrypts, compresses and sends it to |
| 210 | 210 | the other side over TCP or UDP. The application on the other side decompresses |
| 211 | 211 | and decrypts the data received and writes the packet to the TAP device, |
| @@ -183,7 +183,7 @@ M: Realtek linux nic maintainers <nic_swsd@realtek.com> · 182 unmodified lines | ||
| 183 | 183 | M: Heiner Kallweit <hkallweit1@gmail.com> |
| 184 | 184 | L: netdev@vger.kernel.org |
| 185 | 185 | S: Maintained |
| 186 | −F: drivers/net/ethernet/realtek/r8169.c | |
| 186 | +F: drivers/net/ethernet/realtek/r8169* | |
| 187 | 187 | |
| 188 | 188 | 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER |
| 189 | 189 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| @@ -6078,7 +6078,7 @@ M: Florian Fainelli <f.fainelli@gmail.com> · 5888 unmodified lines | ||
| 6078 | 6078 | M: Heiner Kallweit <hkallweit1@gmail.com> |
| 6079 | 6079 | L: netdev@vger.kernel.org |
| 6080 | 6080 | S: Maintained |
| 6081 | −F: Documentation/ABI/testing/sysfs-bus-mdio | |
| 6081 | +F: Documentation/ABI/testing/sysfs-class-net-phydev | |
| 6082 | 6082 | F: Documentation/devicetree/bindings/net/ethernet-phy.yaml |
| 6083 | 6083 | F: Documentation/devicetree/bindings/net/mdio* |
| 6084 | 6084 | F: Documentation/networking/phy.rst |
| @@ -6357,7 +6357,7 @@ FPGA MANAGER FRAMEWORK · 272 unmodified lines | ||
| 6357 | 6357 | M: Moritz Fischer <mdf@kernel.org> |
| 6358 | 6358 | L: linux-fpga@vger.kernel.org |
| 6359 | 6359 | S: Maintained |
| 6360 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git | |
| 6360 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git | |
| 6361 | 6361 | Q: http://patchwork.kernel.org/project/linux-fpga/list/ |
| 6362 | 6362 | F: Documentation/fpga/ |
| 6363 | 6363 | F: Documentation/driver-api/fpga/ |
| @@ -6390,7 +6390,7 @@ FRAMEBUFFER LAYER · 26 unmodified lines | ||
| 6390 | 6390 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
| 6391 | 6391 | L: dri-devel@lists.freedesktop.org |
| 6392 | 6392 | L: linux-fbdev@vger.kernel.org |
| 6393 | −T: git git://github.com/bzolnier/linux.git | |
| 6393 | +T: git git://anongit.freedesktop.org/drm/drm-misc | |
| 6394 | 6394 | Q: http://patchwork.kernel.org/project/linux-fbdev/list/ |
| 6395 | 6395 | S: Maintained |
| 6396 | 6396 | F: Documentation/fb/ |
| @@ -6454,6 +6454,14 @@ S: Maintained · 57 unmodified lines | ||
| 6454 | 6454 | F: drivers/perf/fsl_imx8_ddr_perf.c |
| 6455 | 6455 | F: Documentation/devicetree/bindings/perf/fsl-imx-ddr.txt |
| 6456 | 6456 | |
| 6457 | +FREESCALE IMX I2C DRIVER | |
| 6458 | +M: Oleksij Rempel <o.rempel@pengutronix.de> | |
| 6459 | +R: Pengutronix Kernel Team <kernel@pengutronix.de> | |
| 6460 | +L: linux-i2c@vger.kernel.org | |
| 6461 | +S: Maintained | |
| 6462 | +F: drivers/i2c/busses/i2c-imx.c | |
| 6463 | +F: Documentation/devicetree/bindings/i2c/i2c-imx.txt | |
| 6464 | + | |
| 6457 | 6465 | FREESCALE IMX LPI2C DRIVER |
| 6458 | 6466 | M: Dong Aisheng <aisheng.dong@nxp.com> |
| 6459 | 6467 | L: linux-i2c@vger.kernel.org |
| @@ -7465,7 +7473,7 @@ F: drivers/net/hyperv/ · 1005 unmodified lines | ||
| 7465 | 7473 | F: drivers/scsi/storvsc_drv.c |
| 7466 | 7474 | F: drivers/uio/uio_hv_generic.c |
| 7467 | 7475 | F: drivers/video/fbdev/hyperv_fb.c |
| 7468 | −F: drivers/iommu/hyperv_iommu.c | |
| 7476 | +F: drivers/iommu/hyperv-iommu.c | |
| 7469 | 7477 | F: net/vmw_vsock/hyperv_transport.c |
| 7470 | 7478 | F: include/clocksource/hyperv_timer.h |
| 7471 | 7479 | F: include/linux/hyperv.h |
| @@ -8055,6 +8063,7 @@ S: Maintained · 583 unmodified lines | ||
| 8055 | 8063 | F: drivers/video/fbdev/i810/ |
| 8056 | 8064 | |
| 8057 | 8065 | INTEL ASoC DRIVERS |
| 8066 | +M: Cezary Rojewski <cezary.rojewski@intel.com> | |
| 8058 | 8067 | M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> |
| 8059 | 8068 | M: Liam Girdwood <liam.r.girdwood@linux.intel.com> |
| 8060 | 8069 | M: Jie Yang <yang.jie@linux.intel.com> |
| @@ -8076,6 +8085,13 @@ T: git git://git.code.sf.net/p/intel-sas/isci · 15 unmodified lines | ||
| 8076 | 8085 | S: Supported |
| 8077 | 8086 | F: drivers/scsi/isci/ |
| 8078 | 8087 | |
| 8088 | +INTEL CPU family model numbers | |
| 8089 | +M: Tony Luck <tony.luck@intel.com> | |
| 8090 | +M: x86@kernel.org | |
| 8091 | +L: linux-kernel@vger.kernel.org | |
| 8092 | +S: Supported | |
| 8093 | +F: arch/x86/include/asm/intel-family.h | |
| 8094 | + | |
| 8079 | 8095 | INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) |
| 8080 | 8096 | M: Jani Nikula <jani.nikula@linux.intel.com> |
| 8081 | 8097 | M: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> |
| @@ -8427,7 +8443,6 @@ L: linux-xfs@vger.kernel.org · 345 unmodified lines | ||
| 8427 | 8443 | L: linux-fsdevel@vger.kernel.org |
| 8428 | 8444 | T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git |
| 8429 | 8445 | S: Supported |
| 8430 | −F: fs/iomap.c | |
| 8431 | 8446 | F: fs/iomap/ |
| 8432 | 8447 | F: include/linux/iomap.h |
| 8433 | 8448 | |
| @@ -16097,7 +16112,7 @@ S: Maintained · 7663 unmodified lines | ||
| 16097 | 16112 | F: drivers/net/ethernet/ti/netcp* |
| 16098 | 16113 | |
| 16099 | 16114 | TI PCM3060 ASoC CODEC DRIVER |
| 16100 | −M: Kirill Marinushkin <kmarinushkin@birdec.tech> | |
| 16115 | +M: Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 16101 | 16116 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 16102 | 16117 | S: Maintained |
| 16103 | 16118 | F: Documentation/devicetree/bindings/sound/pcm3060.txt |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 3 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | 6 | NAME = Bobtail Squid |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -419,6 +419,7 @@ NM = $(CROSS_COMPILE)nm · 410 unmodified lines | ||
| 419 | 419 | STRIP = $(CROSS_COMPILE)strip |
| 420 | 420 | OBJCOPY = $(CROSS_COMPILE)objcopy |
| 421 | 421 | OBJDUMP = $(CROSS_COMPILE)objdump |
| 422 | +OBJSIZE = $(CROSS_COMPILE)size | |
| 422 | 423 | PAHOLE = pahole |
| 423 | 424 | LEX = flex |
| 424 | 425 | YACC = bison |
| @@ -475,9 +476,9 @@ GCC_PLUGINS_CFLAGS := · 50 unmodified lines | ||
| 475 | 476 | CLANG_FLAGS := |
| 476 | 477 | |
| 477 | 478 | export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC |
| 478 | −export CPP AR NM STRIP OBJCOPY OBJDUMP PAHOLE KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS | |
| 479 | −export MAKE LEX YACC AWK INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE | |
| 480 | −export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS | |
| 479 | +export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL | |
| 480 | +export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | |
| 481 | +export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE | |
| 481 | 482 | |
| 482 | 483 | export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS |
| 483 | 484 | export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE |
| @@ -845,7 +846,7 @@ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) · 361 unmodified lines | ||
| 845 | 846 | KBUILD_CFLAGS += -Wdeclaration-after-statement |
| 846 | 847 | |
| 847 | 848 | # Warn about unmarked fall-throughs in switch statement. |
| 848 | −KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough=3,) | |
| 849 | +KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,) | |
| 849 | 850 | |
| 850 | 851 | # Variable Length Arrays (VLAs) should not be used anywhere in the kernel |
| 851 | 852 | KBUILD_CFLAGS += -Wvla |
| @@ -1002,6 +1003,8 @@ endif · 150 unmodified lines | ||
| 1002 | 1003 | |
| 1003 | 1004 | PHONY += prepare0 |
| 1004 | 1005 | |
| 1006 | +export MODORDER := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order | |
| 1007 | + | |
| 1005 | 1008 | ifeq ($(KBUILD_EXTMOD),) |
| 1006 | 1009 | core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ |
| 1007 | 1010 | |
| @@ -1771,13 +1774,22 @@ build-dir = $(patsubst %/,%,$(dir $(build-target))) · 763 unmodified lines | ||
| 1771 | 1774 | $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) |
| 1772 | 1775 | %.symtypes: prepare FORCE |
| 1773 | 1776 | $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) |
| 1777 | +ifeq ($(KBUILD_EXTMOD),) | |
| 1778 | +# For the single build of an in-tree module, use a temporary file to avoid | |
| 1779 | +# the situation of modules_install installing an invalid modules.order. | |
| 1780 | +%.ko: MODORDER := .modules.tmp | |
| 1781 | +endif | |
| 1782 | +%.ko: prepare FORCE | |
| 1783 | + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target:.ko=.mod) | |
| 1784 | + $(Q)echo $(build-target) > $(MODORDER) | |
| 1785 | + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost | |
| 1774 | 1786 | |
| 1775 | 1787 | # Modules |
| 1776 | 1788 | PHONY += / |
| 1777 | 1789 | /: ./ |
| 1778 | 1790 | |
| 1779 | 1791 | %/: prepare FORCE |
| 1780 | − $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) | |
| 1792 | + $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) need-modorder=1 | |
| 1781 | 1793 | |
| 1782 | 1794 | # FIXME Should go into a make.lib or something |
| 1783 | 1795 | # =========================================================================== |
| @@ -544,6 +544,7 @@ static int arch_build_bp_info(struct perf_event *bp, · 543 unmodified lines | ||
| 544 | 544 | if ((hw->ctrl.type != ARM_BREAKPOINT_EXECUTE) |
| 545 | 545 | && max_watchpoint_len >= 8) |
| 546 | 546 | break; |
| 547 | + /* Else, fall through */ | |
| 547 | 548 | default: |
| 548 | 549 | return -EINVAL; |
| 549 | 550 | } |
| @@ -608,10 +609,12 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, · 58 unmodified lines | ||
| 608 | 609 | /* Allow halfword watchpoints and breakpoints. */ |
| 609 | 610 | if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2) |
| 610 | 611 | break; |
| 612 | + /* Else, fall through */ | |
| 611 | 613 | case 3: |
| 612 | 614 | /* Allow single byte watchpoint. */ |
| 613 | 615 | if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1) |
| 614 | 616 | break; |
| 617 | + /* Else, fall through */ | |
| 615 | 618 | default: |
| 616 | 619 | ret = -EINVAL; |
| 617 | 620 | goto out; |
| @@ -861,6 +864,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, · 243 unmodified lines | ||
| 861 | 864 | break; |
| 862 | 865 | case ARM_ENTRY_ASYNC_WATCHPOINT: |
| 863 | 866 | WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); |
| 867 | + /* Fall through */ | |
| 864 | 868 | case ARM_ENTRY_SYNC_WATCHPOINT: |
| 865 | 869 | watchpoint_handler(addr, fsr, regs); |
| 866 | 870 | break; |
| @@ -909,6 +913,7 @@ static bool core_has_os_save_restore(void) · 42 unmodified lines | ||
| 909 | 913 | ARM_DBG_READ(c1, c1, 4, oslsr); |
| 910 | 914 | if (oslsr & ARM_OSLSR_OSLM0) |
| 911 | 915 | return true; |
| 916 | + /* Else, fall through */ | |
| 912 | 917 | default: |
| 913 | 918 | return false; |
| 914 | 919 | } |
| @@ -596,6 +596,7 @@ static int do_signal(struct pt_regs *regs, int syscall) · 595 unmodified lines | ||
| 596 | 596 | switch (retval) { |
| 597 | 597 | case -ERESTART_RESTARTBLOCK: |
| 598 | 598 | restart -= 2; |
| 599 | + /* Fall through */ | |
| 599 | 600 | case -ERESTARTNOHAND: |
| 600 | 601 | case -ERESTARTSYS: |
| 601 | 602 | case -ERESTARTNOINTR: |
| @@ -651,13 +651,22 @@ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) · 650 unmodified lines | ||
| 651 | 651 | } |
| 652 | 652 | |
| 653 | 653 | static void reset_coproc_regs(struct kvm_vcpu *vcpu, |
| 654 | − const struct coproc_reg *table, size_t num) | |
| 654 | + const struct coproc_reg *table, size_t num, | |
| 655 | + unsigned long *bmap) | |
| 655 | 656 | { |
| 656 | 657 | unsigned long i; |
| 657 | 658 | |
| 658 | 659 | for (i = 0; i < num; i++) |
| 659 | − if (table[i].reset) | |
| 660 | + if (table[i].reset) { | |
| 661 | + int reg = table[i].reg; | |
| 662 | + | |
| 660 | 663 | table[i].reset(vcpu, &table[i]); |
| 664 | + if (reg > 0 && reg < NR_CP15_REGS) { | |
| 665 | + set_bit(reg, bmap); | |
| 666 | + if (table[i].is_64bit) | |
| 667 | + set_bit(reg + 1, bmap); | |
| 668 | + } | |
| 669 | + } | |
| 661 | 670 | } |
| 662 | 671 | |
| 663 | 672 | static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu) |
| @@ -1432,17 +1441,15 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu) · 768 unmodified lines | ||
| 1432 | 1441 | { |
| 1433 | 1442 | size_t num; |
| 1434 | 1443 | const struct coproc_reg *table; |
| 1435 | − | |
| 1436 | − /* Catch someone adding a register without putting in reset entry. */ | |
| 1437 | − memset(vcpu->arch.ctxt.cp15, 0x42, sizeof(vcpu->arch.ctxt.cp15)); | |
| 1444 | + DECLARE_BITMAP(bmap, NR_CP15_REGS) = { 0, }; | |
| 1438 | 1445 | |
| 1439 | 1446 | /* Generic chip reset first (so target could override). */ |
| 1440 | − reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs)); | |
| 1447 | + reset_coproc_regs(vcpu, cp15_regs, ARRAY_SIZE(cp15_regs), bmap); | |
| 1441 | 1448 | |
| 1442 | 1449 | table = get_target_table(vcpu->arch.target, &num); |
| 1443 | − reset_coproc_regs(vcpu, table, num); | |
| 1450 | + reset_coproc_regs(vcpu, table, num, bmap); | |
| 1444 | 1451 | |
| 1445 | 1452 | for (num = 1; num < NR_CP15_REGS; num++) |
| 1446 | − WARN(vcpu_cp15(vcpu, num) == 0x42424242, | |
| 1453 | + WARN(!test_bit(num, bmap), | |
| 1447 | 1454 | "Didn't reset vcpu_cp15(vcpu, %zi)", num); |
| 1448 | 1455 | } |
| @@ -49,6 +49,7 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) · 48 unmodified lines | ||
| 49 | 49 | * FALLTHROUGH: Ensure we don't try to overwrite our newly |
| 50 | 50 | * initialised state information on the first fault. |
| 51 | 51 | */ |
| 52 | + /* Fall through */ | |
| 52 | 53 | |
| 53 | 54 | case THREAD_NOTIFY_EXIT: |
| 54 | 55 | crunch_task_release(thread); |
| @@ -70,7 +70,7 @@ static void __init tegra_cpu_reset_handler_enable(void) · 69 unmodified lines | ||
| 70 | 70 | switch (err) { |
| 71 | 71 | case -ENOSYS: |
| 72 | 72 | tegra_cpu_reset_handler_set(reset_address); |
| 73 | − /* pass-through */ | |
| 73 | + /* fall through */ | |
| 74 | 74 | case 0: |
| 75 | 75 | is_enabled = true; |
| 76 | 76 | break; |
| @@ -695,7 +695,7 @@ thumb2arm(u16 tinstr) · 694 unmodified lines | ||
| 695 | 695 | return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] | |
| 696 | 696 | (tinstr & 255); /* register_list */ |
| 697 | 697 | } |
| 698 | − /* Else fall through for illegal instruction case */ | |
| 698 | + /* Else, fall through - for illegal instruction case */ | |
| 699 | 699 | |
| 700 | 700 | default: |
| 701 | 701 | return BAD_INSTR; |
| @@ -751,6 +751,8 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, · 49 unmodified lines | ||
| 751 | 751 | case 0xe8e0: |
| 752 | 752 | case 0xe9e0: |
| 753 | 753 | poffset->un = (tinst2 & 0xff) << 2; |
| 754 | + /* Fall through */ | |
| 755 | + | |
| 754 | 756 | case 0xe940: |
| 755 | 757 | case 0xe9c0: |
| 756 | 758 | return do_alignment_ldrdstrd; |
| @@ -2405,9 +2405,7 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, · 2404 unmodified lines | ||
| 2405 | 2405 | pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, |
| 2406 | 2406 | unsigned long attrs) |
| 2407 | 2407 | { |
| 2408 | − if (!dev_is_dma_coherent(dev)) | |
| 2409 | − return __get_dma_pgprot(attrs, prot); | |
| 2410 | − return prot; | |
| 2408 | + return __get_dma_pgprot(attrs, prot); | |
| 2411 | 2409 | } |
| 2412 | 2410 | |
| 2413 | 2411 | void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, |
| @@ -388,17 +388,15 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) · 387 unmodified lines | ||
| 388 | 388 | /* |
| 389 | 389 | * not supported by current hardware on OMAP1 |
| 390 | 390 | * w |= (0x03 << 7); |
| 391 | − * fall through | |
| 392 | 391 | */ |
| 392 | + /* fall through */ | |
| 393 | 393 | case OMAP_DMA_DATA_BURST_16: |
| 394 | 394 | if (dma_omap2plus()) { |
| 395 | 395 | burst = 0x3; |
| 396 | 396 | break; |
| 397 | 397 | } |
| 398 | − /* | |
| 399 | − * OMAP1 don't support burst 16 | |
| 400 | − * fall through | |
| 401 | − */ | |
| 398 | + /* OMAP1 don't support burst 16 */ | |
| 399 | + /* fall through */ | |
| 402 | 400 | default: |
| 403 | 401 | BUG(); |
| 404 | 402 | } |
| @@ -474,10 +472,8 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) · 69 unmodified lines | ||
| 474 | 472 | burst = 0x3; |
| 475 | 473 | break; |
| 476 | 474 | } |
| 477 | − /* | |
| 478 | − * OMAP1 don't support burst 16 | |
| 479 | − * fall through | |
| 480 | − */ | |
| 475 | + /* OMAP1 don't support burst 16 */ | |
| 476 | + /* fall through */ | |
| 481 | 477 | default: |
| 482 | 478 | printk(KERN_ERR "Invalid DMA burst mode\n"); |
| 483 | 479 | BUG(); |
| @@ -316,9 +316,10 @@ · 315 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | #define kvm_arm_exception_class \ |
| 318 | 318 | ECN(UNKNOWN), ECN(WFx), ECN(CP15_32), ECN(CP15_64), ECN(CP14_MR), \ |
| 319 | − ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(CP14_64), ECN(SVC64), \ | |
| 320 | − ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(IMP_DEF), ECN(IABT_LOW), \ | |
| 321 | − ECN(IABT_CUR), ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \ | |
| 319 | + ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(PAC), ECN(CP14_64), \ | |
| 320 | + ECN(SVC64), ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(SVE), \ | |
| 321 | + ECN(IMP_DEF), ECN(IABT_LOW), ECN(IABT_CUR), \ | |
| 322 | + ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \ | |
| 322 | 323 | ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \ |
| 323 | 324 | ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \ |
| 324 | 325 | ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \ |
| @@ -209,7 +209,7 @@ static inline pmd_t pmd_mkcont(pmd_t pmd) · 208 unmodified lines | ||
| 209 | 209 | |
| 210 | 210 | static inline pte_t pte_mkdevmap(pte_t pte) |
| 211 | 211 | { |
| 212 | − return set_pte_bit(pte, __pgprot(PTE_DEVMAP)); | |
| 212 | + return set_pte_bit(pte, __pgprot(PTE_DEVMAP | PTE_SPECIAL)); | |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | 215 | static inline void set_pte(pte_t *ptep, pte_t pte) |
| @@ -396,7 +396,10 @@ static inline int pmd_protnone(pmd_t pmd) · 180 unmodified lines | ||
| 396 | 396 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 397 | 397 | #define pmd_devmap(pmd) pte_devmap(pmd_pte(pmd)) |
| 398 | 398 | #endif |
| 399 | −#define pmd_mkdevmap(pmd) pte_pmd(pte_mkdevmap(pmd_pte(pmd))) | |
| 399 | +static inline pmd_t pmd_mkdevmap(pmd_t pmd) | |
| 400 | +{ | |
| 401 | + return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP))); | |
| 402 | +} | |
| 400 | 403 | |
| 401 | 404 | #define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd)) |
| 402 | 405 | #define __phys_to_pmd_val(phys) __phys_to_pte_val(phys) |
| @@ -184,9 +184,17 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { · 183 unmodified lines | ||
| 184 | 184 | }; |
| 185 | 185 | |
| 186 | 186 | static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { |
| 187 | − S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI), | |
| 188 | − S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI), | |
| 189 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI), | |
| 187 | + /* | |
| 188 | + * We already refuse to boot CPUs that don't support our configured | |
| 189 | + * page size, so we can only detect mismatches for a page size other | |
| 190 | + * than the one we're currently using. Unfortunately, SoCs like this | |
| 191 | + * exist in the wild so, even though we don't like it, we'll have to go | |
| 192 | + * along with it and treat them as non-strict. | |
| 193 | + */ | |
| 194 | + S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI), | |
| 195 | + S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI), | |
| 196 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_TGRAN16_SHIFT, 4, ID_AA64MMFR0_TGRAN16_NI), | |
| 197 | + | |
| 190 | 198 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_BIGENDEL0_SHIFT, 4, 0), |
| 191 | 199 | /* Linux shouldn't care about secure memory */ |
| 192 | 200 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_SNSMEM_SHIFT, 4, 0), |
| @@ -73,7 +73,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | if (offset < -SZ_128M || offset >= SZ_128M) { |
| 75 | 75 | #ifdef CONFIG_ARM64_MODULE_PLTS |
| 76 | − struct plt_entry trampoline; | |
| 76 | + struct plt_entry trampoline, *dst; | |
| 77 | 77 | struct module *mod; |
| 78 | 78 | |
| 79 | 79 | /* |
| @@ -106,23 +106,27 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 26 unmodified lines | ||
| 106 | 106 | * to check if the actual opcodes are in fact identical, |
| 107 | 107 | * regardless of the offset in memory so use memcmp() instead. |
| 108 | 108 | */ |
| 109 | − trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline); | |
| 110 | − if (memcmp(mod->arch.ftrace_trampoline, &trampoline, | |
| 111 | − sizeof(trampoline))) { | |
| 112 | − if (plt_entry_is_initialized(mod->arch.ftrace_trampoline)) { | |
| 109 | + dst = mod->arch.ftrace_trampoline; | |
| 110 | + trampoline = get_plt_entry(addr, dst); | |
| 111 | + if (memcmp(dst, &trampoline, sizeof(trampoline))) { | |
| 112 | + if (plt_entry_is_initialized(dst)) { | |
| 113 | 113 | pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); |
| 114 | 114 | return -EINVAL; |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | 117 | /* point the trampoline to our ftrace entry point */ |
| 118 | 118 | module_disable_ro(mod); |
| 119 | − *mod->arch.ftrace_trampoline = trampoline; | |
| 119 | + *dst = trampoline; | |
| 120 | 120 | module_enable_ro(mod, true); |
| 121 | 121 | |
| 122 | − /* update trampoline before patching in the branch */ | |
| 123 | − smp_wmb(); | |
| 122 | + /* | |
| 123 | + * Ensure updated trampoline is visible to instruction | |
| 124 | + * fetch before we patch in the branch. | |
| 125 | + */ | |
| 126 | + __flush_icache_range((unsigned long)&dst[0], | |
| 127 | + (unsigned long)&dst[1]); | |
| 124 | 128 | } |
| 125 | − addr = (unsigned long)(void *)mod->arch.ftrace_trampoline; | |
| 129 | + addr = (unsigned long)dst; | |
| 126 | 130 | #else /* CONFIG_ARM64_MODULE_PLTS */ |
| 127 | 131 | return -EINVAL; |
| 128 | 132 | #endif /* CONFIG_ARM64_MODULE_PLTS */ |
| @@ -733,6 +733,7 @@ static const char *esr_class_str[] = { · 732 unmodified lines | ||
| 733 | 733 | [ESR_ELx_EC_CP14_LS] = "CP14 LDC/STC", |
| 734 | 734 | [ESR_ELx_EC_FP_ASIMD] = "ASIMD", |
| 735 | 735 | [ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS", |
| 736 | + [ESR_ELx_EC_PAC] = "PAC", | |
| 736 | 737 | [ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC", |
| 737 | 738 | [ESR_ELx_EC_ILL] = "PSTATE.IL", |
| 738 | 739 | [ESR_ELx_EC_SVC32] = "SVC (AArch32)", |
| @@ -18,40 +18,70 @@ · 17 unmodified lines | ||
| 18 | 18 | #define save_debug(ptr,reg,nr) \ |
| 19 | 19 | switch (nr) { \ |
| 20 | 20 | case 15: ptr[15] = read_debug(reg, 15); \ |
| 21 | + /* Fall through */ \ | |
| 21 | 22 | case 14: ptr[14] = read_debug(reg, 14); \ |
| 23 | + /* Fall through */ \ | |
| 22 | 24 | case 13: ptr[13] = read_debug(reg, 13); \ |
| 25 | + /* Fall through */ \ | |
| 23 | 26 | case 12: ptr[12] = read_debug(reg, 12); \ |
| 27 | + /* Fall through */ \ | |
| 24 | 28 | case 11: ptr[11] = read_debug(reg, 11); \ |
| 29 | + /* Fall through */ \ | |
| 25 | 30 | case 10: ptr[10] = read_debug(reg, 10); \ |
| 31 | + /* Fall through */ \ | |
| 26 | 32 | case 9: ptr[9] = read_debug(reg, 9); \ |
| 33 | + /* Fall through */ \ | |
| 27 | 34 | case 8: ptr[8] = read_debug(reg, 8); \ |
| 35 | + /* Fall through */ \ | |
| 28 | 36 | case 7: ptr[7] = read_debug(reg, 7); \ |
| 37 | + /* Fall through */ \ | |
| 29 | 38 | case 6: ptr[6] = read_debug(reg, 6); \ |
| 39 | + /* Fall through */ \ | |
| 30 | 40 | case 5: ptr[5] = read_debug(reg, 5); \ |
| 41 | + /* Fall through */ \ | |
| 31 | 42 | case 4: ptr[4] = read_debug(reg, 4); \ |
| 43 | + /* Fall through */ \ | |
| 32 | 44 | case 3: ptr[3] = read_debug(reg, 3); \ |
| 45 | + /* Fall through */ \ | |
| 33 | 46 | case 2: ptr[2] = read_debug(reg, 2); \ |
| 47 | + /* Fall through */ \ | |
| 34 | 48 | case 1: ptr[1] = read_debug(reg, 1); \ |
| 49 | + /* Fall through */ \ | |
| 35 | 50 | default: ptr[0] = read_debug(reg, 0); \ |
| 36 | 51 | } |
| 37 | 52 | |
| 38 | 53 | #define restore_debug(ptr,reg,nr) \ |
| 39 | 54 | switch (nr) { \ |
| 40 | 55 | case 15: write_debug(ptr[15], reg, 15); \ |
| 56 | + /* Fall through */ \ | |
| 41 | 57 | case 14: write_debug(ptr[14], reg, 14); \ |
| 58 | + /* Fall through */ \ | |
| 42 | 59 | case 13: write_debug(ptr[13], reg, 13); \ |
| 60 | + /* Fall through */ \ | |
| 43 | 61 | case 12: write_debug(ptr[12], reg, 12); \ |
| 62 | + /* Fall through */ \ | |
| 44 | 63 | case 11: write_debug(ptr[11], reg, 11); \ |
| 64 | + /* Fall through */ \ | |
| 45 | 65 | case 10: write_debug(ptr[10], reg, 10); \ |
| 66 | + /* Fall through */ \ | |
| 46 | 67 | case 9: write_debug(ptr[9], reg, 9); \ |
| 68 | + /* Fall through */ \ | |
| 47 | 69 | case 8: write_debug(ptr[8], reg, 8); \ |
| 70 | + /* Fall through */ \ | |
| 48 | 71 | case 7: write_debug(ptr[7], reg, 7); \ |
| 72 | + /* Fall through */ \ | |
| 49 | 73 | case 6: write_debug(ptr[6], reg, 6); \ |
| 74 | + /* Fall through */ \ | |
| 50 | 75 | case 5: write_debug(ptr[5], reg, 5); \ |
| 76 | + /* Fall through */ \ | |
| 51 | 77 | case 4: write_debug(ptr[4], reg, 4); \ |
| 78 | + /* Fall through */ \ | |
| 52 | 79 | case 3: write_debug(ptr[3], reg, 3); \ |
| 80 | + /* Fall through */ \ | |
| 53 | 81 | case 2: write_debug(ptr[2], reg, 2); \ |
| 82 | + /* Fall through */ \ | |
| 54 | 83 | case 1: write_debug(ptr[1], reg, 1); \ |
| 84 | + /* Fall through */ \ | |
| 55 | 85 | default: write_debug(ptr[0], reg, 0); \ |
| 56 | 86 | } |
| 57 | 87 | |
| @@ -178,13 +178,18 @@ void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v) · 177 unmodified lines | ||
| 178 | 178 | switch (spsr_idx) { |
| 179 | 179 | case KVM_SPSR_SVC: |
| 180 | 180 | write_sysreg_el1(v, SYS_SPSR); |
| 181 | + break; | |
| 181 | 182 | case KVM_SPSR_ABT: |
| 182 | 183 | write_sysreg(v, spsr_abt); |
| 184 | + break; | |
| 183 | 185 | case KVM_SPSR_UND: |
| 184 | 186 | write_sysreg(v, spsr_und); |
| 187 | + break; | |
| 185 | 188 | case KVM_SPSR_IRQ: |
| 186 | 189 | write_sysreg(v, spsr_irq); |
| 190 | + break; | |
| 187 | 191 | case KVM_SPSR_FIQ: |
| 188 | 192 | write_sysreg(v, spsr_fiq); |
| 193 | + break; | |
| 189 | 194 | } |
| 190 | 195 | } |
| @@ -632,7 +632,7 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 631 unmodified lines | ||
| 632 | 632 | */ |
| 633 | 633 | val = ((pmcr & ~ARMV8_PMU_PMCR_MASK) |
| 634 | 634 | | (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E); |
| 635 | − __vcpu_sys_reg(vcpu, PMCR_EL0) = val; | |
| 635 | + __vcpu_sys_reg(vcpu, r->reg) = val; | |
| 636 | 636 | } |
| 637 | 637 | |
| 638 | 638 | static bool check_pmu_access_disabled(struct kvm_vcpu *vcpu, u64 flags) |
| @@ -981,13 +981,13 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 342 unmodified lines | ||
| 981 | 981 | /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ |
| 982 | 982 | #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ |
| 983 | 983 | { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ |
| 984 | − trap_bvr, reset_bvr, n, 0, get_bvr, set_bvr }, \ | |
| 984 | + trap_bvr, reset_bvr, 0, 0, get_bvr, set_bvr }, \ | |
| 985 | 985 | { SYS_DESC(SYS_DBGBCRn_EL1(n)), \ |
| 986 | − trap_bcr, reset_bcr, n, 0, get_bcr, set_bcr }, \ | |
| 986 | + trap_bcr, reset_bcr, 0, 0, get_bcr, set_bcr }, \ | |
| 987 | 987 | { SYS_DESC(SYS_DBGWVRn_EL1(n)), \ |
| 988 | − trap_wvr, reset_wvr, n, 0, get_wvr, set_wvr }, \ | |
| 988 | + trap_wvr, reset_wvr, 0, 0, get_wvr, set_wvr }, \ | |
| 989 | 989 | { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ |
| 990 | − trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr } | |
| 990 | + trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } | |
| 991 | 991 | |
| 992 | 992 | /* Macro to expand the PMEVCNTRn_EL0 register */ |
| 993 | 993 | #define PMU_PMEVCNTR_EL0(n) \ |
| @@ -1540,7 +1540,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 546 unmodified lines | ||
| 1540 | 1540 | { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, |
| 1541 | 1541 | { SYS_DESC(SYS_CTR_EL0), access_ctr }, |
| 1542 | 1542 | |
| 1543 | − { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, }, | |
| 1543 | + { SYS_DESC(SYS_PMCR_EL0), access_pmcr, reset_pmcr, PMCR_EL0 }, | |
| 1544 | 1544 | { SYS_DESC(SYS_PMCNTENSET_EL0), access_pmcnten, reset_unknown, PMCNTENSET_EL0 }, |
| 1545 | 1545 | { SYS_DESC(SYS_PMCNTENCLR_EL0), access_pmcnten, NULL, PMCNTENSET_EL0 }, |
| 1546 | 1546 | { SYS_DESC(SYS_PMOVSCLR_EL0), access_pmovs, NULL, PMOVSSET_EL0 }, |
| @@ -2254,13 +2254,19 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu, · 707 unmodified lines | ||
| 2254 | 2254 | } |
| 2255 | 2255 | |
| 2256 | 2256 | static void reset_sys_reg_descs(struct kvm_vcpu *vcpu, |
| 2257 | − const struct sys_reg_desc *table, size_t num) | |
| 2257 | + const struct sys_reg_desc *table, size_t num, | |
| 2258 | + unsigned long *bmap) | |
| 2258 | 2259 | { |
| 2259 | 2260 | unsigned long i; |
| 2260 | 2261 | |
| 2261 | 2262 | for (i = 0; i < num; i++) |
| 2262 | − if (table[i].reset) | |
| 2263 | + if (table[i].reset) { | |
| 2264 | + int reg = table[i].reg; | |
| 2265 | + | |
| 2263 | 2266 | table[i].reset(vcpu, &table[i]); |
| 2267 | + if (reg > 0 && reg < NR_SYS_REGS) | |
| 2268 | + set_bit(reg, bmap); | |
| 2269 | + } | |
| 2264 | 2270 | } |
| 2265 | 2271 | |
| 2266 | 2272 | /** |
| @@ -2774,18 +2780,16 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu) · 507 unmodified lines | ||
| 2774 | 2780 | { |
| 2775 | 2781 | size_t num; |
| 2776 | 2782 | const struct sys_reg_desc *table; |
| 2777 | − | |
| 2778 | − /* Catch someone adding a register without putting in reset entry. */ | |
| 2779 | − memset(&vcpu->arch.ctxt.sys_regs, 0x42, sizeof(vcpu->arch.ctxt.sys_regs)); | |
| 2783 | + DECLARE_BITMAP(bmap, NR_SYS_REGS) = { 0, }; | |
| 2780 | 2784 | |
| 2781 | 2785 | /* Generic chip reset first (so target could override). */ |
| 2782 | − reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); | |
| 2786 | + reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs), bmap); | |
| 2783 | 2787 | |
| 2784 | 2788 | table = get_target_table(vcpu->arch.target, true, &num); |
| 2785 | − reset_sys_reg_descs(vcpu, table, num); | |
| 2789 | + reset_sys_reg_descs(vcpu, table, num, bmap); | |
| 2786 | 2790 | |
| 2787 | 2791 | for (num = 1; num < NR_SYS_REGS; num++) { |
| 2788 | − if (WARN(__vcpu_sys_reg(vcpu, num) == 0x4242424242424242, | |
| 2792 | + if (WARN(!test_bit(num, bmap), | |
| 2789 | 2793 | "Didn't reset __vcpu_sys_reg(%zi)\n", num)) |
| 2790 | 2794 | break; |
| 2791 | 2795 | } |
| @@ -14,9 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, |
| 15 | 15 | unsigned long attrs) |
| 16 | 16 | { |
| 17 | − if (!dev_is_dma_coherent(dev) || (attrs & DMA_ATTR_WRITE_COMBINE)) | |
| 18 | − return pgprot_writecombine(prot); | |
| 19 | − return prot; | |
| 17 | + return pgprot_writecombine(prot); | |
| 20 | 18 | } |
| 21 | 19 | |
| 22 | 20 | void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, |
| @@ -150,16 +150,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 149 unmodified lines | ||
| 150 | 150 | return 0; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | −bool kvm_arch_has_vcpu_debugfs(void) | |
| 154 | −{ | |
| 155 | − return false; | |
| 156 | −} | |
| 157 | − | |
| 158 | −int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 159 | −{ | |
| 160 | − return 0; | |
| 161 | −} | |
| 162 | − | |
| 163 | 153 | void kvm_mips_free_vcpus(struct kvm *kvm) |
| 164 | 154 | { |
| 165 | 155 | unsigned int i; |
| @@ -18,4 +18,4 @@ obj-y := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \ · 17 unmodified lines | ||
| 18 | 18 | # other very old or stripped-down PA-RISC CPUs -- not currently supported |
| 19 | 19 | |
| 20 | 20 | obj-$(CONFIG_MATH_EMULATION) += unimplemented-math-emulation.o |
| 21 | −CFLAGS_REMOVE_fpudispatch.o = -Wimplicit-fallthrough=3 | |
| 21 | +CFLAGS_REMOVE_fpudispatch.o = -Wimplicit-fallthrough | |
| @@ -121,7 +121,6 @@ config PPC · 120 unmodified lines | ||
| 121 | 121 | select ARCH_32BIT_OFF_T if PPC32 |
| 122 | 122 | select ARCH_HAS_DEBUG_VIRTUAL |
| 123 | 123 | select ARCH_HAS_DEVMEM_IS_ALLOWED |
| 124 | − select ARCH_HAS_DMA_MMAP_PGPROT | |
| 125 | 124 | select ARCH_HAS_ELF_RANDOMIZE |
| 126 | 125 | select ARCH_HAS_FORTIFY_SOURCE |
| 127 | 126 | select ARCH_HAS_GCOV_PROFILE_ALL |
| @@ -107,22 +107,22 @@ extern void _set_L3CR(unsigned long); · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | static inline void dcbz(void *addr) |
| 109 | 109 | { |
| 110 | − __asm__ __volatile__ ("dcbz %y0" : : "Z"(*(u8 *)addr) : "memory"); | |
| 110 | + __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory"); | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | static inline void dcbi(void *addr) |
| 114 | 114 | { |
| 115 | − __asm__ __volatile__ ("dcbi %y0" : : "Z"(*(u8 *)addr) : "memory"); | |
| 115 | + __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory"); | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | static inline void dcbf(void *addr) |
| 119 | 119 | { |
| 120 | − __asm__ __volatile__ ("dcbf %y0" : : "Z"(*(u8 *)addr) : "memory"); | |
| 120 | + __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory"); | |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | 123 | static inline void dcbst(void *addr) |
| 124 | 124 | { |
| 125 | − __asm__ __volatile__ ("dcbst %y0" : : "Z"(*(u8 *)addr) : "memory"); | |
| 125 | + __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); | |
| 126 | 126 | } |
| 127 | 127 | #endif /* !__ASSEMBLY__ */ |
| 128 | 128 | #endif /* __KERNEL__ */ |
| @@ -49,8 +49,7 @@ obj-y := cputable.o ptrace.o syscalls.o \ · 48 unmodified lines | ||
| 49 | 49 | signal.o sysfs.o cacheinfo.o time.o \ |
| 50 | 50 | prom.o traps.o setup-common.o \ |
| 51 | 51 | udbg.o misc.o io.o misc_$(BITS).o \ |
| 52 | − of_platform.o prom_parse.o \ | |
| 53 | − dma-common.o | |
| 52 | + of_platform.o prom_parse.o | |
| 54 | 53 | obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ |
| 55 | 54 | signal_64.o ptrace32.o \ |
| 56 | 55 | paca.o nvram_64.o firmware.o |
| @@ -1,17 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | −/* | |
| 3 | − * Contains common dma routines for all powerpc platforms. | |
| 4 | − * | |
| 5 | − * Copyright (C) 2019 Shawn Anastasio. | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#include <linux/mm.h> | |
| 9 | −#include <linux/dma-noncoherent.h> | |
| 10 | − | |
| 11 | −pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, | |
| 12 | − unsigned long attrs) | |
| 13 | −{ | |
| 14 | − if (!dev_is_dma_coherent(dev)) | |
| 15 | − return pgprot_noncached(prot); | |
| 16 | − return prot; | |
| 17 | −} | |
| @@ -50,6 +50,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) · 49 unmodified lines | ||
| 50 | 50 | return !!(v->arch.pending_exceptions) || kvm_request_pending(v); |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | +bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu) | |
| 54 | +{ | |
| 55 | + return kvm_arch_vcpu_runnable(vcpu); | |
| 56 | +} | |
| 57 | + | |
| 53 | 58 | bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) |
| 54 | 59 | { |
| 55 | 60 | return false; |
| @@ -452,16 +457,6 @@ err_out: · 396 unmodified lines | ||
| 452 | 457 | return -EINVAL; |
| 453 | 458 | } |
| 454 | 459 | |
| 455 | −bool kvm_arch_has_vcpu_debugfs(void) | |
| 456 | −{ | |
| 457 | − return false; | |
| 458 | −} | |
| 459 | − | |
| 460 | −int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 461 | −{ | |
| 462 | − return 0; | |
| 463 | −} | |
| 464 | − | |
| 465 | 460 | void kvm_arch_destroy_vm(struct kvm *kvm) |
| 466 | 461 | { |
| 467 | 462 | unsigned int i; |
| @@ -54,6 +54,8 @@ CONFIG_SERIAL_8250_CONSOLE=y · 53 unmodified lines | ||
| 54 | 54 | CONFIG_SERIAL_OF_PLATFORM=y |
| 55 | 55 | CONFIG_SERIAL_EARLYCON_RISCV_SBI=y |
| 56 | 56 | CONFIG_HVC_RISCV_SBI=y |
| 57 | +CONFIG_HW_RANDOM=y | |
| 58 | +CONFIG_HW_RANDOM_VIRTIO=y | |
| 57 | 59 | CONFIG_SPI=y |
| 58 | 60 | CONFIG_SPI_SIFIVE=y |
| 59 | 61 | # CONFIG_PTP_1588_CLOCK is not set |
| @@ -34,6 +34,7 @@ CONFIG_PCIEPORTBUS=y · 33 unmodified lines | ||
| 34 | 34 | CONFIG_PCI_HOST_GENERIC=y |
| 35 | 35 | CONFIG_PCIE_XILINX=y |
| 36 | 36 | CONFIG_DEVTMPFS=y |
| 37 | +CONFIG_DEVTMPFS_MOUNT=y | |
| 37 | 38 | CONFIG_BLK_DEV_LOOP=y |
| 38 | 39 | CONFIG_VIRTIO_BLK=y |
| 39 | 40 | CONFIG_BLK_DEV_SD=y |
| @@ -53,6 +54,8 @@ CONFIG_SERIAL_8250_CONSOLE=y · 13 unmodified lines | ||
| 53 | 54 | CONFIG_SERIAL_OF_PLATFORM=y |
| 54 | 55 | CONFIG_SERIAL_EARLYCON_RISCV_SBI=y |
| 55 | 56 | CONFIG_HVC_RISCV_SBI=y |
| 57 | +CONFIG_HW_RANDOM=y | |
| 58 | +CONFIG_HW_RANDOM_VIRTIO=y | |
| 56 | 59 | # CONFIG_PTP_1588_CLOCK is not set |
| 57 | 60 | CONFIG_DRM=y |
| 58 | 61 | CONFIG_DRM_RADEON=y |
| @@ -16,7 +16,13 @@ extern void __fstate_restore(struct task_struct *restore_from); · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | static inline void __fstate_clean(struct pt_regs *regs) |
| 18 | 18 | { |
| 19 | − regs->sstatus |= (regs->sstatus & ~(SR_FS)) | SR_FS_CLEAN; | |
| 19 | + regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN; | |
| 20 | +} | |
| 21 | + | |
| 22 | +static inline void fstate_off(struct task_struct *task, | |
| 23 | + struct pt_regs *regs) | |
| 24 | +{ | |
| 25 | + regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF; | |
| 20 | 26 | } |
| 21 | 27 | |
| 22 | 28 | static inline void fstate_save(struct task_struct *task, |
| @@ -53,10 +53,17 @@ static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start, · 52 unmodified lines | ||
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | #define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1) |
| 56 | −#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0) | |
| 56 | + | |
| 57 | 57 | #define flush_tlb_range(vma, start, end) \ |
| 58 | 58 | remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start)) |
| 59 | −#define flush_tlb_mm(mm) \ | |
| 59 | + | |
| 60 | +static inline void flush_tlb_page(struct vm_area_struct *vma, | |
| 61 | + unsigned long addr) | |
| 62 | +{ | |
| 63 | + flush_tlb_range(vma, addr, addr + PAGE_SIZE); | |
| 64 | +} | |
| 65 | + | |
| 66 | +#define flush_tlb_mm(mm) \ | |
| 60 | 67 | remote_sfence_vma(mm_cpumask(mm), 0, -1) |
| 61 | 68 | |
| 62 | 69 | #endif /* CONFIG_SMP */ |
| @@ -64,8 +64,14 @@ void start_thread(struct pt_regs *regs, unsigned long pc, · 63 unmodified lines | ||
| 64 | 64 | unsigned long sp) |
| 65 | 65 | { |
| 66 | 66 | regs->sstatus = SR_SPIE; |
| 67 | − if (has_fpu) | |
| 67 | + if (has_fpu) { | |
| 68 | 68 | regs->sstatus |= SR_FS_INITIAL; |
| 69 | + /* | |
| 70 | + * Restore the initial value to the FP register | |
| 71 | + * before starting the user program. | |
| 72 | + */ | |
| 73 | + fstate_restore(current, regs); | |
| 74 | + } | |
| 69 | 75 | regs->sepc = pc; |
| 70 | 76 | regs->sp = sp; |
| 71 | 77 | set_fs(USER_DS); |
| @@ -75,10 +81,11 @@ void flush_thread(void) · 3 unmodified lines | ||
| 75 | 81 | { |
| 76 | 82 | #ifdef CONFIG_FPU |
| 77 | 83 | /* |
| 78 | − * Reset FPU context | |
| 84 | + * Reset FPU state and context | |
| 79 | 85 | * frm: round to nearest, ties to even (IEEE default) |
| 80 | 86 | * fflags: accrued exceptions cleared |
| 81 | 87 | */ |
| 88 | + fstate_off(current, task_pt_regs(current)); | |
| 82 | 89 | memset(¤t->thread.fstate, 0, sizeof(current->thread.fstate)); |
| 83 | 90 | #endif |
| 84 | 91 | } |
| @@ -5,5 +5,3 @@ lib-y += memset.o · 4 unmodified lines | ||
| 5 | 5 | lib-y += uaccess.o |
| 6 | 6 | |
| 7 | 7 | lib-$(CONFIG_64BIT) += tishift.o |
| 8 | − | |
| 9 | −lib-$(CONFIG_32BIT) += udivdi3.o | |
| @@ -81,9 +81,13 @@ EXPORT_SYMBOL(__delay); · 80 unmodified lines | ||
| 81 | 81 | void udelay(unsigned long usecs) |
| 82 | 82 | { |
| 83 | 83 | u64 ucycles = (u64)usecs * lpj_fine * UDELAY_MULT; |
| 84 | + u64 n; | |
| 84 | 85 | |
| 85 | 86 | if (unlikely(usecs > MAX_UDELAY_US)) { |
| 86 | − __delay((u64)usecs * riscv_timebase / 1000000ULL); | |
| 87 | + n = (u64)usecs * riscv_timebase; | |
| 88 | + do_div(n, 1000000); | |
| 89 | + | |
| 90 | + __delay(n); | |
| 87 | 91 | return; |
| 88 | 92 | } |
| 89 | 93 | |
| @@ -1,32 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2016-2017 Free Software Foundation, Inc. | |
| 4 | − */ | |
| 5 | − | |
| 6 | −#include <linux/linkage.h> | |
| 7 | − | |
| 8 | −ENTRY(__udivdi3) | |
| 9 | − mv a2, a1 | |
| 10 | − mv a1, a0 | |
| 11 | − li a0, -1 | |
| 12 | − beqz a2, .L5 | |
| 13 | − li a3, 1 | |
| 14 | − bgeu a2, a1, .L2 | |
| 15 | −.L1: | |
| 16 | − blez a2, .L2 | |
| 17 | − slli a2, a2, 1 | |
| 18 | − slli a3, a3, 1 | |
| 19 | − bgtu a1, a2, .L1 | |
| 20 | −.L2: | |
| 21 | − li a0, 0 | |
| 22 | −.L3: | |
| 23 | − bltu a1, a2, .L4 | |
| 24 | − sub a1, a1, a2 | |
| 25 | − or a0, a0, a3 | |
| 26 | −.L4: | |
| 27 | − srli a3, a3, 1 | |
| 28 | − srli a2, a2, 1 | |
| 29 | − bnez a3, .L3 | |
| 30 | −.L5: | |
| 31 | − ret | |
| 32 | −ENDPROC(__udivdi3) | |
| @@ -48,9 +48,7 @@ void store_ipl_parmblock(void) · 47 unmodified lines | ||
| 48 | 48 | { |
| 49 | 49 | int rc; |
| 50 | 50 | |
| 51 | − uv_set_shared(__pa(&ipl_block)); | |
| 52 | 51 | rc = __diag308(DIAG308_STORE, &ipl_block); |
| 53 | − uv_remove_shared(__pa(&ipl_block)); | |
| 54 | 52 | if (rc == DIAG308_RC_OK && |
| 55 | 53 | ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION) |
| 56 | 54 | ipl_block_valid = 1; |
| @@ -114,12 +114,8 @@ recursion_check: · 113 unmodified lines | ||
| 114 | 114 | * If it comes up a second time then there's something wrong going on: |
| 115 | 115 | * just break out and report an unknown stack type. |
| 116 | 116 | */ |
| 117 | − if (*visit_mask & (1UL << info->type)) { | |
| 118 | − printk_deferred_once(KERN_WARNING | |
| 119 | − "WARNING: stack recursion on stack type %d\n", | |
| 120 | − info->type); | |
| 117 | + if (*visit_mask & (1UL << info->type)) | |
| 121 | 118 | goto unknown; |
| 122 | − } | |
| 123 | 119 | *visit_mask |= 1UL << info->type; |
| 124 | 120 | return 0; |
| 125 | 121 | unknown: |
| @@ -60,12 +60,5 @@ ENTRY(startup_continue) · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | .align 16 |
| 62 | 62 | .LPG1: |
| 63 | −.Lpcmsk:.quad 0x0000000180000000 | |
| 64 | −.L4malign:.quad 0xffffffffffc00000 | |
| 65 | −.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 | |
| 66 | −.Lnop: .long 0x07000700 | |
| 67 | −.Lparmaddr: | |
| 68 | − .quad PARMAREA | |
| 69 | − .align 64 | |
| 70 | 63 | .Ldw: .quad 0x0002000180000000,0x0000000000000000 |
| 71 | 64 | .Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
| @@ -31,7 +31,6 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <asm/os_info.h> |
| 32 | 32 | #include <asm/sections.h> |
| 33 | 33 | #include <asm/boot_data.h> |
| 34 | −#include <asm/uv.h> | |
| 35 | 34 | #include "entry.h" |
| 36 | 35 | |
| 37 | 36 | #define IPL_PARM_BLOCK_VERSION 0 |
| @@ -892,21 +891,15 @@ static void __reipl_run(void *unused) · 854 unmodified lines | ||
| 892 | 891 | { |
| 893 | 892 | switch (reipl_type) { |
| 894 | 893 | case IPL_TYPE_CCW: |
| 895 | − uv_set_shared(__pa(reipl_block_ccw)); | |
| 896 | 894 | diag308(DIAG308_SET, reipl_block_ccw); |
| 897 | − uv_remove_shared(__pa(reipl_block_ccw)); | |
| 898 | 895 | diag308(DIAG308_LOAD_CLEAR, NULL); |
| 899 | 896 | break; |
| 900 | 897 | case IPL_TYPE_FCP: |
| 901 | − uv_set_shared(__pa(reipl_block_fcp)); | |
| 902 | 898 | diag308(DIAG308_SET, reipl_block_fcp); |
| 903 | − uv_remove_shared(__pa(reipl_block_fcp)); | |
| 904 | 899 | diag308(DIAG308_LOAD_CLEAR, NULL); |
| 905 | 900 | break; |
| 906 | 901 | case IPL_TYPE_NSS: |
| 907 | − uv_set_shared(__pa(reipl_block_nss)); | |
| 908 | 902 | diag308(DIAG308_SET, reipl_block_nss); |
| 909 | − uv_remove_shared(__pa(reipl_block_nss)); | |
| 910 | 903 | diag308(DIAG308_LOAD_CLEAR, NULL); |
| 911 | 904 | break; |
| 912 | 905 | case IPL_TYPE_UNKNOWN: |
| @@ -1176,9 +1169,7 @@ static struct kset *dump_kset; · 263 unmodified lines | ||
| 1176 | 1169 | |
| 1177 | 1170 | static void diag308_dump(void *dump_block) |
| 1178 | 1171 | { |
| 1179 | − uv_set_shared(__pa(dump_block)); | |
| 1180 | 1172 | diag308(DIAG308_SET, dump_block); |
| 1181 | − uv_remove_shared(__pa(dump_block)); | |
| 1182 | 1173 | while (1) { |
| 1183 | 1174 | if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302) |
| 1184 | 1175 | break; |
| @@ -1114,8 +1114,7 @@ void __init setup_arch(char **cmdline_p) · 1113 unmodified lines | ||
| 1114 | 1114 | |
| 1115 | 1115 | ROOT_DEV = Root_RAM0; |
| 1116 | 1116 | |
| 1117 | − /* Is init_mm really needed? */ | |
| 1118 | − init_mm.start_code = PAGE_OFFSET; | |
| 1117 | + init_mm.start_code = (unsigned long) _text; | |
| 1119 | 1118 | init_mm.end_code = (unsigned long) _etext; |
| 1120 | 1119 | init_mm.end_data = (unsigned long) _edata; |
| 1121 | 1120 | init_mm.brk = (unsigned long) _end; |
| @@ -216,11 +216,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) · 215 unmodified lines | ||
| 216 | 216 | |
| 217 | 217 | if (!vdso_enabled) |
| 218 | 218 | return 0; |
| 219 | − /* | |
| 220 | − * Only map the vdso for dynamically linked elf binaries. | |
| 221 | − */ | |
| 222 | − if (!uses_interp) | |
| 223 | − return 0; | |
| 224 | 219 | |
| 225 | 220 | vdso_pages = vdso64_pages; |
| 226 | 221 | #ifdef CONFIG_COMPAT_VDSO |
| @@ -32,10 +32,9 @@ PHDRS { · 31 unmodified lines | ||
| 32 | 32 | SECTIONS |
| 33 | 33 | { |
| 34 | 34 | . = 0x100000; |
| 35 | − _stext = .; /* Start of text section */ | |
| 36 | 35 | .text : { |
| 37 | − /* Text and read-only data */ | |
| 38 | − _text = .; | |
| 36 | + _stext = .; /* Start of text section */ | |
| 37 | + _text = .; /* Text and read-only data */ | |
| 39 | 38 | HEAD_TEXT |
| 40 | 39 | TEXT_TEXT |
| 41 | 40 | SCHED_TEXT |
| @@ -47,11 +46,10 @@ SECTIONS · 5 unmodified lines | ||
| 47 | 46 | *(.text.*_indirect_*) |
| 48 | 47 | *(.fixup) |
| 49 | 48 | *(.gnu.warning) |
| 49 | + . = ALIGN(PAGE_SIZE); | |
| 50 | + _etext = .; /* End of text section */ | |
| 50 | 51 | } :text = 0x0700 |
| 51 | 52 | |
| 52 | − . = ALIGN(PAGE_SIZE); | |
| 53 | − _etext = .; /* End of text section */ | |
| 54 | − | |
| 55 | 53 | NOTES :text :note |
| 56 | 54 | |
| 57 | 55 | .dummy : { *(.dummy) } :data |
| @@ -2516,16 +2516,6 @@ out_err: · 2515 unmodified lines | ||
| 2516 | 2516 | return rc; |
| 2517 | 2517 | } |
| 2518 | 2518 | |
| 2519 | −bool kvm_arch_has_vcpu_debugfs(void) | |
| 2520 | −{ | |
| 2521 | − return false; | |
| 2522 | −} | |
| 2523 | − | |
| 2524 | −int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 2525 | −{ | |
| 2526 | − return 0; | |
| 2527 | −} | |
| 2528 | − | |
| 2529 | 2519 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) |
| 2530 | 2520 | { |
| 2531 | 2521 | VCPU_EVENT(vcpu, 3, "%s", "free cpu"); |
| @@ -161,9 +161,9 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, · 160 unmodified lines | ||
| 161 | 161 | } |
| 162 | 162 | #endif |
| 163 | 163 | |
| 164 | − for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++) { | |
| 164 | + pmd = pmd_offset(pud, addr); | |
| 165 | + for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++, pmd++) { | |
| 165 | 166 | st->current_address = addr; |
| 166 | − pmd = pmd_offset(pud, addr); | |
| 167 | 167 | if (!pmd_none(*pmd)) { |
| 168 | 168 | if (pmd_large(*pmd)) { |
| 169 | 169 | prot = pmd_val(*pmd) & |
| @@ -192,9 +192,9 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, · 22 unmodified lines | ||
| 192 | 192 | } |
| 193 | 193 | #endif |
| 194 | 194 | |
| 195 | − for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++) { | |
| 195 | + pud = pud_offset(p4d, addr); | |
| 196 | + for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++, pud++) { | |
| 196 | 197 | st->current_address = addr; |
| 197 | − pud = pud_offset(p4d, addr); | |
| 198 | 198 | if (!pud_none(*pud)) |
| 199 | 199 | if (pud_large(*pud)) { |
| 200 | 200 | prot = pud_val(*pud) & |
| @@ -222,9 +222,9 @@ static void walk_p4d_level(struct seq_file *m, struct pg_state *st, · 21 unmodified lines | ||
| 222 | 222 | } |
| 223 | 223 | #endif |
| 224 | 224 | |
| 225 | − for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++) { | |
| 225 | + p4d = p4d_offset(pgd, addr); | |
| 226 | + for (i = 0; i < PTRS_PER_P4D && addr < max_addr; i++, p4d++) { | |
| 226 | 227 | st->current_address = addr; |
| 227 | − p4d = p4d_offset(pgd, addr); | |
| 228 | 228 | if (!p4d_none(*p4d)) |
| 229 | 229 | walk_pud_level(m, st, p4d, addr); |
| 230 | 230 | else |
| @@ -11,8 +11,7 @@ chkbss: $(addprefix $(obj)/, $(chkbss-files)) · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | quiet_cmd_chkbss = CHKBSS $< |
| 13 | 13 | cmd_chkbss = \ |
| 14 | − if $(OBJDUMP) -h $< | grep -q "\.bss" && \ | |
| 15 | − ! $(OBJDUMP) -j .bss -w -h $< | awk 'END { if ($$3) exit 1 }'; then \ | |
| 14 | + if ! $(OBJSIZE) --common $< | $(AWK) 'END { if ($$3) exit 1 }'; then \ | |
| 16 | 15 | echo "error: $< .bss section is not empty" >&2; exit 1; \ |
| 17 | 16 | fi; \ |
| 18 | 17 | touch $@; |
| @@ -475,8 +475,6 @@ static void print_sh_insn(u32 memaddr, u16 insn) · 474 unmodified lines | ||
| 475 | 475 | printk("dbr"); |
| 476 | 476 | break; |
| 477 | 477 | case FD_REG_N: |
| 478 | − if (0) | |
| 479 | − goto d_reg_n; | |
| 480 | 478 | case F_REG_N: |
| 481 | 479 | printk("fr%d", rn); |
| 482 | 480 | break; |
| @@ -488,7 +486,7 @@ static void print_sh_insn(u32 memaddr, u16 insn) · 5 unmodified lines | ||
| 488 | 486 | printk("xd%d", rn & ~1); |
| 489 | 487 | break; |
| 490 | 488 | } |
| 491 | − d_reg_n: | |
| 489 | + /* else, fall through */ | |
| 492 | 490 | case D_REG_N: |
| 493 | 491 | printk("dr%d", rn); |
| 494 | 492 | break; |
| @@ -497,6 +495,7 @@ static void print_sh_insn(u32 memaddr, u16 insn) · 2 unmodified lines | ||
| 497 | 495 | printk("xd%d", rm & ~1); |
| 498 | 496 | break; |
| 499 | 497 | } |
| 498 | + /* else, fall through */ | |
| 500 | 499 | case D_REG_M: |
| 501 | 500 | printk("dr%d", rm); |
| 502 | 501 | break; |
| @@ -157,6 +157,7 @@ int arch_bp_generic_fields(int sh_len, int sh_type, · 156 unmodified lines | ||
| 157 | 157 | switch (sh_type) { |
| 158 | 158 | case SH_BREAKPOINT_READ: |
| 159 | 159 | *gen_type = HW_BREAKPOINT_R; |
| 160 | + break; | |
| 160 | 161 | case SH_BREAKPOINT_WRITE: |
| 161 | 162 | *gen_type = HW_BREAKPOINT_W; |
| 162 | 163 | break; |
| @@ -37,6 +37,14 @@ int memcmp(const void *s1, const void *s2, size_t len) · 36 unmodified lines | ||
| 37 | 37 | return diff; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | +/* | |
| 41 | + * Clang may lower `memcmp == 0` to `bcmp == 0`. | |
| 42 | + */ | |
| 43 | +int bcmp(const void *s1, const void *s2, size_t len) | |
| 44 | +{ | |
| 45 | + return memcmp(s1, s2, len); | |
| 46 | +} | |
| 47 | + | |
| 40 | 48 | int strcmp(const char *str1, const char *str2) |
| 41 | 49 | { |
| 42 | 50 | const unsigned char *s1 = (const unsigned char *)str1; |
| @@ -18,6 +18,20 @@ · 17 unmodified lines | ||
| 18 | 18 | * Note: efi_info is commonly left uninitialized, but that field has a |
| 19 | 19 | * private magic, so it is better to leave it unchanged. |
| 20 | 20 | */ |
| 21 | + | |
| 22 | +#define sizeof_mbr(type, member) ({ sizeof(((type *)0)->member); }) | |
| 23 | + | |
| 24 | +#define BOOT_PARAM_PRESERVE(struct_member) \ | |
| 25 | + { \ | |
| 26 | + .start = offsetof(struct boot_params, struct_member), \ | |
| 27 | + .len = sizeof_mbr(struct boot_params, struct_member), \ | |
| 28 | + } | |
| 29 | + | |
| 30 | +struct boot_params_to_save { | |
| 31 | + unsigned int start; | |
| 32 | + unsigned int len; | |
| 33 | +}; | |
| 34 | + | |
| 21 | 35 | static void sanitize_boot_params(struct boot_params *boot_params) |
| 22 | 36 | { |
| 23 | 37 | /* |
| @@ -35,21 +49,40 @@ static void sanitize_boot_params(struct boot_params *boot_params) · 11 unmodified lines | ||
| 35 | 49 | * problems again. |
| 36 | 50 | */ |
| 37 | 51 | if (boot_params->sentinel) { |
| 38 | − /* fields in boot_params are left uninitialized, clear them */ | |
| 39 | − boot_params->acpi_rsdp_addr = 0; | |
| 40 | − memset(&boot_params->ext_ramdisk_image, 0, | |
| 41 | − (char *)&boot_params->efi_info - | |
| 42 | − (char *)&boot_params->ext_ramdisk_image); | |
| 43 | − memset(&boot_params->kbd_status, 0, | |
| 44 | − (char *)&boot_params->hdr - | |
| 45 | − (char *)&boot_params->kbd_status); | |
| 46 | − memset(&boot_params->_pad7[0], 0, | |
| 47 | − (char *)&boot_params->edd_mbr_sig_buffer[0] - | |
| 48 | − (char *)&boot_params->_pad7[0]); | |
| 49 | − memset(&boot_params->_pad8[0], 0, | |
| 50 | − (char *)&boot_params->eddbuf[0] - | |
| 51 | − (char *)&boot_params->_pad8[0]); | |
| 52 | − memset(&boot_params->_pad9[0], 0, sizeof(boot_params->_pad9)); | |
| 52 | + static struct boot_params scratch; | |
| 53 | + char *bp_base = (char *)boot_params; | |
| 54 | + char *save_base = (char *)&scratch; | |
| 55 | + int i; | |
| 56 | + | |
| 57 | + const struct boot_params_to_save to_save[] = { | |
| 58 | + BOOT_PARAM_PRESERVE(screen_info), | |
| 59 | + BOOT_PARAM_PRESERVE(apm_bios_info), | |
| 60 | + BOOT_PARAM_PRESERVE(tboot_addr), | |
| 61 | + BOOT_PARAM_PRESERVE(ist_info), | |
| 62 | + BOOT_PARAM_PRESERVE(acpi_rsdp_addr), | |
| 63 | + BOOT_PARAM_PRESERVE(hd0_info), | |
| 64 | + BOOT_PARAM_PRESERVE(hd1_info), | |
| 65 | + BOOT_PARAM_PRESERVE(sys_desc_table), | |
| 66 | + BOOT_PARAM_PRESERVE(olpc_ofw_header), | |
| 67 | + BOOT_PARAM_PRESERVE(efi_info), | |
| 68 | + BOOT_PARAM_PRESERVE(alt_mem_k), | |
| 69 | + BOOT_PARAM_PRESERVE(scratch), | |
| 70 | + BOOT_PARAM_PRESERVE(e820_entries), | |
| 71 | + BOOT_PARAM_PRESERVE(eddbuf_entries), | |
| 72 | + BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries), | |
| 73 | + BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer), | |
| 74 | + BOOT_PARAM_PRESERVE(e820_table), | |
| 75 | + BOOT_PARAM_PRESERVE(eddbuf), | |
| 76 | + }; | |
| 77 | + | |
| 78 | + memset(&scratch, 0, sizeof(scratch)); | |
| 79 | + | |
| 80 | + for (i = 0; i < ARRAY_SIZE(to_save); i++) { | |
| 81 | + memcpy(save_base + to_save[i].start, | |
| 82 | + bp_base + to_save[i].start, to_save[i].len); | |
| 83 | + } | |
| 84 | + | |
| 85 | + memcpy(boot_params, save_base, sizeof(*boot_params)); | |
| 53 | 86 | } |
| 54 | 87 | } |
| 55 | 88 | |
| @@ -35,6 +35,8 @@ · 34 unmodified lines | ||
| 35 | 35 | #include <asm/kvm_vcpu_regs.h> |
| 36 | 36 | #include <asm/hyperv-tlfs.h> |
| 37 | 37 | |
| 38 | +#define __KVM_HAVE_ARCH_VCPU_DEBUGFS | |
| 39 | + | |
| 38 | 40 | #define KVM_MAX_VCPUS 288 |
| 39 | 41 | #define KVM_SOFT_MAX_VCPUS 240 |
| 40 | 42 | #define KVM_MAX_VCPU_ID 1023 |
| @@ -1175,6 +1177,7 @@ struct kvm_x86_ops { · 1134 unmodified lines | ||
| 1175 | 1177 | int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq, |
| 1176 | 1178 | uint32_t guest_irq, bool set); |
| 1177 | 1179 | void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu); |
| 1180 | + bool (*dy_apicv_has_pending_interrupt)(struct kvm_vcpu *vcpu); | |
| 1178 | 1181 | |
| 1179 | 1182 | int (*set_hv_timer)(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc, |
| 1180 | 1183 | bool *expired); |
| @@ -184,7 +184,8 @@ void __init default_setup_apic_routing(void) · 183 unmodified lines | ||
| 184 | 184 | def_to_bigsmp = 0; |
| 185 | 185 | break; |
| 186 | 186 | } |
| 187 | − /* If P4 and above fall through */ | |
| 187 | + /* P4 and above */ | |
| 188 | + /* fall through */ | |
| 188 | 189 | case X86_VENDOR_HYGON: |
| 189 | 190 | case X86_VENDOR_AMD: |
| 190 | 191 | def_to_bigsmp = 1; |
| @@ -98,6 +98,7 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) · 97 unmodified lines | ||
| 98 | 98 | case 7: |
| 99 | 99 | if (size < 0x40) |
| 100 | 100 | break; |
| 101 | + /* Else, fall through */ | |
| 101 | 102 | case 6: |
| 102 | 103 | case 5: |
| 103 | 104 | case 4: |
| @@ -17,6 +17,12 @@ · 16 unmodified lines | ||
| 17 | 17 | */ |
| 18 | 18 | static u32 umwait_control_cached = UMWAIT_CTRL_VAL(100000, UMWAIT_C02_ENABLE); |
| 19 | 19 | |
| 20 | +/* | |
| 21 | + * Cache the original IA32_UMWAIT_CONTROL MSR value which is configured by | |
| 22 | + * hardware or BIOS before kernel boot. | |
| 23 | + */ | |
| 24 | +static u32 orig_umwait_control_cached __ro_after_init; | |
| 25 | + | |
| 20 | 26 | /* |
| 21 | 27 | * Serialize access to umwait_control_cached and IA32_UMWAIT_CONTROL MSR in |
| 22 | 28 | * the sysfs write functions. |
| @@ -52,6 +58,23 @@ static int umwait_cpu_online(unsigned int cpu) · 29 unmodified lines | ||
| 52 | 58 | return 0; |
| 53 | 59 | } |
| 54 | 60 | |
| 61 | +/* | |
| 62 | + * The CPU hotplug callback sets the control MSR to the original control | |
| 63 | + * value. | |
| 64 | + */ | |
| 65 | +static int umwait_cpu_offline(unsigned int cpu) | |
| 66 | +{ | |
| 67 | + /* | |
| 68 | + * This code is protected by the CPU hotplug already and | |
| 69 | + * orig_umwait_control_cached is never changed after it caches | |
| 70 | + * the original control MSR value in umwait_init(). So there | |
| 71 | + * is no race condition here. | |
| 72 | + */ | |
| 73 | + wrmsr(MSR_IA32_UMWAIT_CONTROL, orig_umwait_control_cached, 0); | |
| 74 | + | |
| 75 | + return 0; | |
| 76 | +} | |
| 77 | + | |
| 55 | 78 | /* |
| 56 | 79 | * On resume, restore IA32_UMWAIT_CONTROL MSR on the boot processor which |
| 57 | 80 | * is the only active CPU at this time. The MSR is set up on the APs via the |
| @@ -185,8 +208,22 @@ static int __init umwait_init(void) · 127 unmodified lines | ||
| 185 | 208 | if (!boot_cpu_has(X86_FEATURE_WAITPKG)) |
| 186 | 209 | return -ENODEV; |
| 187 | 210 | |
| 211 | + /* | |
| 212 | + * Cache the original control MSR value before the control MSR is | |
| 213 | + * changed. This is the only place where orig_umwait_control_cached | |
| 214 | + * is modified. | |
| 215 | + */ | |
| 216 | + rdmsrl(MSR_IA32_UMWAIT_CONTROL, orig_umwait_control_cached); | |
| 217 | + | |
| 188 | 218 | ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "umwait:online", |
| 189 | − umwait_cpu_online, NULL); | |
| 219 | + umwait_cpu_online, umwait_cpu_offline); | |
| 220 | + if (ret < 0) { | |
| 221 | + /* | |
| 222 | + * On failure, the control MSR on all CPUs has the | |
| 223 | + * original control value. | |
| 224 | + */ | |
| 225 | + return ret; | |
| 226 | + } | |
| 190 | 227 | |
| 191 | 228 | register_syscore_ops(&umwait_syscore_ops); |
| 192 | 229 | |
| @@ -308,9 +308,6 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val) · 307 unmodified lines | ||
| 308 | 308 | |
| 309 | 309 | static void kvm_guest_cpu_init(void) |
| 310 | 310 | { |
| 311 | − if (!kvm_para_available()) | |
| 312 | − return; | |
| 313 | − | |
| 314 | 311 | if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) { |
| 315 | 312 | u64 pa = slow_virt_to_phys(this_cpu_ptr(&apf_reason)); |
| 316 | 313 | |
| @@ -625,9 +622,6 @@ static void __init kvm_guest_init(void) · 308 unmodified lines | ||
| 625 | 622 | { |
| 626 | 623 | int i; |
| 627 | 624 | |
| 628 | − if (!kvm_para_available()) | |
| 629 | − return; | |
| 630 | − | |
| 631 | 625 | paravirt_ops_setup(); |
| 632 | 626 | register_reboot_notifier(&kvm_pv_reboot_nb); |
| 633 | 627 | for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) |
| @@ -848,8 +842,6 @@ asm( · 214 unmodified lines | ||
| 848 | 842 | */ |
| 849 | 843 | void __init kvm_spinlock_init(void) |
| 850 | 844 | { |
| 851 | − if (!kvm_para_available()) | |
| 852 | − return; | |
| 853 | 845 | /* Does host kernel support KVM_FEATURE_PV_UNHALT? */ |
| 854 | 846 | if (!kvm_para_has_feature(KVM_FEATURE_PV_UNHALT)) |
| 855 | 847 | return; |
| @@ -201,6 +201,7 @@ static int set_segment_reg(struct task_struct *task, · 200 unmodified lines | ||
| 201 | 201 | case offsetof(struct user_regs_struct, ss): |
| 202 | 202 | if (unlikely(value == 0)) |
| 203 | 203 | return -EIO; |
| 204 | + /* Else, fall through */ | |
| 204 | 205 | |
| 205 | 206 | default: |
| 206 | 207 | *pt_regs_access(task_pt_regs(task), offset) = value; |
| @@ -8,11 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/debugfs.h> |
| 9 | 9 | #include "lapic.h" |
| 10 | 10 | |
| 11 | −bool kvm_arch_has_vcpu_debugfs(void) | |
| 12 | −{ | |
| 13 | − return true; | |
| 14 | −} | |
| 15 | − | |
| 16 | 11 | static int vcpu_get_timer_advance_ns(void *data, u64 *val) |
| 17 | 12 | { |
| 18 | 13 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *) data; |
| @@ -48,37 +43,22 @@ static int vcpu_get_tsc_scaling_frac_bits(void *data, u64 *val) · 29 unmodified lines | ||
| 48 | 43 | |
| 49 | 44 | DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_scaling_frac_fops, vcpu_get_tsc_scaling_frac_bits, NULL, "%llu\n"); |
| 50 | 45 | |
| 51 | −int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 46 | +void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 52 | 47 | { |
| 53 | − struct dentry *ret; | |
| 54 | − | |
| 55 | − ret = debugfs_create_file("tsc-offset", 0444, | |
| 56 | − vcpu->debugfs_dentry, | |
| 57 | − vcpu, &vcpu_tsc_offset_fops); | |
| 58 | − if (!ret) | |
| 59 | − return -ENOMEM; | |
| 48 | + debugfs_create_file("tsc-offset", 0444, vcpu->debugfs_dentry, vcpu, | |
| 49 | + &vcpu_tsc_offset_fops); | |
| 60 | 50 | |
| 61 | − if (lapic_in_kernel(vcpu)) { | |
| 62 | − ret = debugfs_create_file("lapic_timer_advance_ns", 0444, | |
| 63 | − vcpu->debugfs_dentry, | |
| 64 | − vcpu, &vcpu_timer_advance_ns_fops); | |
| 65 | − if (!ret) | |
| 66 | − return -ENOMEM; | |
| 67 | − } | |
| 51 | + if (lapic_in_kernel(vcpu)) | |
| 52 | + debugfs_create_file("lapic_timer_advance_ns", 0444, | |
| 53 | + vcpu->debugfs_dentry, vcpu, | |
| 54 | + &vcpu_timer_advance_ns_fops); | |
| 68 | 55 | |
| 69 | 56 | if (kvm_has_tsc_control) { |
| 70 | − ret = debugfs_create_file("tsc-scaling-ratio", 0444, | |
| 71 | − vcpu->debugfs_dentry, | |
| 72 | − vcpu, &vcpu_tsc_scaling_fops); | |
| 73 | − if (!ret) | |
| 74 | − return -ENOMEM; | |
| 75 | − ret = debugfs_create_file("tsc-scaling-ratio-frac-bits", 0444, | |
| 76 | − vcpu->debugfs_dentry, | |
| 77 | − vcpu, &vcpu_tsc_scaling_frac_fops); | |
| 78 | − if (!ret) | |
| 79 | − return -ENOMEM; | |
| 80 | − | |
| 57 | + debugfs_create_file("tsc-scaling-ratio", 0444, | |
| 58 | + vcpu->debugfs_dentry, vcpu, | |
| 59 | + &vcpu_tsc_scaling_fops); | |
| 60 | + debugfs_create_file("tsc-scaling-ratio-frac-bits", 0444, | |
| 61 | + vcpu->debugfs_dentry, vcpu, | |
| 62 | + &vcpu_tsc_scaling_frac_fops); | |
| 81 | 63 | } |
| 82 | − | |
| 83 | − return 0; | |
| 84 | 64 | } |
| @@ -1548,7 +1548,6 @@ static void kvm_apic_inject_pending_timer_irqs(struct kvm_lapic *apic) · 1547 unmodified lines | ||
| 1548 | 1548 | static void apic_timer_expired(struct kvm_lapic *apic) |
| 1549 | 1549 | { |
| 1550 | 1550 | struct kvm_vcpu *vcpu = apic->vcpu; |
| 1551 | − struct swait_queue_head *q = &vcpu->wq; | |
| 1552 | 1551 | struct kvm_timer *ktimer = &apic->lapic_timer; |
| 1553 | 1552 | |
| 1554 | 1553 | if (atomic_read(&apic->lapic_timer.pending)) |
| @@ -1566,13 +1565,6 @@ static void apic_timer_expired(struct kvm_lapic *apic) · 11 unmodified lines | ||
| 1566 | 1565 | |
| 1567 | 1566 | atomic_inc(&apic->lapic_timer.pending); |
| 1568 | 1567 | kvm_set_pending_timer(vcpu); |
| 1569 | − | |
| 1570 | − /* | |
| 1571 | − * For x86, the atomic_inc() is serialized, thus | |
| 1572 | − * using swait_active() is safe. | |
| 1573 | − */ | |
| 1574 | − if (swait_active(q)) | |
| 1575 | − swake_up_one(q); | |
| 1576 | 1568 | } |
| 1577 | 1569 | |
| 1578 | 1570 | static void start_sw_tscdeadline(struct kvm_lapic *apic) |
| @@ -5190,6 +5190,11 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) · 5189 unmodified lines | ||
| 5190 | 5190 | kvm_vcpu_wake_up(vcpu); |
| 5191 | 5191 | } |
| 5192 | 5192 | |
| 5193 | +static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu) | |
| 5194 | +{ | |
| 5195 | + return false; | |
| 5196 | +} | |
| 5197 | + | |
| 5193 | 5198 | static void svm_ir_list_del(struct vcpu_svm *svm, struct amd_iommu_pi_data *pi) |
| 5194 | 5199 | { |
| 5195 | 5200 | unsigned long flags; |
| @@ -7314,6 +7319,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { · 2118 unmodified lines | ||
| 7314 | 7319 | |
| 7315 | 7320 | .pmu_ops = &amd_pmu_ops, |
| 7316 | 7321 | .deliver_posted_interrupt = svm_deliver_avic_intr, |
| 7322 | + .dy_apicv_has_pending_interrupt = svm_dy_apicv_has_pending_interrupt, | |
| 7317 | 7323 | .update_pi_irte = svm_update_pi_irte, |
| 7318 | 7324 | .setup_mce = svm_setup_mce, |
| 7319 | 7325 | |
| @@ -6117,6 +6117,11 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) · 6116 unmodified lines | ||
| 6117 | 6117 | return max_irr; |
| 6118 | 6118 | } |
| 6119 | 6119 | |
| 6120 | +static bool vmx_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu) | |
| 6121 | +{ | |
| 6122 | + return pi_test_on(vcpu_to_pi_desc(vcpu)); | |
| 6123 | +} | |
| 6124 | + | |
| 6120 | 6125 | static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) |
| 6121 | 6126 | { |
| 6122 | 6127 | if (!kvm_vcpu_apicv_active(vcpu)) |
| @@ -7726,6 +7731,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { · 1603 unmodified lines | ||
| 7726 | 7731 | .guest_apic_has_interrupt = vmx_guest_apic_has_interrupt, |
| 7727 | 7732 | .sync_pir_to_irr = vmx_sync_pir_to_irr, |
| 7728 | 7733 | .deliver_posted_interrupt = vmx_deliver_posted_interrupt, |
| 7734 | + .dy_apicv_has_pending_interrupt = vmx_dy_apicv_has_pending_interrupt, | |
| 7729 | 7735 | |
| 7730 | 7736 | .set_tss_addr = vmx_set_tss_addr, |
| 7731 | 7737 | .set_identity_map_addr = vmx_set_identity_map_addr, |
| @@ -9698,6 +9698,22 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) · 9697 unmodified lines | ||
| 9698 | 9698 | return kvm_vcpu_running(vcpu) || kvm_vcpu_has_events(vcpu); |
| 9699 | 9699 | } |
| 9700 | 9700 | |
| 9701 | +bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu) | |
| 9702 | +{ | |
| 9703 | + if (READ_ONCE(vcpu->arch.pv.pv_unhalted)) | |
| 9704 | + return true; | |
| 9705 | + | |
| 9706 | + if (kvm_test_request(KVM_REQ_NMI, vcpu) || | |
| 9707 | + kvm_test_request(KVM_REQ_SMI, vcpu) || | |
| 9708 | + kvm_test_request(KVM_REQ_EVENT, vcpu)) | |
| 9709 | + return true; | |
| 9710 | + | |
| 9711 | + if (vcpu->arch.apicv_active && kvm_x86_ops->dy_apicv_has_pending_interrupt(vcpu)) | |
| 9712 | + return true; | |
| 9713 | + | |
| 9714 | + return false; | |
| 9715 | +} | |
| 9716 | + | |
| 9701 | 9717 | bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) |
| 9702 | 9718 | { |
| 9703 | 9719 | return vcpu->arch.preempted_in_kernel; |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | #include <linux/types.h> |
| 3 | 3 | #include <linux/export.h> |
| 4 | +#include <asm/cpu.h> | |
| 4 | 5 | |
| 5 | 6 | unsigned int x86_family(unsigned int sig) |
| 6 | 7 | { |
| @@ -178,13 +178,15 @@ void FPU_printall(void) · 177 unmodified lines | ||
| 178 | 178 | for (i = 0; i < 8; i++) { |
| 179 | 179 | FPU_REG *r = &st(i); |
| 180 | 180 | u_char tagi = FPU_gettagi(i); |
| 181 | + | |
| 181 | 182 | switch (tagi) { |
| 182 | 183 | case TAG_Empty: |
| 183 | 184 | continue; |
| 184 | − break; | |
| 185 | 185 | case TAG_Zero: |
| 186 | 186 | case TAG_Special: |
| 187 | + /* Update tagi for the printk below */ | |
| 187 | 188 | tagi = FPU_Special(r); |
| 189 | + /* fall through */ | |
| 188 | 190 | case TAG_Valid: |
| 189 | 191 | printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i, |
| 190 | 192 | getsign(r) ? '-' : '+', |
| @@ -198,7 +200,6 @@ void FPU_printall(void) · 7 unmodified lines | ||
| 198 | 200 | printk("Whoops! Error in errors.c: tag%d is %d ", i, |
| 199 | 201 | tagi); |
| 200 | 202 | continue; |
| 201 | − break; | |
| 202 | 203 | } |
| 203 | 204 | printk("%s\n", tag_desc[(int)(unsigned)tagi]); |
| 204 | 205 | } |
| @@ -1352,7 +1352,7 @@ static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag) · 1351 unmodified lines | ||
| 1352 | 1352 | case TW_Denormal: |
| 1353 | 1353 | if (denormal_operand() < 0) |
| 1354 | 1354 | return; |
| 1355 | − | |
| 1355 | + /* fall through */ | |
| 1356 | 1356 | case TAG_Zero: |
| 1357 | 1357 | case TAG_Valid: |
| 1358 | 1358 | setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr)); |
| @@ -390,8 +390,9 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, · 389 unmodified lines | ||
| 390 | 390 | |
| 391 | 391 | emit_prologue(&prog, bpf_prog->aux->stack_depth, |
| 392 | 392 | bpf_prog_was_classic(bpf_prog)); |
| 393 | + addrs[0] = prog - temp; | |
| 393 | 394 | |
| 394 | − for (i = 0; i < insn_cnt; i++, insn++) { | |
| 395 | + for (i = 1; i <= insn_cnt; i++, insn++) { | |
| 395 | 396 | const s32 imm32 = insn->imm; |
| 396 | 397 | u32 dst_reg = insn->dst_reg; |
| 397 | 398 | u32 src_reg = insn->src_reg; |
| @@ -1105,7 +1106,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 707 unmodified lines | ||
| 1105 | 1106 | extra_pass = true; |
| 1106 | 1107 | goto skip_init_addrs; |
| 1107 | 1108 | } |
| 1108 | − addrs = kmalloc_array(prog->len, sizeof(*addrs), GFP_KERNEL); | |
| 1109 | + addrs = kmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); | |
| 1109 | 1110 | if (!addrs) { |
| 1110 | 1111 | prog = orig_prog; |
| 1111 | 1112 | goto out_addrs; |
| @@ -1115,7 +1116,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 3 unmodified lines | ||
| 1115 | 1116 | * Before first pass, make a rough estimation of addrs[] |
| 1116 | 1117 | * each BPF instruction is translated to less than 64 bytes |
| 1117 | 1118 | */ |
| 1118 | − for (proglen = 0, i = 0; i < prog->len; i++) { | |
| 1119 | + for (proglen = 0, i = 0; i <= prog->len; i++) { | |
| 1119 | 1120 | proglen += 64; |
| 1120 | 1121 | addrs[i] = proglen; |
| 1121 | 1122 | } |
| @@ -1180,7 +1181,7 @@ out_image: · 58 unmodified lines | ||
| 1180 | 1181 | |
| 1181 | 1182 | if (!image || !prog->is_func || extra_pass) { |
| 1182 | 1183 | if (image) |
| 1183 | − bpf_prog_fill_jited_linfo(prog, addrs); | |
| 1184 | + bpf_prog_fill_jited_linfo(prog, addrs + 1); | |
| 1184 | 1185 | out_addrs: |
| 1185 | 1186 | kfree(addrs); |
| 1186 | 1187 | kfree(jit_data); |
| @@ -6,6 +6,9 @@ purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string · 5 unmodified lines | ||
| 6 | 6 | targets += $(purgatory-y) |
| 7 | 7 | PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) |
| 8 | 8 | |
| 9 | +$(obj)/string.o: $(srctree)/arch/x86/boot/compressed/string.c FORCE | |
| 10 | + $(call if_changed_rule,cc_o_c) | |
| 11 | + | |
| 9 | 12 | $(obj)/sha256.o: $(srctree)/lib/sha256.c FORCE |
| 10 | 13 | $(call if_changed_rule,cc_o_c) |
| 11 | 14 | |
| @@ -17,11 +20,34 @@ KCOV_INSTRUMENT := n · 5 unmodified lines | ||
| 17 | 20 | |
| 18 | 21 | # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That |
| 19 | 22 | # in turn leaves some undefined symbols like __fentry__ in purgatory and not |
| 20 | −# sure how to relocate those. Like kexec-tools, use custom flags. | |
| 21 | − | |
| 22 | −KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -Os -mcmodel=large | |
| 23 | −KBUILD_CFLAGS += -m$(BITS) | |
| 24 | −KBUILD_CFLAGS += $(call cc-option,-fno-PIE) | |
| 23 | +# sure how to relocate those. | |
| 24 | +ifdef CONFIG_FUNCTION_TRACER | |
| 25 | +CFLAGS_REMOVE_sha256.o += $(CC_FLAGS_FTRACE) | |
| 26 | +CFLAGS_REMOVE_purgatory.o += $(CC_FLAGS_FTRACE) | |
| 27 | +CFLAGS_REMOVE_string.o += $(CC_FLAGS_FTRACE) | |
| 28 | +CFLAGS_REMOVE_kexec-purgatory.o += $(CC_FLAGS_FTRACE) | |
| 29 | +endif | |
| 30 | + | |
| 31 | +ifdef CONFIG_STACKPROTECTOR | |
| 32 | +CFLAGS_REMOVE_sha256.o += -fstack-protector | |
| 33 | +CFLAGS_REMOVE_purgatory.o += -fstack-protector | |
| 34 | +CFLAGS_REMOVE_string.o += -fstack-protector | |
| 35 | +CFLAGS_REMOVE_kexec-purgatory.o += -fstack-protector | |
| 36 | +endif | |
| 37 | + | |
| 38 | +ifdef CONFIG_STACKPROTECTOR_STRONG | |
| 39 | +CFLAGS_REMOVE_sha256.o += -fstack-protector-strong | |
| 40 | +CFLAGS_REMOVE_purgatory.o += -fstack-protector-strong | |
| 41 | +CFLAGS_REMOVE_string.o += -fstack-protector-strong | |
| 42 | +CFLAGS_REMOVE_kexec-purgatory.o += -fstack-protector-strong | |
| 43 | +endif | |
| 44 | + | |
| 45 | +ifdef CONFIG_RETPOLINE | |
| 46 | +CFLAGS_REMOVE_sha256.o += $(RETPOLINE_CFLAGS) | |
| 47 | +CFLAGS_REMOVE_purgatory.o += $(RETPOLINE_CFLAGS) | |
| 48 | +CFLAGS_REMOVE_string.o += $(RETPOLINE_CFLAGS) | |
| 49 | +CFLAGS_REMOVE_kexec-purgatory.o += $(RETPOLINE_CFLAGS) | |
| 50 | +endif | |
| 25 | 51 | |
| 26 | 52 | $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE |
| 27 | 53 | $(call if_changed,ld) |
| @@ -68,3 +68,9 @@ void purgatory(void) · 67 unmodified lines | ||
| 68 | 68 | } |
| 69 | 69 | copy_backup_region(); |
| 70 | 70 | } |
| 71 | + | |
| 72 | +/* | |
| 73 | + * Defined in order to reuse memcpy() and memset() from | |
| 74 | + * arch/x86/boot/compressed/string.c | |
| 75 | + */ | |
| 76 | +void warn(const char *msg) {} | |
| @@ -1,23 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | −/* | |
| 3 | − * Simple string functions. | |
| 4 | − * | |
| 5 | − * Copyright (C) 2014 Red Hat Inc. | |
| 6 | − * | |
| 7 | − * Author: | |
| 8 | − * Vivek Goyal <vgoyal@redhat.com> | |
| 9 | − */ | |
| 10 | − | |
| 11 | −#include <linux/types.h> | |
| 12 | − | |
| 13 | −#include "../boot/string.c" | |
| 14 | − | |
| 15 | −void *memcpy(void *dst, const void *src, size_t len) | |
| 16 | −{ | |
| 17 | − return __builtin_memcpy(dst, src, len); | |
| 18 | −} | |
| 19 | − | |
| 20 | −void *memset(void *dst, int c, size_t len) | |
| 21 | −{ | |
| 22 | − return __builtin_memset(dst, c, len); | |
| 23 | −} | |
| @@ -511,6 +511,7 @@ void cpu_reset(void) · 510 unmodified lines | ||
| 511 | 511 | "add %2, %2, %7\n\t" |
| 512 | 512 | "addi %0, %0, -1\n\t" |
| 513 | 513 | "bnez %0, 1b\n\t" |
| 514 | + "isync\n\t" | |
| 514 | 515 | /* Jump to identity mapping */ |
| 515 | 516 | "jx %3\n" |
| 516 | 517 | "2:\n\t" |
| @@ -1924,12 +1924,13 @@ static void bfq_add_request(struct request *rq) · 1923 unmodified lines | ||
| 1924 | 1924 | * confirmed no later than during the next |
| 1925 | 1925 | * I/O-plugging interval for bfqq. |
| 1926 | 1926 | */ |
| 1927 | − if (!bfq_bfqq_has_short_ttime(bfqq) && | |
| 1927 | + if (bfqd->last_completed_rq_bfqq && | |
| 1928 | + !bfq_bfqq_has_short_ttime(bfqq) && | |
| 1928 | 1929 | ktime_get_ns() - bfqd->last_completion < |
| 1929 | 1930 | 200 * NSEC_PER_USEC) { |
| 1930 | 1931 | if (bfqd->last_completed_rq_bfqq != bfqq && |
| 1931 | − bfqd->last_completed_rq_bfqq != | |
| 1932 | − bfqq->waker_bfqq) { | |
| 1932 | + bfqd->last_completed_rq_bfqq != | |
| 1933 | + bfqq->waker_bfqq) { | |
| 1933 | 1934 | /* |
| 1934 | 1935 | * First synchronization detected with |
| 1935 | 1936 | * a candidate waker queue, or with a |
| @@ -2250,9 +2251,14 @@ static void bfq_request_merged(struct request_queue *q, struct request *req, · 314 unmodified lines | ||
| 2250 | 2251 | blk_rq_pos(container_of(rb_prev(&req->rb_node), |
| 2251 | 2252 | struct request, rb_node))) { |
| 2252 | 2253 | struct bfq_queue *bfqq = bfq_init_rq(req); |
| 2253 | − struct bfq_data *bfqd = bfqq->bfqd; | |
| 2254 | + struct bfq_data *bfqd; | |
| 2254 | 2255 | struct request *prev, *next_rq; |
| 2255 | 2256 | |
| 2257 | + if (!bfqq) | |
| 2258 | + return; | |
| 2259 | + | |
| 2260 | + bfqd = bfqq->bfqd; | |
| 2261 | + | |
| 2256 | 2262 | /* Reposition request in its sort_list */ |
| 2257 | 2263 | elv_rb_del(&bfqq->sort_list, req); |
| 2258 | 2264 | elv_rb_add(&bfqq->sort_list, req); |
| @@ -2299,6 +2305,9 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq, · 40 unmodified lines | ||
| 2299 | 2305 | struct bfq_queue *bfqq = bfq_init_rq(rq), |
| 2300 | 2306 | *next_bfqq = bfq_init_rq(next); |
| 2301 | 2307 | |
| 2308 | + if (!bfqq) | |
| 2309 | + return; | |
| 2310 | + | |
| 2302 | 2311 | /* |
| 2303 | 2312 | * If next and rq belong to the same bfq_queue and next is older |
| 2304 | 2313 | * than rq, then reposition rq in the fifo (by substituting next |
| @@ -4764,6 +4773,8 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx) · 2459 unmodified lines | ||
| 4764 | 4773 | */ |
| 4765 | 4774 | void bfq_put_queue(struct bfq_queue *bfqq) |
| 4766 | 4775 | { |
| 4776 | + struct bfq_queue *item; | |
| 4777 | + struct hlist_node *n; | |
| 4767 | 4778 | #ifdef CONFIG_BFQ_GROUP_IOSCHED |
| 4768 | 4779 | struct bfq_group *bfqg = bfqq_group(bfqq); |
| 4769 | 4780 | #endif |
| @@ -4808,6 +4819,36 @@ void bfq_put_queue(struct bfq_queue *bfqq) · 38 unmodified lines | ||
| 4808 | 4819 | bfqq->bfqd->burst_size--; |
| 4809 | 4820 | } |
| 4810 | 4821 | |
| 4822 | + /* | |
| 4823 | + * bfqq does not exist any longer, so it cannot be woken by | |
| 4824 | + * any other queue, and cannot wake any other queue. Then bfqq | |
| 4825 | + * must be removed from the woken list of its possible waker | |
| 4826 | + * queue, and all queues in the woken list of bfqq must stop | |
| 4827 | + * having a waker queue. Strictly speaking, these updates | |
| 4828 | + * should be performed when bfqq remains with no I/O source | |
| 4829 | + * attached to it, which happens before bfqq gets freed. In | |
| 4830 | + * particular, this happens when the last process associated | |
| 4831 | + * with bfqq exits or gets associated with a different | |
| 4832 | + * queue. However, both events lead to bfqq being freed soon, | |
| 4833 | + * and dangling references would come out only after bfqq gets | |
| 4834 | + * freed. So these updates are done here, as a simple and safe | |
| 4835 | + * way to handle all cases. | |
| 4836 | + */ | |
| 4837 | + /* remove bfqq from woken list */ | |
| 4838 | + if (!hlist_unhashed(&bfqq->woken_list_node)) | |
| 4839 | + hlist_del_init(&bfqq->woken_list_node); | |
| 4840 | + | |
| 4841 | + /* reset waker for all queues in woken list */ | |
| 4842 | + hlist_for_each_entry_safe(item, n, &bfqq->woken_list, | |
| 4843 | + woken_list_node) { | |
| 4844 | + item->waker_bfqq = NULL; | |
| 4845 | + bfq_clear_bfqq_has_waker(item); | |
| 4846 | + hlist_del_init(&item->woken_list_node); | |
| 4847 | + } | |
| 4848 | + | |
| 4849 | + if (bfqq->bfqd && bfqq->bfqd->last_completed_rq_bfqq == bfqq) | |
| 4850 | + bfqq->bfqd->last_completed_rq_bfqq = NULL; | |
| 4851 | + | |
| 4811 | 4852 | kmem_cache_free(bfq_pool, bfqq); |
| 4812 | 4853 | #ifdef CONFIG_BFQ_GROUP_IOSCHED |
| 4813 | 4854 | bfqg_and_blkg_put(bfqg); |
| @@ -4835,9 +4876,6 @@ static void bfq_put_cooperator(struct bfq_queue *bfqq) · 21 unmodified lines | ||
| 4835 | 4876 | |
| 4836 | 4877 | static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) |
| 4837 | 4878 | { |
| 4838 | − struct bfq_queue *item; | |
| 4839 | − struct hlist_node *n; | |
| 4840 | − | |
| 4841 | 4879 | if (bfqq == bfqd->in_service_queue) { |
| 4842 | 4880 | __bfq_bfqq_expire(bfqd, bfqq, BFQQE_BUDGET_TIMEOUT); |
| 4843 | 4881 | bfq_schedule_dispatch(bfqd); |
| @@ -4847,18 +4885,6 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) · 3 unmodified lines | ||
| 4847 | 4885 | |
| 4848 | 4886 | bfq_put_cooperator(bfqq); |
| 4849 | 4887 | |
| 4850 | − /* remove bfqq from woken list */ | |
| 4851 | − if (!hlist_unhashed(&bfqq->woken_list_node)) | |
| 4852 | − hlist_del_init(&bfqq->woken_list_node); | |
| 4853 | − | |
| 4854 | − /* reset waker for all queues in woken list */ | |
| 4855 | − hlist_for_each_entry_safe(item, n, &bfqq->woken_list, | |
| 4856 | − woken_list_node) { | |
| 4857 | − item->waker_bfqq = NULL; | |
| 4858 | − bfq_clear_bfqq_has_waker(item); | |
| 4859 | − hlist_del_init(&item->woken_list_node); | |
| 4860 | − } | |
| 4861 | − | |
| 4862 | 4888 | bfq_put_queue(bfqq); /* release process reference */ |
| 4863 | 4889 | } |
| 4864 | 4890 | |
| @@ -5436,12 +5462,12 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, · 571 unmodified lines | ||
| 5436 | 5462 | |
| 5437 | 5463 | spin_lock_irq(&bfqd->lock); |
| 5438 | 5464 | bfqq = bfq_init_rq(rq); |
| 5439 | − if (at_head || blk_rq_is_passthrough(rq)) { | |
| 5465 | + if (!bfqq || at_head || blk_rq_is_passthrough(rq)) { | |
| 5440 | 5466 | if (at_head) |
| 5441 | 5467 | list_add(&rq->queuelist, &bfqd->dispatch); |
| 5442 | 5468 | else |
| 5443 | 5469 | list_add_tail(&rq->queuelist, &bfqd->dispatch); |
| 5444 | − } else { /* bfqq is assumed to be non null here */ | |
| 5470 | + } else { | |
| 5445 | 5471 | idle_timer_disabled = __bfq_insert_request(bfqd, rq); |
| 5446 | 5472 | /* |
| 5447 | 5473 | * Update bfqq, because, if a queue merge has occurred |
| @@ -1958,13 +1958,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 1957 unmodified lines | ||
| 1958 | 1958 | rq = blk_mq_get_request(q, bio, &data); |
| 1959 | 1959 | if (unlikely(!rq)) { |
| 1960 | 1960 | rq_qos_cleanup(q, bio); |
| 1961 | − | |
| 1962 | − cookie = BLK_QC_T_NONE; | |
| 1963 | − if (bio->bi_opf & REQ_NOWAIT_INLINE) | |
| 1964 | − cookie = BLK_QC_T_EAGAIN; | |
| 1965 | − else if (bio->bi_opf & REQ_NOWAIT) | |
| 1961 | + if (bio->bi_opf & REQ_NOWAIT) | |
| 1966 | 1962 | bio_wouldblock_error(bio); |
| 1967 | − return cookie; | |
| 1963 | + return BLK_QC_T_NONE; | |
| 1968 | 1964 | } |
| 1969 | 1965 | |
| 1970 | 1966 | trace_block_getrq(q, bio, bio->bi_opf); |
| @@ -2666,8 +2662,6 @@ void blk_mq_release(struct request_queue *q) · 695 unmodified lines | ||
| 2666 | 2662 | struct blk_mq_hw_ctx *hctx, *next; |
| 2667 | 2663 | int i; |
| 2668 | 2664 | |
| 2669 | − cancel_delayed_work_sync(&q->requeue_work); | |
| 2670 | − | |
| 2671 | 2665 | queue_for_each_hw_ctx(q, hctx, i) |
| 2672 | 2666 | WARN_ON_ONCE(hctx && list_empty(&hctx->hctx_list)); |
| 2673 | 2667 | |
| @@ -892,6 +892,9 @@ static void __blk_release_queue(struct work_struct *work) · 891 unmodified lines | ||
| 892 | 892 | |
| 893 | 893 | blk_free_queue_stats(q->stats); |
| 894 | 894 | |
| 895 | + if (queue_is_mq(q)) | |
| 896 | + cancel_delayed_work_sync(&q->requeue_work); | |
| 897 | + | |
| 895 | 898 | blk_exit_queue(q); |
| 896 | 899 | |
| 897 | 900 | blk_queue_free_zone_bitmaps(q); |
| @@ -1786,6 +1786,21 @@ nothing_to_do: · 1785 unmodified lines | ||
| 1786 | 1786 | return 1; |
| 1787 | 1787 | } |
| 1788 | 1788 | |
| 1789 | +static bool ata_check_nblocks(struct scsi_cmnd *scmd, u32 n_blocks) | |
| 1790 | +{ | |
| 1791 | + struct request *rq = scmd->request; | |
| 1792 | + u32 req_blocks; | |
| 1793 | + | |
| 1794 | + if (!blk_rq_is_passthrough(rq)) | |
| 1795 | + return true; | |
| 1796 | + | |
| 1797 | + req_blocks = blk_rq_bytes(rq) / scmd->device->sector_size; | |
| 1798 | + if (n_blocks > req_blocks) | |
| 1799 | + return false; | |
| 1800 | + | |
| 1801 | + return true; | |
| 1802 | +} | |
| 1803 | + | |
| 1789 | 1804 | /** |
| 1790 | 1805 | * ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one |
| 1791 | 1806 | * @qc: Storage for translated ATA taskfile |
| @@ -1830,6 +1845,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) · 38 unmodified lines | ||
| 1830 | 1845 | scsi_10_lba_len(cdb, &block, &n_block); |
| 1831 | 1846 | if (cdb[1] & (1 << 3)) |
| 1832 | 1847 | tf_flags |= ATA_TFLAG_FUA; |
| 1848 | + if (!ata_check_nblocks(scmd, n_block)) | |
| 1849 | + goto invalid_fld; | |
| 1833 | 1850 | break; |
| 1834 | 1851 | case READ_6: |
| 1835 | 1852 | case WRITE_6: |
| @@ -1844,6 +1861,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) · 8 unmodified lines | ||
| 1844 | 1861 | */ |
| 1845 | 1862 | if (!n_block) |
| 1846 | 1863 | n_block = 256; |
| 1864 | + if (!ata_check_nblocks(scmd, n_block)) | |
| 1865 | + goto invalid_fld; | |
| 1847 | 1866 | break; |
| 1848 | 1867 | case READ_16: |
| 1849 | 1868 | case WRITE_16: |
| @@ -1854,6 +1873,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) · 4 unmodified lines | ||
| 1854 | 1873 | scsi_16_lba_len(cdb, &block, &n_block); |
| 1855 | 1874 | if (cdb[1] & (1 << 3)) |
| 1856 | 1875 | tf_flags |= ATA_TFLAG_FUA; |
| 1876 | + if (!ata_check_nblocks(scmd, n_block)) | |
| 1877 | + goto invalid_fld; | |
| 1857 | 1878 | break; |
| 1858 | 1879 | default: |
| 1859 | 1880 | DPRINTK("no-byte command\n"); |
| @@ -658,6 +658,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) · 657 unmodified lines | ||
| 658 | 658 | unsigned int offset; |
| 659 | 659 | unsigned char *buf; |
| 660 | 660 | |
| 661 | + if (!qc->cursg) { | |
| 662 | + qc->curbytes = qc->nbytes; | |
| 663 | + return; | |
| 664 | + } | |
| 661 | 665 | if (qc->curbytes == qc->nbytes - qc->sect_size) |
| 662 | 666 | ap->hsm_task_state = HSM_ST_LAST; |
| 663 | 667 | |
| @@ -683,6 +687,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) · 19 unmodified lines | ||
| 683 | 687 | |
| 684 | 688 | if (qc->cursg_ofs == qc->cursg->length) { |
| 685 | 689 | qc->cursg = sg_next(qc->cursg); |
| 690 | + if (!qc->cursg) | |
| 691 | + ap->hsm_task_state = HSM_ST_LAST; | |
| 686 | 692 | qc->cursg_ofs = 0; |
| 687 | 693 | } |
| 688 | 694 | } |
| @@ -158,7 +158,6 @@ static int rb532_pata_driver_probe(struct platform_device *pdev) · 157 unmodified lines | ||
| 158 | 158 | static int rb532_pata_driver_remove(struct platform_device *pdev) |
| 159 | 159 | { |
| 160 | 160 | struct ata_host *ah = platform_get_drvdata(pdev); |
| 161 | − struct rb532_cf_info *info = ah->private_data; | |
| 162 | 161 | |
| 163 | 162 | ata_host_detach(ah); |
| 164 | 163 | |
| @@ -448,6 +448,11 @@ config PANEL_BOOT_MESSAGE · 447 unmodified lines | ||
| 448 | 448 | choice |
| 449 | 449 | prompt "Backlight initial state" |
| 450 | 450 | default CHARLCD_BL_FLASH |
| 451 | + ---help--- | |
| 452 | + Select the initial backlight state on boot or module load. | |
| 453 | + | |
| 454 | + Previously, there was no option for this: the backlight flashed | |
| 455 | + briefly on init. Now you can also turn it off/on. | |
| 451 | 456 | |
| 452 | 457 | config CHARLCD_BL_OFF |
| 453 | 458 | bool "Off" |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include <generated/utsrelease.h> |
| 22 | 22 | |
| 23 | −#include <misc/charlcd.h> | |
| 23 | +#include "charlcd.h" | |
| 24 | 24 | |
| 25 | 25 | #define LCD_MINOR 156 |
| 26 | 26 | |
| @@ -6,6 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | * Copyright (C) 2016-2017 Glider bvba |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | +#ifndef _CHARLCD_H | |
| 10 | +#define _CHARLCD_H | |
| 11 | + | |
| 9 | 12 | struct charlcd { |
| 10 | 13 | const struct charlcd_ops *ops; |
| 11 | 14 | const unsigned char *char_conv; /* Optional */ |
| @@ -37,3 +40,5 @@ int charlcd_register(struct charlcd *lcd); · 25 unmodified lines | ||
| 37 | 40 | int charlcd_unregister(struct charlcd *lcd); |
| 38 | 41 | |
| 39 | 42 | void charlcd_poke(struct charlcd *lcd); |
| 43 | + | |
| 44 | +#endif /* CHARLCD_H */ | |
| @@ -14,8 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/property.h> |
| 15 | 15 | #include <linux/slab.h> |
| 16 | 16 | |
| 17 | −#include <misc/charlcd.h> | |
| 18 | − | |
| 17 | +#include "charlcd.h" | |
| 19 | 18 | |
| 20 | 19 | enum hd44780_pin { |
| 21 | 20 | /* Order does matter due to writing to GPIO array subsets! */ |
| @@ -55,7 +55,7 @@ · 54 unmodified lines | ||
| 55 | 55 | #include <linux/io.h> |
| 56 | 56 | #include <linux/uaccess.h> |
| 57 | 57 | |
| 58 | −#include <misc/charlcd.h> | |
| 58 | +#include "charlcd.h" | |
| 59 | 59 | |
| 60 | 60 | #define KEYPAD_MINOR 185 |
| 61 | 61 | |
| @@ -1617,6 +1617,8 @@ static void panel_attach(struct parport *port) · 1555 unmodified lines | ||
| 1617 | 1617 | return; |
| 1618 | 1618 | |
| 1619 | 1619 | err_lcd_unreg: |
| 1620 | + if (scan_timer.function) | |
| 1621 | + del_timer_sync(&scan_timer); | |
| 1620 | 1622 | if (lcd.enabled) |
| 1621 | 1623 | charlcd_unregister(lcd.charlcd); |
| 1622 | 1624 | err_unreg_device: |
| @@ -1823,12 +1823,63 @@ static inline struct kobject *get_glue_dir(struct device *dev) · 1822 unmodified lines | ||
| 1823 | 1823 | */ |
| 1824 | 1824 | static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) |
| 1825 | 1825 | { |
| 1826 | + unsigned int ref; | |
| 1827 | + | |
| 1826 | 1828 | /* see if we live in a "glue" directory */ |
| 1827 | 1829 | if (!live_in_glue_dir(glue_dir, dev)) |
| 1828 | 1830 | return; |
| 1829 | 1831 | |
| 1830 | 1832 | mutex_lock(&gdp_mutex); |
| 1831 | − if (!kobject_has_children(glue_dir)) | |
| 1833 | + /** | |
| 1834 | + * There is a race condition between removing glue directory | |
| 1835 | + * and adding a new device under the glue directory. | |
| 1836 | + * | |
| 1837 | + * CPU1: CPU2: | |
| 1838 | + * | |
| 1839 | + * device_add() | |
| 1840 | + * get_device_parent() | |
| 1841 | + * class_dir_create_and_add() | |
| 1842 | + * kobject_add_internal() | |
| 1843 | + * create_dir() // create glue_dir | |
| 1844 | + * | |
| 1845 | + * device_add() | |
| 1846 | + * get_device_parent() | |
| 1847 | + * kobject_get() // get glue_dir | |
| 1848 | + * | |
| 1849 | + * device_del() | |
| 1850 | + * cleanup_glue_dir() | |
| 1851 | + * kobject_del(glue_dir) | |
| 1852 | + * | |
| 1853 | + * kobject_add() | |
| 1854 | + * kobject_add_internal() | |
| 1855 | + * create_dir() // in glue_dir | |
| 1856 | + * sysfs_create_dir_ns() | |
| 1857 | + * kernfs_create_dir_ns(sd) | |
| 1858 | + * | |
| 1859 | + * sysfs_remove_dir() // glue_dir->sd=NULL | |
| 1860 | + * sysfs_put() // free glue_dir->sd | |
| 1861 | + * | |
| 1862 | + * // sd is freed | |
| 1863 | + * kernfs_new_node(sd) | |
| 1864 | + * kernfs_get(glue_dir) | |
| 1865 | + * kernfs_add_one() | |
| 1866 | + * kernfs_put() | |
| 1867 | + * | |
| 1868 | + * Before CPU1 remove last child device under glue dir, if CPU2 add | |
| 1869 | + * a new device under glue dir, the glue_dir kobject reference count | |
| 1870 | + * will be increase to 2 in kobject_get(k). And CPU2 has been called | |
| 1871 | + * kernfs_create_dir_ns(). Meanwhile, CPU1 call sysfs_remove_dir() | |
| 1872 | + * and sysfs_put(). This result in glue_dir->sd is freed. | |
| 1873 | + * | |
| 1874 | + * Then the CPU2 will see a stale "empty" but still potentially used | |
| 1875 | + * glue dir around in kernfs_new_node(). | |
| 1876 | + * | |
| 1877 | + * In order to avoid this happening, we also should make sure that | |
| 1878 | + * kernfs_node for glue_dir is released in CPU1 only when refcount | |
| 1879 | + * for glue_dir kobj is 1. | |
| 1880 | + */ | |
| 1881 | + ref = kref_read(&glue_dir->kref); | |
| 1882 | + if (!kobject_has_children(glue_dir) && !--ref) | |
| 1832 | 1883 | kobject_del(glue_dir); |
| 1833 | 1884 | kobject_put(glue_dir); |
| 1834 | 1885 | mutex_unlock(&gdp_mutex); |
| @@ -157,8 +157,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) · 156 unmodified lines | ||
| 157 | 157 | * the device will only expose one IRQ, and this fallback |
| 158 | 158 | * allows a common code path across either kind of resource. |
| 159 | 159 | */ |
| 160 | − if (num == 0 && has_acpi_companion(&dev->dev)) | |
| 161 | − return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); | |
| 160 | + if (num == 0 && has_acpi_companion(&dev->dev)) { | |
| 161 | + int ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); | |
| 162 | + | |
| 163 | + /* Our callers expect -ENXIO for missing IRQs. */ | |
| 164 | + if (ret >= 0 || ret == -EPROBE_DEFER) | |
| 165 | + return ret; | |
| 166 | + } | |
| 162 | 167 | |
| 163 | 168 | return -ENXIO; |
| 164 | 169 | #endif |
| @@ -44,7 +44,7 @@ config REGMAP_IRQ · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | config REGMAP_SOUNDWIRE |
| 46 | 46 | tristate |
| 47 | − depends on SOUNDWIRE_BUS | |
| 47 | + depends on SOUNDWIRE | |
| 48 | 48 | |
| 49 | 49 | config REGMAP_SCCB |
| 50 | 50 | tristate |
| @@ -323,10 +323,14 @@ flush(const char __user *str, size_t cnt, int exiting) · 322 unmodified lines | ||
| 323 | 323 | } |
| 324 | 324 | |
| 325 | 325 | flush_scheduled_work(); |
| 326 | − /* pass one: without sleeping, do aoedev_downdev */ | |
| 326 | + /* pass one: do aoedev_downdev, which might sleep */ | |
| 327 | +restart1: | |
| 327 | 328 | spin_lock_irqsave(&devlist_lock, flags); |
| 328 | 329 | for (d = devlist; d; d = d->next) { |
| 329 | 330 | spin_lock(&d->lock); |
| 331 | + if (d->flags & DEVFL_TKILL) | |
| 332 | + goto cont; | |
| 333 | + | |
| 330 | 334 | if (exiting) { |
| 331 | 335 | /* unconditionally take each device down */ |
| 332 | 336 | } else if (specified) { |
| @@ -338,8 +342,11 @@ flush(const char __user *str, size_t cnt, int exiting) · 5 unmodified lines | ||
| 338 | 342 | || d->ref) |
| 339 | 343 | goto cont; |
| 340 | 344 | |
| 345 | + spin_unlock(&d->lock); | |
| 346 | + spin_unlock_irqrestore(&devlist_lock, flags); | |
| 341 | 347 | aoedev_downdev(d); |
| 342 | 348 | d->flags |= DEVFL_TKILL; |
| 349 | + goto restart1; | |
| 343 | 350 | cont: |
| 344 | 351 | spin_unlock(&d->lock); |
| 345 | 352 | } |
| @@ -348,7 +355,7 @@ cont: · 2 unmodified lines | ||
| 348 | 355 | /* pass two: call freedev, which might sleep, |
| 349 | 356 | * for aoedevs marked with DEVFL_TKILL |
| 350 | 357 | */ |
| 351 | −restart: | |
| 358 | +restart2: | |
| 352 | 359 | spin_lock_irqsave(&devlist_lock, flags); |
| 353 | 360 | for (d = devlist; d; d = d->next) { |
| 354 | 361 | spin_lock(&d->lock); |
| @@ -357,7 +364,7 @@ restart: · 2 unmodified lines | ||
| 357 | 364 | spin_unlock(&d->lock); |
| 358 | 365 | spin_unlock_irqrestore(&devlist_lock, flags); |
| 359 | 366 | freedev(d); |
| 360 | − goto restart; | |
| 367 | + goto restart2; | |
| 361 | 368 | } |
| 362 | 369 | spin_unlock(&d->lock); |
| 363 | 370 | } |
| @@ -885,7 +885,7 @@ static void loop_unprepare_queue(struct loop_device *lo) · 884 unmodified lines | ||
| 885 | 885 | |
| 886 | 886 | static int loop_kthread_worker_fn(void *worker_ptr) |
| 887 | 887 | { |
| 888 | − current->flags |= PF_LESS_THROTTLE; | |
| 888 | + current->flags |= PF_LESS_THROTTLE | PF_MEMALLOC_NOIO; | |
| 889 | 889 | return kthread_worker_fn(worker_ptr); |
| 890 | 890 | } |
| 891 | 891 | |
| @@ -965,6 +965,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) · 964 unmodified lines | ||
| 965 | 965 | } |
| 966 | 966 | } |
| 967 | 967 | |
| 968 | + err = -ENOMEM; | |
| 968 | 969 | for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { |
| 969 | 970 | req = kzalloc(sizeof(*req), GFP_KERNEL); |
| 970 | 971 | if (!req) |
| @@ -987,7 +988,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) · 16 unmodified lines | ||
| 987 | 988 | err = xen_blkif_map(ring, ring_ref, nr_grefs, evtchn); |
| 988 | 989 | if (err) { |
| 989 | 990 | xenbus_dev_fatal(dev, err, "mapping ring-ref port %u", evtchn); |
| 990 | − return err; | |
| 991 | + goto fail; | |
| 991 | 992 | } |
| 992 | 993 | |
| 993 | 994 | return 0; |
| @@ -1007,8 +1008,7 @@ fail: · 13 unmodified lines | ||
| 1007 | 1008 | } |
| 1008 | 1009 | kfree(req); |
| 1009 | 1010 | } |
| 1010 | − return -ENOMEM; | |
| 1011 | − | |
| 1011 | + return err; | |
| 1012 | 1012 | } |
| 1013 | 1013 | |
| 1014 | 1014 | static int connect_ring(struct backend_info *be) |
| @@ -99,6 +99,27 @@ static int qca_send_reset(struct hci_dev *hdev) · 98 unmodified lines | ||
| 99 | 99 | return 0; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | +int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) | |
| 103 | +{ | |
| 104 | + struct sk_buff *skb; | |
| 105 | + int err; | |
| 106 | + | |
| 107 | + bt_dev_dbg(hdev, "QCA pre shutdown cmd"); | |
| 108 | + | |
| 109 | + skb = __hci_cmd_sync(hdev, QCA_PRE_SHUTDOWN_CMD, 0, | |
| 110 | + NULL, HCI_INIT_TIMEOUT); | |
| 111 | + if (IS_ERR(skb)) { | |
| 112 | + err = PTR_ERR(skb); | |
| 113 | + bt_dev_err(hdev, "QCA preshutdown_cmd failed (%d)", err); | |
| 114 | + return err; | |
| 115 | + } | |
| 116 | + | |
| 117 | + kfree_skb(skb); | |
| 118 | + | |
| 119 | + return 0; | |
| 120 | +} | |
| 121 | +EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); | |
| 122 | + | |
| 102 | 123 | static void qca_tlv_check_data(struct rome_config *config, |
| 103 | 124 | const struct firmware *fw) |
| 104 | 125 | { |
| @@ -119,6 +140,7 @@ static void qca_tlv_check_data(struct rome_config *config, · 14 unmodified lines | ||
| 119 | 140 | BT_DBG("Length\t\t : %d bytes", length); |
| 120 | 141 | |
| 121 | 142 | config->dnld_mode = ROME_SKIP_EVT_NONE; |
| 143 | + config->dnld_type = ROME_SKIP_EVT_NONE; | |
| 122 | 144 | |
| 123 | 145 | switch (config->type) { |
| 124 | 146 | case TLV_TYPE_PATCH: |
| @@ -268,7 +290,7 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev) · 143 unmodified lines | ||
| 268 | 290 | |
| 269 | 291 | evt = skb_put(skb, sizeof(*evt)); |
| 270 | 292 | evt->ncmd = 1; |
| 271 | − evt->opcode = QCA_HCI_CC_OPCODE; | |
| 293 | + evt->opcode = cpu_to_le16(QCA_HCI_CC_OPCODE); | |
| 272 | 294 | |
| 273 | 295 | skb_put_u8(skb, QCA_HCI_CC_SUCCESS); |
| 274 | 296 | |
| @@ -323,7 +345,7 @@ static int qca_download_firmware(struct hci_dev *hdev, · 48 unmodified lines | ||
| 323 | 345 | */ |
| 324 | 346 | if (config->dnld_type == ROME_SKIP_EVT_VSE_CC || |
| 325 | 347 | config->dnld_type == ROME_SKIP_EVT_VSE) |
| 326 | − return qca_inject_cmd_complete_event(hdev); | |
| 348 | + ret = qca_inject_cmd_complete_event(hdev); | |
| 327 | 349 | |
| 328 | 350 | out: |
| 329 | 351 | release_firmware(fw); |
| @@ -388,6 +410,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, · 58 unmodified lines | ||
| 388 | 410 | return err; |
| 389 | 411 | } |
| 390 | 412 | |
| 413 | + /* Give the controller some time to get ready to receive the NVM */ | |
| 414 | + msleep(10); | |
| 415 | + | |
| 391 | 416 | /* Download NVM configuration */ |
| 392 | 417 | config.type = TLV_TYPE_NVM; |
| 393 | 418 | if (firmware_name) |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #define EDL_PATCH_TLV_REQ_CMD (0x1E) |
| 14 | 14 | #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) |
| 15 | 15 | #define MAX_SIZE_PER_TLV_SEGMENT (243) |
| 16 | +#define QCA_PRE_SHUTDOWN_CMD (0xFC08) | |
| 16 | 17 | |
| 17 | 18 | #define EDL_CMD_REQ_RES_EVT (0x00) |
| 18 | 19 | #define EDL_PATCH_VER_RES_EVT (0x19) |
| @@ -135,6 +136,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, · 116 unmodified lines | ||
| 135 | 136 | const char *firmware_name); |
| 136 | 137 | int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); |
| 137 | 138 | int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); |
| 139 | +int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); | |
| 138 | 140 | static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) |
| 139 | 141 | { |
| 140 | 142 | return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3998; |
| @@ -167,4 +169,9 @@ static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) · 26 unmodified lines | ||
| 167 | 169 | { |
| 168 | 170 | return false; |
| 169 | 171 | } |
| 172 | + | |
| 173 | +static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) | |
| 174 | +{ | |
| 175 | + return -EOPNOTSUPP; | |
| 176 | +} | |
| 170 | 177 | #endif |
| @@ -2762,8 +2762,10 @@ static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) · 2761 unmodified lines | ||
| 2762 | 2762 | fw_size = fw->size; |
| 2763 | 2763 | |
| 2764 | 2764 | /* The size of patch header is 30 bytes, should be skip */ |
| 2765 | − if (fw_size < 30) | |
| 2765 | + if (fw_size < 30) { | |
| 2766 | + err = -EINVAL; | |
| 2766 | 2767 | goto err_release_fw; |
| 2768 | + } | |
| 2767 | 2769 | |
| 2768 | 2770 | fw_size -= 30; |
| 2769 | 2771 | fw_ptr += 30; |
| @@ -705,7 +705,7 @@ static void device_want_to_sleep(struct hci_uart *hu) · 704 unmodified lines | ||
| 705 | 705 | unsigned long flags; |
| 706 | 706 | struct qca_data *qca = hu->priv; |
| 707 | 707 | |
| 708 | − BT_DBG("hu %p want to sleep", hu); | |
| 708 | + BT_DBG("hu %p want to sleep in %d state", hu, qca->rx_ibs_state); | |
| 709 | 709 | |
| 710 | 710 | spin_lock_irqsave(&qca->hci_ibs_lock, flags); |
| 711 | 711 | |
| @@ -720,7 +720,7 @@ static void device_want_to_sleep(struct hci_uart *hu) · 8 unmodified lines | ||
| 720 | 720 | break; |
| 721 | 721 | |
| 722 | 722 | case HCI_IBS_RX_ASLEEP: |
| 723 | − /* Fall through */ | |
| 723 | + break; | |
| 724 | 724 | |
| 725 | 725 | default: |
| 726 | 726 | /* Any other state is illegal */ |
| @@ -912,7 +912,7 @@ static int qca_recv_event(struct hci_dev *hdev, struct sk_buff *skb) · 185 unmodified lines | ||
| 912 | 912 | if (hdr->evt == HCI_EV_VENDOR) |
| 913 | 913 | complete(&qca->drop_ev_comp); |
| 914 | 914 | |
| 915 | − kfree(skb); | |
| 915 | + kfree_skb(skb); | |
| 916 | 916 | |
| 917 | 917 | return 0; |
| 918 | 918 | } |
| @@ -1386,6 +1386,9 @@ static int qca_power_off(struct hci_dev *hdev) · 467 unmodified lines | ||
| 1386 | 1386 | { |
| 1387 | 1387 | struct hci_uart *hu = hci_get_drvdata(hdev); |
| 1388 | 1388 | |
| 1389 | + /* Perform pre shutdown command */ | |
| 1390 | + qca_send_pre_shutdown_cmd(hdev); | |
| 1391 | + | |
| 1389 | 1392 | qca_power_shutdown(hu); |
| 1390 | 1393 | return 0; |
| 1391 | 1394 | } |
| @@ -55,7 +55,7 @@ static u64 riscv_sched_clock(void) · 54 unmodified lines | ||
| 55 | 55 | return get_cycles64(); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | −static DEFINE_PER_CPU(struct clocksource, riscv_clocksource) = { | |
| 58 | +static struct clocksource riscv_clocksource = { | |
| 59 | 59 | .name = "riscv_clocksource", |
| 60 | 60 | .rating = 300, |
| 61 | 61 | .mask = CLOCKSOURCE_MASK(64), |
| @@ -92,7 +92,6 @@ void riscv_timer_interrupt(void) · 30 unmodified lines | ||
| 92 | 92 | static int __init riscv_timer_init_dt(struct device_node *n) |
| 93 | 93 | { |
| 94 | 94 | int cpuid, hartid, error; |
| 95 | − struct clocksource *cs; | |
| 96 | 95 | |
| 97 | 96 | hartid = riscv_of_processor_hartid(n); |
| 98 | 97 | if (hartid < 0) { |
| @@ -112,8 +111,7 @@ static int __init riscv_timer_init_dt(struct device_node *n) · 13 unmodified lines | ||
| 112 | 111 | |
| 113 | 112 | pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n", |
| 114 | 113 | __func__, cpuid, hartid); |
| 115 | − cs = per_cpu_ptr(&riscv_clocksource, cpuid); | |
| 116 | − error = clocksource_register_hz(cs, riscv_timebase); | |
| 114 | + error = clocksource_register_hz(&riscv_clocksource, riscv_timebase); | |
| 117 | 115 | if (error) { |
| 118 | 116 | pr_err("RISCV timer register failed [%d] for cpu = [%d]\n", |
| 119 | 117 | error, cpuid); |
| @@ -2528,7 +2528,7 @@ static int cpufreq_boost_set_sw(int state) · 2527 unmodified lines | ||
| 2528 | 2528 | } |
| 2529 | 2529 | |
| 2530 | 2530 | ret = dev_pm_qos_update_request(policy->max_freq_req, policy->max); |
| 2531 | − if (ret) | |
| 2531 | + if (ret < 0) | |
| 2532 | 2532 | break; |
| 2533 | 2533 | } |
| 2534 | 2534 | |
| @@ -58,6 +58,19 @@ static int ccp_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key, · 57 unmodified lines | ||
| 58 | 58 | static int ccp_aes_gcm_setauthsize(struct crypto_aead *tfm, |
| 59 | 59 | unsigned int authsize) |
| 60 | 60 | { |
| 61 | + switch (authsize) { | |
| 62 | + case 16: | |
| 63 | + case 15: | |
| 64 | + case 14: | |
| 65 | + case 13: | |
| 66 | + case 12: | |
| 67 | + case 8: | |
| 68 | + case 4: | |
| 69 | + break; | |
| 70 | + default: | |
| 71 | + return -EINVAL; | |
| 72 | + } | |
| 73 | + | |
| 61 | 74 | return 0; |
| 62 | 75 | } |
| 63 | 76 | |
| @@ -104,6 +117,7 @@ static int ccp_aes_gcm_crypt(struct aead_request *req, bool encrypt) · 40 unmodified lines | ||
| 104 | 117 | memset(&rctx->cmd, 0, sizeof(rctx->cmd)); |
| 105 | 118 | INIT_LIST_HEAD(&rctx->cmd.entry); |
| 106 | 119 | rctx->cmd.engine = CCP_ENGINE_AES; |
| 120 | + rctx->cmd.u.aes.authsize = crypto_aead_authsize(tfm); | |
| 107 | 121 | rctx->cmd.u.aes.type = ctx->u.aes.type; |
| 108 | 122 | rctx->cmd.u.aes.mode = ctx->u.aes.mode; |
| 109 | 123 | rctx->cmd.u.aes.action = encrypt; |
| @@ -622,6 +622,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, · 621 unmodified lines | ||
| 622 | 622 | |
| 623 | 623 | unsigned long long *final; |
| 624 | 624 | unsigned int dm_offset; |
| 625 | + unsigned int authsize; | |
| 625 | 626 | unsigned int jobid; |
| 626 | 627 | unsigned int ilen; |
| 627 | 628 | bool in_place = true; /* Default value */ |
| @@ -643,6 +644,21 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, · 15 unmodified lines | ||
| 643 | 644 | if (!aes->key) /* Gotta have a key SGL */ |
| 644 | 645 | return -EINVAL; |
| 645 | 646 | |
| 647 | + /* Zero defaults to 16 bytes, the maximum size */ | |
| 648 | + authsize = aes->authsize ? aes->authsize : AES_BLOCK_SIZE; | |
| 649 | + switch (authsize) { | |
| 650 | + case 16: | |
| 651 | + case 15: | |
| 652 | + case 14: | |
| 653 | + case 13: | |
| 654 | + case 12: | |
| 655 | + case 8: | |
| 656 | + case 4: | |
| 657 | + break; | |
| 658 | + default: | |
| 659 | + return -EINVAL; | |
| 660 | + } | |
| 661 | + | |
| 646 | 662 | /* First, decompose the source buffer into AAD & PT, |
| 647 | 663 | * and the destination buffer into AAD, CT & tag, or |
| 648 | 664 | * the input into CT & tag. |
| @@ -657,7 +673,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, · 8 unmodified lines | ||
| 657 | 673 | p_tag = scatterwalk_ffwd(sg_tag, p_outp, ilen); |
| 658 | 674 | } else { |
| 659 | 675 | /* Input length for decryption includes tag */ |
| 660 | − ilen = aes->src_len - AES_BLOCK_SIZE; | |
| 676 | + ilen = aes->src_len - authsize; | |
| 661 | 677 | p_tag = scatterwalk_ffwd(sg_tag, p_inp, ilen); |
| 662 | 678 | } |
| 663 | 679 | |
| @@ -766,8 +782,7 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, · 102 unmodified lines | ||
| 766 | 782 | while (src.sg_wa.bytes_left) { |
| 767 | 783 | ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true); |
| 768 | 784 | if (!src.sg_wa.bytes_left) { |
| 769 | − unsigned int nbytes = aes->src_len | |
| 770 | − % AES_BLOCK_SIZE; | |
| 785 | + unsigned int nbytes = ilen % AES_BLOCK_SIZE; | |
| 771 | 786 | |
| 772 | 787 | if (nbytes) { |
| 773 | 788 | op.eom = 1; |
| @@ -839,19 +854,19 @@ static int ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, · 65 unmodified lines | ||
| 839 | 854 | |
| 840 | 855 | if (aes->action == CCP_AES_ACTION_ENCRYPT) { |
| 841 | 856 | /* Put the ciphered tag after the ciphertext. */ |
| 842 | − ccp_get_dm_area(&final_wa, 0, p_tag, 0, AES_BLOCK_SIZE); | |
| 857 | + ccp_get_dm_area(&final_wa, 0, p_tag, 0, authsize); | |
| 843 | 858 | } else { |
| 844 | 859 | /* Does this ciphered tag match the input? */ |
| 845 | − ret = ccp_init_dm_workarea(&tag, cmd_q, AES_BLOCK_SIZE, | |
| 860 | + ret = ccp_init_dm_workarea(&tag, cmd_q, authsize, | |
| 846 | 861 | DMA_BIDIRECTIONAL); |
| 847 | 862 | if (ret) |
| 848 | 863 | goto e_tag; |
| 849 | − ret = ccp_set_dm_area(&tag, 0, p_tag, 0, AES_BLOCK_SIZE); | |
| 864 | + ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize); | |
| 850 | 865 | if (ret) |
| 851 | 866 | goto e_tag; |
| 852 | 867 | |
| 853 | 868 | ret = crypto_memneq(tag.address, final_wa.address, |
| 854 | − AES_BLOCK_SIZE) ? -EBADMSG : 0; | |
| 869 | + authsize) ? -EBADMSG : 0; | |
| 855 | 870 | ccp_dm_free(&tag); |
| 856 | 871 | } |
| 857 | 872 | |
| @@ -859,11 +874,11 @@ e_tag: · 1 unmodified line | ||
| 859 | 874 | ccp_dm_free(&final_wa); |
| 860 | 875 | |
| 861 | 876 | e_dst: |
| 862 | − if (aes->src_len && !in_place) | |
| 877 | + if (ilen > 0 && !in_place) | |
| 863 | 878 | ccp_free_data(&dst, cmd_q); |
| 864 | 879 | |
| 865 | 880 | e_src: |
| 866 | − if (aes->src_len) | |
| 881 | + if (ilen > 0) | |
| 867 | 882 | ccp_free_data(&src, cmd_q); |
| 868 | 883 | |
| 869 | 884 | e_aad: |
| @@ -314,14 +314,17 @@ void cryp_save_device_context(struct cryp_device_data *device_data, · 313 unmodified lines | ||
| 314 | 314 | case CRYP_KEY_SIZE_256: |
| 315 | 315 | ctx->key_4_l = readl_relaxed(&src_reg->key_4_l); |
| 316 | 316 | ctx->key_4_r = readl_relaxed(&src_reg->key_4_r); |
| 317 | + /* Fall through */ | |
| 317 | 318 | |
| 318 | 319 | case CRYP_KEY_SIZE_192: |
| 319 | 320 | ctx->key_3_l = readl_relaxed(&src_reg->key_3_l); |
| 320 | 321 | ctx->key_3_r = readl_relaxed(&src_reg->key_3_r); |
| 322 | + /* Fall through */ | |
| 321 | 323 | |
| 322 | 324 | case CRYP_KEY_SIZE_128: |
| 323 | 325 | ctx->key_2_l = readl_relaxed(&src_reg->key_2_l); |
| 324 | 326 | ctx->key_2_r = readl_relaxed(&src_reg->key_2_r); |
| 327 | + /* Fall through */ | |
| 325 | 328 | |
| 326 | 329 | default: |
| 327 | 330 | ctx->key_1_l = readl_relaxed(&src_reg->key_1_l); |
| @@ -361,14 +364,17 @@ void cryp_restore_device_context(struct cryp_device_data *device_data, · 33 unmodified lines | ||
| 361 | 364 | case CRYP_KEY_SIZE_256: |
| 362 | 365 | writel_relaxed(ctx->key_4_l, ®->key_4_l); |
| 363 | 366 | writel_relaxed(ctx->key_4_r, ®->key_4_r); |
| 367 | + /* Fall through */ | |
| 364 | 368 | |
| 365 | 369 | case CRYP_KEY_SIZE_192: |
| 366 | 370 | writel_relaxed(ctx->key_3_l, ®->key_3_l); |
| 367 | 371 | writel_relaxed(ctx->key_3_r, ®->key_3_r); |
| 372 | + /* Fall through */ | |
| 368 | 373 | |
| 369 | 374 | case CRYP_KEY_SIZE_128: |
| 370 | 375 | writel_relaxed(ctx->key_2_l, ®->key_2_l); |
| 371 | 376 | writel_relaxed(ctx->key_2_r, ®->key_2_r); |
| 377 | + /* Fall through */ | |
| 372 | 378 | |
| 373 | 379 | default: |
| 374 | 380 | writel_relaxed(ctx->key_1_l, ®->key_1_l); |
| @@ -50,7 +50,7 @@ struct dw_edma_burst { · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | struct dw_edma_region { |
| 52 | 52 | phys_addr_t paddr; |
| 53 | − dma_addr_t vaddr; | |
| 53 | + void __iomem *vaddr; | |
| 54 | 54 | size_t sz; |
| 55 | 55 | }; |
| 56 | 56 | |
| @@ -130,19 +130,19 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, · 129 unmodified lines | ||
| 130 | 130 | chip->id = pdev->devfn; |
| 131 | 131 | chip->irq = pdev->irq; |
| 132 | 132 | |
| 133 | − dw->rg_region.vaddr = (dma_addr_t)pcim_iomap_table(pdev)[pdata->rg_bar]; | |
| 133 | + dw->rg_region.vaddr = pcim_iomap_table(pdev)[pdata->rg_bar]; | |
| 134 | 134 | dw->rg_region.vaddr += pdata->rg_off; |
| 135 | 135 | dw->rg_region.paddr = pdev->resource[pdata->rg_bar].start; |
| 136 | 136 | dw->rg_region.paddr += pdata->rg_off; |
| 137 | 137 | dw->rg_region.sz = pdata->rg_sz; |
| 138 | 138 | |
| 139 | − dw->ll_region.vaddr = (dma_addr_t)pcim_iomap_table(pdev)[pdata->ll_bar]; | |
| 139 | + dw->ll_region.vaddr = pcim_iomap_table(pdev)[pdata->ll_bar]; | |
| 140 | 140 | dw->ll_region.vaddr += pdata->ll_off; |
| 141 | 141 | dw->ll_region.paddr = pdev->resource[pdata->ll_bar].start; |
| 142 | 142 | dw->ll_region.paddr += pdata->ll_off; |
| 143 | 143 | dw->ll_region.sz = pdata->ll_sz; |
| 144 | 144 | |
| 145 | − dw->dt_region.vaddr = (dma_addr_t)pcim_iomap_table(pdev)[pdata->dt_bar]; | |
| 145 | + dw->dt_region.vaddr = pcim_iomap_table(pdev)[pdata->dt_bar]; | |
| 146 | 146 | dw->dt_region.vaddr += pdata->dt_off; |
| 147 | 147 | dw->dt_region.paddr = pdev->resource[pdata->dt_bar].start; |
| 148 | 148 | dw->dt_region.paddr += pdata->dt_off; |
| @@ -158,17 +158,17 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, · 9 unmodified lines | ||
| 158 | 158 | pci_dbg(pdev, "Mode:\t%s\n", |
| 159 | 159 | dw->mode == EDMA_MODE_LEGACY ? "Legacy" : "Unroll"); |
| 160 | 160 | |
| 161 | − pci_dbg(pdev, "Registers:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%pa, p=%pa)\n", | |
| 161 | + pci_dbg(pdev, "Registers:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%p, p=%pa)\n", | |
| 162 | 162 | pdata->rg_bar, pdata->rg_off, pdata->rg_sz, |
| 163 | − &dw->rg_region.vaddr, &dw->rg_region.paddr); | |
| 163 | + dw->rg_region.vaddr, &dw->rg_region.paddr); | |
| 164 | 164 | |
| 165 | − pci_dbg(pdev, "L. List:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%pa, p=%pa)\n", | |
| 165 | + pci_dbg(pdev, "L. List:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%p, p=%pa)\n", | |
| 166 | 166 | pdata->ll_bar, pdata->ll_off, pdata->ll_sz, |
| 167 | − &dw->ll_region.vaddr, &dw->ll_region.paddr); | |
| 167 | + dw->ll_region.vaddr, &dw->ll_region.paddr); | |
| 168 | 168 | |
| 169 | − pci_dbg(pdev, "Data:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%pa, p=%pa)\n", | |
| 169 | + pci_dbg(pdev, "Data:\tBAR=%u, off=0x%.8lx, sz=0x%zx bytes, addr(v=%p, p=%pa)\n", | |
| 170 | 170 | pdata->dt_bar, pdata->dt_off, pdata->dt_sz, |
| 171 | − &dw->dt_region.vaddr, &dw->dt_region.paddr); | |
| 171 | + dw->dt_region.vaddr, &dw->dt_region.paddr); | |
| 172 | 172 | |
| 173 | 173 | pci_dbg(pdev, "Nr. IRQs:\t%u\n", dw->nr_irqs); |
| 174 | 174 | |
| @@ -25,7 +25,7 @@ enum dw_edma_control { · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | static inline struct dw_edma_v0_regs __iomem *__dw_regs(struct dw_edma *dw) |
| 27 | 27 | { |
| 28 | − return (struct dw_edma_v0_regs __iomem *)dw->rg_region.vaddr; | |
| 28 | + return dw->rg_region.vaddr; | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | #define SET(dw, name, value) \ |
| @@ -192,13 +192,12 @@ u32 dw_edma_v0_core_status_abort_int(struct dw_edma *dw, enum dw_edma_dir dir) · 160 unmodified lines | ||
| 192 | 192 | static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk) |
| 193 | 193 | { |
| 194 | 194 | struct dw_edma_burst *child; |
| 195 | − struct dw_edma_v0_lli *lli; | |
| 196 | − struct dw_edma_v0_llp *llp; | |
| 195 | + struct dw_edma_v0_lli __iomem *lli; | |
| 196 | + struct dw_edma_v0_llp __iomem *llp; | |
| 197 | 197 | u32 control = 0, i = 0; |
| 198 | − u64 sar, dar, addr; | |
| 199 | 198 | int j; |
| 200 | 199 | |
| 201 | − lli = (struct dw_edma_v0_lli *)chunk->ll_region.vaddr; | |
| 200 | + lli = chunk->ll_region.vaddr; | |
| 202 | 201 | |
| 203 | 202 | if (chunk->cb) |
| 204 | 203 | control = DW_EDMA_V0_CB; |
| @@ -214,17 +213,15 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk) · 9 unmodified lines | ||
| 214 | 213 | /* Transfer size */ |
| 215 | 214 | SET_LL(&lli[i].transfer_size, child->sz); |
| 216 | 215 | /* SAR - low, high */ |
| 217 | − sar = cpu_to_le64(child->sar); | |
| 218 | − SET_LL(&lli[i].sar_low, lower_32_bits(sar)); | |
| 219 | − SET_LL(&lli[i].sar_high, upper_32_bits(sar)); | |
| 216 | + SET_LL(&lli[i].sar_low, lower_32_bits(child->sar)); | |
| 217 | + SET_LL(&lli[i].sar_high, upper_32_bits(child->sar)); | |
| 220 | 218 | /* DAR - low, high */ |
| 221 | − dar = cpu_to_le64(child->dar); | |
| 222 | − SET_LL(&lli[i].dar_low, lower_32_bits(dar)); | |
| 223 | − SET_LL(&lli[i].dar_high, upper_32_bits(dar)); | |
| 219 | + SET_LL(&lli[i].dar_low, lower_32_bits(child->dar)); | |
| 220 | + SET_LL(&lli[i].dar_high, upper_32_bits(child->dar)); | |
| 224 | 221 | i++; |
| 225 | 222 | } |
| 226 | 223 | |
| 227 | − llp = (struct dw_edma_v0_llp *)&lli[i]; | |
| 224 | + llp = (void __iomem *)&lli[i]; | |
| 228 | 225 | control = DW_EDMA_V0_LLP | DW_EDMA_V0_TCB; |
| 229 | 226 | if (!chunk->cb) |
| 230 | 227 | control |= DW_EDMA_V0_CB; |
| @@ -232,9 +229,8 @@ static void dw_edma_v0_core_write_chunk(struct dw_edma_chunk *chunk) · 1 unmodified line | ||
| 232 | 229 | /* Channel control */ |
| 233 | 230 | SET_LL(&llp->control, control); |
| 234 | 231 | /* Linked list - low, high */ |
| 235 | − addr = cpu_to_le64(chunk->ll_region.paddr); | |
| 236 | − SET_LL(&llp->llp_low, lower_32_bits(addr)); | |
| 237 | − SET_LL(&llp->llp_high, upper_32_bits(addr)); | |
| 232 | + SET_LL(&llp->llp_low, lower_32_bits(chunk->ll_region.paddr)); | |
| 233 | + SET_LL(&llp->llp_high, upper_32_bits(chunk->ll_region.paddr)); | |
| 238 | 234 | } |
| 239 | 235 | |
| 240 | 236 | void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) |
| @@ -242,7 +238,6 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) · 1 unmodified line | ||
| 242 | 238 | struct dw_edma_chan *chan = chunk->chan; |
| 243 | 239 | struct dw_edma *dw = chan->chip->dw; |
| 244 | 240 | u32 tmp; |
| 245 | − u64 llp; | |
| 246 | 241 | |
| 247 | 242 | dw_edma_v0_core_write_chunk(chunk); |
| 248 | 243 | |
| @@ -262,9 +257,10 @@ void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first) · 13 unmodified lines | ||
| 262 | 257 | SET_CH(dw, chan->dir, chan->id, ch_control1, |
| 263 | 258 | (DW_EDMA_V0_CCS | DW_EDMA_V0_LLE)); |
| 264 | 259 | /* Linked list - low, high */ |
| 265 | − llp = cpu_to_le64(chunk->ll_region.paddr); | |
| 266 | − SET_CH(dw, chan->dir, chan->id, llp_low, lower_32_bits(llp)); | |
| 267 | − SET_CH(dw, chan->dir, chan->id, llp_high, upper_32_bits(llp)); | |
| 260 | + SET_CH(dw, chan->dir, chan->id, llp_low, | |
| 261 | + lower_32_bits(chunk->ll_region.paddr)); | |
| 262 | + SET_CH(dw, chan->dir, chan->id, llp_high, | |
| 263 | + upper_32_bits(chunk->ll_region.paddr)); | |
| 268 | 264 | } |
| 269 | 265 | /* Doorbell */ |
| 270 | 266 | SET_RW(dw, chan->dir, doorbell, |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include "dw-edma-core.h" |
| 15 | 15 | |
| 16 | 16 | #define REGS_ADDR(name) \ |
| 17 | − ((dma_addr_t *)®s->name) | |
| 17 | + ((void __force *)®s->name) | |
| 18 | 18 | #define REGISTER(name) \ |
| 19 | 19 | { #name, REGS_ADDR(name) } |
| 20 | 20 | |
| @@ -40,36 +40,37 @@ · 19 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | static struct dentry *base_dir; |
| 42 | 42 | static struct dw_edma *dw; |
| 43 | −static struct dw_edma_v0_regs *regs; | |
| 43 | +static struct dw_edma_v0_regs __iomem *regs; | |
| 44 | 44 | |
| 45 | 45 | static struct { |
| 46 | − void *start; | |
| 47 | − void *end; | |
| 46 | + void __iomem *start; | |
| 47 | + void __iomem *end; | |
| 48 | 48 | } lim[2][EDMA_V0_MAX_NR_CH]; |
| 49 | 49 | |
| 50 | 50 | struct debugfs_entries { |
| 51 | − char name[24]; | |
| 51 | + const char *name; | |
| 52 | 52 | dma_addr_t *reg; |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | 55 | static int dw_edma_debugfs_u32_get(void *data, u64 *val) |
| 56 | 56 | { |
| 57 | + void __iomem *reg = (void __force __iomem *)data; | |
| 57 | 58 | if (dw->mode == EDMA_MODE_LEGACY && |
| 58 | − data >= (void *)®s->type.legacy.ch) { | |
| 59 | − void *ptr = (void *)®s->type.legacy.ch; | |
| 59 | + reg >= (void __iomem *)®s->type.legacy.ch) { | |
| 60 | + void __iomem *ptr = ®s->type.legacy.ch; | |
| 60 | 61 | u32 viewport_sel = 0; |
| 61 | 62 | unsigned long flags; |
| 62 | 63 | u16 ch; |
| 63 | 64 | |
| 64 | 65 | for (ch = 0; ch < dw->wr_ch_cnt; ch++) |
| 65 | − if (lim[0][ch].start >= data && data < lim[0][ch].end) { | |
| 66 | − ptr += (data - lim[0][ch].start); | |
| 66 | + if (lim[0][ch].start >= reg && reg < lim[0][ch].end) { | |
| 67 | + ptr += (reg - lim[0][ch].start); | |
| 67 | 68 | goto legacy_sel_wr; |
| 68 | 69 | } |
| 69 | 70 | |
| 70 | 71 | for (ch = 0; ch < dw->rd_ch_cnt; ch++) |
| 71 | − if (lim[1][ch].start >= data && data < lim[1][ch].end) { | |
| 72 | − ptr += (data - lim[1][ch].start); | |
| 72 | + if (lim[1][ch].start >= reg && reg < lim[1][ch].end) { | |
| 73 | + ptr += (reg - lim[1][ch].start); | |
| 73 | 74 | goto legacy_sel_rd; |
| 74 | 75 | } |
| 75 | 76 | |
| @@ -86,7 +87,7 @@ legacy_sel_wr: · 10 unmodified lines | ||
| 86 | 87 | |
| 87 | 88 | raw_spin_unlock_irqrestore(&dw->lock, flags); |
| 88 | 89 | } else { |
| 89 | − *val = readl(data); | |
| 90 | + *val = readl(reg); | |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | 93 | return 0; |
| @@ -105,7 +106,7 @@ static void dw_edma_debugfs_create_x32(const struct debugfs_entries entries[], · 12 unmodified lines | ||
| 105 | 106 | } |
| 106 | 107 | } |
| 107 | 108 | |
| 108 | −static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs *regs, | |
| 109 | +static void dw_edma_debugfs_regs_ch(struct dw_edma_v0_ch_regs __iomem *regs, | |
| 109 | 110 | struct dentry *dir) |
| 110 | 111 | { |
| 111 | 112 | int nr_entries; |
| @@ -288,7 +289,7 @@ void dw_edma_v0_debugfs_on(struct dw_edma_chip *chip) · 176 unmodified lines | ||
| 288 | 289 | if (!dw) |
| 289 | 290 | return; |
| 290 | 291 | |
| 291 | − regs = (struct dw_edma_v0_regs *)dw->rg_region.vaddr; | |
| 292 | + regs = dw->rg_region.vaddr; | |
| 292 | 293 | if (!regs) |
| 293 | 294 | return; |
| 294 | 295 | |
| @@ -142,7 +142,7 @@ enum d40_events { · 141 unmodified lines | ||
| 142 | 142 | * when the DMA hw is powered off. |
| 143 | 143 | * TODO: Add save/restore of D40_DREG_GCC on dma40 v3 or later, if that works. |
| 144 | 144 | */ |
| 145 | −static u32 d40_backup_regs[] = { | |
| 145 | +static __maybe_unused u32 d40_backup_regs[] = { | |
| 146 | 146 | D40_DREG_LCPA, |
| 147 | 147 | D40_DREG_LCLA, |
| 148 | 148 | D40_DREG_PRMSE, |
| @@ -211,7 +211,7 @@ static u32 d40_backup_regs_v4b[] = { · 62 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | #define BACKUP_REGS_SZ_V4B ARRAY_SIZE(d40_backup_regs_v4b) |
| 213 | 213 | |
| 214 | −static u32 d40_backup_regs_chan[] = { | |
| 214 | +static __maybe_unused u32 d40_backup_regs_chan[] = { | |
| 215 | 215 | D40_CHAN_REG_SSCFG, |
| 216 | 216 | D40_CHAN_REG_SSELT, |
| 217 | 217 | D40_CHAN_REG_SSPTR, |
| @@ -1366,7 +1366,7 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) · 1365 unmodified lines | ||
| 1366 | 1366 | |
| 1367 | 1367 | chan = &dmadev->chan[id]; |
| 1368 | 1368 | if (!chan) { |
| 1369 | − dev_err(chan2dev(chan), "MDMA channel not initialized\n"); | |
| 1369 | + dev_dbg(mdma2dev(dmadev), "MDMA channel not initialized\n"); | |
| 1370 | 1370 | goto exit; |
| 1371 | 1371 | } |
| 1372 | 1372 | |
| @@ -712,7 +712,7 @@ static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec, · 711 unmodified lines | ||
| 712 | 712 | return chan; |
| 713 | 713 | } |
| 714 | 714 | |
| 715 | −static int tegra_adma_runtime_suspend(struct device *dev) | |
| 715 | +static int __maybe_unused tegra_adma_runtime_suspend(struct device *dev) | |
| 716 | 716 | { |
| 717 | 717 | struct tegra_adma *tdma = dev_get_drvdata(dev); |
| 718 | 718 | struct tegra_adma_chan_regs *ch_reg; |
| @@ -744,7 +744,7 @@ clk_disable: · 25 unmodified lines | ||
| 744 | 744 | return 0; |
| 745 | 745 | } |
| 746 | 746 | |
| 747 | −static int tegra_adma_runtime_resume(struct device *dev) | |
| 747 | +static int __maybe_unused tegra_adma_runtime_resume(struct device *dev) | |
| 748 | 748 | { |
| 749 | 749 | struct tegra_adma *tdma = dev_get_drvdata(dev); |
| 750 | 750 | struct tegra_adma_chan_regs *ch_reg; |
| @@ -1234,7 +1234,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( · 1233 unmodified lines | ||
| 1234 | 1234 | if (src_icg) { |
| 1235 | 1235 | d->ccr |= CCR_SRC_AMODE_DBLIDX; |
| 1236 | 1236 | d->ei = 1; |
| 1237 | − d->fi = src_icg; | |
| 1237 | + d->fi = src_icg + 1; | |
| 1238 | 1238 | } else if (xt->src_inc) { |
| 1239 | 1239 | d->ccr |= CCR_SRC_AMODE_POSTINC; |
| 1240 | 1240 | d->fi = 0; |
| @@ -1249,7 +1249,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( · 8 unmodified lines | ||
| 1249 | 1249 | if (dst_icg) { |
| 1250 | 1250 | d->ccr |= CCR_DST_AMODE_DBLIDX; |
| 1251 | 1251 | sg->ei = 1; |
| 1252 | − sg->fi = dst_icg; | |
| 1252 | + sg->fi = dst_icg + 1; | |
| 1253 | 1253 | } else if (xt->dst_inc) { |
| 1254 | 1254 | d->ccr |= CCR_DST_AMODE_POSTINC; |
| 1255 | 1255 | sg->fi = 0; |
| @@ -927,17 +927,33 @@ fail: · 926 unmodified lines | ||
| 927 | 927 | return status; |
| 928 | 928 | } |
| 929 | 929 | |
| 930 | +#define GET_EFI_CONFIG_TABLE(bits) \ | |
| 931 | +static void *get_efi_config_table##bits(efi_system_table_t *_sys_table, \ | |
| 932 | + efi_guid_t guid) \ | |
| 933 | +{ \ | |
| 934 | + efi_system_table_##bits##_t *sys_table; \ | |
| 935 | + efi_config_table_##bits##_t *tables; \ | |
| 936 | + int i; \ | |
| 937 | + \ | |
| 938 | + sys_table = (typeof(sys_table))_sys_table; \ | |
| 939 | + tables = (typeof(tables))(unsigned long)sys_table->tables; \ | |
| 940 | + \ | |
| 941 | + for (i = 0; i < sys_table->nr_tables; i++) { \ | |
| 942 | + if (efi_guidcmp(tables[i].guid, guid) != 0) \ | |
| 943 | + continue; \ | |
| 944 | + \ | |
| 945 | + return (void *)(unsigned long)tables[i].table; \ | |
| 946 | + } \ | |
| 947 | + \ | |
| 948 | + return NULL; \ | |
| 949 | +} | |
| 950 | +GET_EFI_CONFIG_TABLE(32) | |
| 951 | +GET_EFI_CONFIG_TABLE(64) | |
| 952 | + | |
| 930 | 953 | void *get_efi_config_table(efi_system_table_t *sys_table, efi_guid_t guid) |
| 931 | 954 | { |
| 932 | − efi_config_table_t *tables = (efi_config_table_t *)sys_table->tables; | |
| 933 | − int i; | |
| 934 | − | |
| 935 | − for (i = 0; i < sys_table->nr_tables; i++) { | |
| 936 | − if (efi_guidcmp(tables[i].guid, guid) != 0) | |
| 937 | − continue; | |
| 938 | − | |
| 939 | − return (void *)tables[i].table; | |
| 940 | − } | |
| 941 | − | |
| 942 | − return NULL; | |
| 955 | + if (efi_is_64bit()) | |
| 956 | + return get_efi_config_table64(sys_table, guid); | |
| 957 | + else | |
| 958 | + return get_efi_config_table32(sys_table, guid); | |
| 943 | 959 | } |
| @@ -32,7 +32,6 @@ struct amdgpu_gds { · 31 unmodified lines | ||
| 32 | 32 | uint32_t gws_size; |
| 33 | 33 | uint32_t oa_size; |
| 34 | 34 | uint32_t gds_compute_max_wave_id; |
| 35 | − uint32_t vgt_gs_max_wave_id; | |
| 36 | 35 | }; |
| 37 | 36 | |
| 38 | 37 | struct amdgpu_gds_reg_offset { |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define AMDGPU_VCN_FIRMWARE_OFFSET 256 |
| 31 | 31 | #define AMDGPU_VCN_MAX_ENC_RINGS 3 |
| 32 | 32 | |
| 33 | +#define VCN_DEC_KMD_CMD 0x80000000 | |
| 33 | 34 | #define VCN_DEC_CMD_FENCE 0x00000000 |
| 34 | 35 | #define VCN_DEC_CMD_TRAP 0x00000001 |
| 35 | 36 | #define VCN_DEC_CMD_WRITE_REG 0x00000004 |
| @@ -4206,15 +4206,6 @@ static void gfx_v10_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, · 4205 unmodified lines | ||
| 4206 | 4206 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); |
| 4207 | 4207 | u32 header, control = 0; |
| 4208 | 4208 | |
| 4209 | − /* Prevent a hw deadlock due to a wave ID mismatch between ME and GDS. | |
| 4210 | − * This resets the wave ID counters. (needed by transform feedback) | |
| 4211 | − * TODO: This might only be needed on a VMID switch when we change | |
| 4212 | − * the GDS OA mapping, not sure. | |
| 4213 | − */ | |
| 4214 | − amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | |
| 4215 | − amdgpu_ring_write(ring, mmVGT_GS_MAX_WAVE_ID); | |
| 4216 | − amdgpu_ring_write(ring, ring->adev->gds.vgt_gs_max_wave_id); | |
| 4217 | − | |
| 4218 | 4209 | if (ib->flags & AMDGPU_IB_FLAG_CE) |
| 4219 | 4210 | header = PACKET3(PACKET3_INDIRECT_BUFFER_CNST, 2); |
| 4220 | 4211 | else |
| @@ -4961,7 +4952,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = { · 740 unmodified lines | ||
| 4961 | 4952 | 5 + /* HDP_INVL */ |
| 4962 | 4953 | 8 + 8 + /* FENCE x2 */ |
| 4963 | 4954 | 2, /* SWITCH_BUFFER */ |
| 4964 | − .emit_ib_size = 7, /* gfx_v10_0_ring_emit_ib_gfx */ | |
| 4955 | + .emit_ib_size = 4, /* gfx_v10_0_ring_emit_ib_gfx */ | |
| 4965 | 4956 | .emit_ib = gfx_v10_0_ring_emit_ib_gfx, |
| 4966 | 4957 | .emit_fence = gfx_v10_0_ring_emit_fence, |
| 4967 | 4958 | .emit_pipeline_sync = gfx_v10_0_ring_emit_pipeline_sync, |
| @@ -5112,7 +5103,6 @@ static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev) · 144 unmodified lines | ||
| 5112 | 5103 | default: |
| 5113 | 5104 | adev->gds.gds_size = 0x10000; |
| 5114 | 5105 | adev->gds.gds_compute_max_wave_id = 0x4ff; |
| 5115 | − adev->gds.vgt_gs_max_wave_id = 0x3ff; | |
| 5116 | 5106 | break; |
| 5117 | 5107 | } |
| 5118 | 5108 | |
| @@ -1321,6 +1321,39 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) · 1320 unmodified lines | ||
| 1321 | 1321 | return 0; |
| 1322 | 1322 | } |
| 1323 | 1323 | |
| 1324 | +static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev) | |
| 1325 | +{ | |
| 1326 | + int r; | |
| 1327 | + | |
| 1328 | + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); | |
| 1329 | + if (unlikely(r != 0)) | |
| 1330 | + return r; | |
| 1331 | + | |
| 1332 | + r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, | |
| 1333 | + AMDGPU_GEM_DOMAIN_VRAM); | |
| 1334 | + if (!r) | |
| 1335 | + adev->gfx.rlc.clear_state_gpu_addr = | |
| 1336 | + amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj); | |
| 1337 | + | |
| 1338 | + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | |
| 1339 | + | |
| 1340 | + return r; | |
| 1341 | +} | |
| 1342 | + | |
| 1343 | +static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev) | |
| 1344 | +{ | |
| 1345 | + int r; | |
| 1346 | + | |
| 1347 | + if (!adev->gfx.rlc.clear_state_obj) | |
| 1348 | + return; | |
| 1349 | + | |
| 1350 | + r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true); | |
| 1351 | + if (likely(r == 0)) { | |
| 1352 | + amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); | |
| 1353 | + amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); | |
| 1354 | + } | |
| 1355 | +} | |
| 1356 | + | |
| 1324 | 1357 | static void gfx_v8_0_mec_fini(struct amdgpu_device *adev) |
| 1325 | 1358 | { |
| 1326 | 1359 | amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL); |
| @@ -4785,6 +4818,10 @@ static int gfx_v8_0_hw_init(void *handle) · 3458 unmodified lines | ||
| 4785 | 4818 | gfx_v8_0_init_golden_registers(adev); |
| 4786 | 4819 | gfx_v8_0_constants_init(adev); |
| 4787 | 4820 | |
| 4821 | + r = gfx_v8_0_csb_vram_pin(adev); | |
| 4822 | + if (r) | |
| 4823 | + return r; | |
| 4824 | + | |
| 4788 | 4825 | r = adev->gfx.rlc.funcs->resume(adev); |
| 4789 | 4826 | if (r) |
| 4790 | 4827 | return r; |
| @@ -4901,6 +4938,9 @@ static int gfx_v8_0_hw_fini(void *handle) · 110 unmodified lines | ||
| 4901 | 4938 | else |
| 4902 | 4939 | pr_err("rlc is busy, skip halt rlc\n"); |
| 4903 | 4940 | amdgpu_gfx_rlc_exit_safe_mode(adev); |
| 4941 | + | |
| 4942 | + gfx_v8_0_csb_vram_unpin(adev); | |
| 4943 | + | |
| 4904 | 4944 | return 0; |
| 4905 | 4945 | } |
| 4906 | 4946 | |
| @@ -4869,7 +4869,7 @@ static void gfx_v9_0_ring_soft_recovery(struct amdgpu_ring *ring, unsigned vmid) · 4868 unmodified lines | ||
| 4869 | 4869 | value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01); |
| 4870 | 4870 | value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1); |
| 4871 | 4871 | value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid); |
| 4872 | − WREG32(mmSQ_CMD, value); | |
| 4872 | + WREG32_SOC15(GC, 0, mmSQ_CMD, value); | |
| 4873 | 4873 | } |
| 4874 | 4874 | |
| 4875 | 4875 | static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, |
| @@ -1485,7 +1485,7 @@ static void vcn_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring) · 1484 unmodified lines | ||
| 1485 | 1485 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0)); |
| 1486 | 1486 | amdgpu_ring_write(ring, 0); |
| 1487 | 1487 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1488 | − amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_START << 1); | |
| 1488 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_START << 1)); | |
| 1489 | 1489 | } |
| 1490 | 1490 | |
| 1491 | 1491 | /** |
| @@ -1498,7 +1498,7 @@ static void vcn_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring) · 6 unmodified lines | ||
| 1498 | 1498 | static void vcn_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring) |
| 1499 | 1499 | { |
| 1500 | 1500 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1501 | − amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_END << 1); | |
| 1501 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_END << 1)); | |
| 1502 | 1502 | } |
| 1503 | 1503 | |
| 1504 | 1504 | /** |
| @@ -1543,7 +1543,7 @@ static void vcn_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 · 38 unmodified lines | ||
| 1543 | 1543 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); |
| 1544 | 1544 | |
| 1545 | 1545 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1546 | − amdgpu_ring_write(ring, VCN_DEC_CMD_FENCE << 1); | |
| 1546 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_FENCE << 1)); | |
| 1547 | 1547 | |
| 1548 | 1548 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET, 0)); |
| 1549 | 1549 | amdgpu_ring_write(ring, 0); |
| @@ -1553,7 +1553,7 @@ static void vcn_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 · 3 unmodified lines | ||
| 1553 | 1553 | |
| 1554 | 1554 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1555 | 1555 | |
| 1556 | − amdgpu_ring_write(ring, VCN_DEC_CMD_TRAP << 1); | |
| 1556 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_TRAP << 1)); | |
| 1557 | 1557 | } |
| 1558 | 1558 | |
| 1559 | 1559 | /** |
| @@ -1597,7 +1597,7 @@ static void vcn_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring, · 37 unmodified lines | ||
| 1597 | 1597 | |
| 1598 | 1598 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1599 | 1599 | |
| 1600 | − amdgpu_ring_write(ring, VCN_DEC_CMD_REG_READ_COND_WAIT << 1); | |
| 1600 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_REG_READ_COND_WAIT << 1)); | |
| 1601 | 1601 | } |
| 1602 | 1602 | |
| 1603 | 1603 | static void vcn_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, |
| @@ -1626,7 +1626,7 @@ static void vcn_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, · 22 unmodified lines | ||
| 1626 | 1626 | |
| 1627 | 1627 | amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); |
| 1628 | 1628 | |
| 1629 | − amdgpu_ring_write(ring, VCN_DEC_CMD_WRITE_REG << 1); | |
| 1629 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_WRITE_REG << 1)); | |
| 1630 | 1630 | } |
| 1631 | 1631 | |
| 1632 | 1632 | /** |
| @@ -2079,6 +2079,36 @@ static int vcn_v2_0_process_interrupt(struct amdgpu_device *adev, · 446 unmodified lines | ||
| 2079 | 2079 | return 0; |
| 2080 | 2080 | } |
| 2081 | 2081 | |
| 2082 | +static int vcn_v2_0_dec_ring_test_ring(struct amdgpu_ring *ring) | |
| 2083 | +{ | |
| 2084 | + struct amdgpu_device *adev = ring->adev; | |
| 2085 | + uint32_t tmp = 0; | |
| 2086 | + unsigned i; | |
| 2087 | + int r; | |
| 2088 | + | |
| 2089 | + WREG32(adev->vcn.external.scratch9, 0xCAFEDEAD); | |
| 2090 | + r = amdgpu_ring_alloc(ring, 4); | |
| 2091 | + if (r) | |
| 2092 | + return r; | |
| 2093 | + amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET, 0)); | |
| 2094 | + amdgpu_ring_write(ring, VCN_DEC_KMD_CMD | (VCN_DEC_CMD_PACKET_START << 1)); | |
| 2095 | + amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0)); | |
| 2096 | + amdgpu_ring_write(ring, 0xDEADBEEF); | |
| 2097 | + amdgpu_ring_commit(ring); | |
| 2098 | + for (i = 0; i < adev->usec_timeout; i++) { | |
| 2099 | + tmp = RREG32(adev->vcn.external.scratch9); | |
| 2100 | + if (tmp == 0xDEADBEEF) | |
| 2101 | + break; | |
| 2102 | + DRM_UDELAY(1); | |
| 2103 | + } | |
| 2104 | + | |
| 2105 | + if (i >= adev->usec_timeout) | |
| 2106 | + r = -ETIMEDOUT; | |
| 2107 | + | |
| 2108 | + return r; | |
| 2109 | +} | |
| 2110 | + | |
| 2111 | + | |
| 2082 | 2112 | static int vcn_v2_0_set_powergating_state(void *handle, |
| 2083 | 2113 | enum amd_powergating_state state) |
| 2084 | 2114 | { |
| @@ -2142,7 +2172,7 @@ static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = { · 57 unmodified lines | ||
| 2142 | 2172 | .emit_ib = vcn_v2_0_dec_ring_emit_ib, |
| 2143 | 2173 | .emit_fence = vcn_v2_0_dec_ring_emit_fence, |
| 2144 | 2174 | .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush, |
| 2145 | − .test_ring = amdgpu_vcn_dec_ring_test_ring, | |
| 2175 | + .test_ring = vcn_v2_0_dec_ring_test_ring, | |
| 2146 | 2176 | .test_ib = amdgpu_vcn_dec_ring_test_ib, |
| 2147 | 2177 | .insert_nop = vcn_v2_0_dec_ring_insert_nop, |
| 2148 | 2178 | .insert_start = vcn_v2_0_dec_ring_insert_start, |
| @@ -1567,32 +1567,6 @@ copy_from_user_failed: · 1566 unmodified lines | ||
| 1567 | 1567 | return err; |
| 1568 | 1568 | } |
| 1569 | 1569 | |
| 1570 | −static int kfd_ioctl_alloc_queue_gws(struct file *filep, | |
| 1571 | − struct kfd_process *p, void *data) | |
| 1572 | −{ | |
| 1573 | − int retval; | |
| 1574 | − struct kfd_ioctl_alloc_queue_gws_args *args = data; | |
| 1575 | − struct kfd_dev *dev; | |
| 1576 | − | |
| 1577 | − if (!hws_gws_support) | |
| 1578 | − return -ENODEV; | |
| 1579 | − | |
| 1580 | − dev = kfd_device_by_id(args->gpu_id); | |
| 1581 | − if (!dev) { | |
| 1582 | − pr_debug("Could not find gpu id 0x%x\n", args->gpu_id); | |
| 1583 | − return -ENODEV; | |
| 1584 | − } | |
| 1585 | − if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) | |
| 1586 | − return -ENODEV; | |
| 1587 | − | |
| 1588 | − mutex_lock(&p->mutex); | |
| 1589 | − retval = pqm_set_gws(&p->pqm, args->queue_id, args->num_gws ? dev->gws : NULL); | |
| 1590 | − mutex_unlock(&p->mutex); | |
| 1591 | − | |
| 1592 | − args->first_gws = 0; | |
| 1593 | − return retval; | |
| 1594 | −} | |
| 1595 | − | |
| 1596 | 1570 | static int kfd_ioctl_get_dmabuf_info(struct file *filep, |
| 1597 | 1571 | struct kfd_process *p, void *data) |
| 1598 | 1572 | { |
| @@ -1795,8 +1769,6 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { · 196 unmodified lines | ||
| 1795 | 1769 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_IMPORT_DMABUF, |
| 1796 | 1770 | kfd_ioctl_import_dmabuf, 0), |
| 1797 | 1771 | |
| 1798 | − AMDKFD_IOCTL_DEF(AMDKFD_IOC_ALLOC_QUEUE_GWS, | |
| 1799 | − kfd_ioctl_alloc_queue_gws, 0), | |
| 1800 | 1772 | }; |
| 1801 | 1773 | |
| 1802 | 1774 | #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | 25 | #include <linux/slab.h> |
| 26 | +#include <linux/mm.h> | |
| 26 | 27 | |
| 27 | 28 | #include "dm_services.h" |
| 28 | 29 | |
| @@ -1171,8 +1172,8 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) · 1142 unmodified lines | ||
| 1171 | 1172 | |
| 1172 | 1173 | struct dc_state *dc_create_state(struct dc *dc) |
| 1173 | 1174 | { |
| 1174 | − struct dc_state *context = kzalloc(sizeof(struct dc_state), | |
| 1175 | − GFP_KERNEL); | |
| 1175 | + struct dc_state *context = kvzalloc(sizeof(struct dc_state), | |
| 1176 | + GFP_KERNEL); | |
| 1176 | 1177 | |
| 1177 | 1178 | if (!context) |
| 1178 | 1179 | return NULL; |
| @@ -1192,11 +1193,11 @@ struct dc_state *dc_create_state(struct dc *dc) · 13 unmodified lines | ||
| 1192 | 1193 | struct dc_state *dc_copy_state(struct dc_state *src_ctx) |
| 1193 | 1194 | { |
| 1194 | 1195 | int i, j; |
| 1195 | − struct dc_state *new_ctx = kmemdup(src_ctx, | |
| 1196 | − sizeof(struct dc_state), GFP_KERNEL); | |
| 1196 | + struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL); | |
| 1197 | 1197 | |
| 1198 | 1198 | if (!new_ctx) |
| 1199 | 1199 | return NULL; |
| 1200 | + memcpy(new_ctx, src_ctx, sizeof(struct dc_state)); | |
| 1200 | 1201 | |
| 1201 | 1202 | for (i = 0; i < MAX_PIPES; i++) { |
| 1202 | 1203 | struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i]; |
| @@ -1230,7 +1231,7 @@ static void dc_state_free(struct kref *kref) · 27 unmodified lines | ||
| 1230 | 1231 | { |
| 1231 | 1232 | struct dc_state *context = container_of(kref, struct dc_state, refcount); |
| 1232 | 1233 | dc_resource_state_destruct(context); |
| 1233 | − kfree(context); | |
| 1234 | + kvfree(context); | |
| 1234 | 1235 | } |
| 1235 | 1236 | |
| 1236 | 1237 | void dc_release_state(struct dc_state *context) |
| @@ -315,6 +315,8 @@ int smu_get_power_num_states(struct smu_context *smu, · 314 unmodified lines | ||
| 315 | 315 | int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, |
| 316 | 316 | void *data, uint32_t *size) |
| 317 | 317 | { |
| 318 | + struct smu_power_context *smu_power = &smu->smu_power; | |
| 319 | + struct smu_power_gate *power_gate = &smu_power->power_gate; | |
| 318 | 320 | int ret = 0; |
| 319 | 321 | |
| 320 | 322 | switch (sensor) { |
| @@ -339,7 +341,7 @@ int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, · 18 unmodified lines | ||
| 339 | 341 | *size = 4; |
| 340 | 342 | break; |
| 341 | 343 | case AMDGPU_PP_SENSOR_VCN_POWER_STATE: |
| 342 | − *(uint32_t *)data = smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT) ? 1 : 0; | |
| 344 | + *(uint32_t *)data = power_gate->vcn_gated ? 0 : 1; | |
| 343 | 345 | *size = 4; |
| 344 | 346 | break; |
| 345 | 347 | default: |
| @@ -451,6 +451,7 @@ struct smu_dpm_context { · 450 unmodified lines | ||
| 451 | 451 | struct smu_power_gate { |
| 452 | 452 | bool uvd_gated; |
| 453 | 453 | bool vce_gated; |
| 454 | + bool vcn_gated; | |
| 454 | 455 | }; |
| 455 | 456 | |
| 456 | 457 | struct smu_power_context { |
| @@ -502,6 +502,8 @@ static int navi10_store_powerplay_table(struct smu_context *smu) · 501 unmodified lines | ||
| 502 | 502 | |
| 503 | 503 | static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables) |
| 504 | 504 | { |
| 505 | + struct smu_table_context *smu_table = &smu->smu_table; | |
| 506 | + | |
| 505 | 507 | SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t), |
| 506 | 508 | PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); |
| 507 | 509 | SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), |
| @@ -516,9 +518,35 @@ static int navi10_tables_init(struct smu_context *smu, struct smu_table *tables) · 8 unmodified lines | ||
| 516 | 518 | sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE, |
| 517 | 519 | AMDGPU_GEM_DOMAIN_VRAM); |
| 518 | 520 | |
| 521 | + smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); | |
| 522 | + if (!smu_table->metrics_table) | |
| 523 | + return -ENOMEM; | |
| 524 | + smu_table->metrics_time = 0; | |
| 525 | + | |
| 519 | 526 | return 0; |
| 520 | 527 | } |
| 521 | 528 | |
| 529 | +static int navi10_get_metrics_table(struct smu_context *smu, | |
| 530 | + SmuMetrics_t *metrics_table) | |
| 531 | +{ | |
| 532 | + struct smu_table_context *smu_table= &smu->smu_table; | |
| 533 | + int ret = 0; | |
| 534 | + | |
| 535 | + if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { | |
| 536 | + ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | |
| 537 | + (void *)smu_table->metrics_table, false); | |
| 538 | + if (ret) { | |
| 539 | + pr_info("Failed to export SMU metrics table!\n"); | |
| 540 | + return ret; | |
| 541 | + } | |
| 542 | + smu_table->metrics_time = jiffies; | |
| 543 | + } | |
| 544 | + | |
| 545 | + memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); | |
| 546 | + | |
| 547 | + return ret; | |
| 548 | +} | |
| 549 | + | |
| 522 | 550 | static int navi10_allocate_dpm_context(struct smu_context *smu) |
| 523 | 551 | { |
| 524 | 552 | struct smu_dpm_context *smu_dpm = &smu->smu_dpm; |
| @@ -577,20 +605,27 @@ static int navi10_set_default_dpm_table(struct smu_context *smu) · 52 unmodified lines | ||
| 577 | 605 | |
| 578 | 606 | static int navi10_dpm_set_uvd_enable(struct smu_context *smu, bool enable) |
| 579 | 607 | { |
| 608 | + struct smu_power_context *smu_power = &smu->smu_power; | |
| 609 | + struct smu_power_gate *power_gate = &smu_power->power_gate; | |
| 580 | 610 | int ret = 0; |
| 581 | 611 | |
| 582 | 612 | if (enable) { |
| 583 | − ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1); | |
| 584 | − if (ret) | |
| 585 | − return ret; | |
| 613 | + /* vcn dpm on is a prerequisite for vcn power gate messages */ | |
| 614 | + if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { | |
| 615 | + ret = smu_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1); | |
| 616 | + if (ret) | |
| 617 | + return ret; | |
| 618 | + } | |
| 619 | + power_gate->vcn_gated = false; | |
| 586 | 620 | } else { |
| 587 | − ret = smu_send_smc_msg(smu, SMU_MSG_PowerDownVcn); | |
| 588 | − if (ret) | |
| 589 | − return ret; | |
| 621 | + if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { | |
| 622 | + ret = smu_send_smc_msg(smu, SMU_MSG_PowerDownVcn); | |
| 623 | + if (ret) | |
| 624 | + return ret; | |
| 625 | + } | |
| 626 | + power_gate->vcn_gated = true; | |
| 590 | 627 | } |
| 591 | 628 | |
| 592 | − ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, enable); | |
| 593 | − | |
| 594 | 629 | return ret; |
| 595 | 630 | } |
| 596 | 631 | |
| @@ -598,15 +633,10 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, · 1 unmodified line | ||
| 598 | 633 | enum smu_clk_type clk_type, |
| 599 | 634 | uint32_t *value) |
| 600 | 635 | { |
| 601 | − static SmuMetrics_t metrics; | |
| 602 | 636 | int ret = 0, clk_id = 0; |
| 637 | + SmuMetrics_t metrics; | |
| 603 | 638 | |
| 604 | − if (!value) | |
| 605 | − return -EINVAL; | |
| 606 | − | |
| 607 | − memset(&metrics, 0, sizeof(metrics)); | |
| 608 | − | |
| 609 | − ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false); | |
| 639 | + ret = navi10_get_metrics_table(smu, &metrics); | |
| 610 | 640 | if (ret) |
| 611 | 641 | return ret; |
| 612 | 642 | |
| @@ -894,8 +924,9 @@ static int navi10_get_gpu_power(struct smu_context *smu, uint32_t *value) · 281 unmodified lines | ||
| 894 | 924 | if (!value) |
| 895 | 925 | return -EINVAL; |
| 896 | 926 | |
| 897 | − ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, | |
| 898 | − false); | |
| 927 | + ret = navi10_get_metrics_table(smu, &metrics); | |
| 928 | + if (ret) | |
| 929 | + return ret; | |
| 899 | 930 | if (ret) |
| 900 | 931 | return ret; |
| 901 | 932 | |
| @@ -914,10 +945,7 @@ static int navi10_get_current_activity_percent(struct smu_context *smu, · 12 unmodified lines | ||
| 914 | 945 | if (!value) |
| 915 | 946 | return -EINVAL; |
| 916 | 947 | |
| 917 | − msleep(1); | |
| 918 | − | |
| 919 | − ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | |
| 920 | − (void *)&metrics, false); | |
| 948 | + ret = navi10_get_metrics_table(smu, &metrics); | |
| 921 | 949 | if (ret) |
| 922 | 950 | return ret; |
| 923 | 951 | |
| @@ -956,10 +984,9 @@ static int navi10_get_fan_speed_rpm(struct smu_context *smu, · 32 unmodified lines | ||
| 956 | 984 | if (!speed) |
| 957 | 985 | return -EINVAL; |
| 958 | 986 | |
| 959 | − memset(&metrics, 0, sizeof(metrics)); | |
| 960 | − | |
| 961 | − ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, | |
| 962 | − (void *)&metrics, false); | |
| 987 | + ret = navi10_get_metrics_table(smu, &metrics); | |
| 988 | + if (ret) | |
| 989 | + return ret; | |
| 963 | 990 | if (ret) |
| 964 | 991 | return ret; |
| 965 | 992 | |
| @@ -1307,7 +1334,7 @@ static int navi10_thermal_get_temperature(struct smu_context *smu, · 341 unmodified lines | ||
| 1307 | 1334 | if (!value) |
| 1308 | 1335 | return -EINVAL; |
| 1309 | 1336 | |
| 1310 | − ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false); | |
| 1337 | + ret = navi10_get_metrics_table(smu, &metrics); | |
| 1311 | 1338 | if (ret) |
| 1312 | 1339 | return ret; |
| 1313 | 1340 | |
| @@ -1391,7 +1391,7 @@ smu_v11_0_smc_fan_control(struct smu_context *smu, bool start) · 1390 unmodified lines | ||
| 1391 | 1391 | { |
| 1392 | 1392 | int ret = 0; |
| 1393 | 1393 | |
| 1394 | − if (smu_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT)) | |
| 1394 | + if (!smu_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT)) | |
| 1395 | 1395 | return 0; |
| 1396 | 1396 | |
| 1397 | 1397 | ret = smu_feature_set_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT, start); |
| @@ -131,8 +131,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) · 130 unmodified lines | ||
| 131 | 131 | |
| 132 | 132 | |
| 133 | 133 | /* Enable extended register access */ |
| 134 | − ast_enable_mmio(dev); | |
| 135 | 134 | ast_open_key(ast); |
| 135 | + ast_enable_mmio(dev); | |
| 136 | 136 | |
| 137 | 137 | /* Find out whether P2A works or whether to use device-tree */ |
| 138 | 138 | ast_detect_config_mode(dev, &scu_rev); |
| @@ -576,6 +576,9 @@ void ast_driver_unload(struct drm_device *dev) · 437 unmodified lines | ||
| 576 | 576 | { |
| 577 | 577 | struct ast_private *ast = dev->dev_private; |
| 578 | 578 | |
| 579 | + /* enable standard VGA decode */ | |
| 580 | + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); | |
| 581 | + | |
| 579 | 582 | ast_release_firmware(dev); |
| 580 | 583 | kfree(ast->dp501_fw_addr); |
| 581 | 584 | ast_mode_fini(dev); |
| @@ -604,7 +604,7 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, · 603 unmodified lines | ||
| 604 | 604 | return -EINVAL; |
| 605 | 605 | ast_open_key(ast); |
| 606 | 606 | |
| 607 | − ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); | |
| 607 | + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); | |
| 608 | 608 | |
| 609 | 609 | ast_set_std_reg(crtc, adjusted_mode, &vbios_mode); |
| 610 | 610 | ast_set_crtc_reg(crtc, adjusted_mode, &vbios_mode); |
| @@ -46,7 +46,7 @@ void ast_enable_mmio(struct drm_device *dev) · 45 unmodified lines | ||
| 46 | 46 | { |
| 47 | 47 | struct ast_private *ast = dev->dev_private; |
| 48 | 48 | |
| 49 | − ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x04); | |
| 49 | + ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); | |
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | |
| @@ -1770,7 +1770,9 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, · 1769 unmodified lines | ||
| 1770 | 1770 | } |
| 1771 | 1771 | |
| 1772 | 1772 | if (named_mode) { |
| 1773 | − strncpy(mode->name, name, mode_end); | |
| 1773 | + if (mode_end + 1 > DRM_DISPLAY_MODE_LEN) | |
| 1774 | + return false; | |
| 1775 | + strscpy(mode->name, name, mode_end + 1); | |
| 1774 | 1776 | } else { |
| 1775 | 1777 | ret = drm_mode_parse_cmdline_res_mode(name, mode_end, |
| 1776 | 1778 | parse_extras, |
| @@ -536,7 +536,8 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector) · 535 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | if (drm_hdcp_check_ksvs_revoked(dev, ksv_fifo, num_downstream)) { |
| 538 | 538 | DRM_ERROR("Revoked Ksv(s) in ksv_fifo\n"); |
| 539 | − return -EPERM; | |
| 539 | + ret = -EPERM; | |
| 540 | + goto err; | |
| 540 | 541 | } |
| 541 | 542 | |
| 542 | 543 | /* |
| @@ -396,8 +396,8 @@ static void glk_dsi_program_esc_clock(struct drm_device *dev, · 395 unmodified lines | ||
| 396 | 396 | else |
| 397 | 397 | txesc2_div = 10; |
| 398 | 398 | |
| 399 | − I915_WRITE(MIPIO_TXESC_CLK_DIV1, txesc1_div & GLK_TX_ESC_CLK_DIV1_MASK); | |
| 400 | − I915_WRITE(MIPIO_TXESC_CLK_DIV2, txesc2_div & GLK_TX_ESC_CLK_DIV2_MASK); | |
| 399 | + I915_WRITE(MIPIO_TXESC_CLK_DIV1, (1 << (txesc1_div - 1)) & GLK_TX_ESC_CLK_DIV1_MASK); | |
| 400 | + I915_WRITE(MIPIO_TXESC_CLK_DIV2, (1 << (txesc2_div - 1)) & GLK_TX_ESC_CLK_DIV2_MASK); | |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | /* Program BXT Mipi clocks and dividers */ |
| @@ -1628,6 +1628,7 @@ static int check_relocations(const struct drm_i915_gem_exec_object2 *entry) · 1627 unmodified lines | ||
| 1628 | 1628 | |
| 1629 | 1629 | static int eb_copy_relocations(const struct i915_execbuffer *eb) |
| 1630 | 1630 | { |
| 1631 | + struct drm_i915_gem_relocation_entry *relocs; | |
| 1631 | 1632 | const unsigned int count = eb->buffer_count; |
| 1632 | 1633 | unsigned int i; |
| 1633 | 1634 | int err; |
| @@ -1635,7 +1636,6 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) · 1 unmodified line | ||
| 1635 | 1636 | for (i = 0; i < count; i++) { |
| 1636 | 1637 | const unsigned int nreloc = eb->exec[i].relocation_count; |
| 1637 | 1638 | struct drm_i915_gem_relocation_entry __user *urelocs; |
| 1638 | − struct drm_i915_gem_relocation_entry *relocs; | |
| 1639 | 1639 | unsigned long size; |
| 1640 | 1640 | unsigned long copied; |
| 1641 | 1641 | |
| @@ -1663,14 +1663,8 @@ static int eb_copy_relocations(const struct i915_execbuffer *eb) · 21 unmodified lines | ||
| 1663 | 1663 | |
| 1664 | 1664 | if (__copy_from_user((char *)relocs + copied, |
| 1665 | 1665 | (char __user *)urelocs + copied, |
| 1666 | − len)) { | |
| 1667 | −end_user: | |
| 1668 | − user_access_end(); | |
| 1669 | −end: | |
| 1670 | − kvfree(relocs); | |
| 1671 | − err = -EFAULT; | |
| 1672 | − goto err; | |
| 1673 | − } | |
| 1666 | + len)) | |
| 1667 | + goto end; | |
| 1674 | 1668 | |
| 1675 | 1669 | copied += len; |
| 1676 | 1670 | } while (copied < size); |
| @@ -1699,10 +1693,14 @@ end: · 22 unmodified lines | ||
| 1699 | 1693 | |
| 1700 | 1694 | return 0; |
| 1701 | 1695 | |
| 1696 | +end_user: | |
| 1697 | + user_access_end(); | |
| 1698 | +end: | |
| 1699 | + kvfree(relocs); | |
| 1700 | + err = -EFAULT; | |
| 1702 | 1701 | err: |
| 1703 | 1702 | while (i--) { |
| 1704 | − struct drm_i915_gem_relocation_entry *relocs = | |
| 1705 | − u64_to_ptr(typeof(*relocs), eb->exec[i].relocs_ptr); | |
| 1703 | + relocs = u64_to_ptr(typeof(*relocs), eb->exec[i].relocs_ptr); | |
| 1706 | 1704 | if (eb->exec[i].relocation_count) |
| 1707 | 1705 | kvfree(relocs); |
| 1708 | 1706 | } |
| @@ -1528,9 +1528,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, · 1527 unmodified lines | ||
| 1528 | 1528 | if (!intel_gvt_ggtt_validate_range(vgpu, |
| 1529 | 1529 | workload->wa_ctx.indirect_ctx.guest_gma, |
| 1530 | 1530 | workload->wa_ctx.indirect_ctx.size)) { |
| 1531 | − kmem_cache_free(s->workloads, workload); | |
| 1532 | 1531 | gvt_vgpu_err("invalid wa_ctx at: 0x%lx\n", |
| 1533 | 1532 | workload->wa_ctx.indirect_ctx.guest_gma); |
| 1533 | + kmem_cache_free(s->workloads, workload); | |
| 1534 | 1534 | return ERR_PTR(-EINVAL); |
| 1535 | 1535 | } |
| 1536 | 1536 | } |
| @@ -1542,9 +1542,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, · 5 unmodified lines | ||
| 1542 | 1542 | if (!intel_gvt_ggtt_validate_range(vgpu, |
| 1543 | 1543 | workload->wa_ctx.per_ctx.guest_gma, |
| 1544 | 1544 | CACHELINE_BYTES)) { |
| 1545 | − kmem_cache_free(s->workloads, workload); | |
| 1546 | 1545 | gvt_vgpu_err("invalid per_ctx at: 0x%lx\n", |
| 1547 | 1546 | workload->wa_ctx.per_ctx.guest_gma); |
| 1547 | + kmem_cache_free(s->workloads, workload); | |
| 1548 | 1548 | return ERR_PTR(-EINVAL); |
| 1549 | 1549 | } |
| 1550 | 1550 | } |
| @@ -771,16 +771,20 @@ nv50_msto_atomic_check(struct drm_encoder *encoder, · 770 unmodified lines | ||
| 771 | 771 | struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); |
| 772 | 772 | int slots; |
| 773 | 773 | |
| 774 | − /* When restoring duplicated states, we need to make sure that the | |
| 775 | − * bw remains the same and avoid recalculating it, as the connector's | |
| 776 | − * bpc may have changed after the state was duplicated | |
| 777 | − */ | |
| 778 | − if (!state->duplicated) | |
| 779 | − asyh->dp.pbn = | |
| 780 | − drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, | |
| 781 | − connector->display_info.bpc * 3); | |
| 774 | + if (crtc_state->mode_changed || crtc_state->connectors_changed) { | |
| 775 | + /* | |
| 776 | + * When restoring duplicated states, we need to make sure that | |
| 777 | + * the bw remains the same and avoid recalculating it, as the | |
| 778 | + * connector's bpc may have changed after the state was | |
| 779 | + * duplicated | |
| 780 | + */ | |
| 781 | + if (!state->duplicated) { | |
| 782 | + const int bpp = connector->display_info.bpc * 3; | |
| 783 | + const int clock = crtc_state->adjusted_mode.clock; | |
| 784 | + | |
| 785 | + asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp); | |
| 786 | + } | |
| 782 | 787 | |
| 783 | − if (crtc_state->mode_changed) { | |
| 784 | 788 | slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, |
| 785 | 789 | mstc->port, |
| 786 | 790 | asyh->dp.pbn); |
| @@ -432,7 +432,7 @@ static int rockchip_dp_resume(struct device *dev) · 431 unmodified lines | ||
| 432 | 432 | |
| 433 | 433 | static const struct dev_pm_ops rockchip_dp_pm_ops = { |
| 434 | 434 | #ifdef CONFIG_PM_SLEEP |
| 435 | − .suspend = rockchip_dp_suspend, | |
| 435 | + .suspend_late = rockchip_dp_suspend, | |
| 436 | 436 | .resume_early = rockchip_dp_resume, |
| 437 | 437 | #endif |
| 438 | 438 | }; |
| @@ -95,7 +95,7 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity) · 94 unmodified lines | ||
| 95 | 95 | rmb(); /* for list_empty to work without lock */ |
| 96 | 96 | |
| 97 | 97 | if (list_empty(&entity->list) || |
| 98 | − spsc_queue_peek(&entity->job_queue) == NULL) | |
| 98 | + spsc_queue_count(&entity->job_queue) == 0) | |
| 99 | 99 | return true; |
| 100 | 100 | |
| 101 | 101 | return false; |
| @@ -281,7 +281,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity) · 179 unmodified lines | ||
| 281 | 281 | /* Consumption of existing IBs wasn't completed. Forcefully |
| 282 | 282 | * remove them here. |
| 283 | 283 | */ |
| 284 | − if (spsc_queue_peek(&entity->job_queue)) { | |
| 284 | + if (spsc_queue_count(&entity->job_queue)) { | |
| 285 | 285 | if (sched) { |
| 286 | 286 | /* Park the kernel for a moment to make sure it isn't processing |
| 287 | 287 | * our enity. |
| @@ -126,8 +126,12 @@ int tegra_output_probe(struct tegra_output *output) · 125 unmodified lines | ||
| 126 | 126 | "nvidia,hpd-gpio", 0, |
| 127 | 127 | GPIOD_IN, |
| 128 | 128 | "HDMI hotplug detect"); |
| 129 | − if (IS_ERR(output->hpd_gpio)) | |
| 130 | − return PTR_ERR(output->hpd_gpio); | |
| 129 | + if (IS_ERR(output->hpd_gpio)) { | |
| 130 | + if (PTR_ERR(output->hpd_gpio) != -ENOENT) | |
| 131 | + return PTR_ERR(output->hpd_gpio); | |
| 132 | + | |
| 133 | + output->hpd_gpio = NULL; | |
| 134 | + } | |
| 131 | 135 | |
| 132 | 136 | if (output->hpd_gpio) { |
| 133 | 137 | err = gpiod_to_irq(output->hpd_gpio); |
| @@ -389,8 +389,10 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg, · 388 unmodified lines | ||
| 389 | 389 | break; |
| 390 | 390 | } |
| 391 | 391 | |
| 392 | − if (retries == RETRIES) | |
| 392 | + if (retries == RETRIES) { | |
| 393 | + kfree(reply); | |
| 393 | 394 | return -EINVAL; |
| 395 | + } | |
| 394 | 396 | |
| 395 | 397 | *msg_len = reply_len; |
| 396 | 398 | *msg = reply; |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | |
| 3 | 3 | #undef TRACE_SYSTEM |
| 4 | 4 | #define TRACE_SYSTEM hyperv |
| @@ -343,7 +343,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) · 342 unmodified lines | ||
| 343 | 343 | data->sample_time = MSEC_PER_SEC / 2; |
| 344 | 344 | break; |
| 345 | 345 | case tmp75b: /* not one-shot mode, Conversion rate 37Hz */ |
| 346 | − clr_mask |= 1 << 15 | 0x3 << 13; | |
| 346 | + clr_mask |= 1 << 7 | 0x3 << 5; | |
| 347 | 347 | data->resolution = 12; |
| 348 | 348 | data->sample_time = MSEC_PER_SEC / 37; |
| 349 | 349 | break; |
| @@ -704,7 +704,7 @@ static struct attribute *nct7802_in_attrs[] = { · 703 unmodified lines | ||
| 704 | 704 | &sensor_dev_attr_in3_alarm.dev_attr.attr, |
| 705 | 705 | &sensor_dev_attr_in3_beep.dev_attr.attr, |
| 706 | 706 | |
| 707 | − &sensor_dev_attr_in4_input.dev_attr.attr, /* 17 */ | |
| 707 | + &sensor_dev_attr_in4_input.dev_attr.attr, /* 16 */ | |
| 708 | 708 | &sensor_dev_attr_in4_min.dev_attr.attr, |
| 709 | 709 | &sensor_dev_attr_in4_max.dev_attr.attr, |
| 710 | 710 | &sensor_dev_attr_in4_alarm.dev_attr.attr, |
| @@ -730,9 +730,9 @@ static umode_t nct7802_in_is_visible(struct kobject *kobj, · 19 unmodified lines | ||
| 730 | 730 | |
| 731 | 731 | if (index >= 6 && index < 11 && (reg & 0x03) != 0x03) /* VSEN1 */ |
| 732 | 732 | return 0; |
| 733 | − if (index >= 11 && index < 17 && (reg & 0x0c) != 0x0c) /* VSEN2 */ | |
| 733 | + if (index >= 11 && index < 16 && (reg & 0x0c) != 0x0c) /* VSEN2 */ | |
| 734 | 734 | return 0; |
| 735 | − if (index >= 17 && (reg & 0x30) != 0x30) /* VSEN3 */ | |
| 735 | + if (index >= 16 && (reg & 0x30) != 0x30) /* VSEN3 */ | |
| 736 | 736 | return 0; |
| 737 | 737 | |
| 738 | 738 | return attr->mode; |
| @@ -544,6 +544,7 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev) · 543 unmodified lines | ||
| 544 | 544 | /* See function coresight_get_sink_by_id() to know where this is used */ |
| 545 | 545 | hash = hashlen_hash(hashlen_string(NULL, name)); |
| 546 | 546 | |
| 547 | + sysfs_attr_init(&ea->attr.attr); | |
| 547 | 548 | ea->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL); |
| 548 | 549 | if (!ea->attr.attr.name) |
| 549 | 550 | return -ENOMEM; |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | /* |
| 3 | 3 | * Intel(R) Trace Hub Memory Storage Unit (MSU) data structures |
| 4 | 4 | * |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | /* |
| 3 | 3 | * Intel(R) Trace Hub PTI output data structures |
| 4 | 4 | * |
| @@ -69,6 +69,7 @@ struct em_i2c_device { · 68 unmodified lines | ||
| 69 | 69 | struct completion msg_done; |
| 70 | 70 | struct clk *sclk; |
| 71 | 71 | struct i2c_client *slave; |
| 72 | + int irq; | |
| 72 | 73 | }; |
| 73 | 74 | |
| 74 | 75 | static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg) |
| @@ -339,6 +340,12 @@ static int em_i2c_unreg_slave(struct i2c_client *slave) · 264 unmodified lines | ||
| 339 | 340 | |
| 340 | 341 | writeb(0, priv->base + I2C_OFS_SVA0); |
| 341 | 342 | |
| 343 | + /* | |
| 344 | + * Wait for interrupt to finish. New slave irqs cannot happen because we | |
| 345 | + * cleared the slave address and, thus, only extension codes will be | |
| 346 | + * detected which do not use the slave ptr. | |
| 347 | + */ | |
| 348 | + synchronize_irq(priv->irq); | |
| 342 | 349 | priv->slave = NULL; |
| 343 | 350 | |
| 344 | 351 | return 0; |
| @@ -355,7 +362,7 @@ static int em_i2c_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 355 | 362 | { |
| 356 | 363 | struct em_i2c_device *priv; |
| 357 | 364 | struct resource *r; |
| 358 | − int irq, ret; | |
| 365 | + int ret; | |
| 359 | 366 | |
| 360 | 367 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 361 | 368 | if (!priv) |
| @@ -390,8 +397,8 @@ static int em_i2c_probe(struct platform_device *pdev) · 28 unmodified lines | ||
| 390 | 397 | |
| 391 | 398 | em_i2c_reset(&priv->adap); |
| 392 | 399 | |
| 393 | − irq = platform_get_irq(pdev, 0); | |
| 394 | − ret = devm_request_irq(&pdev->dev, irq, em_i2c_irq_handler, 0, | |
| 400 | + priv->irq = platform_get_irq(pdev, 0); | |
| 401 | + ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0, | |
| 395 | 402 | "em_i2c", priv); |
| 396 | 403 | if (ret) |
| 397 | 404 | goto err_clk; |
| @@ -401,7 +408,8 @@ static int em_i2c_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 401 | 408 | if (ret) |
| 402 | 409 | goto err_clk; |
| 403 | 410 | |
| 404 | − dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, irq); | |
| 411 | + dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, | |
| 412 | + priv->irq); | |
| 405 | 413 | |
| 406 | 414 | return 0; |
| 407 | 415 | |
| @@ -273,8 +273,8 @@ static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx, · 272 unmodified lines | ||
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | /* Functions for DMA support */ |
| 276 | −static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, | |
| 277 | − dma_addr_t phy_addr) | |
| 276 | +static void i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, | |
| 277 | + dma_addr_t phy_addr) | |
| 278 | 278 | { |
| 279 | 279 | struct imx_i2c_dma *dma; |
| 280 | 280 | struct dma_slave_config dma_sconfig; |
| @@ -283,7 +283,7 @@ static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, · 2 unmodified lines | ||
| 283 | 283 | |
| 284 | 284 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); |
| 285 | 285 | if (!dma) |
| 286 | − return -ENOMEM; | |
| 286 | + return; | |
| 287 | 287 | |
| 288 | 288 | dma->chan_tx = dma_request_chan(dev, "tx"); |
| 289 | 289 | if (IS_ERR(dma->chan_tx)) { |
| @@ -328,7 +328,7 @@ static int i2c_imx_dma_request(struct imx_i2c_struct *i2c_imx, · 38 unmodified lines | ||
| 328 | 328 | dev_info(dev, "using %s (tx) and %s (rx) for DMA transfers\n", |
| 329 | 329 | dma_chan_name(dma->chan_tx), dma_chan_name(dma->chan_rx)); |
| 330 | 330 | |
| 331 | − return 0; | |
| 331 | + return; | |
| 332 | 332 | |
| 333 | 333 | fail_rx: |
| 334 | 334 | dma_release_channel(dma->chan_rx); |
| @@ -336,8 +336,6 @@ fail_tx: · 1 unmodified line | ||
| 336 | 336 | dma_release_channel(dma->chan_tx); |
| 337 | 337 | fail_al: |
| 338 | 338 | devm_kfree(dev, dma); |
| 339 | − /* return successfully if there is no dma support */ | |
| 340 | − return ret == -ENODEV ? 0 : ret; | |
| 341 | 339 | } |
| 342 | 340 | |
| 343 | 341 | static void i2c_imx_dma_callback(void *arg) |
| @@ -1165,17 +1163,13 @@ static int i2c_imx_probe(struct platform_device *pdev) · 821 unmodified lines | ||
| 1165 | 1163 | dev_dbg(&i2c_imx->adapter.dev, "device resources: %pR\n", res); |
| 1166 | 1164 | dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n", |
| 1167 | 1165 | i2c_imx->adapter.name); |
| 1166 | + dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); | |
| 1168 | 1167 | |
| 1169 | 1168 | /* Init DMA config if supported */ |
| 1170 | − ret = i2c_imx_dma_request(i2c_imx, phy_addr); | |
| 1171 | − if (ret < 0) | |
| 1172 | − goto del_adapter; | |
| 1169 | + i2c_imx_dma_request(i2c_imx, phy_addr); | |
| 1173 | 1170 | |
| 1174 | − dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); | |
| 1175 | 1171 | return 0; /* Return OK */ |
| 1176 | 1172 | |
| 1177 | −del_adapter: | |
| 1178 | − i2c_del_adapter(&i2c_imx->adapter); | |
| 1179 | 1173 | clk_notifier_unregister: |
| 1180 | 1174 | clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb); |
| 1181 | 1175 | rpm_disable: |
| @@ -139,6 +139,7 @@ struct rcar_i2c_priv { · 138 unmodified lines | ||
| 139 | 139 | enum dma_data_direction dma_direction; |
| 140 | 140 | |
| 141 | 141 | struct reset_control *rstc; |
| 142 | + int irq; | |
| 142 | 143 | }; |
| 143 | 144 | |
| 144 | 145 | #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) |
| @@ -861,9 +862,11 @@ static int rcar_unreg_slave(struct i2c_client *slave) · 716 unmodified lines | ||
| 861 | 862 | |
| 862 | 863 | WARN_ON(!priv->slave); |
| 863 | 864 | |
| 865 | + /* disable irqs and ensure none is running before clearing ptr */ | |
| 864 | 866 | rcar_i2c_write(priv, ICSIER, 0); |
| 865 | 867 | rcar_i2c_write(priv, ICSCR, 0); |
| 866 | 868 | |
| 869 | + synchronize_irq(priv->irq); | |
| 867 | 870 | priv->slave = NULL; |
| 868 | 871 | |
| 869 | 872 | pm_runtime_put(rcar_i2c_priv_to_dev(priv)); |
| @@ -918,7 +921,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) · 48 unmodified lines | ||
| 918 | 921 | struct i2c_adapter *adap; |
| 919 | 922 | struct device *dev = &pdev->dev; |
| 920 | 923 | struct i2c_timings i2c_t; |
| 921 | − int irq, ret; | |
| 924 | + int ret; | |
| 922 | 925 | |
| 923 | 926 | /* Otherwise logic will break because some bytes must always use PIO */ |
| 924 | 927 | BUILD_BUG_ON_MSG(RCAR_MIN_DMA_LEN < 3, "Invalid min DMA length"); |
| @@ -984,10 +987,10 @@ static int rcar_i2c_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 984 | 987 | pm_runtime_put(dev); |
| 985 | 988 | |
| 986 | 989 | |
| 987 | − irq = platform_get_irq(pdev, 0); | |
| 988 | − ret = devm_request_irq(dev, irq, rcar_i2c_irq, 0, dev_name(dev), priv); | |
| 990 | + priv->irq = platform_get_irq(pdev, 0); | |
| 991 | + ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0, dev_name(dev), priv); | |
| 989 | 992 | if (ret < 0) { |
| 990 | − dev_err(dev, "cannot get irq %d\n", irq); | |
| 993 | + dev_err(dev, "cannot get irq %d\n", priv->irq); | |
| 991 | 994 | goto out_pm_disable; |
| 992 | 995 | } |
| 993 | 996 | |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | /* |
| 3 | 3 | * i2c-stm32.h |
| 4 | 4 | * |
| @@ -319,7 +319,6 @@ static const struct iio_chan_spec_ext_info cros_ec_accel_legacy_ext_info[] = { · 318 unmodified lines | ||
| 319 | 319 | .modified = 1, \ |
| 320 | 320 | .info_mask_separate = \ |
| 321 | 321 | BIT(IIO_CHAN_INFO_RAW) | \ |
| 322 | − BIT(IIO_CHAN_INFO_SCALE) | \ | |
| 323 | 322 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ |
| 324 | 323 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ |
| 325 | 324 | .ext_info = cros_ec_accel_legacy_ext_info, \ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/iio/iio.h> |
| 12 | 12 | #include <linux/io.h> |
| 13 | 13 | #include <linux/iopoll.h> |
| 14 | +#include <linux/kernel.h> | |
| 14 | 15 | #include <linux/module.h> |
| 15 | 16 | #include <linux/mutex.h> |
| 16 | 17 | #include <linux/platform_device.h> |
| @@ -22,8 +23,11 @@ · 5 unmodified lines | ||
| 22 | 23 | #define JZ_ADC_REG_ADTCH 0x18 |
| 23 | 24 | #define JZ_ADC_REG_ADBDAT 0x1c |
| 24 | 25 | #define JZ_ADC_REG_ADSDAT 0x20 |
| 26 | +#define JZ_ADC_REG_ADCLK 0x28 | |
| 25 | 27 | |
| 26 | 28 | #define JZ_ADC_REG_CFG_BAT_MD BIT(4) |
| 29 | +#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0 | |
| 30 | +#define JZ_ADC_REG_ADCLK_CLKDIV10US_LSB 16 | |
| 27 | 31 | |
| 28 | 32 | #define JZ_ADC_AUX_VREF 3300 |
| 29 | 33 | #define JZ_ADC_AUX_VREF_BITS 12 |
| @@ -34,6 +38,8 @@ · 4 unmodified lines | ||
| 34 | 38 | #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986) |
| 35 | 39 | #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12 |
| 36 | 40 | |
| 41 | +struct ingenic_adc; | |
| 42 | + | |
| 37 | 43 | struct ingenic_adc_soc_data { |
| 38 | 44 | unsigned int battery_high_vref; |
| 39 | 45 | unsigned int battery_high_vref_bits; |
| @@ -41,6 +47,7 @@ struct ingenic_adc_soc_data { · 1 unmodified line | ||
| 41 | 47 | size_t battery_raw_avail_size; |
| 42 | 48 | const int *battery_scale_avail; |
| 43 | 49 | size_t battery_scale_avail_size; |
| 50 | + int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc); | |
| 44 | 51 | }; |
| 45 | 52 | |
| 46 | 53 | struct ingenic_adc { |
| @@ -151,6 +158,42 @@ static const int jz4740_adc_battery_scale_avail[] = { · 104 unmodified lines | ||
| 151 | 158 | JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS, |
| 152 | 159 | }; |
| 153 | 160 | |
| 161 | +static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc) | |
| 162 | +{ | |
| 163 | + struct clk *parent_clk; | |
| 164 | + unsigned long parent_rate, rate; | |
| 165 | + unsigned int div_main, div_10us; | |
| 166 | + | |
| 167 | + parent_clk = clk_get_parent(adc->clk); | |
| 168 | + if (!parent_clk) { | |
| 169 | + dev_err(dev, "ADC clock has no parent\n"); | |
| 170 | + return -ENODEV; | |
| 171 | + } | |
| 172 | + parent_rate = clk_get_rate(parent_clk); | |
| 173 | + | |
| 174 | + /* | |
| 175 | + * The JZ4725B ADC works at 500 kHz to 8 MHz. | |
| 176 | + * We pick the highest rate possible. | |
| 177 | + * In practice we typically get 6 MHz, half of the 12 MHz EXT clock. | |
| 178 | + */ | |
| 179 | + div_main = DIV_ROUND_UP(parent_rate, 8000000); | |
| 180 | + div_main = clamp(div_main, 1u, 64u); | |
| 181 | + rate = parent_rate / div_main; | |
| 182 | + if (rate < 500000 || rate > 8000000) { | |
| 183 | + dev_err(dev, "No valid divider for ADC main clock\n"); | |
| 184 | + return -EINVAL; | |
| 185 | + } | |
| 186 | + | |
| 187 | + /* We also need a divider that produces a 10us clock. */ | |
| 188 | + div_10us = DIV_ROUND_UP(rate, 100000); | |
| 189 | + | |
| 190 | + writel(((div_10us - 1) << JZ_ADC_REG_ADCLK_CLKDIV10US_LSB) | | |
| 191 | + (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB, | |
| 192 | + adc->base + JZ_ADC_REG_ADCLK); | |
| 193 | + | |
| 194 | + return 0; | |
| 195 | +} | |
| 196 | + | |
| 154 | 197 | static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = { |
| 155 | 198 | .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF, |
| 156 | 199 | .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS, |
| @@ -158,6 +201,7 @@ static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = { · 1 unmodified line | ||
| 158 | 201 | .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail), |
| 159 | 202 | .battery_scale_avail = jz4725b_adc_battery_scale_avail, |
| 160 | 203 | .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail), |
| 204 | + .init_clk_div = jz4725b_adc_init_clk_div, | |
| 161 | 205 | }; |
| 162 | 206 | |
| 163 | 207 | static const struct ingenic_adc_soc_data jz4740_adc_soc_data = { |
| @@ -167,6 +211,7 @@ static const struct ingenic_adc_soc_data jz4740_adc_soc_data = { · 3 unmodified lines | ||
| 167 | 211 | .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail), |
| 168 | 212 | .battery_scale_avail = jz4740_adc_battery_scale_avail, |
| 169 | 213 | .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail), |
| 214 | + .init_clk_div = NULL, /* no ADCLK register on JZ4740 */ | |
| 170 | 215 | }; |
| 171 | 216 | |
| 172 | 217 | static int ingenic_adc_read_avail(struct iio_dev *iio_dev, |
| @@ -317,6 +362,15 @@ static int ingenic_adc_probe(struct platform_device *pdev) · 144 unmodified lines | ||
| 317 | 362 | return ret; |
| 318 | 363 | } |
| 319 | 364 | |
| 365 | + /* Set clock dividers. */ | |
| 366 | + if (soc_data->init_clk_div) { | |
| 367 | + ret = soc_data->init_clk_div(dev, adc); | |
| 368 | + if (ret) { | |
| 369 | + clk_disable_unprepare(adc->clk); | |
| 370 | + return ret; | |
| 371 | + } | |
| 372 | + } | |
| 373 | + | |
| 320 | 374 | /* Put hardware in a known passive state. */ |
| 321 | 375 | writeb(0x00, adc->base + JZ_ADC_REG_ENABLE); |
| 322 | 376 | writeb(0xff, adc->base + JZ_ADC_REG_CTRL); |
| @@ -83,7 +83,7 @@ · 82 unmodified lines | ||
| 83 | 83 | #define MAX9611_TEMP_MAX_POS 0x7f80 |
| 84 | 84 | #define MAX9611_TEMP_MAX_NEG 0xff80 |
| 85 | 85 | #define MAX9611_TEMP_MIN_NEG 0xd980 |
| 86 | −#define MAX9611_TEMP_MASK GENMASK(7, 15) | |
| 86 | +#define MAX9611_TEMP_MASK GENMASK(15, 7) | |
| 87 | 87 | #define MAX9611_TEMP_SHIFT 0x07 |
| 88 | 88 | #define MAX9611_TEMP_RAW(_r) ((_r) >> MAX9611_TEMP_SHIFT) |
| 89 | 89 | #define MAX9611_TEMP_SCALE_NUM 1000000 |
| @@ -480,7 +480,7 @@ static int max9611_init(struct max9611_dev *max9611) · 390 unmodified lines | ||
| 480 | 480 | if (ret) |
| 481 | 481 | return ret; |
| 482 | 482 | |
| 483 | − regval = ret & MAX9611_TEMP_MASK; | |
| 483 | + regval &= MAX9611_TEMP_MASK; | |
| 484 | 484 | |
| 485 | 485 | if ((regval > MAX9611_TEMP_MAX_POS && |
| 486 | 486 | regval < MAX9611_TEMP_MIN_NEG) || |
| @@ -382,7 +382,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 381 unmodified lines | ||
| 382 | 382 | dev_err(dev, |
| 383 | 383 | "Only %i channels supported with %pOFn, but reg = <%i>.\n", |
| 384 | 384 | num_channels, child, reg); |
| 385 | − return ret; | |
| 385 | + return -EINVAL; | |
| 386 | 386 | } |
| 387 | 387 | } |
| 388 | 388 | |
| @@ -391,7 +391,7 @@ static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev) · 2 unmodified lines | ||
| 391 | 391 | dev_err(dev, |
| 392 | 392 | "Channel %i uses different ADC mode than the rest.\n", |
| 393 | 393 | reg); |
| 394 | − return ret; | |
| 394 | + return -EINVAL; | |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | 397 | /* Channel is valid, grab the regulator. */ |
| @@ -276,11 +276,11 @@ static int adf4371_set_freq(struct adf4371_state *st, unsigned long long freq, · 275 unmodified lines | ||
| 276 | 276 | st->buf[0] = st->integer >> 8; |
| 277 | 277 | st->buf[1] = 0x40; /* REG12 default */ |
| 278 | 278 | st->buf[2] = 0x00; |
| 279 | − st->buf[3] = st->fract2 & 0xFF; | |
| 280 | − st->buf[4] = st->fract2 >> 7; | |
| 281 | − st->buf[5] = st->fract2 >> 15; | |
| 279 | + st->buf[3] = st->fract1 & 0xFF; | |
| 280 | + st->buf[4] = st->fract1 >> 8; | |
| 281 | + st->buf[5] = st->fract1 >> 16; | |
| 282 | 282 | st->buf[6] = ADF4371_FRAC2WORD_L(st->fract2 & 0x7F) | |
| 283 | − ADF4371_FRAC1WORD(st->fract1 >> 23); | |
| 283 | + ADF4371_FRAC1WORD(st->fract1 >> 24); | |
| 284 | 284 | st->buf[7] = ADF4371_FRAC2WORD_H(st->fract2 >> 7); |
| 285 | 285 | st->buf[8] = st->mod2 & 0xFF; |
| 286 | 286 | st->buf[9] = ADF4371_MOD2WORD(st->mod2 >> 8); |
| @@ -845,6 +845,25 @@ static const struct iio_chan_spec inv_mpu_channels[] = { · 844 unmodified lines | ||
| 845 | 845 | INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z), |
| 846 | 846 | }; |
| 847 | 847 | |
| 848 | +static const unsigned long inv_mpu_scan_masks[] = { | |
| 849 | + /* 3-axis accel */ | |
| 850 | + BIT(INV_MPU6050_SCAN_ACCL_X) | |
| 851 | + | BIT(INV_MPU6050_SCAN_ACCL_Y) | |
| 852 | + | BIT(INV_MPU6050_SCAN_ACCL_Z), | |
| 853 | + /* 3-axis gyro */ | |
| 854 | + BIT(INV_MPU6050_SCAN_GYRO_X) | |
| 855 | + | BIT(INV_MPU6050_SCAN_GYRO_Y) | |
| 856 | + | BIT(INV_MPU6050_SCAN_GYRO_Z), | |
| 857 | + /* 6-axis accel + gyro */ | |
| 858 | + BIT(INV_MPU6050_SCAN_ACCL_X) | |
| 859 | + | BIT(INV_MPU6050_SCAN_ACCL_Y) | |
| 860 | + | BIT(INV_MPU6050_SCAN_ACCL_Z) | |
| 861 | + | BIT(INV_MPU6050_SCAN_GYRO_X) | |
| 862 | + | BIT(INV_MPU6050_SCAN_GYRO_Y) | |
| 863 | + | BIT(INV_MPU6050_SCAN_GYRO_Z), | |
| 864 | + 0, | |
| 865 | +}; | |
| 866 | + | |
| 848 | 867 | static const struct iio_chan_spec inv_icm20602_channels[] = { |
| 849 | 868 | IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP), |
| 850 | 869 | { |
| @@ -871,6 +890,28 @@ static const struct iio_chan_spec inv_icm20602_channels[] = { · 20 unmodified lines | ||
| 871 | 890 | INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z), |
| 872 | 891 | }; |
| 873 | 892 | |
| 893 | +static const unsigned long inv_icm20602_scan_masks[] = { | |
| 894 | + /* 3-axis accel + temp (mandatory) */ | |
| 895 | + BIT(INV_ICM20602_SCAN_ACCL_X) | |
| 896 | + | BIT(INV_ICM20602_SCAN_ACCL_Y) | |
| 897 | + | BIT(INV_ICM20602_SCAN_ACCL_Z) | |
| 898 | + | BIT(INV_ICM20602_SCAN_TEMP), | |
| 899 | + /* 3-axis gyro + temp (mandatory) */ | |
| 900 | + BIT(INV_ICM20602_SCAN_GYRO_X) | |
| 901 | + | BIT(INV_ICM20602_SCAN_GYRO_Y) | |
| 902 | + | BIT(INV_ICM20602_SCAN_GYRO_Z) | |
| 903 | + | BIT(INV_ICM20602_SCAN_TEMP), | |
| 904 | + /* 6-axis accel + gyro + temp (mandatory) */ | |
| 905 | + BIT(INV_ICM20602_SCAN_ACCL_X) | |
| 906 | + | BIT(INV_ICM20602_SCAN_ACCL_Y) | |
| 907 | + | BIT(INV_ICM20602_SCAN_ACCL_Z) | |
| 908 | + | BIT(INV_ICM20602_SCAN_GYRO_X) | |
| 909 | + | BIT(INV_ICM20602_SCAN_GYRO_Y) | |
| 910 | + | BIT(INV_ICM20602_SCAN_GYRO_Z) | |
| 911 | + | BIT(INV_ICM20602_SCAN_TEMP), | |
| 912 | + 0, | |
| 913 | +}; | |
| 914 | + | |
| 874 | 915 | /* |
| 875 | 916 | * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and |
| 876 | 917 | * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the |
| @@ -1130,9 +1171,11 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, · 253 unmodified lines | ||
| 1130 | 1171 | if (chip_type == INV_ICM20602) { |
| 1131 | 1172 | indio_dev->channels = inv_icm20602_channels; |
| 1132 | 1173 | indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels); |
| 1174 | + indio_dev->available_scan_masks = inv_icm20602_scan_masks; | |
| 1133 | 1175 | } else { |
| 1134 | 1176 | indio_dev->channels = inv_mpu_channels; |
| 1135 | 1177 | indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); |
| 1178 | + indio_dev->available_scan_masks = inv_mpu_scan_masks; | |
| 1136 | 1179 | } |
| 1137 | 1180 | |
| 1138 | 1181 | indio_dev->info = &mpu_info; |
| @@ -38,6 +38,9 @@ int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, · 37 unmodified lines | ||
| 38 | 38 | int ret; |
| 39 | 39 | |
| 40 | 40 | port_counter = &dev->port_data[port].port_counter; |
| 41 | + if (!port_counter->hstats) | |
| 42 | + return -EOPNOTSUPP; | |
| 43 | + | |
| 41 | 44 | mutex_lock(&port_counter->lock); |
| 42 | 45 | if (on) { |
| 43 | 46 | ret = __counter_set_mode(&port_counter->mode, |
| @@ -509,6 +512,9 @@ int rdma_counter_bind_qpn_alloc(struct ib_device *dev, u8 port, · 465 unmodified lines | ||
| 509 | 512 | if (!rdma_is_port_valid(dev, port)) |
| 510 | 513 | return -EINVAL; |
| 511 | 514 | |
| 515 | + if (!dev->port_data[port].port_counter.hstats) | |
| 516 | + return -EOPNOTSUPP; | |
| 517 | + | |
| 512 | 518 | qp = rdma_counter_get_qp(dev, qp_num); |
| 513 | 519 | if (!qp) |
| 514 | 520 | return -ENOENT; |
| @@ -1952,12 +1952,16 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh, · 1951 unmodified lines | ||
| 1952 | 1952 | |
| 1953 | 1953 | if (fill_nldev_handle(msg, device) || |
| 1954 | 1954 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port) || |
| 1955 | − nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_MODE, mode)) | |
| 1955 | + nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_MODE, mode)) { | |
| 1956 | + ret = -EMSGSIZE; | |
| 1956 | 1957 | goto err_msg; |
| 1958 | + } | |
| 1957 | 1959 | |
| 1958 | 1960 | if ((mode == RDMA_COUNTER_MODE_AUTO) && |
| 1959 | − nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK, mask)) | |
| 1961 | + nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK, mask)) { | |
| 1962 | + ret = -EMSGSIZE; | |
| 1960 | 1963 | goto err_msg; |
| 1964 | + } | |
| 1961 | 1965 | |
| 1962 | 1966 | nlmsg_end(msg, nlh); |
| 1963 | 1967 | ib_device_put(device); |
| @@ -112,10 +112,6 @@ static int ib_umem_notifier_release_trampoline(struct ib_umem_odp *umem_odp, · 111 unmodified lines | ||
| 112 | 112 | * prevent any further fault handling on this MR. |
| 113 | 113 | */ |
| 114 | 114 | ib_umem_notifier_start_account(umem_odp); |
| 115 | − umem_odp->dying = 1; | |
| 116 | − /* Make sure that the fact the umem is dying is out before we release | |
| 117 | − * all pending page faults. */ | |
| 118 | − smp_wmb(); | |
| 119 | 115 | complete_all(&umem_odp->notifier_completion); |
| 120 | 116 | umem_odp->umem.context->invalidate_range( |
| 121 | 117 | umem_odp, ib_umem_start(umem_odp), ib_umem_end(umem_odp)); |
| @@ -2026,7 +2026,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_SUBSCRIBE_EVENT)( · 2025 unmodified lines | ||
| 2026 | 2026 | event_sub->eventfd = |
| 2027 | 2027 | eventfd_ctx_fdget(redirect_fd); |
| 2028 | 2028 | |
| 2029 | − if (IS_ERR(event_sub)) { | |
| 2029 | + if (IS_ERR(event_sub->eventfd)) { | |
| 2030 | 2030 | err = PTR_ERR(event_sub->eventfd); |
| 2031 | 2031 | event_sub->eventfd = NULL; |
| 2032 | 2032 | goto err; |
| @@ -2644,12 +2644,13 @@ static int devx_async_event_close(struct inode *inode, struct file *filp) · 611 unmodified lines | ||
| 2644 | 2644 | struct devx_async_event_file *ev_file = filp->private_data; |
| 2645 | 2645 | struct devx_event_subscription *event_sub, *event_sub_tmp; |
| 2646 | 2646 | struct devx_async_event_data *entry, *tmp; |
| 2647 | + struct mlx5_ib_dev *dev = ev_file->dev; | |
| 2647 | 2648 | |
| 2648 | − mutex_lock(&ev_file->dev->devx_event_table.event_xa_lock); | |
| 2649 | + mutex_lock(&dev->devx_event_table.event_xa_lock); | |
| 2649 | 2650 | /* delete the subscriptions which are related to this FD */ |
| 2650 | 2651 | list_for_each_entry_safe(event_sub, event_sub_tmp, |
| 2651 | 2652 | &ev_file->subscribed_events_list, file_list) { |
| 2652 | − devx_cleanup_subscription(ev_file->dev, event_sub); | |
| 2653 | + devx_cleanup_subscription(dev, event_sub); | |
| 2653 | 2654 | if (event_sub->eventfd) |
| 2654 | 2655 | eventfd_ctx_put(event_sub->eventfd); |
| 2655 | 2656 | |
| @@ -2658,7 +2659,7 @@ static int devx_async_event_close(struct inode *inode, struct file *filp) · 2 unmodified lines | ||
| 2658 | 2659 | kfree_rcu(event_sub, rcu); |
| 2659 | 2660 | } |
| 2660 | 2661 | |
| 2661 | − mutex_unlock(&ev_file->dev->devx_event_table.event_xa_lock); | |
| 2662 | + mutex_unlock(&dev->devx_event_table.event_xa_lock); | |
| 2662 | 2663 | |
| 2663 | 2664 | /* free the pending events allocation */ |
| 2664 | 2665 | if (!ev_file->omit_data) { |
| @@ -2670,7 +2671,7 @@ static int devx_async_event_close(struct inode *inode, struct file *filp) · 5 unmodified lines | ||
| 2670 | 2671 | } |
| 2671 | 2672 | |
| 2672 | 2673 | uverbs_close_fd(filp); |
| 2673 | − put_device(&ev_file->dev->ib_dev.dev); | |
| 2674 | + put_device(&dev->ib_dev.dev); | |
| 2674 | 2675 | return 0; |
| 2675 | 2676 | } |
| 2676 | 2677 | |
| @@ -579,7 +579,6 @@ static int pagefault_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, · 578 unmodified lines | ||
| 579 | 579 | u32 flags) |
| 580 | 580 | { |
| 581 | 581 | int npages = 0, current_seq, page_shift, ret, np; |
| 582 | − bool implicit = false; | |
| 583 | 582 | struct ib_umem_odp *odp_mr = to_ib_umem_odp(mr->umem); |
| 584 | 583 | bool downgrade = flags & MLX5_PF_FLAGS_DOWNGRADE; |
| 585 | 584 | bool prefetch = flags & MLX5_PF_FLAGS_PREFETCH; |
| @@ -594,7 +593,6 @@ static int pagefault_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, · 8 unmodified lines | ||
| 594 | 593 | if (IS_ERR(odp)) |
| 595 | 594 | return PTR_ERR(odp); |
| 596 | 595 | mr = odp->private; |
| 597 | − implicit = true; | |
| 598 | 596 | } else { |
| 599 | 597 | odp = odp_mr; |
| 600 | 598 | } |
| @@ -682,19 +680,15 @@ next_mr: · 81 unmodified lines | ||
| 682 | 680 | |
| 683 | 681 | out: |
| 684 | 682 | if (ret == -EAGAIN) { |
| 685 | − if (implicit || !odp->dying) { | |
| 686 | − unsigned long timeout = | |
| 687 | − msecs_to_jiffies(MMU_NOTIFIER_TIMEOUT); | |
| 688 | − | |
| 689 | − if (!wait_for_completion_timeout( | |
| 690 | − &odp->notifier_completion, | |
| 691 | − timeout)) { | |
| 692 | − mlx5_ib_warn(dev, "timeout waiting for mmu notifier. seq %d against %d. notifiers_count=%d\n", | |
| 693 | − current_seq, odp->notifiers_seq, odp->notifiers_count); | |
| 694 | − } | |
| 695 | − } else { | |
| 696 | − /* The MR is being killed, kill the QP as well. */ | |
| 697 | − ret = -EFAULT; | |
| 683 | + unsigned long timeout = msecs_to_jiffies(MMU_NOTIFIER_TIMEOUT); | |
| 684 | + | |
| 685 | + if (!wait_for_completion_timeout(&odp->notifier_completion, | |
| 686 | + timeout)) { | |
| 687 | + mlx5_ib_warn( | |
| 688 | + dev, | |
| 689 | + "timeout waiting for mmu notifier. seq %d against %d. notifiers_count=%d\n", | |
| 690 | + current_seq, odp->notifiers_seq, | |
| 691 | + odp->notifiers_count); | |
| 698 | 692 | } |
| 699 | 693 | } |
| 700 | 694 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config RDMA_SIW |
| 2 | 2 | tristate "Software RDMA over TCP/IP (iWARP) driver" |
| 3 | − depends on INET && INFINIBAND && LIBCRC32C && 64BIT | |
| 3 | + depends on INET && INFINIBAND && LIBCRC32C | |
| 4 | 4 | select DMA_VIRT_OPS |
| 5 | 5 | help |
| 6 | 6 | This driver implements the iWARP RDMA transport over |
| @@ -214,7 +214,7 @@ struct siw_wqe { · 213 unmodified lines | ||
| 214 | 214 | struct siw_cq { |
| 215 | 215 | struct ib_cq base_cq; |
| 216 | 216 | spinlock_t lock; |
| 217 | − u64 *notify; | |
| 217 | + struct siw_cq_ctrl *notify; | |
| 218 | 218 | struct siw_cqe *queue; |
| 219 | 219 | u32 cq_put; |
| 220 | 220 | u32 cq_get; |
| @@ -160,10 +160,8 @@ static int siw_init_cpulist(void) · 159 unmodified lines | ||
| 160 | 160 | |
| 161 | 161 | out_err: |
| 162 | 162 | siw_cpu_info.num_nodes = 0; |
| 163 | − while (i) { | |
| 163 | + while (--i >= 0) | |
| 164 | 164 | kfree(siw_cpu_info.tx_valid_cpus[i]); |
| 165 | − siw_cpu_info.tx_valid_cpus[i--] = NULL; | |
| 166 | − } | |
| 167 | 165 | kfree(siw_cpu_info.tx_valid_cpus); |
| 168 | 166 | siw_cpu_info.tx_valid_cpus = NULL; |
| 169 | 167 | |
| @@ -1013,18 +1013,24 @@ out: · 1012 unmodified lines | ||
| 1013 | 1013 | */ |
| 1014 | 1014 | static bool siw_cq_notify_now(struct siw_cq *cq, u32 flags) |
| 1015 | 1015 | { |
| 1016 | − u64 cq_notify; | |
| 1016 | + u32 cq_notify; | |
| 1017 | 1017 | |
| 1018 | 1018 | if (!cq->base_cq.comp_handler) |
| 1019 | 1019 | return false; |
| 1020 | 1020 | |
| 1021 | − cq_notify = READ_ONCE(*cq->notify); | |
| 1021 | + /* Read application shared notification state */ | |
| 1022 | + cq_notify = READ_ONCE(cq->notify->flags); | |
| 1022 | 1023 | |
| 1023 | 1024 | if ((cq_notify & SIW_NOTIFY_NEXT_COMPLETION) || |
| 1024 | 1025 | ((cq_notify & SIW_NOTIFY_SOLICITED) && |
| 1025 | 1026 | (flags & SIW_WQE_SOLICITED))) { |
| 1026 | − /* dis-arm CQ */ | |
| 1027 | − smp_store_mb(*cq->notify, SIW_NOTIFY_NOT); | |
| 1027 | + /* | |
| 1028 | + * CQ notification is one-shot: Since the | |
| 1029 | + * current CQE causes user notification, | |
| 1030 | + * the CQ gets dis-aremd and must be re-aremd | |
| 1031 | + * by the user for a new notification. | |
| 1032 | + */ | |
| 1033 | + WRITE_ONCE(cq->notify->flags, SIW_NOTIFY_NOT); | |
| 1028 | 1034 | |
| 1029 | 1035 | return true; |
| 1030 | 1036 | } |
| @@ -1049,7 +1049,7 @@ int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr, · 1048 unmodified lines | ||
| 1049 | 1049 | |
| 1050 | 1050 | spin_lock_init(&cq->lock); |
| 1051 | 1051 | |
| 1052 | − cq->notify = &((struct siw_cq_ctrl *)&cq->queue[size])->notify; | |
| 1052 | + cq->notify = (struct siw_cq_ctrl *)&cq->queue[size]; | |
| 1053 | 1053 | |
| 1054 | 1054 | if (udata) { |
| 1055 | 1055 | struct siw_uresp_create_cq uresp = {}; |
| @@ -1141,11 +1141,17 @@ int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags) · 85 unmodified lines | ||
| 1141 | 1141 | siw_dbg_cq(cq, "flags: 0x%02x\n", flags); |
| 1142 | 1142 | |
| 1143 | 1143 | if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) |
| 1144 | − /* CQ event for next solicited completion */ | |
| 1145 | − smp_store_mb(*cq->notify, SIW_NOTIFY_SOLICITED); | |
| 1144 | + /* | |
| 1145 | + * Enable CQ event for next solicited completion. | |
| 1146 | + * and make it visible to all associated producers. | |
| 1147 | + */ | |
| 1148 | + smp_store_mb(cq->notify->flags, SIW_NOTIFY_SOLICITED); | |
| 1146 | 1149 | else |
| 1147 | − /* CQ event for any signalled completion */ | |
| 1148 | − smp_store_mb(*cq->notify, SIW_NOTIFY_ALL); | |
| 1150 | + /* | |
| 1151 | + * Enable CQ event for any signalled completion. | |
| 1152 | + * and make it visible to all associated producers. | |
| 1153 | + */ | |
| 1154 | + smp_store_mb(cq->notify->flags, SIW_NOTIFY_ALL); | |
| 1149 | 1155 | |
| 1150 | 1156 | if (flags & IB_CQ_REPORT_MISSED_EVENTS) |
| 1151 | 1157 | return cq->cq_put - cq->cq_get; |
| @@ -201,7 +201,12 @@ static int iforce_usb_probe(struct usb_interface *intf, · 200 unmodified lines | ||
| 201 | 201 | return -ENODEV; |
| 202 | 202 | |
| 203 | 203 | epirq = &interface->endpoint[0].desc; |
| 204 | + if (!usb_endpoint_is_int_in(epirq)) | |
| 205 | + return -ENODEV; | |
| 206 | + | |
| 204 | 207 | epout = &interface->endpoint[1].desc; |
| 208 | + if (!usb_endpoint_is_int_out(epout)) | |
| 209 | + return -ENODEV; | |
| 205 | 210 | |
| 206 | 211 | iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL); |
| 207 | 212 | if (!iforce_usb) |
| @@ -76,6 +76,8 @@ config KEYBOARD_APPLESPI · 75 unmodified lines | ||
| 76 | 76 | depends on ACPI && EFI |
| 77 | 77 | depends on SPI |
| 78 | 78 | depends on X86 || COMPILE_TEST |
| 79 | + depends on LEDS_CLASS | |
| 80 | + select CRC16 | |
| 79 | 81 | help |
| 80 | 82 | Say Y here if you are running Linux on any Apple MacBook8,1 or later, |
| 81 | 83 | or any MacBookPro13,* or MacBookPro14,*. |
| @@ -134,10 +134,10 @@ struct keyboard_protocol { · 133 unmodified lines | ||
| 134 | 134 | * struct tp_finger - single trackpad finger structure, le16-aligned |
| 135 | 135 | * |
| 136 | 136 | * @origin: zero when switching track finger |
| 137 | − * @abs_x: absolute x coodinate | |
| 138 | − * @abs_y: absolute y coodinate | |
| 139 | − * @rel_x: relative x coodinate | |
| 140 | − * @rel_y: relative y coodinate | |
| 137 | + * @abs_x: absolute x coordinate | |
| 138 | + * @abs_y: absolute y coordinate | |
| 139 | + * @rel_x: relative x coordinate | |
| 140 | + * @rel_y: relative y coordinate | |
| 141 | 141 | * @tool_major: tool area, major axis |
| 142 | 142 | * @tool_minor: tool area, minor axis |
| 143 | 143 | * @orientation: 16384 when point, else 15 bit angle |
| @@ -944,10 +944,14 @@ static inline int le16_to_int(__le16 x) · 800 unmodified lines | ||
| 944 | 944 | static void applespi_debug_update_dimensions(struct applespi_data *applespi, |
| 945 | 945 | const struct tp_finger *f) |
| 946 | 946 | { |
| 947 | − applespi->tp_dim_min_x = min_t(int, applespi->tp_dim_min_x, f->abs_x); | |
| 948 | − applespi->tp_dim_max_x = max_t(int, applespi->tp_dim_max_x, f->abs_x); | |
| 949 | − applespi->tp_dim_min_y = min_t(int, applespi->tp_dim_min_y, f->abs_y); | |
| 950 | − applespi->tp_dim_max_y = max_t(int, applespi->tp_dim_max_y, f->abs_y); | |
| 947 | + applespi->tp_dim_min_x = min(applespi->tp_dim_min_x, | |
| 948 | + le16_to_int(f->abs_x)); | |
| 949 | + applespi->tp_dim_max_x = max(applespi->tp_dim_max_x, | |
| 950 | + le16_to_int(f->abs_x)); | |
| 951 | + applespi->tp_dim_min_y = min(applespi->tp_dim_min_y, | |
| 952 | + le16_to_int(f->abs_y)); | |
| 953 | + applespi->tp_dim_max_y = max(applespi->tp_dim_max_y, | |
| 954 | + le16_to_int(f->abs_y)); | |
| 951 | 955 | } |
| 952 | 956 | |
| 953 | 957 | static int applespi_tp_dim_open(struct inode *inode, struct file *file) |
| @@ -1490,8 +1494,7 @@ static void applespi_got_data(struct applespi_data *applespi) · 536 unmodified lines | ||
| 1490 | 1494 | size_t tp_len; |
| 1491 | 1495 | |
| 1492 | 1496 | tp = &message->touchpad; |
| 1493 | − tp_len = sizeof(*tp) + | |
| 1494 | − tp->number_of_fingers * sizeof(tp->fingers[0]); | |
| 1497 | + tp_len = struct_size(tp, fingers, tp->number_of_fingers); | |
| 1495 | 1498 | |
| 1496 | 1499 | if (le16_to_cpu(message->length) + 2 != tp_len) { |
| 1497 | 1500 | dev_warn_ratelimited(&applespi->spi->dev, |
| @@ -1611,8 +1614,8 @@ static void applespi_save_bl_level(struct applespi_data *applespi, · 113 unmodified lines | ||
| 1611 | 1614 | efi_attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | |
| 1612 | 1615 | EFI_VARIABLE_RUNTIME_ACCESS; |
| 1613 | 1616 | |
| 1614 | − sts = efivar_entry_set_safe(EFI_BL_LEVEL_NAME, efi_guid, efi_attr, true, | |
| 1615 | − efi_data_len, &efi_data); | |
| 1617 | + sts = efivar_entry_set_safe((efi_char16_t *)EFI_BL_LEVEL_NAME, efi_guid, | |
| 1618 | + efi_attr, true, efi_data_len, &efi_data); | |
| 1616 | 1619 | if (sts) |
| 1617 | 1620 | dev_warn(&applespi->spi->dev, |
| 1618 | 1621 | "Error saving backlight level to EFI vars: %d\n", sts); |
| @@ -1953,7 +1956,7 @@ static const struct acpi_device_id applespi_acpi_match[] = { · 334 unmodified lines | ||
| 1953 | 1956 | }; |
| 1954 | 1957 | MODULE_DEVICE_TABLE(acpi, applespi_acpi_match); |
| 1955 | 1958 | |
| 1956 | −const struct dev_pm_ops applespi_pm_ops = { | |
| 1959 | +static const struct dev_pm_ops applespi_pm_ops = { | |
| 1957 | 1960 | SET_SYSTEM_SLEEP_PM_OPS(applespi_suspend, applespi_resume) |
| 1958 | 1961 | .poweroff_late = applespi_poweroff_late, |
| 1959 | 1962 | }; |
| @@ -1827,6 +1827,31 @@ static int elantech_create_smbus(struct psmouse *psmouse, · 1826 unmodified lines | ||
| 1827 | 1827 | leave_breadcrumbs); |
| 1828 | 1828 | } |
| 1829 | 1829 | |
| 1830 | +static bool elantech_use_host_notify(struct psmouse *psmouse, | |
| 1831 | + struct elantech_device_info *info) | |
| 1832 | +{ | |
| 1833 | + if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | |
| 1834 | + return true; | |
| 1835 | + | |
| 1836 | + switch (info->bus) { | |
| 1837 | + case ETP_BUS_PS2_ONLY: | |
| 1838 | + /* expected case */ | |
| 1839 | + break; | |
| 1840 | + case ETP_BUS_SMB_HST_NTFY_ONLY: | |
| 1841 | + case ETP_BUS_PS2_SMB_HST_NTFY: | |
| 1842 | + /* SMbus implementation is stable since 2018 */ | |
| 1843 | + if (dmi_get_bios_year() >= 2018) | |
| 1844 | + return true; | |
| 1845 | + /* fall through */ | |
| 1846 | + default: | |
| 1847 | + psmouse_dbg(psmouse, | |
| 1848 | + "Ignoring SMBus bus provider %d\n", info->bus); | |
| 1849 | + break; | |
| 1850 | + } | |
| 1851 | + | |
| 1852 | + return false; | |
| 1853 | +} | |
| 1854 | + | |
| 1830 | 1855 | /** |
| 1831 | 1856 | * elantech_setup_smbus - called once the PS/2 devices are enumerated |
| 1832 | 1857 | * and decides to instantiate a SMBus InterTouch device. |
| @@ -1846,7 +1871,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse, · 13 unmodified lines | ||
| 1846 | 1871 | * i2c_blacklist_pnp_ids. |
| 1847 | 1872 | * Old ICs are up to the user to decide. |
| 1848 | 1873 | */ |
| 1849 | − if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) || | |
| 1874 | + if (!elantech_use_host_notify(psmouse, info) || | |
| 1850 | 1875 | psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids)) |
| 1851 | 1876 | return -ENXIO; |
| 1852 | 1877 | } |
| @@ -1866,34 +1891,6 @@ static int elantech_setup_smbus(struct psmouse *psmouse, · 13 unmodified lines | ||
| 1866 | 1891 | return 0; |
| 1867 | 1892 | } |
| 1868 | 1893 | |
| 1869 | −static bool elantech_use_host_notify(struct psmouse *psmouse, | |
| 1870 | − struct elantech_device_info *info) | |
| 1871 | −{ | |
| 1872 | − if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | |
| 1873 | − return true; | |
| 1874 | − | |
| 1875 | − switch (info->bus) { | |
| 1876 | − case ETP_BUS_PS2_ONLY: | |
| 1877 | − /* expected case */ | |
| 1878 | − break; | |
| 1879 | − case ETP_BUS_SMB_ALERT_ONLY: | |
| 1880 | − /* fall-through */ | |
| 1881 | − case ETP_BUS_PS2_SMB_ALERT: | |
| 1882 | − psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n"); | |
| 1883 | − break; | |
| 1884 | − case ETP_BUS_SMB_HST_NTFY_ONLY: | |
| 1885 | − /* fall-through */ | |
| 1886 | − case ETP_BUS_PS2_SMB_HST_NTFY: | |
| 1887 | − return true; | |
| 1888 | − default: | |
| 1889 | − psmouse_dbg(psmouse, | |
| 1890 | − "Ignoring SMBus bus provider %d.\n", | |
| 1891 | − info->bus); | |
| 1892 | − } | |
| 1893 | − | |
| 1894 | − return false; | |
| 1895 | −} | |
| 1896 | − | |
| 1897 | 1894 | int elantech_init_smbus(struct psmouse *psmouse) |
| 1898 | 1895 | { |
| 1899 | 1896 | struct elantech_device_info info; |
| @@ -182,6 +182,7 @@ static const char * const smbus_pnp_ids[] = { · 181 unmodified lines | ||
| 182 | 182 | "LEN2055", /* E580 */ |
| 183 | 183 | "SYN3052", /* HP EliteBook 840 G4 */ |
| 184 | 184 | "SYN3221", /* HP 15-ay000 */ |
| 185 | + "SYN323d", /* HP Spectre X360 13-w013dx */ | |
| 185 | 186 | NULL |
| 186 | 187 | }; |
| 187 | 188 | |
| @@ -117,6 +117,10 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i · 116 unmodified lines | ||
| 117 | 117 | if (intf->cur_altsetting->desc.bNumEndpoints < 1) |
| 118 | 118 | return -ENODEV; |
| 119 | 119 | |
| 120 | + endpoint = &intf->cur_altsetting->endpoint[0].desc; | |
| 121 | + if (!usb_endpoint_is_int_in(endpoint)) | |
| 122 | + return -ENODEV; | |
| 123 | + | |
| 120 | 124 | kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); |
| 121 | 125 | input_dev = input_allocate_device(); |
| 122 | 126 | if (!kbtab || !input_dev) |
| @@ -155,8 +159,6 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i · 32 unmodified lines | ||
| 155 | 159 | input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0); |
| 156 | 160 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); |
| 157 | 161 | |
| 158 | − endpoint = &intf->cur_altsetting->endpoint[0].desc; | |
| 159 | − | |
| 160 | 162 | usb_fill_int_urb(kbtab->irq, dev, |
| 161 | 163 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
| 162 | 164 | kbtab->data, 8, |
| @@ -1659,6 +1659,8 @@ static int usbtouch_probe(struct usb_interface *intf, · 1658 unmodified lines | ||
| 1659 | 1659 | if (!usbtouch || !input_dev) |
| 1660 | 1660 | goto out_free; |
| 1661 | 1661 | |
| 1662 | + mutex_init(&usbtouch->pm_mutex); | |
| 1663 | + | |
| 1662 | 1664 | type = &usbtouch_dev_info[id->driver_info]; |
| 1663 | 1665 | usbtouch->type = type; |
| 1664 | 1666 | if (!type->process_pkt) |
| @@ -1186,8 +1186,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid, · 1185 unmodified lines | ||
| 1186 | 1186 | ste_live = true; |
| 1187 | 1187 | break; |
| 1188 | 1188 | case STRTAB_STE_0_CFG_ABORT: |
| 1189 | − if (disable_bypass) | |
| 1190 | − break; | |
| 1189 | + BUG_ON(!disable_bypass); | |
| 1190 | + break; | |
| 1191 | 1191 | default: |
| 1192 | 1192 | BUG(); /* STE corruption */ |
| 1193 | 1193 | } |
| @@ -459,13 +459,11 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys, · 458 unmodified lines | ||
| 459 | 459 | { |
| 460 | 460 | struct iommu_domain *domain = iommu_get_dma_domain(dev); |
| 461 | 461 | struct iommu_dma_cookie *cookie = domain->iova_cookie; |
| 462 | − size_t iova_off = 0; | |
| 462 | + struct iova_domain *iovad = &cookie->iovad; | |
| 463 | + size_t iova_off = iova_offset(iovad, phys); | |
| 463 | 464 | dma_addr_t iova; |
| 464 | 465 | |
| 465 | − if (cookie->type == IOMMU_DMA_IOVA_COOKIE) { | |
| 466 | − iova_off = iova_offset(&cookie->iovad, phys); | |
| 467 | − size = iova_align(&cookie->iovad, size + iova_off); | |
| 468 | − } | |
| 466 | + size = iova_align(iovad, size + iova_off); | |
| 469 | 467 | |
| 470 | 468 | iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); |
| 471 | 469 | if (!iova) |
| @@ -574,7 +572,7 @@ static void *iommu_dma_alloc_remap(struct device *dev, size_t size, · 102 unmodified lines | ||
| 574 | 572 | struct iova_domain *iovad = &cookie->iovad; |
| 575 | 573 | bool coherent = dev_is_dma_coherent(dev); |
| 576 | 574 | int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs); |
| 577 | − pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs); | |
| 575 | + pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs); | |
| 578 | 576 | unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; |
| 579 | 577 | struct page **pages; |
| 580 | 578 | struct sg_table sgt; |
| @@ -764,7 +762,7 @@ static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents, · 183 unmodified lines | ||
| 764 | 762 | * - and wouldn't make the resulting output segment too long |
| 765 | 763 | */ |
| 766 | 764 | if (cur_len && !s_iova_off && (dma_addr & seg_mask) && |
| 767 | − (cur_len + s_length <= max_len)) { | |
| 765 | + (max_len - cur_len >= s_length)) { | |
| 768 | 766 | /* ...then concatenate it with the previous one */ |
| 769 | 767 | cur_len += s_length; |
| 770 | 768 | } else { |
| @@ -975,7 +973,7 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size, · 204 unmodified lines | ||
| 975 | 973 | return NULL; |
| 976 | 974 | |
| 977 | 975 | if (IS_ENABLED(CONFIG_DMA_REMAP) && (!coherent || PageHighMem(page))) { |
| 978 | − pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs); | |
| 976 | + pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs); | |
| 979 | 977 | |
| 980 | 978 | cpu_addr = dma_common_contiguous_remap(page, alloc_size, |
| 981 | 979 | VM_USERMAP, prot, __builtin_return_address(0)); |
| @@ -1035,7 +1033,7 @@ static int iommu_dma_mmap(struct device *dev, struct vm_area_struct *vma, · 53 unmodified lines | ||
| 1035 | 1033 | unsigned long pfn, off = vma->vm_pgoff; |
| 1036 | 1034 | int ret; |
| 1037 | 1035 | |
| 1038 | − vma->vm_page_prot = arch_dma_mmap_pgprot(dev, vma->vm_page_prot, attrs); | |
| 1036 | + vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs); | |
| 1039 | 1037 | |
| 1040 | 1038 | if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) |
| 1041 | 1039 | return ret; |
| @@ -1147,16 +1145,21 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, · 105 unmodified lines | ||
| 1147 | 1145 | if (!msi_page) |
| 1148 | 1146 | return NULL; |
| 1149 | 1147 | |
| 1150 | − iova = __iommu_dma_map(dev, msi_addr, size, prot); | |
| 1151 | − if (iova == DMA_MAPPING_ERROR) | |
| 1148 | + iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); | |
| 1149 | + if (!iova) | |
| 1152 | 1150 | goto out_free_page; |
| 1153 | 1151 | |
| 1152 | + if (iommu_map(domain, iova, msi_addr, size, prot)) | |
| 1153 | + goto out_free_iova; | |
| 1154 | + | |
| 1154 | 1155 | INIT_LIST_HEAD(&msi_page->list); |
| 1155 | 1156 | msi_page->phys = msi_addr; |
| 1156 | 1157 | msi_page->iova = iova; |
| 1157 | 1158 | list_add(&msi_page->list, &cookie->msi_page_list); |
| 1158 | 1159 | return msi_page; |
| 1159 | 1160 | |
| 1161 | +out_free_iova: | |
| 1162 | + iommu_dma_free_iova(cookie, iova, size); | |
| 1160 | 1163 | out_free_page: |
| 1161 | 1164 | kfree(msi_page); |
| 1162 | 1165 | return NULL; |
| @@ -235,7 +235,7 @@ static void ctx_tbl_walk(struct seq_file *m, struct intel_iommu *iommu, u16 bus) · 234 unmodified lines | ||
| 235 | 235 | tbl_wlk.ctx_entry = context; |
| 236 | 236 | m->private = &tbl_wlk; |
| 237 | 237 | |
| 238 | − if (pasid_supported(iommu) && is_pasid_enabled(context)) { | |
| 238 | + if (dmar_readq(iommu->reg + DMAR_RTADDR_REG) & DMA_RTADDR_SMT) { | |
| 239 | 239 | pasid_dir_ptr = context->lo & VTD_PAGE_MASK; |
| 240 | 240 | pasid_dir_size = get_pasid_dir_size(context); |
| 241 | 241 | pasid_dir_walk(m, pasid_dir_ptr, pasid_dir_size); |
| @@ -3449,6 +3449,7 @@ static bool iommu_need_mapping(struct device *dev) · 3448 unmodified lines | ||
| 3449 | 3449 | dmar_domain = to_dmar_domain(domain); |
| 3450 | 3450 | dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN; |
| 3451 | 3451 | } |
| 3452 | + dmar_remove_one_dev_info(dev); | |
| 3452 | 3453 | get_private_domain_for_dev(dev); |
| 3453 | 3454 | } |
| 3454 | 3455 | |
| @@ -4790,7 +4791,8 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info) · 1335 unmodified lines | ||
| 4790 | 4791 | |
| 4791 | 4792 | /* free the private domain */ |
| 4792 | 4793 | if (domain->flags & DOMAIN_FLAG_LOSE_CHILDREN && |
| 4793 | − !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) | |
| 4794 | + !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && | |
| 4795 | + list_empty(&domain->devices)) | |
| 4794 | 4796 | domain_exit(info->domain); |
| 4795 | 4797 | |
| 4796 | 4798 | free_devinfo_mem(info); |
| @@ -4803,7 +4805,8 @@ static void dmar_remove_one_dev_info(struct device *dev) · 6 unmodified lines | ||
| 4803 | 4805 | |
| 4804 | 4806 | spin_lock_irqsave(&device_domain_lock, flags); |
| 4805 | 4807 | info = dev->archdata.iommu; |
| 4806 | − __dmar_remove_one_dev_info(info); | |
| 4808 | + if (info) | |
| 4809 | + __dmar_remove_one_dev_info(info); | |
| 4807 | 4810 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| 4808 | 4811 | } |
| 4809 | 4812 | |
| @@ -5281,6 +5284,7 @@ static int intel_iommu_add_device(struct device *dev) · 471 unmodified lines | ||
| 5281 | 5284 | if (device_def_domain_type(dev) == IOMMU_DOMAIN_IDENTITY) { |
| 5282 | 5285 | ret = iommu_request_dm_for_dev(dev); |
| 5283 | 5286 | if (ret) { |
| 5287 | + dmar_remove_one_dev_info(dev); | |
| 5284 | 5288 | dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN; |
| 5285 | 5289 | domain_add_dev_info(si_domain, dev); |
| 5286 | 5290 | dev_info(dev, |
| @@ -5291,6 +5295,7 @@ static int intel_iommu_add_device(struct device *dev) · 4 unmodified lines | ||
| 5291 | 5295 | if (device_def_domain_type(dev) == IOMMU_DOMAIN_DMA) { |
| 5292 | 5296 | ret = iommu_request_dma_domain_for_dev(dev); |
| 5293 | 5297 | if (ret) { |
| 5298 | + dmar_remove_one_dev_info(dev); | |
| 5294 | 5299 | dmar_domain->flags |= DOMAIN_FLAG_LOSE_CHILDREN; |
| 5295 | 5300 | if (!get_private_domain_for_dev(dev)) { |
| 5296 | 5301 | dev_warn(dev, |
| @@ -5316,6 +5321,8 @@ static void intel_iommu_remove_device(struct device *dev) · 19 unmodified lines | ||
| 5316 | 5321 | if (!iommu) |
| 5317 | 5322 | return; |
| 5318 | 5323 | |
| 5324 | + dmar_remove_one_dev_info(dev); | |
| 5325 | + | |
| 5319 | 5326 | iommu_group_remove_device(dev); |
| 5320 | 5327 | |
| 5321 | 5328 | iommu_device_unlink(&iommu->iommu, dev); |
| @@ -23,24 +23,28 @@ static const char * const bch_cache_modes[] = { · 22 unmodified lines | ||
| 23 | 23 | "writethrough", |
| 24 | 24 | "writeback", |
| 25 | 25 | "writearound", |
| 26 | − "none" | |
| 26 | + "none", | |
| 27 | + NULL | |
| 27 | 28 | }; |
| 28 | 29 | |
| 29 | 30 | /* Default is 0 ("auto") */ |
| 30 | 31 | static const char * const bch_stop_on_failure_modes[] = { |
| 31 | 32 | "auto", |
| 32 | − "always" | |
| 33 | + "always", | |
| 34 | + NULL | |
| 33 | 35 | }; |
| 34 | 36 | |
| 35 | 37 | static const char * const cache_replacement_policies[] = { |
| 36 | 38 | "lru", |
| 37 | 39 | "fifo", |
| 38 | − "random" | |
| 40 | + "random", | |
| 41 | + NULL | |
| 39 | 42 | }; |
| 40 | 43 | |
| 41 | 44 | static const char * const error_actions[] = { |
| 42 | 45 | "unregister", |
| 43 | − "panic" | |
| 46 | + "panic", | |
| 47 | + NULL | |
| 44 | 48 | }; |
| 45 | 49 | |
| 46 | 50 | write_attribute(attach); |
| @@ -338,7 +342,7 @@ STORE(__cached_dev) · 291 unmodified lines | ||
| 338 | 342 | } |
| 339 | 343 | |
| 340 | 344 | if (attr == &sysfs_cache_mode) { |
| 341 | − v = sysfs_match_string(bch_cache_modes, buf); | |
| 345 | + v = __sysfs_match_string(bch_cache_modes, -1, buf); | |
| 342 | 346 | if (v < 0) |
| 343 | 347 | return v; |
| 344 | 348 | |
| @@ -349,7 +353,7 @@ STORE(__cached_dev) · 4 unmodified lines | ||
| 349 | 353 | } |
| 350 | 354 | |
| 351 | 355 | if (attr == &sysfs_stop_when_cache_set_failed) { |
| 352 | − v = sysfs_match_string(bch_stop_on_failure_modes, buf); | |
| 356 | + v = __sysfs_match_string(bch_stop_on_failure_modes, -1, buf); | |
| 353 | 357 | if (v < 0) |
| 354 | 358 | return v; |
| 355 | 359 | |
| @@ -816,7 +820,7 @@ STORE(__bch_cache_set) · 460 unmodified lines | ||
| 816 | 820 | 0, UINT_MAX); |
| 817 | 821 | |
| 818 | 822 | if (attr == &sysfs_errors) { |
| 819 | − v = sysfs_match_string(error_actions, buf); | |
| 823 | + v = __sysfs_match_string(error_actions, -1, buf); | |
| 820 | 824 | if (v < 0) |
| 821 | 825 | return v; |
| 822 | 826 | |
| @@ -1088,7 +1092,7 @@ STORE(__bch_cache) · 265 unmodified lines | ||
| 1088 | 1092 | } |
| 1089 | 1093 | |
| 1090 | 1094 | if (attr == &sysfs_cache_replacement_policy) { |
| 1091 | − v = sysfs_match_string(cache_replacement_policies, buf); | |
| 1095 | + v = __sysfs_match_string(cache_replacement_policies, -1, buf); | |
| 1092 | 1096 | if (v < 0) |
| 1093 | 1097 | return v; |
| 1094 | 1098 | |
| @@ -253,8 +253,7 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, · 252 unmodified lines | ||
| 253 | 253 | */ |
| 254 | 254 | |
| 255 | 255 | pixsize = vout->bpp * vout->vrfb_bpp; |
| 256 | − dst_icg = ((MAX_PIXELS_PER_LINE * pixsize) - | |
| 257 | − (vout->pix.width * vout->bpp)) + 1; | |
| 256 | + dst_icg = MAX_PIXELS_PER_LINE * pixsize - vout->pix.width * vout->bpp; | |
| 258 | 257 | |
| 259 | 258 | xt->src_start = vout->buf_phy_addr[vb->i]; |
| 260 | 259 | xt->dst_start = vout->vrfb_context[vb->i].paddr[0]; |
| @@ -1099,6 +1099,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 1098 unmodified lines | ||
| 1099 | 1099 | |
| 1100 | 1100 | /* start creating the vb2 queues */ |
| 1101 | 1101 | if (dev->has_vid_cap) { |
| 1102 | + snprintf(dev->vid_cap_dev.name, sizeof(dev->vid_cap_dev.name), | |
| 1103 | + "vivid-%03d-vid-cap", inst); | |
| 1102 | 1104 | /* initialize vid_cap queue */ |
| 1103 | 1105 | q = &dev->vb_vid_cap_q; |
| 1104 | 1106 | q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : |
| @@ -1122,6 +1124,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 17 unmodified lines | ||
| 1122 | 1124 | } |
| 1123 | 1125 | |
| 1124 | 1126 | if (dev->has_vid_out) { |
| 1127 | + snprintf(dev->vid_out_dev.name, sizeof(dev->vid_out_dev.name), | |
| 1128 | + "vivid-%03d-vid-out", inst); | |
| 1125 | 1129 | /* initialize vid_out queue */ |
| 1126 | 1130 | q = &dev->vb_vid_out_q; |
| 1127 | 1131 | q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : |
| @@ -1265,8 +1269,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 137 unmodified lines | ||
| 1265 | 1269 | /* finally start creating the device nodes */ |
| 1266 | 1270 | if (dev->has_vid_cap) { |
| 1267 | 1271 | vfd = &dev->vid_cap_dev; |
| 1268 | − snprintf(vfd->name, sizeof(vfd->name), | |
| 1269 | − "vivid-%03d-vid-cap", inst); | |
| 1270 | 1272 | vfd->fops = &vivid_fops; |
| 1271 | 1273 | vfd->ioctl_ops = &vivid_ioctl_ops; |
| 1272 | 1274 | vfd->device_caps = dev->vid_cap_caps; |
| @@ -1312,8 +1314,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) · 39 unmodified lines | ||
| 1312 | 1314 | |
| 1313 | 1315 | if (dev->has_vid_out) { |
| 1314 | 1316 | vfd = &dev->vid_out_dev; |
| 1315 | − snprintf(vfd->name, sizeof(vfd->name), | |
| 1316 | − "vivid-%03d-vid-out", inst); | |
| 1317 | 1317 | vfd->vfl_dir = VFL_DIR_TX; |
| 1318 | 1318 | vfd->fops = &vivid_fops; |
| 1319 | 1319 | vfd->ioctl_ops = &vivid_ioctl_ops; |
| @@ -1590,8 +1590,10 @@ static unsigned long dsiclk_rate(u8 n) · 1589 unmodified lines | ||
| 1590 | 1590 | switch (divsel) { |
| 1591 | 1591 | case PRCM_DSI_PLLOUT_SEL_PHI_4: |
| 1592 | 1592 | div *= 2; |
| 1593 | + /* Fall through */ | |
| 1593 | 1594 | case PRCM_DSI_PLLOUT_SEL_PHI_2: |
| 1594 | 1595 | div *= 2; |
| 1596 | + /* Fall through */ | |
| 1595 | 1597 | case PRCM_DSI_PLLOUT_SEL_PHI: |
| 1596 | 1598 | return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK), |
| 1597 | 1599 | PLL_RAW) / div; |
| @@ -308,7 +308,7 @@ static int usbhs_runtime_resume(struct device *dev) · 307 unmodified lines | ||
| 308 | 308 | i, r); |
| 309 | 309 | } |
| 310 | 310 | } |
| 311 | − /* Fall through as HSIC mode needs utmi_clk */ | |
| 311 | + /* Fall through - as HSIC mode needs utmi_clk */ | |
| 312 | 312 | |
| 313 | 313 | case OMAP_EHCI_PORT_MODE_TLL: |
| 314 | 314 | if (!IS_ERR(omap->utmi_clk[i])) { |
| @@ -344,7 +344,7 @@ static int usbhs_runtime_suspend(struct device *dev) · 29 unmodified lines | ||
| 344 | 344 | |
| 345 | 345 | if (!IS_ERR(omap->hsic480m_clk[i])) |
| 346 | 346 | clk_disable_unprepare(omap->hsic480m_clk[i]); |
| 347 | − /* Fall through as utmi_clks were used in HSIC mode */ | |
| 347 | + /* Fall through - as utmi_clks were used in HSIC mode */ | |
| 348 | 348 | |
| 349 | 349 | case OMAP_EHCI_PORT_MODE_TLL: |
| 350 | 350 | if (!IS_ERR(omap->utmi_clk[i])) |
| @@ -465,6 +465,7 @@ config PCI_ENDPOINT_TEST · 464 unmodified lines | ||
| 465 | 465 | |
| 466 | 466 | config XILINX_SDFEC |
| 467 | 467 | tristate "Xilinx SDFEC 16" |
| 468 | + depends on HAS_IOMEM | |
| 468 | 469 | help |
| 469 | 470 | This option enables support for the Xilinx SDFEC (Soft Decision |
| 470 | 471 | Forward Error Correction) driver. This enables a char driver |
| @@ -683,7 +683,7 @@ int hl_cs_ioctl(struct hl_fpriv *hpriv, void *data) · 682 unmodified lines | ||
| 683 | 683 | |
| 684 | 684 | rc = hl_poll_timeout_memory(hdev, |
| 685 | 685 | &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1), |
| 686 | − 100, jiffies_to_usecs(hdev->timeout_jiffies)); | |
| 686 | + 100, jiffies_to_usecs(hdev->timeout_jiffies), false); | |
| 687 | 687 | |
| 688 | 688 | if (rc == -ETIMEDOUT) { |
| 689 | 689 | dev_err(hdev->dev, |
| @@ -970,7 +970,8 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) · 969 unmodified lines | ||
| 970 | 970 | rc = hl_ctx_init(hdev, hdev->kernel_ctx, true); |
| 971 | 971 | if (rc) { |
| 972 | 972 | dev_err(hdev->dev, "failed to initialize kernel context\n"); |
| 973 | − goto free_ctx; | |
| 973 | + kfree(hdev->kernel_ctx); | |
| 974 | + goto mmu_fini; | |
| 974 | 975 | } |
| 975 | 976 | |
| 976 | 977 | rc = hl_cb_pool_init(hdev); |
| @@ -1053,8 +1054,6 @@ release_ctx: · 76 unmodified lines | ||
| 1053 | 1054 | if (hl_ctx_put(hdev->kernel_ctx) != 1) |
| 1054 | 1055 | dev_err(hdev->dev, |
| 1055 | 1056 | "kernel ctx is still alive on initialization failure\n"); |
| 1056 | −free_ctx: | |
| 1057 | − kfree(hdev->kernel_ctx); | |
| 1058 | 1057 | mmu_fini: |
| 1059 | 1058 | hl_mmu_fini(hdev); |
| 1060 | 1059 | eq_fini: |
| @@ -24,7 +24,7 @@ int hl_fw_push_fw_to_device(struct hl_device *hdev, const char *fw_name, · 23 unmodified lines | ||
| 24 | 24 | { |
| 25 | 25 | const struct firmware *fw; |
| 26 | 26 | const u64 *fw_data; |
| 27 | − size_t fw_size, i; | |
| 27 | + size_t fw_size; | |
| 28 | 28 | int rc; |
| 29 | 29 | |
| 30 | 30 | rc = request_firmware(&fw, fw_name, hdev->dev); |
| @@ -45,22 +45,7 @@ int hl_fw_push_fw_to_device(struct hl_device *hdev, const char *fw_name, · 14 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | fw_data = (const u64 *) fw->data; |
| 47 | 47 | |
| 48 | − if ((fw->size % 8) != 0) | |
| 49 | − fw_size -= 8; | |
| 50 | − | |
| 51 | − for (i = 0 ; i < fw_size ; i += 8, fw_data++, dst += 8) { | |
| 52 | − if (!(i & (0x80000 - 1))) { | |
| 53 | − dev_dbg(hdev->dev, | |
| 54 | − "copied so far %zu out of %zu for %s firmware", | |
| 55 | − i, fw_size, fw_name); | |
| 56 | − usleep_range(20, 100); | |
| 57 | − } | |
| 58 | − | |
| 59 | − writeq(*fw_data, dst); | |
| 60 | − } | |
| 61 | − | |
| 62 | − if ((fw->size % 8) != 0) | |
| 63 | − writel(*(const u32 *) fw_data, dst); | |
| 48 | + memcpy_toio(dst, fw_data, fw_size); | |
| 64 | 49 | |
| 65 | 50 | out: |
| 66 | 51 | release_firmware(fw); |
| @@ -112,7 +97,8 @@ int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, · 45 unmodified lines | ||
| 112 | 97 | } |
| 113 | 98 | |
| 114 | 99 | rc = hl_poll_timeout_memory(hdev, &pkt->fence, tmp, |
| 115 | − (tmp == ARMCP_PACKET_FENCE_VAL), 1000, timeout); | |
| 100 | + (tmp == ARMCP_PACKET_FENCE_VAL), 1000, | |
| 101 | + timeout, true); | |
| 116 | 102 | |
| 117 | 103 | hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id); |
| 118 | 104 | |
| @@ -2729,9 +2729,10 @@ void goya_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi) · 2728 unmodified lines | ||
| 2729 | 2729 | GOYA_ASYNC_EVENT_ID_PI_UPDATE); |
| 2730 | 2730 | } |
| 2731 | 2731 | |
| 2732 | −void goya_flush_pq_write(struct hl_device *hdev, u64 *pq, u64 exp_val) | |
| 2732 | +void goya_pqe_write(struct hl_device *hdev, __le64 *pqe, struct hl_bd *bd) | |
| 2733 | 2733 | { |
| 2734 | − /* Not needed in Goya */ | |
| 2734 | + /* The QMANs are on the SRAM so need to copy to IO space */ | |
| 2735 | + memcpy_toio((void __iomem *) pqe, bd, sizeof(struct hl_bd)); | |
| 2735 | 2736 | } |
| 2736 | 2737 | |
| 2737 | 2738 | static void *goya_dma_alloc_coherent(struct hl_device *hdev, size_t size, |
| @@ -2864,7 +2865,8 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job) · 126 unmodified lines | ||
| 2864 | 2865 | } |
| 2865 | 2866 | |
| 2866 | 2867 | rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, |
| 2867 | − (tmp == GOYA_QMAN0_FENCE_VAL), 1000, timeout); | |
| 2868 | + (tmp == GOYA_QMAN0_FENCE_VAL), 1000, | |
| 2869 | + timeout, true); | |
| 2868 | 2870 | |
| 2869 | 2871 | hl_hw_queue_inc_ci_kernel(hdev, GOYA_QUEUE_ID_DMA_0); |
| 2870 | 2872 | |
| @@ -2945,7 +2947,7 @@ int goya_test_queue(struct hl_device *hdev, u32 hw_queue_id) · 74 unmodified lines | ||
| 2945 | 2947 | } |
| 2946 | 2948 | |
| 2947 | 2949 | rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, (tmp == fence_val), |
| 2948 | − 1000, GOYA_TEST_QUEUE_WAIT_USEC); | |
| 2950 | + 1000, GOYA_TEST_QUEUE_WAIT_USEC, true); | |
| 2949 | 2951 | |
| 2950 | 2952 | hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id); |
| 2951 | 2953 | |
| @@ -3312,9 +3314,11 @@ static int goya_validate_dma_pkt_no_mmu(struct hl_device *hdev, · 360 unmodified lines | ||
| 3312 | 3314 | int rc; |
| 3313 | 3315 | |
| 3314 | 3316 | dev_dbg(hdev->dev, "DMA packet details:\n"); |
| 3315 | − dev_dbg(hdev->dev, "source == 0x%llx\n", user_dma_pkt->src_addr); | |
| 3316 | − dev_dbg(hdev->dev, "destination == 0x%llx\n", user_dma_pkt->dst_addr); | |
| 3317 | − dev_dbg(hdev->dev, "size == %u\n", user_dma_pkt->tsize); | |
| 3317 | + dev_dbg(hdev->dev, "source == 0x%llx\n", | |
| 3318 | + le64_to_cpu(user_dma_pkt->src_addr)); | |
| 3319 | + dev_dbg(hdev->dev, "destination == 0x%llx\n", | |
| 3320 | + le64_to_cpu(user_dma_pkt->dst_addr)); | |
| 3321 | + dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize)); | |
| 3318 | 3322 | |
| 3319 | 3323 | ctl = le32_to_cpu(user_dma_pkt->ctl); |
| 3320 | 3324 | user_dir = (ctl & GOYA_PKT_LIN_DMA_CTL_DMA_DIR_MASK) >> |
| @@ -3343,9 +3347,11 @@ static int goya_validate_dma_pkt_mmu(struct hl_device *hdev, · 22 unmodified lines | ||
| 3343 | 3347 | struct packet_lin_dma *user_dma_pkt) |
| 3344 | 3348 | { |
| 3345 | 3349 | dev_dbg(hdev->dev, "DMA packet details:\n"); |
| 3346 | − dev_dbg(hdev->dev, "source == 0x%llx\n", user_dma_pkt->src_addr); | |
| 3347 | − dev_dbg(hdev->dev, "destination == 0x%llx\n", user_dma_pkt->dst_addr); | |
| 3348 | − dev_dbg(hdev->dev, "size == %u\n", user_dma_pkt->tsize); | |
| 3350 | + dev_dbg(hdev->dev, "source == 0x%llx\n", | |
| 3351 | + le64_to_cpu(user_dma_pkt->src_addr)); | |
| 3352 | + dev_dbg(hdev->dev, "destination == 0x%llx\n", | |
| 3353 | + le64_to_cpu(user_dma_pkt->dst_addr)); | |
| 3354 | + dev_dbg(hdev->dev, "size == %u\n", le32_to_cpu(user_dma_pkt->tsize)); | |
| 3349 | 3355 | |
| 3350 | 3356 | /* |
| 3351 | 3357 | * WA for HW-23. |
| @@ -3385,7 +3391,8 @@ static int goya_validate_wreg32(struct hl_device *hdev, · 33 unmodified lines | ||
| 3385 | 3391 | |
| 3386 | 3392 | dev_dbg(hdev->dev, "WREG32 packet details:\n"); |
| 3387 | 3393 | dev_dbg(hdev->dev, "reg_offset == 0x%x\n", reg_offset); |
| 3388 | − dev_dbg(hdev->dev, "value == 0x%x\n", wreg_pkt->value); | |
| 3394 | + dev_dbg(hdev->dev, "value == 0x%x\n", | |
| 3395 | + le32_to_cpu(wreg_pkt->value)); | |
| 3389 | 3396 | |
| 3390 | 3397 | if (reg_offset != (mmDMA_CH_0_WR_COMP_ADDR_LO & 0x1FFF)) { |
| 3391 | 3398 | dev_err(hdev->dev, "WREG32 packet with illegal address 0x%x\n", |
| @@ -3427,12 +3434,13 @@ static int goya_validate_cb(struct hl_device *hdev, · 35 unmodified lines | ||
| 3427 | 3434 | while (cb_parsed_length < parser->user_cb_size) { |
| 3428 | 3435 | enum packet_id pkt_id; |
| 3429 | 3436 | u16 pkt_size; |
| 3430 | − void *user_pkt; | |
| 3437 | + struct goya_packet *user_pkt; | |
| 3431 | 3438 | |
| 3432 | − user_pkt = (void *) (uintptr_t) | |
| 3439 | + user_pkt = (struct goya_packet *) (uintptr_t) | |
| 3433 | 3440 | (parser->user_cb->kernel_address + cb_parsed_length); |
| 3434 | 3441 | |
| 3435 | − pkt_id = (enum packet_id) (((*(u64 *) user_pkt) & | |
| 3442 | + pkt_id = (enum packet_id) ( | |
| 3443 | + (le64_to_cpu(user_pkt->header) & | |
| 3436 | 3444 | PACKET_HEADER_PACKET_ID_MASK) >> |
| 3437 | 3445 | PACKET_HEADER_PACKET_ID_SHIFT); |
| 3438 | 3446 | |
| @@ -3452,7 +3460,8 @@ static int goya_validate_cb(struct hl_device *hdev, · 13 unmodified lines | ||
| 3452 | 3460 | * need to validate here as well because patch_cb() is |
| 3453 | 3461 | * not called in MMU path while this function is called |
| 3454 | 3462 | */ |
| 3455 | − rc = goya_validate_wreg32(hdev, parser, user_pkt); | |
| 3463 | + rc = goya_validate_wreg32(hdev, | |
| 3464 | + parser, (struct packet_wreg32 *) user_pkt); | |
| 3456 | 3465 | break; |
| 3457 | 3466 | |
| 3458 | 3467 | case PACKET_WREG_BULK: |
| @@ -3480,10 +3489,10 @@ static int goya_validate_cb(struct hl_device *hdev, · 21 unmodified lines | ||
| 3480 | 3489 | case PACKET_LIN_DMA: |
| 3481 | 3490 | if (is_mmu) |
| 3482 | 3491 | rc = goya_validate_dma_pkt_mmu(hdev, parser, |
| 3483 | − user_pkt); | |
| 3492 | + (struct packet_lin_dma *) user_pkt); | |
| 3484 | 3493 | else |
| 3485 | 3494 | rc = goya_validate_dma_pkt_no_mmu(hdev, parser, |
| 3486 | − user_pkt); | |
| 3495 | + (struct packet_lin_dma *) user_pkt); | |
| 3487 | 3496 | break; |
| 3488 | 3497 | |
| 3489 | 3498 | case PACKET_MSG_LONG: |
| @@ -3656,15 +3665,16 @@ static int goya_patch_cb(struct hl_device *hdev, · 166 unmodified lines | ||
| 3656 | 3665 | enum packet_id pkt_id; |
| 3657 | 3666 | u16 pkt_size; |
| 3658 | 3667 | u32 new_pkt_size = 0; |
| 3659 | − void *user_pkt, *kernel_pkt; | |
| 3668 | + struct goya_packet *user_pkt, *kernel_pkt; | |
| 3660 | 3669 | |
| 3661 | − user_pkt = (void *) (uintptr_t) | |
| 3670 | + user_pkt = (struct goya_packet *) (uintptr_t) | |
| 3662 | 3671 | (parser->user_cb->kernel_address + cb_parsed_length); |
| 3663 | − kernel_pkt = (void *) (uintptr_t) | |
| 3672 | + kernel_pkt = (struct goya_packet *) (uintptr_t) | |
| 3664 | 3673 | (parser->patched_cb->kernel_address + |
| 3665 | 3674 | cb_patched_cur_length); |
| 3666 | 3675 | |
| 3667 | − pkt_id = (enum packet_id) (((*(u64 *) user_pkt) & | |
| 3676 | + pkt_id = (enum packet_id) ( | |
| 3677 | + (le64_to_cpu(user_pkt->header) & | |
| 3668 | 3678 | PACKET_HEADER_PACKET_ID_MASK) >> |
| 3669 | 3679 | PACKET_HEADER_PACKET_ID_SHIFT); |
| 3670 | 3680 | |
| @@ -3679,15 +3689,18 @@ static int goya_patch_cb(struct hl_device *hdev, · 8 unmodified lines | ||
| 3679 | 3689 | |
| 3680 | 3690 | switch (pkt_id) { |
| 3681 | 3691 | case PACKET_LIN_DMA: |
| 3682 | − rc = goya_patch_dma_packet(hdev, parser, user_pkt, | |
| 3683 | − kernel_pkt, &new_pkt_size); | |
| 3692 | + rc = goya_patch_dma_packet(hdev, parser, | |
| 3693 | + (struct packet_lin_dma *) user_pkt, | |
| 3694 | + (struct packet_lin_dma *) kernel_pkt, | |
| 3695 | + &new_pkt_size); | |
| 3684 | 3696 | cb_patched_cur_length += new_pkt_size; |
| 3685 | 3697 | break; |
| 3686 | 3698 | |
| 3687 | 3699 | case PACKET_WREG_32: |
| 3688 | 3700 | memcpy(kernel_pkt, user_pkt, pkt_size); |
| 3689 | 3701 | cb_patched_cur_length += pkt_size; |
| 3690 | − rc = goya_validate_wreg32(hdev, parser, kernel_pkt); | |
| 3702 | + rc = goya_validate_wreg32(hdev, parser, | |
| 3703 | + (struct packet_wreg32 *) kernel_pkt); | |
| 3691 | 3704 | break; |
| 3692 | 3705 | |
| 3693 | 3706 | case PACKET_WREG_BULK: |
| @@ -4351,6 +4364,8 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, · 657 unmodified lines | ||
| 4351 | 4364 | size_t total_pkt_size; |
| 4352 | 4365 | long result; |
| 4353 | 4366 | int rc; |
| 4367 | + int irq_num_entries, irq_arr_index; | |
| 4368 | + __le32 *goya_irq_arr; | |
| 4354 | 4369 | |
| 4355 | 4370 | total_pkt_size = sizeof(struct armcp_unmask_irq_arr_packet) + |
| 4356 | 4371 | irq_arr_size; |
| @@ -4368,8 +4383,16 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, · 11 unmodified lines | ||
| 4368 | 4383 | if (!pkt) |
| 4369 | 4384 | return -ENOMEM; |
| 4370 | 4385 | |
| 4371 | − pkt->length = cpu_to_le32(irq_arr_size / sizeof(irq_arr[0])); | |
| 4372 | − memcpy(&pkt->irqs, irq_arr, irq_arr_size); | |
| 4386 | + irq_num_entries = irq_arr_size / sizeof(irq_arr[0]); | |
| 4387 | + pkt->length = cpu_to_le32(irq_num_entries); | |
| 4388 | + | |
| 4389 | + /* We must perform any necessary endianness conversation on the irq | |
| 4390 | + * array being passed to the goya hardware | |
| 4391 | + */ | |
| 4392 | + for (irq_arr_index = 0, goya_irq_arr = (__le32 *) &pkt->irqs; | |
| 4393 | + irq_arr_index < irq_num_entries ; irq_arr_index++) | |
| 4394 | + goya_irq_arr[irq_arr_index] = | |
| 4395 | + cpu_to_le32(irq_arr[irq_arr_index]); | |
| 4373 | 4396 | |
| 4374 | 4397 | pkt->armcp_pkt.ctl = cpu_to_le32(ARMCP_PACKET_UNMASK_RAZWI_IRQ_ARRAY << |
| 4375 | 4398 | ARMCP_PKT_CTL_OPCODE_SHIFT); |
| @@ -5041,7 +5064,7 @@ static const struct hl_asic_funcs goya_funcs = { · 665 unmodified lines | ||
| 5041 | 5064 | .resume = goya_resume, |
| 5042 | 5065 | .cb_mmap = goya_cb_mmap, |
| 5043 | 5066 | .ring_doorbell = goya_ring_doorbell, |
| 5044 | − .flush_pq_write = goya_flush_pq_write, | |
| 5067 | + .pqe_write = goya_pqe_write, | |
| 5045 | 5068 | .asic_dma_alloc_coherent = goya_dma_alloc_coherent, |
| 5046 | 5069 | .asic_dma_free_coherent = goya_dma_free_coherent, |
| 5047 | 5070 | .get_int_queue_base = goya_get_int_queue_base, |
| @@ -177,7 +177,7 @@ int goya_late_init(struct hl_device *hdev); · 176 unmodified lines | ||
| 177 | 177 | void goya_late_fini(struct hl_device *hdev); |
| 178 | 178 | |
| 179 | 179 | void goya_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi); |
| 180 | −void goya_flush_pq_write(struct hl_device *hdev, u64 *pq, u64 exp_val); | |
| 180 | +void goya_pqe_write(struct hl_device *hdev, __le64 *pqe, struct hl_bd *bd); | |
| 181 | 181 | void goya_update_eq_ci(struct hl_device *hdev, u32 val); |
| 182 | 182 | void goya_restore_phase_topology(struct hl_device *hdev); |
| 183 | 183 | int goya_context_switch(struct hl_device *hdev, u32 asid); |
| @@ -441,7 +441,11 @@ enum hl_pll_frequency { · 440 unmodified lines | ||
| 441 | 441 | * @resume: handles IP specific H/W or SW changes for resume. |
| 442 | 442 | * @cb_mmap: maps a CB. |
| 443 | 443 | * @ring_doorbell: increment PI on a given QMAN. |
| 444 | − * @flush_pq_write: flush PQ entry write if necessary, WARN if flushing failed. | |
| 444 | + * @pqe_write: Write the PQ entry to the PQ. This is ASIC-specific | |
| 445 | + * function because the PQs are located in different memory areas | |
| 446 | + * per ASIC (SRAM, DRAM, Host memory) and therefore, the method of | |
| 447 | + * writing the PQE must match the destination memory area | |
| 448 | + * properties. | |
| 445 | 449 | * @asic_dma_alloc_coherent: Allocate coherent DMA memory by calling |
| 446 | 450 | * dma_alloc_coherent(). This is ASIC function because |
| 447 | 451 | * its implementation is not trivial when the driver |
| @@ -510,7 +514,8 @@ struct hl_asic_funcs { · 62 unmodified lines | ||
| 510 | 514 | int (*cb_mmap)(struct hl_device *hdev, struct vm_area_struct *vma, |
| 511 | 515 | u64 kaddress, phys_addr_t paddress, u32 size); |
| 512 | 516 | void (*ring_doorbell)(struct hl_device *hdev, u32 hw_queue_id, u32 pi); |
| 513 | − void (*flush_pq_write)(struct hl_device *hdev, u64 *pq, u64 exp_val); | |
| 517 | + void (*pqe_write)(struct hl_device *hdev, __le64 *pqe, | |
| 518 | + struct hl_bd *bd); | |
| 514 | 519 | void* (*asic_dma_alloc_coherent)(struct hl_device *hdev, size_t size, |
| 515 | 520 | dma_addr_t *dma_handle, gfp_t flag); |
| 516 | 521 | void (*asic_dma_free_coherent)(struct hl_device *hdev, size_t size, |
| @@ -1062,9 +1067,17 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); · 545 unmodified lines | ||
| 1062 | 1067 | /* |
| 1063 | 1068 | * address in this macro points always to a memory location in the |
| 1064 | 1069 | * host's (server's) memory. That location is updated asynchronously |
| 1065 | − * either by the direct access of the device or by another core | |
| 1070 | + * either by the direct access of the device or by another core. | |
| 1071 | + * | |
| 1072 | + * To work both in LE and BE architectures, we need to distinguish between the | |
| 1073 | + * two states (device or another core updates the memory location). Therefore, | |
| 1074 | + * if mem_written_by_device is true, the host memory being polled will be | |
| 1075 | + * updated directly by the device. If false, the host memory being polled will | |
| 1076 | + * be updated by host CPU. Required so host knows whether or not the memory | |
| 1077 | + * might need to be byte-swapped before returning value to caller. | |
| 1066 | 1078 | */ |
| 1067 | −#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us) \ | |
| 1079 | +#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us, \ | |
| 1080 | + mem_written_by_device) \ | |
| 1068 | 1081 | ({ \ |
| 1069 | 1082 | ktime_t __timeout; \ |
| 1070 | 1083 | /* timeout should be longer when working with simulator */ \ |
| @@ -1077,10 +1090,14 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); · 6 unmodified lines | ||
| 1077 | 1090 | /* Verify we read updates done by other cores or by device */ \ |
| 1078 | 1091 | mb(); \ |
| 1079 | 1092 | (val) = *((u32 *) (uintptr_t) (addr)); \ |
| 1093 | + if (mem_written_by_device) \ | |
| 1094 | + (val) = le32_to_cpu(val); \ | |
| 1080 | 1095 | if (cond) \ |
| 1081 | 1096 | break; \ |
| 1082 | 1097 | if (timeout_us && ktime_compare(ktime_get(), __timeout) > 0) { \ |
| 1083 | 1098 | (val) = *((u32 *) (uintptr_t) (addr)); \ |
| 1099 | + if (mem_written_by_device) \ | |
| 1100 | + (val) = le32_to_cpu(val); \ | |
| 1084 | 1101 | break; \ |
| 1085 | 1102 | } \ |
| 1086 | 1103 | if (sleep_us) \ |
| @@ -290,23 +290,19 @@ static void int_hw_queue_schedule_job(struct hl_cs_job *job) · 289 unmodified lines | ||
| 290 | 290 | struct hl_device *hdev = job->cs->ctx->hdev; |
| 291 | 291 | struct hl_hw_queue *q = &hdev->kernel_queues[job->hw_queue_id]; |
| 292 | 292 | struct hl_bd bd; |
| 293 | − u64 *pi, *pbd = (u64 *) &bd; | |
| 293 | + __le64 *pi; | |
| 294 | 294 | |
| 295 | 295 | bd.ctl = 0; |
| 296 | − bd.len = __cpu_to_le32(job->job_cb_size); | |
| 297 | − bd.ptr = __cpu_to_le64((u64) (uintptr_t) job->user_cb); | |
| 296 | + bd.len = cpu_to_le32(job->job_cb_size); | |
| 297 | + bd.ptr = cpu_to_le64((u64) (uintptr_t) job->user_cb); | |
| 298 | 298 | |
| 299 | − pi = (u64 *) (uintptr_t) (q->kernel_address + | |
| 299 | + pi = (__le64 *) (uintptr_t) (q->kernel_address + | |
| 300 | 300 | ((q->pi & (q->int_queue_len - 1)) * sizeof(bd))); |
| 301 | 301 | |
| 302 | − pi[0] = pbd[0]; | |
| 303 | − pi[1] = pbd[1]; | |
| 304 | − | |
| 305 | 302 | q->pi++; |
| 306 | 303 | q->pi &= ((q->int_queue_len << 1) - 1); |
| 307 | 304 | |
| 308 | − /* Flush PQ entry write. Relevant only for specific ASICs */ | |
| 309 | − hdev->asic_funcs->flush_pq_write(hdev, pi, pbd[0]); | |
| 305 | + hdev->asic_funcs->pqe_write(hdev, pi, &bd); | |
| 310 | 306 | |
| 311 | 307 | hdev->asic_funcs->ring_doorbell(hdev, q->hw_queue_id, q->pi); |
| 312 | 308 | } |
| @@ -52,6 +52,19 @@ enum goya_dma_direction { · 51 unmodified lines | ||
| 52 | 52 | #define GOYA_PKT_CTL_MB_SHIFT 31 |
| 53 | 53 | #define GOYA_PKT_CTL_MB_MASK 0x80000000 |
| 54 | 54 | |
| 55 | +/* All packets have, at least, an 8-byte header, which contains | |
| 56 | + * the packet type. The kernel driver uses the packet header for packet | |
| 57 | + * validation and to perform any necessary required preparation before | |
| 58 | + * sending them off to the hardware. | |
| 59 | + */ | |
| 60 | +struct goya_packet { | |
| 61 | + __le64 header; | |
| 62 | + /* The rest of the packet data follows. Use the corresponding | |
| 63 | + * packet_XXX struct to deference the data, based on packet type | |
| 64 | + */ | |
| 65 | + u8 contents[0]; | |
| 66 | +}; | |
| 67 | + | |
| 55 | 68 | struct packet_nop { |
| 56 | 69 | __le32 reserved; |
| 57 | 70 | __le32 ctl; |
| @@ -80,8 +80,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) · 79 unmodified lines | ||
| 80 | 80 | struct hl_cs_job *job; |
| 81 | 81 | bool shadow_index_valid; |
| 82 | 82 | u16 shadow_index; |
| 83 | − u32 *cq_entry; | |
| 84 | − u32 *cq_base; | |
| 83 | + struct hl_cq_entry *cq_entry, *cq_base; | |
| 85 | 84 | |
| 86 | 85 | if (hdev->disabled) { |
| 87 | 86 | dev_dbg(hdev->dev, |
| @@ -90,29 +89,29 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) · 2 unmodified lines | ||
| 90 | 89 | return IRQ_HANDLED; |
| 91 | 90 | } |
| 92 | 91 | |
| 93 | − cq_base = (u32 *) (uintptr_t) cq->kernel_address; | |
| 92 | + cq_base = (struct hl_cq_entry *) (uintptr_t) cq->kernel_address; | |
| 94 | 93 | |
| 95 | 94 | while (1) { |
| 96 | − bool entry_ready = ((cq_base[cq->ci] & CQ_ENTRY_READY_MASK) | |
| 95 | + bool entry_ready = ((le32_to_cpu(cq_base[cq->ci].data) & | |
| 96 | + CQ_ENTRY_READY_MASK) | |
| 97 | 97 | >> CQ_ENTRY_READY_SHIFT); |
| 98 | 98 | |
| 99 | 99 | if (!entry_ready) |
| 100 | 100 | break; |
| 101 | 101 | |
| 102 | − cq_entry = (u32 *) &cq_base[cq->ci]; | |
| 102 | + cq_entry = (struct hl_cq_entry *) &cq_base[cq->ci]; | |
| 103 | 103 | |
| 104 | − /* | |
| 105 | − * Make sure we read CQ entry contents after we've | |
| 104 | + /* Make sure we read CQ entry contents after we've | |
| 106 | 105 | * checked the ownership bit. |
| 107 | 106 | */ |
| 108 | 107 | dma_rmb(); |
| 109 | 108 | |
| 110 | − shadow_index_valid = | |
| 111 | − ((*cq_entry & CQ_ENTRY_SHADOW_INDEX_VALID_MASK) | |
| 109 | + shadow_index_valid = ((le32_to_cpu(cq_entry->data) & | |
| 110 | + CQ_ENTRY_SHADOW_INDEX_VALID_MASK) | |
| 112 | 111 | >> CQ_ENTRY_SHADOW_INDEX_VALID_SHIFT); |
| 113 | 112 | |
| 114 | − shadow_index = (u16) | |
| 115 | − ((*cq_entry & CQ_ENTRY_SHADOW_INDEX_MASK) | |
| 113 | + shadow_index = (u16) ((le32_to_cpu(cq_entry->data) & | |
| 114 | + CQ_ENTRY_SHADOW_INDEX_MASK) | |
| 116 | 115 | >> CQ_ENTRY_SHADOW_INDEX_SHIFT); |
| 117 | 116 | |
| 118 | 117 | queue = &hdev->kernel_queues[cq->hw_queue_id]; |
| @@ -122,8 +121,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) · 3 unmodified lines | ||
| 122 | 121 | queue_work(hdev->cq_wq, &job->finish_work); |
| 123 | 122 | } |
| 124 | 123 | |
| 125 | − /* | |
| 126 | − * Update ci of the context's queue. There is no | |
| 124 | + /* Update ci of the context's queue. There is no | |
| 127 | 125 | * need to protect it with spinlock because this update is |
| 128 | 126 | * done only inside IRQ and there is a different IRQ per |
| 129 | 127 | * queue |
| @@ -131,7 +129,8 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) · 1 unmodified line | ||
| 131 | 129 | queue->ci = hl_queue_inc_ptr(queue->ci); |
| 132 | 130 | |
| 133 | 131 | /* Clear CQ entry ready bit */ |
| 134 | − cq_base[cq->ci] &= ~CQ_ENTRY_READY_MASK; | |
| 132 | + cq_entry->data = cpu_to_le32(le32_to_cpu(cq_entry->data) & | |
| 133 | + ~CQ_ENTRY_READY_MASK); | |
| 135 | 134 | |
| 136 | 135 | cq->ci = hl_cq_inc_ptr(cq->ci); |
| 137 | 136 | |
| @@ -1629,6 +1629,8 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx) · 1628 unmodified lines | ||
| 1629 | 1629 | dev_dbg(hdev->dev, |
| 1630 | 1630 | "page list 0x%p of asid %d is still alive\n", |
| 1631 | 1631 | phys_pg_list, ctx->asid); |
| 1632 | + atomic64_sub(phys_pg_list->total_size, | |
| 1633 | + &hdev->dram_used_mem); | |
| 1632 | 1634 | free_phys_pg_pack(hdev, phys_pg_list); |
| 1633 | 1635 | idr_remove(&vm->phys_pg_pack_handles, i); |
| 1634 | 1636 | } |
| @@ -374,6 +374,7 @@ static int finish_dma_single(struct cvm_mmc_host *host, struct mmc_data *data) · 373 unmodified lines | ||
| 374 | 374 | { |
| 375 | 375 | data->bytes_xfered = data->blocks * data->blksz; |
| 376 | 376 | data->error = 0; |
| 377 | + dma_unmap_sg(host->dev, data->sg, data->sg_len, get_dma_dir(data)); | |
| 377 | 378 | return 1; |
| 378 | 379 | } |
| 379 | 380 | |
| @@ -1046,7 +1047,8 @@ int cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host) · 666 unmodified lines | ||
| 1046 | 1047 | mmc->max_segs = 1; |
| 1047 | 1048 | |
| 1048 | 1049 | /* DMA size field can address up to 8 MB */ |
| 1049 | − mmc->max_seg_size = 8 * 1024 * 1024; | |
| 1050 | + mmc->max_seg_size = min_t(unsigned int, 8 * 1024 * 1024, | |
| 1051 | + dma_get_max_seg_size(host->dev)); | |
| 1050 | 1052 | mmc->max_req_size = mmc->max_seg_size; |
| 1051 | 1053 | /* External DMA is in 512 byte blocks */ |
| 1052 | 1054 | mmc->max_blk_size = 512; |
| @@ -883,7 +883,7 @@ static int sdhci_acpi_runtime_resume(struct device *dev) · 882 unmodified lines | ||
| 883 | 883 | |
| 884 | 884 | sdhci_acpi_byt_setting(&c->pdev->dev); |
| 885 | 885 | |
| 886 | − return sdhci_runtime_resume_host(c->host); | |
| 886 | + return sdhci_runtime_resume_host(c->host, 0); | |
| 887 | 887 | } |
| 888 | 888 | |
| 889 | 889 | #endif |
| @@ -1705,7 +1705,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev) · 1704 unmodified lines | ||
| 1705 | 1705 | esdhc_pltfm_set_clock(host, imx_data->actual_clock); |
| 1706 | 1706 | } |
| 1707 | 1707 | |
| 1708 | − err = sdhci_runtime_resume_host(host); | |
| 1708 | + err = sdhci_runtime_resume_host(host, 0); | |
| 1709 | 1709 | if (err) |
| 1710 | 1710 | goto disable_ipg_clk; |
| 1711 | 1711 | |
| @@ -289,7 +289,7 @@ static int sdhci_at91_runtime_resume(struct device *dev) · 288 unmodified lines | ||
| 289 | 289 | } |
| 290 | 290 | |
| 291 | 291 | out: |
| 292 | − return sdhci_runtime_resume_host(host); | |
| 292 | + return sdhci_runtime_resume_host(host, 0); | |
| 293 | 293 | } |
| 294 | 294 | #endif /* CONFIG_PM */ |
| 295 | 295 | |
| @@ -167,7 +167,7 @@ static int sdhci_pci_runtime_suspend_host(struct sdhci_pci_chip *chip) · 166 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | err_pci_runtime_suspend: |
| 169 | 169 | while (--i >= 0) |
| 170 | − sdhci_runtime_resume_host(chip->slots[i]->host); | |
| 170 | + sdhci_runtime_resume_host(chip->slots[i]->host, 0); | |
| 171 | 171 | return ret; |
| 172 | 172 | } |
| 173 | 173 | |
| @@ -181,7 +181,7 @@ static int sdhci_pci_runtime_resume_host(struct sdhci_pci_chip *chip) · 7 unmodified lines | ||
| 181 | 181 | if (!slot) |
| 182 | 182 | continue; |
| 183 | 183 | |
| 184 | − ret = sdhci_runtime_resume_host(slot->host); | |
| 184 | + ret = sdhci_runtime_resume_host(slot->host, 0); | |
| 185 | 185 | if (ret) |
| 186 | 186 | return ret; |
| 187 | 187 | } |
| @@ -554,7 +554,7 @@ static int sdhci_pxav3_runtime_resume(struct device *dev) · 553 unmodified lines | ||
| 554 | 554 | if (!IS_ERR(pxa->clk_core)) |
| 555 | 555 | clk_prepare_enable(pxa->clk_core); |
| 556 | 556 | |
| 557 | − return sdhci_runtime_resume_host(host); | |
| 557 | + return sdhci_runtime_resume_host(host, 0); | |
| 558 | 558 | } |
| 559 | 559 | #endif |
| 560 | 560 | |
| @@ -745,7 +745,7 @@ static int sdhci_s3c_runtime_resume(struct device *dev) · 744 unmodified lines | ||
| 745 | 745 | clk_prepare_enable(busclk); |
| 746 | 746 | if (ourhost->cur_clk >= 0) |
| 747 | 747 | clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); |
| 748 | − ret = sdhci_runtime_resume_host(host); | |
| 748 | + ret = sdhci_runtime_resume_host(host, 0); | |
| 749 | 749 | return ret; |
| 750 | 750 | } |
| 751 | 751 | #endif |
| @@ -696,7 +696,7 @@ static int sdhci_sprd_runtime_resume(struct device *dev) · 695 unmodified lines | ||
| 696 | 696 | if (ret) |
| 697 | 697 | goto clk_disable; |
| 698 | 698 | |
| 699 | − sdhci_runtime_resume_host(host); | |
| 699 | + sdhci_runtime_resume_host(host, 1); | |
| 700 | 700 | return 0; |
| 701 | 701 | |
| 702 | 702 | clk_disable: |
| @@ -638,7 +638,7 @@ static int xenon_runtime_resume(struct device *dev) · 637 unmodified lines | ||
| 638 | 638 | priv->restore_needed = false; |
| 639 | 639 | } |
| 640 | 640 | |
| 641 | − ret = sdhci_runtime_resume_host(host); | |
| 641 | + ret = sdhci_runtime_resume_host(host, 0); | |
| 642 | 642 | if (ret) |
| 643 | 643 | goto out; |
| 644 | 644 | return 0; |
| @@ -3320,7 +3320,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host) · 3319 unmodified lines | ||
| 3320 | 3320 | } |
| 3321 | 3321 | EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host); |
| 3322 | 3322 | |
| 3323 | −int sdhci_runtime_resume_host(struct sdhci_host *host) | |
| 3323 | +int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset) | |
| 3324 | 3324 | { |
| 3325 | 3325 | struct mmc_host *mmc = host->mmc; |
| 3326 | 3326 | unsigned long flags; |
| @@ -3331,7 +3331,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) · 4 unmodified lines | ||
| 3331 | 3331 | host->ops->enable_dma(host); |
| 3332 | 3332 | } |
| 3333 | 3333 | |
| 3334 | − sdhci_init(host, 0); | |
| 3334 | + sdhci_init(host, soft_reset); | |
| 3335 | 3335 | |
| 3336 | 3336 | if (mmc->ios.power_mode != MMC_POWER_UNDEFINED && |
| 3337 | 3337 | mmc->ios.power_mode != MMC_POWER_OFF) { |
| @@ -781,7 +781,7 @@ void sdhci_adma_write_desc(struct sdhci_host *host, void **desc, · 780 unmodified lines | ||
| 781 | 781 | int sdhci_suspend_host(struct sdhci_host *host); |
| 782 | 782 | int sdhci_resume_host(struct sdhci_host *host); |
| 783 | 783 | int sdhci_runtime_suspend_host(struct sdhci_host *host); |
| 784 | −int sdhci_runtime_resume_host(struct sdhci_host *host); | |
| 784 | +int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset); | |
| 785 | 785 | #endif |
| 786 | 786 | |
| 787 | 787 | void sdhci_cqe_enable(struct mmc_host *mmc); |
| @@ -3780,8 +3780,6 @@ static int spi_nor_init_params(struct spi_nor *nor, · 3779 unmodified lines | ||
| 3780 | 3780 | default: |
| 3781 | 3781 | /* Kept only for backward compatibility purpose. */ |
| 3782 | 3782 | params->quad_enable = spansion_quad_enable; |
| 3783 | − if (nor->clear_sr_bp) | |
| 3784 | − nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp; | |
| 3785 | 3783 | break; |
| 3786 | 3784 | } |
| 3787 | 3785 | |
| @@ -4035,6 +4033,9 @@ static int spi_nor_init(struct spi_nor *nor) · 247 unmodified lines | ||
| 4035 | 4033 | int err; |
| 4036 | 4034 | |
| 4037 | 4035 | if (nor->clear_sr_bp) { |
| 4036 | + if (nor->quad_enable == spansion_quad_enable) | |
| 4037 | + nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp; | |
| 4038 | + | |
| 4038 | 4039 | err = nor->clear_sr_bp(nor); |
| 4039 | 4040 | if (err) { |
| 4040 | 4041 | dev_err(nor->dev, |
| @@ -1126,6 +1126,8 @@ static void bond_compute_features(struct bonding *bond) · 1125 unmodified lines | ||
| 1126 | 1126 | done: |
| 1127 | 1127 | bond_dev->vlan_features = vlan_features; |
| 1128 | 1128 | bond_dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | |
| 1129 | + NETIF_F_HW_VLAN_CTAG_TX | | |
| 1130 | + NETIF_F_HW_VLAN_STAG_TX | | |
| 1129 | 1131 | NETIF_F_GSO_UDP_L4; |
| 1130 | 1132 | bond_dev->mpls_features = mpls_features; |
| 1131 | 1133 | bond_dev->gso_max_segs = gso_max_segs; |
| @@ -1223,12 +1223,8 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port, · 1222 unmodified lines | ||
| 1223 | 1223 | { |
| 1224 | 1224 | struct sja1105_private *priv = ds->priv; |
| 1225 | 1225 | struct device *dev = ds->dev; |
| 1226 | − u16 rx_vid, tx_vid; | |
| 1227 | 1226 | int i; |
| 1228 | 1227 | |
| 1229 | − rx_vid = dsa_8021q_rx_vid(ds, port); | |
| 1230 | − tx_vid = dsa_8021q_tx_vid(ds, port); | |
| 1231 | − | |
| 1232 | 1228 | for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { |
| 1233 | 1229 | struct sja1105_l2_lookup_entry l2_lookup = {0}; |
| 1234 | 1230 | u8 macaddr[ETH_ALEN]; |
| @@ -3057,12 +3057,13 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link) · 3056 unmodified lines | ||
| 3057 | 3057 | /* if VF indicate to PF this function is going down (PF will delete sp |
| 3058 | 3058 | * elements and clear initializations |
| 3059 | 3059 | */ |
| 3060 | − if (IS_VF(bp)) | |
| 3060 | + if (IS_VF(bp)) { | |
| 3061 | + bnx2x_clear_vlan_info(bp); | |
| 3061 | 3062 | bnx2x_vfpf_close_vf(bp); |
| 3062 | − else if (unload_mode != UNLOAD_RECOVERY) | |
| 3063 | + } else if (unload_mode != UNLOAD_RECOVERY) { | |
| 3063 | 3064 | /* if this is a normal/close unload need to clean up chip*/ |
| 3064 | 3065 | bnx2x_chip_cleanup(bp, unload_mode, keep_link); |
| 3065 | − else { | |
| 3066 | + } else { | |
| 3066 | 3067 | /* Send the UNLOAD_REQUEST to the MCP */ |
| 3067 | 3068 | bnx2x_send_unload_req(bp, unload_mode); |
| 3068 | 3069 | |
| @@ -425,6 +425,8 @@ void bnx2x_set_reset_global(struct bnx2x *bp); · 424 unmodified lines | ||
| 425 | 425 | void bnx2x_disable_close_the_gate(struct bnx2x *bp); |
| 426 | 426 | int bnx2x_init_hw_func_cnic(struct bnx2x *bp); |
| 427 | 427 | |
| 428 | +void bnx2x_clear_vlan_info(struct bnx2x *bp); | |
| 429 | + | |
| 428 | 430 | /** |
| 429 | 431 | * bnx2x_sp_event - handle ramrods completion. |
| 430 | 432 | * |
| @@ -8482,11 +8482,21 @@ int bnx2x_set_vlan_one(struct bnx2x *bp, u16 vlan, · 8481 unmodified lines | ||
| 8482 | 8482 | return rc; |
| 8483 | 8483 | } |
| 8484 | 8484 | |
| 8485 | +void bnx2x_clear_vlan_info(struct bnx2x *bp) | |
| 8486 | +{ | |
| 8487 | + struct bnx2x_vlan_entry *vlan; | |
| 8488 | + | |
| 8489 | + /* Mark that hw forgot all entries */ | |
| 8490 | + list_for_each_entry(vlan, &bp->vlan_reg, link) | |
| 8491 | + vlan->hw = false; | |
| 8492 | + | |
| 8493 | + bp->vlan_cnt = 0; | |
| 8494 | +} | |
| 8495 | + | |
| 8485 | 8496 | static int bnx2x_del_all_vlans(struct bnx2x *bp) |
| 8486 | 8497 | { |
| 8487 | 8498 | struct bnx2x_vlan_mac_obj *vlan_obj = &bp->sp_objs[0].vlan_obj; |
| 8488 | 8499 | unsigned long ramrod_flags = 0, vlan_flags = 0; |
| 8489 | − struct bnx2x_vlan_entry *vlan; | |
| 8490 | 8500 | int rc; |
| 8491 | 8501 | |
| 8492 | 8502 | __set_bit(RAMROD_COMP_WAIT, &ramrod_flags); |
| @@ -8495,10 +8505,7 @@ static int bnx2x_del_all_vlans(struct bnx2x *bp) · 2 unmodified lines | ||
| 8495 | 8505 | if (rc) |
| 8496 | 8506 | return rc; |
| 8497 | 8507 | |
| 8498 | − /* Mark that hw forgot all entries */ | |
| 8499 | − list_for_each_entry(vlan, &bp->vlan_reg, link) | |
| 8500 | − vlan->hw = false; | |
| 8501 | − bp->vlan_cnt = 0; | |
| 8508 | + bnx2x_clear_vlan_info(bp); | |
| 8502 | 8509 | |
| 8503 | 8510 | return 0; |
| 8504 | 8511 | } |
| @@ -2152,9 +2152,9 @@ static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi) · 2151 unmodified lines | ||
| 2152 | 2152 | if (bnapi->events & BNXT_RX_EVENT) { |
| 2153 | 2153 | struct bnxt_rx_ring_info *rxr = bnapi->rx_ring; |
| 2154 | 2154 | |
| 2155 | − bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); | |
| 2156 | 2155 | if (bnapi->events & BNXT_AGG_EVENT) |
| 2157 | 2156 | bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); |
| 2157 | + bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); | |
| 2158 | 2158 | } |
| 2159 | 2159 | bnapi->events = 0; |
| 2160 | 2160 | } |
| @@ -5255,6 +5255,7 @@ static void bnxt_set_db(struct bnxt *bp, struct bnxt_db_info *db, u32 ring_type, · 3094 unmodified lines | ||
| 5255 | 5255 | |
| 5256 | 5256 | static int bnxt_hwrm_ring_alloc(struct bnxt *bp) |
| 5257 | 5257 | { |
| 5258 | + bool agg_rings = !!(bp->flags & BNXT_FLAG_AGG_RINGS); | |
| 5258 | 5259 | int i, rc = 0; |
| 5259 | 5260 | u32 type; |
| 5260 | 5261 | |
| @@ -5330,7 +5331,9 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp) · 69 unmodified lines | ||
| 5330 | 5331 | if (rc) |
| 5331 | 5332 | goto err_out; |
| 5332 | 5333 | bnxt_set_db(bp, &rxr->rx_db, type, map_idx, ring->fw_ring_id); |
| 5333 | − bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); | |
| 5334 | + /* If we have agg rings, post agg buffers first. */ | |
| 5335 | + if (!agg_rings) | |
| 5336 | + bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); | |
| 5334 | 5337 | bp->grp_info[map_idx].rx_fw_ring_id = ring->fw_ring_id; |
| 5335 | 5338 | if (bp->flags & BNXT_FLAG_CHIP_P5) { |
| 5336 | 5339 | struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; |
| @@ -5349,7 +5352,7 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp) · 12 unmodified lines | ||
| 5349 | 5352 | } |
| 5350 | 5353 | } |
| 5351 | 5354 | |
| 5352 | − if (bp->flags & BNXT_FLAG_AGG_RINGS) { | |
| 5355 | + if (agg_rings) { | |
| 5353 | 5356 | type = HWRM_RING_ALLOC_AGG; |
| 5354 | 5357 | for (i = 0; i < bp->rx_nr_rings; i++) { |
| 5355 | 5358 | struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; |
| @@ -5365,6 +5368,7 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp) · 9 unmodified lines | ||
| 5365 | 5368 | bnxt_set_db(bp, &rxr->rx_agg_db, type, map_idx, |
| 5366 | 5369 | ring->fw_ring_id); |
| 5367 | 5370 | bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); |
| 5371 | + bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod); | |
| 5368 | 5372 | bp->grp_info[grp_idx].agg_fw_ring_id = ring->fw_ring_id; |
| 5369 | 5373 | } |
| 5370 | 5374 | } |
| @@ -7208,19 +7212,29 @@ static void bnxt_hwrm_clear_vnic_rss(struct bnxt *bp) · 1837 unmodified lines | ||
| 7208 | 7212 | bnxt_hwrm_vnic_set_rss(bp, i, false); |
| 7209 | 7213 | } |
| 7210 | 7214 | |
| 7211 | −static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path, | |
| 7212 | − bool irq_re_init) | |
| 7215 | +static void bnxt_clear_vnic(struct bnxt *bp) | |
| 7213 | 7216 | { |
| 7214 | − if (bp->vnic_info) { | |
| 7215 | − bnxt_hwrm_clear_vnic_filter(bp); | |
| 7217 | + if (!bp->vnic_info) | |
| 7218 | + return; | |
| 7219 | + | |
| 7220 | + bnxt_hwrm_clear_vnic_filter(bp); | |
| 7221 | + if (!(bp->flags & BNXT_FLAG_CHIP_P5)) { | |
| 7216 | 7222 | /* clear all RSS setting before free vnic ctx */ |
| 7217 | 7223 | bnxt_hwrm_clear_vnic_rss(bp); |
| 7218 | 7224 | bnxt_hwrm_vnic_ctx_free(bp); |
| 7219 | − /* before free the vnic, undo the vnic tpa settings */ | |
| 7220 | − if (bp->flags & BNXT_FLAG_TPA) | |
| 7221 | − bnxt_set_tpa(bp, false); | |
| 7222 | − bnxt_hwrm_vnic_free(bp); | |
| 7223 | 7225 | } |
| 7226 | + /* before free the vnic, undo the vnic tpa settings */ | |
| 7227 | + if (bp->flags & BNXT_FLAG_TPA) | |
| 7228 | + bnxt_set_tpa(bp, false); | |
| 7229 | + bnxt_hwrm_vnic_free(bp); | |
| 7230 | + if (bp->flags & BNXT_FLAG_CHIP_P5) | |
| 7231 | + bnxt_hwrm_vnic_ctx_free(bp); | |
| 7232 | +} | |
| 7233 | + | |
| 7234 | +static void bnxt_hwrm_resource_free(struct bnxt *bp, bool close_path, | |
| 7235 | + bool irq_re_init) | |
| 7236 | +{ | |
| 7237 | + bnxt_clear_vnic(bp); | |
| 7224 | 7238 | bnxt_hwrm_ring_free(bp, close_path); |
| 7225 | 7239 | bnxt_hwrm_ring_grp_free(bp); |
| 7226 | 7240 | if (irq_re_init) { |
| @@ -98,10 +98,13 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, · 97 unmodified lines | ||
| 98 | 98 | if (idx) |
| 99 | 99 | req->dimensions = cpu_to_le16(1); |
| 100 | 100 | |
| 101 | − if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) | |
| 101 | + if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) { | |
| 102 | 102 | memcpy(data_addr, buf, bytesize); |
| 103 | − | |
| 104 | − rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT); | |
| 103 | + rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT); | |
| 104 | + } else { | |
| 105 | + rc = hwrm_send_message_silent(bp, msg, msg_len, | |
| 106 | + HWRM_CMD_TIMEOUT); | |
| 107 | + } | |
| 105 | 108 | if (!rc && req->req_type == cpu_to_le16(HWRM_NVM_GET_VARIABLE)) |
| 106 | 109 | memcpy(buf, data_addr, bytesize); |
| 107 | 110 | |
| @@ -2072,21 +2072,19 @@ static int bnxt_flash_package_from_file(struct net_device *dev, · 2071 unmodified lines | ||
| 2072 | 2072 | mutex_lock(&bp->hwrm_cmd_lock); |
| 2073 | 2073 | hwrm_err = _hwrm_send_message(bp, &install, sizeof(install), |
| 2074 | 2074 | INSTALL_PACKAGE_TIMEOUT); |
| 2075 | − if (hwrm_err) | |
| 2076 | − goto flash_pkg_exit; | |
| 2077 | − | |
| 2078 | − if (resp->error_code) { | |
| 2075 | + if (hwrm_err) { | |
| 2079 | 2076 | u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err; |
| 2080 | 2077 | |
| 2081 | − if (error_code == NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { | |
| 2078 | + if (resp->error_code && error_code == | |
| 2079 | + NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { | |
| 2082 | 2080 | install.flags |= cpu_to_le16( |
| 2083 | 2081 | NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); |
| 2084 | 2082 | hwrm_err = _hwrm_send_message(bp, &install, |
| 2085 | 2083 | sizeof(install), |
| 2086 | 2084 | INSTALL_PACKAGE_TIMEOUT); |
| 2087 | − if (hwrm_err) | |
| 2088 | − goto flash_pkg_exit; | |
| 2089 | 2085 | } |
| 2086 | + if (hwrm_err) | |
| 2087 | + goto flash_pkg_exit; | |
| 2090 | 2088 | } |
| 2091 | 2089 | |
| 2092 | 2090 | if (resp->result) { |
| @@ -1236,7 +1236,7 @@ static int __bnxt_tc_del_flow(struct bnxt *bp, · 1235 unmodified lines | ||
| 1236 | 1236 | static void bnxt_tc_set_flow_dir(struct bnxt *bp, struct bnxt_tc_flow *flow, |
| 1237 | 1237 | u16 src_fid) |
| 1238 | 1238 | { |
| 1239 | − flow->dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX; | |
| 1239 | + flow->l2_key.dir = (bp->pf.fw_fid == src_fid) ? BNXT_DIR_RX : BNXT_DIR_TX; | |
| 1240 | 1240 | } |
| 1241 | 1241 | |
| 1242 | 1242 | static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, |
| @@ -1285,9 +1285,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, · 42 unmodified lines | ||
| 1285 | 1285 | goto free_node; |
| 1286 | 1286 | |
| 1287 | 1287 | bnxt_tc_set_src_fid(bp, flow, src_fid); |
| 1288 | − | |
| 1289 | − if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE) | |
| 1290 | − bnxt_tc_set_flow_dir(bp, flow, src_fid); | |
| 1288 | + bnxt_tc_set_flow_dir(bp, flow, flow->src_fid); | |
| 1291 | 1289 | |
| 1292 | 1290 | if (!bnxt_tc_can_offload(bp, flow)) { |
| 1293 | 1291 | rc = -EOPNOTSUPP; |
| @@ -1407,7 +1405,7 @@ static void bnxt_fill_cfa_stats_req(struct bnxt *bp, · 113 unmodified lines | ||
| 1407 | 1405 | * 2. 15th bit of flow_handle must specify the flow |
| 1408 | 1406 | * direction (TX/RX). |
| 1409 | 1407 | */ |
| 1410 | − if (flow_node->flow.dir == BNXT_DIR_RX) | |
| 1408 | + if (flow_node->flow.l2_key.dir == BNXT_DIR_RX) | |
| 1411 | 1409 | handle = CFA_FLOW_INFO_REQ_FLOW_HANDLE_DIR_RX | |
| 1412 | 1410 | CFA_FLOW_INFO_REQ_FLOW_HANDLE_MAX_MASK; |
| 1413 | 1411 | else |
| @@ -23,6 +23,9 @@ struct bnxt_tc_l2_key { · 22 unmodified lines | ||
| 23 | 23 | __be16 inner_vlan_tci; |
| 24 | 24 | __be16 ether_type; |
| 25 | 25 | u8 num_vlans; |
| 26 | + u8 dir; | |
| 27 | +#define BNXT_DIR_RX 1 | |
| 28 | +#define BNXT_DIR_TX 0 | |
| 26 | 29 | }; |
| 27 | 30 | |
| 28 | 31 | struct bnxt_tc_l3_key { |
| @@ -98,9 +101,6 @@ struct bnxt_tc_flow { · 69 unmodified lines | ||
| 98 | 101 | |
| 99 | 102 | /* flow applicable to pkts ingressing on this fid */ |
| 100 | 103 | u16 src_fid; |
| 101 | − u8 dir; | |
| 102 | −#define BNXT_DIR_RX 1 | |
| 103 | −#define BNXT_DIR_TX 0 | |
| 104 | 104 | struct bnxt_tc_l2_key l2_key; |
| 105 | 105 | struct bnxt_tc_l2_key l2_mask; |
| 106 | 106 | struct bnxt_tc_l3_key l3_key; |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #include "cavium_ptp.h" |
| 12 | 12 | |
| 13 | −#define DRV_NAME "Cavium PTP Driver" | |
| 13 | +#define DRV_NAME "cavium_ptp" | |
| 14 | 14 | |
| 15 | 15 | #define PCI_DEVICE_ID_CAVIUM_PTP 0xA00C |
| 16 | 16 | #define PCI_DEVICE_ID_CAVIUM_RST 0xA00E |
| @@ -237,8 +237,10 @@ int octeon_setup_iq(struct octeon_device *oct, · 236 unmodified lines | ||
| 237 | 237 | } |
| 238 | 238 | |
| 239 | 239 | oct->num_iqs++; |
| 240 | − if (oct->fn_list.enable_io_queues(oct)) | |
| 240 | + if (oct->fn_list.enable_io_queues(oct)) { | |
| 241 | + octeon_delete_instr_queue(oct, iq_no); | |
| 241 | 242 | return 1; |
| 243 | + } | |
| 242 | 244 | |
| 243 | 245 | return 0; |
| 244 | 246 | } |
| @@ -3236,8 +3236,10 @@ static ssize_t blocked_fl_write(struct file *filp, const char __user *ubuf, · 3235 unmodified lines | ||
| 3236 | 3236 | return -ENOMEM; |
| 3237 | 3237 | |
| 3238 | 3238 | err = bitmap_parse_user(ubuf, count, t, adap->sge.egr_sz); |
| 3239 | − if (err) | |
| 3239 | + if (err) { | |
| 3240 | + kvfree(t); | |
| 3240 | 3241 | return err; |
| 3242 | + } | |
| 3241 | 3243 | |
| 3242 | 3244 | bitmap_copy(adap->sge.blocked_fl, t, adap->sge.egr_sz); |
| 3243 | 3245 | kvfree(t); |
| @@ -167,7 +167,7 @@ struct nps_enet_priv { · 166 unmodified lines | ||
| 167 | 167 | }; |
| 168 | 168 | |
| 169 | 169 | /** |
| 170 | − * nps_reg_set - Sets ENET register with provided value. | |
| 170 | + * nps_enet_reg_set - Sets ENET register with provided value. | |
| 171 | 171 | * @priv: Pointer to EZchip ENET private data structure. |
| 172 | 172 | * @reg: Register offset from base address. |
| 173 | 173 | * @value: Value to set in register. |
| @@ -179,7 +179,7 @@ static inline void nps_enet_reg_set(struct nps_enet_priv *priv, · 5 unmodified lines | ||
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | /** |
| 182 | − * nps_reg_get - Gets value of specified ENET register. | |
| 182 | + * nps_enet_reg_get - Gets value of specified ENET register. | |
| 183 | 183 | * @priv: Pointer to EZchip ENET private data structure. |
| 184 | 184 | * @reg: Register offset from base address. |
| 185 | 185 | * |
| @@ -1605,7 +1605,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) · 1604 unmodified lines | ||
| 1605 | 1605 | struct net_device *netdev; |
| 1606 | 1606 | struct ibmveth_adapter *adapter; |
| 1607 | 1607 | unsigned char *mac_addr_p; |
| 1608 | − unsigned int *mcastFilterSize_p; | |
| 1608 | + __be32 *mcastFilterSize_p; | |
| 1609 | 1609 | long ret; |
| 1610 | 1610 | unsigned long ret_attr; |
| 1611 | 1611 | |
| @@ -1627,8 +1627,9 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) · 15 unmodified lines | ||
| 1627 | 1627 | return -EINVAL; |
| 1628 | 1628 | } |
| 1629 | 1629 | |
| 1630 | − mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev, | |
| 1631 | − VETH_MCAST_FILTER_SIZE, NULL); | |
| 1630 | + mcastFilterSize_p = (__be32 *)vio_get_attribute(dev, | |
| 1631 | + VETH_MCAST_FILTER_SIZE, | |
| 1632 | + NULL); | |
| 1632 | 1633 | if (!mcastFilterSize_p) { |
| 1633 | 1634 | dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE " |
| 1634 | 1635 | "attribute\n"); |
| @@ -1645,7 +1646,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) · 10 unmodified lines | ||
| 1645 | 1646 | |
| 1646 | 1647 | adapter->vdev = dev; |
| 1647 | 1648 | adapter->netdev = netdev; |
| 1648 | − adapter->mcastFilterSize = *mcastFilterSize_p; | |
| 1649 | + adapter->mcastFilterSize = be32_to_cpu(*mcastFilterSize_p); | |
| 1649 | 1650 | adapter->pool_config = 0; |
| 1650 | 1651 | |
| 1651 | 1652 | netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); |
| @@ -1568,6 +1568,8 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) · 1567 unmodified lines | ||
| 1568 | 1568 | lpar_rc = send_subcrq_indirect(adapter, handle_array[queue_num], |
| 1569 | 1569 | (u64)tx_buff->indir_dma, |
| 1570 | 1570 | (u64)num_entries); |
| 1571 | + dma_unmap_single(dev, tx_buff->indir_dma, | |
| 1572 | + sizeof(tx_buff->indir_arr), DMA_TO_DEVICE); | |
| 1571 | 1573 | } else { |
| 1572 | 1574 | tx_buff->num_entries = num_entries; |
| 1573 | 1575 | lpar_rc = send_subcrq(adapter, handle_array[queue_num], |
| @@ -2788,7 +2790,6 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter, · 1214 unmodified lines | ||
| 2788 | 2790 | union sub_crq *next; |
| 2789 | 2791 | int index; |
| 2790 | 2792 | int i, j; |
| 2791 | − u8 *first; | |
| 2792 | 2793 | |
| 2793 | 2794 | restart_loop: |
| 2794 | 2795 | while (pending_scrq(adapter, scrq)) { |
| @@ -2818,14 +2819,6 @@ restart_loop: · 23 unmodified lines | ||
| 2818 | 2819 | |
| 2819 | 2820 | txbuff->data_dma[j] = 0; |
| 2820 | 2821 | } |
| 2821 | − /* if sub_crq was sent indirectly */ | |
| 2822 | − first = &txbuff->indir_arr[0].generic.first; | |
| 2823 | − if (*first == IBMVNIC_CRQ_CMD) { | |
| 2824 | − dma_unmap_single(dev, txbuff->indir_dma, | |
| 2825 | − sizeof(txbuff->indir_arr), | |
| 2826 | − DMA_TO_DEVICE); | |
| 2827 | − *first = 0; | |
| 2828 | − } | |
| 2829 | 2822 | |
| 2830 | 2823 | if (txbuff->last_frag) { |
| 2831 | 2824 | dev_kfree_skb_any(txbuff->skb); |
| @@ -7897,11 +7897,8 @@ static void ixgbe_service_task(struct work_struct *work) · 7896 unmodified lines | ||
| 7897 | 7897 | return; |
| 7898 | 7898 | } |
| 7899 | 7899 | if (ixgbe_check_fw_error(adapter)) { |
| 7900 | − if (!test_bit(__IXGBE_DOWN, &adapter->state)) { | |
| 7901 | − rtnl_lock(); | |
| 7900 | + if (!test_bit(__IXGBE_DOWN, &adapter->state)) | |
| 7902 | 7901 | unregister_netdev(adapter->netdev); |
| 7903 | − rtnl_unlock(); | |
| 7904 | − } | |
| 7905 | 7902 | ixgbe_service_event_complete(adapter); |
| 7906 | 7903 | return; |
| 7907 | 7904 | } |
| @@ -1187,7 +1187,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) · 1186 unmodified lines | ||
| 1187 | 1187 | err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp); |
| 1188 | 1188 | if (err) { |
| 1189 | 1189 | en_err(priv, "Failed to allocate RSS indirection QP\n"); |
| 1190 | − goto rss_err; | |
| 1190 | + goto qp_alloc_err; | |
| 1191 | 1191 | } |
| 1192 | 1192 | |
| 1193 | 1193 | rss_map->indir_qp->event = mlx4_en_sqp_event; |
| @@ -1241,6 +1241,7 @@ indir_err: · 47 unmodified lines | ||
| 1241 | 1241 | MLX4_QP_STATE_RST, NULL, 0, 0, rss_map->indir_qp); |
| 1242 | 1242 | mlx4_qp_remove(mdev->dev, rss_map->indir_qp); |
| 1243 | 1243 | mlx4_qp_free(mdev->dev, rss_map->indir_qp); |
| 1244 | +qp_alloc_err: | |
| 1244 | 1245 | kfree(rss_map->indir_qp); |
| 1245 | 1246 | rss_map->indir_qp = NULL; |
| 1246 | 1247 | rss_err: |
| @@ -184,8 +184,13 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) · 183 unmodified lines | ||
| 184 | 184 | |
| 185 | 185 | struct mlx5e_tx_wqe { |
| 186 | 186 | struct mlx5_wqe_ctrl_seg ctrl; |
| 187 | − struct mlx5_wqe_eth_seg eth; | |
| 188 | − struct mlx5_wqe_data_seg data[0]; | |
| 187 | + union { | |
| 188 | + struct { | |
| 189 | + struct mlx5_wqe_eth_seg eth; | |
| 190 | + struct mlx5_wqe_data_seg data[0]; | |
| 191 | + }; | |
| 192 | + u8 tls_progress_params_ctx[0]; | |
| 193 | + }; | |
| 189 | 194 | }; |
| 190 | 195 | |
| 191 | 196 | struct mlx5e_rx_wqe_ll { |
| @@ -1099,6 +1104,8 @@ u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv); · 907 unmodified lines | ||
| 1099 | 1104 | u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv); |
| 1100 | 1105 | int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv, |
| 1101 | 1106 | struct ethtool_ts_info *info); |
| 1107 | +int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv, | |
| 1108 | + struct ethtool_flash *flash); | |
| 1102 | 1109 | void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv, |
| 1103 | 1110 | struct ethtool_pauseparam *pauseparam); |
| 1104 | 1111 | int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, |
| @@ -75,26 +75,21 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq) · 74 unmodified lines | ||
| 75 | 75 | u8 state; |
| 76 | 76 | int err; |
| 77 | 77 | |
| 78 | − if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) | |
| 79 | − return 0; | |
| 80 | − | |
| 81 | 78 | err = mlx5_core_query_sq_state(mdev, sq->sqn, &state); |
| 82 | 79 | if (err) { |
| 83 | 80 | netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n", |
| 84 | 81 | sq->sqn, err); |
| 85 | − return err; | |
| 82 | + goto out; | |
| 86 | 83 | } |
| 87 | 84 | |
| 88 | − if (state != MLX5_SQC_STATE_ERR) { | |
| 89 | − netdev_err(dev, "SQ 0x%x not in ERROR state\n", sq->sqn); | |
| 90 | − return -EINVAL; | |
| 91 | − } | |
| 85 | + if (state != MLX5_SQC_STATE_ERR) | |
| 86 | + goto out; | |
| 92 | 87 | |
| 93 | 88 | mlx5e_tx_disable_queue(sq->txq); |
| 94 | 89 | |
| 95 | 90 | err = mlx5e_wait_for_sq_flush(sq); |
| 96 | 91 | if (err) |
| 97 | − return err; | |
| 92 | + goto out; | |
| 98 | 93 | |
| 99 | 94 | /* At this point, no new packets will arrive from the stack as TXQ is |
| 100 | 95 | * marked with QUEUE_STATE_DRV_XOFF. In addition, NAPI cleared all |
| @@ -103,13 +98,17 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq) · 2 unmodified lines | ||
| 103 | 98 | |
| 104 | 99 | err = mlx5e_sq_to_ready(sq, state); |
| 105 | 100 | if (err) |
| 106 | − return err; | |
| 101 | + goto out; | |
| 107 | 102 | |
| 108 | 103 | mlx5e_reset_txqsq_cc_pc(sq); |
| 109 | 104 | sq->stats->recover++; |
| 105 | + clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); | |
| 110 | 106 | mlx5e_activate_txqsq(sq); |
| 111 | 107 | |
| 112 | 108 | return 0; |
| 109 | +out: | |
| 110 | + clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); | |
| 111 | + return err; | |
| 113 | 112 | } |
| 114 | 113 | |
| 115 | 114 | static int mlx5_tx_health_report(struct devlink_health_reporter *tx_reporter, |
| @@ -152,7 +152,10 @@ void mlx5e_activate_xsk(struct mlx5e_channel *c) · 151 unmodified lines | ||
| 152 | 152 | { |
| 153 | 153 | set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state); |
| 154 | 154 | /* TX queue is created active. */ |
| 155 | + | |
| 156 | + spin_lock(&c->xskicosq_lock); | |
| 155 | 157 | mlx5e_trigger_irq(&c->xskicosq); |
| 158 | + spin_unlock(&c->xskicosq_lock); | |
| 156 | 159 | } |
| 157 | 160 | |
| 158 | 161 | void mlx5e_deactivate_xsk(struct mlx5e_channel *c) |
| @@ -11,12 +11,14 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "accel/tls.h" |
| 12 | 12 | |
| 13 | 13 | #define MLX5E_KTLS_STATIC_UMR_WQE_SZ \ |
| 14 | − (sizeof(struct mlx5e_umr_wqe) + MLX5_ST_SZ_BYTES(tls_static_params)) | |
| 14 | + (offsetof(struct mlx5e_umr_wqe, tls_static_params_ctx) + \ | |
| 15 | + MLX5_ST_SZ_BYTES(tls_static_params)) | |
| 15 | 16 | #define MLX5E_KTLS_STATIC_WQEBBS \ |
| 16 | 17 | (DIV_ROUND_UP(MLX5E_KTLS_STATIC_UMR_WQE_SZ, MLX5_SEND_WQE_BB)) |
| 17 | 18 | |
| 18 | 19 | #define MLX5E_KTLS_PROGRESS_WQE_SZ \ |
| 19 | − (sizeof(struct mlx5e_tx_wqe) + MLX5_ST_SZ_BYTES(tls_progress_params)) | |
| 20 | + (offsetof(struct mlx5e_tx_wqe, tls_progress_params_ctx) + \ | |
| 21 | + MLX5_ST_SZ_BYTES(tls_progress_params)) | |
| 20 | 22 | #define MLX5E_KTLS_PROGRESS_WQEBBS \ |
| 21 | 23 | (DIV_ROUND_UP(MLX5E_KTLS_PROGRESS_WQE_SZ, MLX5_SEND_WQE_BB)) |
| 22 | 24 | #define MLX5E_KTLS_MAX_DUMP_WQEBBS 2 |
| @@ -69,7 +69,7 @@ build_static_params(struct mlx5e_umr_wqe *wqe, u16 pc, u32 sqn, · 68 unmodified lines | ||
| 69 | 69 | cseg->qpn_ds = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) | |
| 70 | 70 | STATIC_PARAMS_DS_CNT); |
| 71 | 71 | cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0; |
| 72 | − cseg->imm = cpu_to_be32(priv_tx->tisn); | |
| 72 | + cseg->tisn = cpu_to_be32(priv_tx->tisn << 8); | |
| 73 | 73 | |
| 74 | 74 | ucseg->flags = MLX5_UMR_INLINE; |
| 75 | 75 | ucseg->bsf_octowords = cpu_to_be16(MLX5_ST_SZ_BYTES(tls_static_params) / 16); |
| @@ -80,7 +80,7 @@ build_static_params(struct mlx5e_umr_wqe *wqe, u16 pc, u32 sqn, · 4 unmodified lines | ||
| 80 | 80 | static void |
| 81 | 81 | fill_progress_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx) |
| 82 | 82 | { |
| 83 | − MLX5_SET(tls_progress_params, ctx, pd, priv_tx->tisn); | |
| 83 | + MLX5_SET(tls_progress_params, ctx, tisn, priv_tx->tisn); | |
| 84 | 84 | MLX5_SET(tls_progress_params, ctx, record_tracker_state, |
| 85 | 85 | MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START); |
| 86 | 86 | MLX5_SET(tls_progress_params, ctx, auth_state, |
| @@ -104,7 +104,7 @@ build_progress_params(struct mlx5e_tx_wqe *wqe, u16 pc, u32 sqn, · 17 unmodified lines | ||
| 104 | 104 | PROGRESS_PARAMS_DS_CNT); |
| 105 | 105 | cseg->fm_ce_se = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0; |
| 106 | 106 | |
| 107 | − fill_progress_params_ctx(wqe->data, priv_tx); | |
| 107 | + fill_progress_params_ctx(wqe->tls_progress_params_ctx, priv_tx); | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | static void tx_fill_wi(struct mlx5e_txqsq *sq, |
| @@ -278,7 +278,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 167 unmodified lines | ||
| 278 | 278 | |
| 279 | 279 | cseg->opmod_idx_opcode = cpu_to_be32((sq->pc << 8) | MLX5_OPCODE_DUMP); |
| 280 | 280 | cseg->qpn_ds = cpu_to_be32((sq->sqn << 8) | ds_cnt); |
| 281 | − cseg->imm = cpu_to_be32(tisn); | |
| 281 | + cseg->tisn = cpu_to_be32(tisn << 8); | |
| 282 | 282 | cseg->fm_ce_se = first ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0; |
| 283 | 283 | |
| 284 | 284 | eseg->inline_hdr.sz = cpu_to_be16(ihs); |
| @@ -434,7 +434,7 @@ struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev, · 149 unmodified lines | ||
| 434 | 434 | priv_tx->expected_seq = seq + datalen; |
| 435 | 435 | |
| 436 | 436 | cseg = &(*wqe)->ctrl; |
| 437 | − cseg->imm = cpu_to_be32(priv_tx->tisn); | |
| 437 | + cseg->tisn = cpu_to_be32(priv_tx->tisn << 8); | |
| 438 | 438 | |
| 439 | 439 | stats->tls_encrypted_packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; |
| 440 | 440 | stats->tls_encrypted_bytes += datalen; |
| @@ -437,12 +437,6 @@ arfs_hash_bucket(struct arfs_table *arfs_t, __be16 src_port, · 436 unmodified lines | ||
| 437 | 437 | return &arfs_t->rules_hash[bucket_idx]; |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | −static u8 arfs_get_ip_proto(const struct sk_buff *skb) | |
| 441 | −{ | |
| 442 | − return (skb->protocol == htons(ETH_P_IP)) ? | |
| 443 | − ip_hdr(skb)->protocol : ipv6_hdr(skb)->nexthdr; | |
| 444 | −} | |
| 445 | − | |
| 446 | 440 | static struct arfs_table *arfs_get_table(struct mlx5e_arfs_tables *arfs, |
| 447 | 441 | u8 ip_proto, __be16 etype) |
| 448 | 442 | { |
| @@ -602,31 +596,9 @@ out: · 153 unmodified lines | ||
| 602 | 596 | arfs_may_expire_flow(priv); |
| 603 | 597 | } |
| 604 | 598 | |
| 605 | −/* return L4 destination port from ip4/6 packets */ | |
| 606 | −static __be16 arfs_get_dst_port(const struct sk_buff *skb) | |
| 607 | −{ | |
| 608 | − char *transport_header; | |
| 609 | − | |
| 610 | − transport_header = skb_transport_header(skb); | |
| 611 | − if (arfs_get_ip_proto(skb) == IPPROTO_TCP) | |
| 612 | − return ((struct tcphdr *)transport_header)->dest; | |
| 613 | − return ((struct udphdr *)transport_header)->dest; | |
| 614 | −} | |
| 615 | − | |
| 616 | −/* return L4 source port from ip4/6 packets */ | |
| 617 | −static __be16 arfs_get_src_port(const struct sk_buff *skb) | |
| 618 | −{ | |
| 619 | − char *transport_header; | |
| 620 | − | |
| 621 | − transport_header = skb_transport_header(skb); | |
| 622 | − if (arfs_get_ip_proto(skb) == IPPROTO_TCP) | |
| 623 | − return ((struct tcphdr *)transport_header)->source; | |
| 624 | − return ((struct udphdr *)transport_header)->source; | |
| 625 | −} | |
| 626 | − | |
| 627 | 599 | static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv, |
| 628 | 600 | struct arfs_table *arfs_t, |
| 629 | − const struct sk_buff *skb, | |
| 601 | + const struct flow_keys *fk, | |
| 630 | 602 | u16 rxq, u32 flow_id) |
| 631 | 603 | { |
| 632 | 604 | struct arfs_rule *rule; |
| @@ -641,19 +613,19 @@ static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv, · 8 unmodified lines | ||
| 641 | 613 | INIT_WORK(&rule->arfs_work, arfs_handle_work); |
| 642 | 614 | |
| 643 | 615 | tuple = &rule->tuple; |
| 644 | − tuple->etype = skb->protocol; | |
| 616 | + tuple->etype = fk->basic.n_proto; | |
| 617 | + tuple->ip_proto = fk->basic.ip_proto; | |
| 645 | 618 | if (tuple->etype == htons(ETH_P_IP)) { |
| 646 | − tuple->src_ipv4 = ip_hdr(skb)->saddr; | |
| 647 | − tuple->dst_ipv4 = ip_hdr(skb)->daddr; | |
| 619 | + tuple->src_ipv4 = fk->addrs.v4addrs.src; | |
| 620 | + tuple->dst_ipv4 = fk->addrs.v4addrs.dst; | |
| 648 | 621 | } else { |
| 649 | − memcpy(&tuple->src_ipv6, &ipv6_hdr(skb)->saddr, | |
| 622 | + memcpy(&tuple->src_ipv6, &fk->addrs.v6addrs.src, | |
| 650 | 623 | sizeof(struct in6_addr)); |
| 651 | − memcpy(&tuple->dst_ipv6, &ipv6_hdr(skb)->daddr, | |
| 624 | + memcpy(&tuple->dst_ipv6, &fk->addrs.v6addrs.dst, | |
| 652 | 625 | sizeof(struct in6_addr)); |
| 653 | 626 | } |
| 654 | − tuple->ip_proto = arfs_get_ip_proto(skb); | |
| 655 | − tuple->src_port = arfs_get_src_port(skb); | |
| 656 | − tuple->dst_port = arfs_get_dst_port(skb); | |
| 627 | + tuple->src_port = fk->ports.src; | |
| 628 | + tuple->dst_port = fk->ports.dst; | |
| 657 | 629 | |
| 658 | 630 | rule->flow_id = flow_id; |
| 659 | 631 | rule->filter_id = priv->fs.arfs.last_filter_id++ % RPS_NO_FILTER; |
| @@ -664,37 +636,33 @@ static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv, · 4 unmodified lines | ||
| 664 | 636 | return rule; |
| 665 | 637 | } |
| 666 | 638 | |
| 667 | −static bool arfs_cmp_ips(struct arfs_tuple *tuple, | |
| 668 | − const struct sk_buff *skb) | |
| 639 | +static bool arfs_cmp(const struct arfs_tuple *tuple, const struct flow_keys *fk) | |
| 669 | 640 | { |
| 670 | − if (tuple->etype == htons(ETH_P_IP) && | |
| 671 | − tuple->src_ipv4 == ip_hdr(skb)->saddr && | |
| 672 | − tuple->dst_ipv4 == ip_hdr(skb)->daddr) | |
| 673 | − return true; | |
| 674 | − if (tuple->etype == htons(ETH_P_IPV6) && | |
| 675 | − (!memcmp(&tuple->src_ipv6, &ipv6_hdr(skb)->saddr, | |
| 676 | − sizeof(struct in6_addr))) && | |
| 677 | − (!memcmp(&tuple->dst_ipv6, &ipv6_hdr(skb)->daddr, | |
| 678 | − sizeof(struct in6_addr)))) | |
| 679 | − return true; | |
| 641 | + if (tuple->src_port != fk->ports.src || tuple->dst_port != fk->ports.dst) | |
| 642 | + return false; | |
| 643 | + if (tuple->etype != fk->basic.n_proto) | |
| 644 | + return false; | |
| 645 | + if (tuple->etype == htons(ETH_P_IP)) | |
| 646 | + return tuple->src_ipv4 == fk->addrs.v4addrs.src && | |
| 647 | + tuple->dst_ipv4 == fk->addrs.v4addrs.dst; | |
| 648 | + if (tuple->etype == htons(ETH_P_IPV6)) | |
| 649 | + return !memcmp(&tuple->src_ipv6, &fk->addrs.v6addrs.src, | |
| 650 | + sizeof(struct in6_addr)) && | |
| 651 | + !memcmp(&tuple->dst_ipv6, &fk->addrs.v6addrs.dst, | |
| 652 | + sizeof(struct in6_addr)); | |
| 680 | 653 | return false; |
| 681 | 654 | } |
| 682 | 655 | |
| 683 | 656 | static struct arfs_rule *arfs_find_rule(struct arfs_table *arfs_t, |
| 684 | − const struct sk_buff *skb) | |
| 657 | + const struct flow_keys *fk) | |
| 685 | 658 | { |
| 686 | 659 | struct arfs_rule *arfs_rule; |
| 687 | 660 | struct hlist_head *head; |
| 688 | − __be16 src_port = arfs_get_src_port(skb); | |
| 689 | − __be16 dst_port = arfs_get_dst_port(skb); | |
| 690 | 661 | |
| 691 | − head = arfs_hash_bucket(arfs_t, src_port, dst_port); | |
| 662 | + head = arfs_hash_bucket(arfs_t, fk->ports.src, fk->ports.dst); | |
| 692 | 663 | hlist_for_each_entry(arfs_rule, head, hlist) { |
| 693 | − if (arfs_rule->tuple.src_port == src_port && | |
| 694 | − arfs_rule->tuple.dst_port == dst_port && | |
| 695 | − arfs_cmp_ips(&arfs_rule->tuple, skb)) { | |
| 664 | + if (arfs_cmp(&arfs_rule->tuple, fk)) | |
| 696 | 665 | return arfs_rule; |
| 697 | − } | |
| 698 | 666 | } |
| 699 | 667 | |
| 700 | 668 | return NULL; |
| @@ -707,20 +675,24 @@ int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, · 6 unmodified lines | ||
| 707 | 675 | struct mlx5e_arfs_tables *arfs = &priv->fs.arfs; |
| 708 | 676 | struct arfs_table *arfs_t; |
| 709 | 677 | struct arfs_rule *arfs_rule; |
| 678 | + struct flow_keys fk; | |
| 679 | + | |
| 680 | + if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) | |
| 681 | + return -EPROTONOSUPPORT; | |
| 710 | 682 | |
| 711 | − if (skb->protocol != htons(ETH_P_IP) && | |
| 712 | − skb->protocol != htons(ETH_P_IPV6)) | |
| 683 | + if (fk.basic.n_proto != htons(ETH_P_IP) && | |
| 684 | + fk.basic.n_proto != htons(ETH_P_IPV6)) | |
| 713 | 685 | return -EPROTONOSUPPORT; |
| 714 | 686 | |
| 715 | 687 | if (skb->encapsulation) |
| 716 | 688 | return -EPROTONOSUPPORT; |
| 717 | 689 | |
| 718 | − arfs_t = arfs_get_table(arfs, arfs_get_ip_proto(skb), skb->protocol); | |
| 690 | + arfs_t = arfs_get_table(arfs, fk.basic.ip_proto, fk.basic.n_proto); | |
| 719 | 691 | if (!arfs_t) |
| 720 | 692 | return -EPROTONOSUPPORT; |
| 721 | 693 | |
| 722 | 694 | spin_lock_bh(&arfs->arfs_lock); |
| 723 | − arfs_rule = arfs_find_rule(arfs_t, skb); | |
| 695 | + arfs_rule = arfs_find_rule(arfs_t, &fk); | |
| 724 | 696 | if (arfs_rule) { |
| 725 | 697 | if (arfs_rule->rxq == rxq_index) { |
| 726 | 698 | spin_unlock_bh(&arfs->arfs_lock); |
| @@ -728,8 +700,7 @@ int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, · 1 unmodified line | ||
| 728 | 700 | } |
| 729 | 701 | arfs_rule->rxq = rxq_index; |
| 730 | 702 | } else { |
| 731 | − arfs_rule = arfs_alloc_rule(priv, arfs_t, skb, | |
| 732 | − rxq_index, flow_id); | |
| 703 | + arfs_rule = arfs_alloc_rule(priv, arfs_t, &fk, rxq_index, flow_id); | |
| 733 | 704 | if (!arfs_rule) { |
| 734 | 705 | spin_unlock_bh(&arfs->arfs_lock); |
| 735 | 706 | return -ENOMEM; |
| @@ -1081,6 +1081,14 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, · 1080 unmodified lines | ||
| 1081 | 1081 | link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : |
| 1082 | 1082 | mlx5e_port_speed2linkmodes(mdev, speed, !ext); |
| 1083 | 1083 | |
| 1084 | + if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && | |
| 1085 | + autoneg != AUTONEG_ENABLE) { | |
| 1086 | + netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n", | |
| 1087 | + __func__); | |
| 1088 | + err = -EINVAL; | |
| 1089 | + goto out; | |
| 1090 | + } | |
| 1091 | + | |
| 1084 | 1092 | link_modes = link_modes & eproto.cap; |
| 1085 | 1093 | if (!link_modes) { |
| 1086 | 1094 | netdev_err(priv->netdev, "%s: Not supported link mode(s) requested", |
| @@ -1338,6 +1346,9 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, · 251 unmodified lines | ||
| 1338 | 1346 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1339 | 1347 | int err; |
| 1340 | 1348 | |
| 1349 | + if (!MLX5_CAP_GEN(mdev, vport_group_manager)) | |
| 1350 | + return -EOPNOTSUPP; | |
| 1351 | + | |
| 1341 | 1352 | if (pauseparam->autoneg) |
| 1342 | 1353 | return -EINVAL; |
| 1343 | 1354 | |
| @@ -1679,6 +1690,40 @@ static int mlx5e_get_module_eeprom(struct net_device *netdev, · 335 unmodified lines | ||
| 1679 | 1690 | return 0; |
| 1680 | 1691 | } |
| 1681 | 1692 | |
| 1693 | +int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv, | |
| 1694 | + struct ethtool_flash *flash) | |
| 1695 | +{ | |
| 1696 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 1697 | + struct net_device *dev = priv->netdev; | |
| 1698 | + const struct firmware *fw; | |
| 1699 | + int err; | |
| 1700 | + | |
| 1701 | + if (flash->region != ETHTOOL_FLASH_ALL_REGIONS) | |
| 1702 | + return -EOPNOTSUPP; | |
| 1703 | + | |
| 1704 | + err = request_firmware_direct(&fw, flash->data, &dev->dev); | |
| 1705 | + if (err) | |
| 1706 | + return err; | |
| 1707 | + | |
| 1708 | + dev_hold(dev); | |
| 1709 | + rtnl_unlock(); | |
| 1710 | + | |
| 1711 | + err = mlx5_firmware_flash(mdev, fw, NULL); | |
| 1712 | + release_firmware(fw); | |
| 1713 | + | |
| 1714 | + rtnl_lock(); | |
| 1715 | + dev_put(dev); | |
| 1716 | + return err; | |
| 1717 | +} | |
| 1718 | + | |
| 1719 | +static int mlx5e_flash_device(struct net_device *dev, | |
| 1720 | + struct ethtool_flash *flash) | |
| 1721 | +{ | |
| 1722 | + struct mlx5e_priv *priv = netdev_priv(dev); | |
| 1723 | + | |
| 1724 | + return mlx5e_ethtool_flash_device(priv, flash); | |
| 1725 | +} | |
| 1726 | + | |
| 1682 | 1727 | static int set_pflag_cqe_based_moder(struct net_device *netdev, bool enable, |
| 1683 | 1728 | bool is_rx_cq) |
| 1684 | 1729 | { |
| @@ -1965,6 +2010,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = { · 280 unmodified lines | ||
| 1965 | 2010 | .set_wol = mlx5e_set_wol, |
| 1966 | 2011 | .get_module_info = mlx5e_get_module_info, |
| 1967 | 2012 | .get_module_eeprom = mlx5e_get_module_eeprom, |
| 2013 | + .flash_device = mlx5e_flash_device, | |
| 1968 | 2014 | .get_priv_flags = mlx5e_get_priv_flags, |
| 1969 | 2015 | .set_priv_flags = mlx5e_set_priv_flags, |
| 1970 | 2016 | .self_test = mlx5e_self_test, |
| @@ -1323,7 +1323,6 @@ err_free_txqsq: · 1322 unmodified lines | ||
| 1323 | 1323 | void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq) |
| 1324 | 1324 | { |
| 1325 | 1325 | sq->txq = netdev_get_tx_queue(sq->channel->netdev, sq->txq_ix); |
| 1326 | − clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); | |
| 1327 | 1326 | set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state); |
| 1328 | 1327 | netdev_tx_reset_queue(sq->txq); |
| 1329 | 1328 | netif_tx_start_queue(sq->txq); |
| @@ -1702,7 +1702,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 1701 unmodified lines | ||
| 1702 | 1702 | struct mlx5_flow_spec *spec, |
| 1703 | 1703 | struct flow_cls_offload *f, |
| 1704 | 1704 | struct net_device *filter_dev, |
| 1705 | − u8 *match_level, u8 *tunnel_match_level) | |
| 1705 | + u8 *inner_match_level, u8 *outer_match_level) | |
| 1706 | 1706 | { |
| 1707 | 1707 | struct netlink_ext_ack *extack = f->common.extack; |
| 1708 | 1708 | void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, |
| @@ -1717,8 +1717,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 8 unmodified lines | ||
| 1717 | 1717 | struct flow_dissector *dissector = rule->match.dissector; |
| 1718 | 1718 | u16 addr_type = 0; |
| 1719 | 1719 | u8 ip_proto = 0; |
| 1720 | + u8 *match_level; | |
| 1720 | 1721 | |
| 1721 | − *match_level = MLX5_MATCH_NONE; | |
| 1722 | + match_level = outer_match_level; | |
| 1722 | 1723 | |
| 1723 | 1724 | if (dissector->used_keys & |
| 1724 | 1725 | ~(BIT(FLOW_DISSECTOR_KEY_META) | |
| @@ -1746,12 +1747,14 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 21 unmodified lines | ||
| 1746 | 1747 | } |
| 1747 | 1748 | |
| 1748 | 1749 | if (mlx5e_get_tc_tun(filter_dev)) { |
| 1749 | − if (parse_tunnel_attr(priv, spec, f, filter_dev, tunnel_match_level)) | |
| 1750 | + if (parse_tunnel_attr(priv, spec, f, filter_dev, | |
| 1751 | + outer_match_level)) | |
| 1750 | 1752 | return -EOPNOTSUPP; |
| 1751 | 1753 | |
| 1752 | − /* In decap flow, header pointers should point to the inner | |
| 1754 | + /* At this point, header pointers should point to the inner | |
| 1753 | 1755 | * headers, outer header were already set by parse_tunnel_attr |
| 1754 | 1756 | */ |
| 1757 | + match_level = inner_match_level; | |
| 1755 | 1758 | headers_c = get_match_headers_criteria(MLX5_FLOW_CONTEXT_ACTION_DECAP, |
| 1756 | 1759 | spec); |
| 1757 | 1760 | headers_v = get_match_headers_value(MLX5_FLOW_CONTEXT_ACTION_DECAP, |
| @@ -2053,37 +2056,43 @@ static int parse_cls_flower(struct mlx5e_priv *priv, · 295 unmodified lines | ||
| 2053 | 2056 | struct flow_cls_offload *f, |
| 2054 | 2057 | struct net_device *filter_dev) |
| 2055 | 2058 | { |
| 2059 | + u8 inner_match_level, outer_match_level, non_tunnel_match_level; | |
| 2056 | 2060 | struct netlink_ext_ack *extack = f->common.extack; |
| 2057 | 2061 | struct mlx5_core_dev *dev = priv->mdev; |
| 2058 | 2062 | struct mlx5_eswitch *esw = dev->priv.eswitch; |
| 2059 | 2063 | struct mlx5e_rep_priv *rpriv = priv->ppriv; |
| 2060 | − u8 match_level, tunnel_match_level = MLX5_MATCH_NONE; | |
| 2061 | 2064 | struct mlx5_eswitch_rep *rep; |
| 2062 | 2065 | bool is_eswitch_flow; |
| 2063 | 2066 | int err; |
| 2064 | 2067 | |
| 2065 | − err = __parse_cls_flower(priv, spec, f, filter_dev, &match_level, &tunnel_match_level); | |
| 2068 | + inner_match_level = MLX5_MATCH_NONE; | |
| 2069 | + outer_match_level = MLX5_MATCH_NONE; | |
| 2070 | + | |
| 2071 | + err = __parse_cls_flower(priv, spec, f, filter_dev, &inner_match_level, | |
| 2072 | + &outer_match_level); | |
| 2073 | + non_tunnel_match_level = (inner_match_level == MLX5_MATCH_NONE) ? | |
| 2074 | + outer_match_level : inner_match_level; | |
| 2066 | 2075 | |
| 2067 | 2076 | is_eswitch_flow = mlx5e_is_eswitch_flow(flow); |
| 2068 | 2077 | if (!err && is_eswitch_flow) { |
| 2069 | 2078 | rep = rpriv->rep; |
| 2070 | 2079 | if (rep->vport != MLX5_VPORT_UPLINK && |
| 2071 | 2080 | (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE && |
| 2072 | − esw->offloads.inline_mode < match_level)) { | |
| 2081 | + esw->offloads.inline_mode < non_tunnel_match_level)) { | |
| 2073 | 2082 | NL_SET_ERR_MSG_MOD(extack, |
| 2074 | 2083 | "Flow is not offloaded due to min inline setting"); |
| 2075 | 2084 | netdev_warn(priv->netdev, |
| 2076 | 2085 | "Flow is not offloaded due to min inline setting, required %d actual %d\n", |
| 2077 | − match_level, esw->offloads.inline_mode); | |
| 2086 | + non_tunnel_match_level, esw->offloads.inline_mode); | |
| 2078 | 2087 | return -EOPNOTSUPP; |
| 2079 | 2088 | } |
| 2080 | 2089 | } |
| 2081 | 2090 | |
| 2082 | 2091 | if (is_eswitch_flow) { |
| 2083 | − flow->esw_attr->match_level = match_level; | |
| 2084 | − flow->esw_attr->tunnel_match_level = tunnel_match_level; | |
| 2092 | + flow->esw_attr->inner_match_level = inner_match_level; | |
| 2093 | + flow->esw_attr->outer_match_level = outer_match_level; | |
| 2085 | 2094 | } else { |
| 2086 | − flow->nic_attr->match_level = match_level; | |
| 2095 | + flow->nic_attr->match_level = non_tunnel_match_level; | |
| 2087 | 2096 | } |
| 2088 | 2097 | |
| 2089 | 2098 | return err; |
| @@ -3437,7 +3446,7 @@ mlx5e_flow_esw_attr_init(struct mlx5_esw_flow_attr *esw_attr, · 1347 unmodified lines | ||
| 3437 | 3446 | |
| 3438 | 3447 | esw_attr->parse_attr = parse_attr; |
| 3439 | 3448 | esw_attr->chain = f->common.chain_index; |
| 3440 | − esw_attr->prio = TC_H_MAJ(f->common.prio) >> 16; | |
| 3449 | + esw_attr->prio = f->common.prio; | |
| 3441 | 3450 | |
| 3442 | 3451 | esw_attr->in_rep = in_rep; |
| 3443 | 3452 | esw_attr->in_mdev = in_mdev; |
| @@ -390,8 +390,8 @@ struct mlx5_esw_flow_attr { · 389 unmodified lines | ||
| 390 | 390 | struct mlx5_termtbl_handle *termtbl; |
| 391 | 391 | } dests[MLX5_MAX_FLOW_FWD_VPORTS]; |
| 392 | 392 | u32 mod_hdr_id; |
| 393 | − u8 match_level; | |
| 394 | − u8 tunnel_match_level; | |
| 393 | + u8 inner_match_level; | |
| 394 | + u8 outer_match_level; | |
| 395 | 395 | struct mlx5_fc *counter; |
| 396 | 396 | u32 chain; |
| 397 | 397 | u16 prio; |
| @@ -207,14 +207,10 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, · 206 unmodified lines | ||
| 207 | 207 | |
| 208 | 208 | mlx5_eswitch_set_rule_source_port(esw, spec, attr); |
| 209 | 209 | |
| 210 | − if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DECAP) { | |
| 211 | − if (attr->tunnel_match_level != MLX5_MATCH_NONE) | |
| 212 | − spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; | |
| 213 | − if (attr->match_level != MLX5_MATCH_NONE) | |
| 214 | − spec->match_criteria_enable |= MLX5_MATCH_INNER_HEADERS; | |
| 215 | − } else if (attr->match_level != MLX5_MATCH_NONE) { | |
| 210 | + if (attr->outer_match_level != MLX5_MATCH_NONE) | |
| 216 | 211 | spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; |
| 217 | − } | |
| 212 | + if (attr->inner_match_level != MLX5_MATCH_NONE) | |
| 213 | + spec->match_criteria_enable |= MLX5_MATCH_INNER_HEADERS; | |
| 218 | 214 | |
| 219 | 215 | if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) |
| 220 | 216 | flow_act.modify_id = attr->mod_hdr_id; |
| @@ -290,7 +286,7 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw, · 69 unmodified lines | ||
| 290 | 286 | mlx5_eswitch_set_rule_source_port(esw, spec, attr); |
| 291 | 287 | |
| 292 | 288 | spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS; |
| 293 | − if (attr->match_level != MLX5_MATCH_NONE) | |
| 289 | + if (attr->outer_match_level != MLX5_MATCH_NONE) | |
| 294 | 290 | spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; |
| 295 | 291 | |
| 296 | 292 | rule = mlx5_add_flow_rules(fast_fdb, spec, &flow_act, dest, i); |
| @@ -122,6 +122,14 @@ static int mlx5i_get_ts_info(struct net_device *netdev, · 121 unmodified lines | ||
| 122 | 122 | return mlx5e_ethtool_get_ts_info(priv, info); |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | +static int mlx5i_flash_device(struct net_device *netdev, | |
| 126 | + struct ethtool_flash *flash) | |
| 127 | +{ | |
| 128 | + struct mlx5e_priv *priv = mlx5i_epriv(netdev); | |
| 129 | + | |
| 130 | + return mlx5e_ethtool_flash_device(priv, flash); | |
| 131 | +} | |
| 132 | + | |
| 125 | 133 | enum mlx5_ptys_width { |
| 126 | 134 | MLX5_PTYS_WIDTH_1X = 1 << 0, |
| 127 | 135 | MLX5_PTYS_WIDTH_2X = 1 << 1, |
| @@ -233,6 +241,7 @@ const struct ethtool_ops mlx5i_ethtool_ops = { · 105 unmodified lines | ||
| 233 | 241 | .get_ethtool_stats = mlx5i_get_ethtool_stats, |
| 234 | 242 | .get_ringparam = mlx5i_get_ringparam, |
| 235 | 243 | .set_ringparam = mlx5i_set_ringparam, |
| 244 | + .flash_device = mlx5i_flash_device, | |
| 236 | 245 | .get_channels = mlx5i_get_channels, |
| 237 | 246 | .set_channels = mlx5i_set_channels, |
| 238 | 247 | .get_coalesce = mlx5i_get_coalesce, |
| @@ -27,6 +27,7 @@ int mlx5_create_encryption_key(struct mlx5_core_dev *mdev, · 26 unmodified lines | ||
| 27 | 27 | case 128: |
| 28 | 28 | general_obj_key_size = |
| 29 | 29 | MLX5_GENERAL_OBJECT_TYPE_ENCRYPTION_KEY_KEY_SIZE_128; |
| 30 | + key_p += sz_bytes; | |
| 30 | 31 | break; |
| 31 | 32 | case 256: |
| 32 | 33 | general_obj_key_size = |
| @@ -477,7 +477,7 @@ int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei) · 476 unmodified lines | ||
| 477 | 477 | void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei, |
| 478 | 478 | unsigned int priority) |
| 479 | 479 | { |
| 480 | − rulei->priority = priority >> 16; | |
| 480 | + rulei->priority = priority; | |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | void mlxsw_sp_acl_rulei_keymask_u32(struct mlxsw_sp_acl_rule_info *rulei, |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | struct mlxsw_sp_ptp_state { |
| 31 | 31 | struct mlxsw_sp *mlxsw_sp; |
| 32 | − struct rhashtable unmatched_ht; | |
| 32 | + struct rhltable unmatched_ht; | |
| 33 | 33 | spinlock_t unmatched_lock; /* protects the HT */ |
| 34 | 34 | struct delayed_work ht_gc_dw; |
| 35 | 35 | u32 gc_cycle; |
| @@ -45,7 +45,7 @@ struct mlxsw_sp1_ptp_key { · 9 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | struct mlxsw_sp1_ptp_unmatched { |
| 47 | 47 | struct mlxsw_sp1_ptp_key key; |
| 48 | − struct rhash_head ht_node; | |
| 48 | + struct rhlist_head ht_node; | |
| 49 | 49 | struct rcu_head rcu; |
| 50 | 50 | struct sk_buff *skb; |
| 51 | 51 | u64 timestamp; |
| @@ -359,7 +359,7 @@ static int mlxsw_sp_ptp_parse(struct sk_buff *skb, · 307 unmodified lines | ||
| 359 | 359 | /* Returns NULL on successful insertion, a pointer on conflict, or an ERR_PTR on |
| 360 | 360 | * error. |
| 361 | 361 | */ |
| 362 | −static struct mlxsw_sp1_ptp_unmatched * | |
| 362 | +static int | |
| 363 | 363 | mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp, |
| 364 | 364 | struct mlxsw_sp1_ptp_key key, |
| 365 | 365 | struct sk_buff *skb, |
| @@ -368,41 +368,51 @@ mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp, · 2 unmodified lines | ||
| 368 | 368 | int cycles = MLXSW_SP1_PTP_HT_GC_TIMEOUT / MLXSW_SP1_PTP_HT_GC_INTERVAL; |
| 369 | 369 | struct mlxsw_sp_ptp_state *ptp_state = mlxsw_sp->ptp_state; |
| 370 | 370 | struct mlxsw_sp1_ptp_unmatched *unmatched; |
| 371 | − struct mlxsw_sp1_ptp_unmatched *conflict; | |
| 371 | + int err; | |
| 372 | 372 | |
| 373 | 373 | unmatched = kzalloc(sizeof(*unmatched), GFP_ATOMIC); |
| 374 | 374 | if (!unmatched) |
| 375 | − return ERR_PTR(-ENOMEM); | |
| 375 | + return -ENOMEM; | |
| 376 | 376 | |
| 377 | 377 | unmatched->key = key; |
| 378 | 378 | unmatched->skb = skb; |
| 379 | 379 | unmatched->timestamp = timestamp; |
| 380 | 380 | unmatched->gc_cycle = mlxsw_sp->ptp_state->gc_cycle + cycles; |
| 381 | 381 | |
| 382 | − conflict = rhashtable_lookup_get_insert_fast(&ptp_state->unmatched_ht, | |
| 383 | − &unmatched->ht_node, | |
| 384 | − mlxsw_sp1_ptp_unmatched_ht_params); | |
| 385 | − if (conflict) | |
| 382 | + err = rhltable_insert(&ptp_state->unmatched_ht, &unmatched->ht_node, | |
| 383 | + mlxsw_sp1_ptp_unmatched_ht_params); | |
| 384 | + if (err) | |
| 386 | 385 | kfree(unmatched); |
| 387 | 386 | |
| 388 | − return conflict; | |
| 387 | + return err; | |
| 389 | 388 | } |
| 390 | 389 | |
| 391 | 390 | static struct mlxsw_sp1_ptp_unmatched * |
| 392 | 391 | mlxsw_sp1_ptp_unmatched_lookup(struct mlxsw_sp *mlxsw_sp, |
| 393 | − struct mlxsw_sp1_ptp_key key) | |
| 392 | + struct mlxsw_sp1_ptp_key key, int *p_length) | |
| 394 | 393 | { |
| 395 | − return rhashtable_lookup(&mlxsw_sp->ptp_state->unmatched_ht, &key, | |
| 396 | − mlxsw_sp1_ptp_unmatched_ht_params); | |
| 394 | + struct mlxsw_sp1_ptp_unmatched *unmatched, *last = NULL; | |
| 395 | + struct rhlist_head *tmp, *list; | |
| 396 | + int length = 0; | |
| 397 | + | |
| 398 | + list = rhltable_lookup(&mlxsw_sp->ptp_state->unmatched_ht, &key, | |
| 399 | + mlxsw_sp1_ptp_unmatched_ht_params); | |
| 400 | + rhl_for_each_entry_rcu(unmatched, tmp, list, ht_node) { | |
| 401 | + last = unmatched; | |
| 402 | + length++; | |
| 403 | + } | |
| 404 | + | |
| 405 | + *p_length = length; | |
| 406 | + return last; | |
| 397 | 407 | } |
| 398 | 408 | |
| 399 | 409 | static int |
| 400 | 410 | mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp, |
| 401 | 411 | struct mlxsw_sp1_ptp_unmatched *unmatched) |
| 402 | 412 | { |
| 403 | − return rhashtable_remove_fast(&mlxsw_sp->ptp_state->unmatched_ht, | |
| 404 | − &unmatched->ht_node, | |
| 405 | − mlxsw_sp1_ptp_unmatched_ht_params); | |
| 413 | + return rhltable_remove(&mlxsw_sp->ptp_state->unmatched_ht, | |
| 414 | + &unmatched->ht_node, | |
| 415 | + mlxsw_sp1_ptp_unmatched_ht_params); | |
| 406 | 416 | } |
| 407 | 417 | |
| 408 | 418 | /* This function is called in the following scenarios: |
| @@ -489,75 +499,38 @@ static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp, · 80 unmodified lines | ||
| 489 | 499 | struct mlxsw_sp1_ptp_key key, |
| 490 | 500 | struct sk_buff *skb, u64 timestamp) |
| 491 | 501 | { |
| 492 | − struct mlxsw_sp1_ptp_unmatched *unmatched, *conflict; | |
| 502 | + struct mlxsw_sp1_ptp_unmatched *unmatched; | |
| 503 | + int length; | |
| 493 | 504 | int err; |
| 494 | 505 | |
| 495 | 506 | rcu_read_lock(); |
| 496 | 507 | |
| 497 | − unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key); | |
| 498 | − | |
| 499 | 508 | spin_lock(&mlxsw_sp->ptp_state->unmatched_lock); |
| 500 | 509 | |
| 501 | − if (unmatched) { | |
| 502 | − /* There was an unmatched entry when we looked, but it may have | |
| 503 | − * been removed before we took the lock. | |
| 504 | − */ | |
| 505 | − err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched); | |
| 506 | − if (err) | |
| 507 | − unmatched = NULL; | |
| 508 | − } | |
| 509 | − | |
| 510 | − if (!unmatched) { | |
| 511 | − /* We have no unmatched entry, but one may have been added after | |
| 512 | − * we looked, but before we took the lock. | |
| 513 | − */ | |
| 514 | − unmatched = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key, | |
| 515 | − skb, timestamp); | |
| 516 | − if (IS_ERR(unmatched)) { | |
| 517 | − if (skb) | |
| 518 | − mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb, | |
| 519 | − key.local_port, | |
| 520 | − key.ingress, NULL); | |
| 521 | − unmatched = NULL; | |
| 522 | − } else if (unmatched) { | |
| 523 | − /* Save just told us, under lock, that the entry is | |
| 524 | − * there, so this has to work. | |
| 525 | − */ | |
| 526 | − err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, | |
| 527 | − unmatched); | |
| 528 | − WARN_ON_ONCE(err); | |
| 529 | − } | |
| 530 | − } | |
| 531 | − | |
| 532 | − /* If unmatched is non-NULL here, it comes either from the lookup, or | |
| 533 | − * from the save attempt above. In either case the entry was removed | |
| 534 | − * from the hash table. If unmatched is NULL, a new unmatched entry was | |
| 535 | − * added to the hash table, and there was no conflict. | |
| 536 | − */ | |
| 537 | − | |
| 510 | + unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key, &length); | |
| 538 | 511 | if (skb && unmatched && unmatched->timestamp) { |
| 539 | 512 | unmatched->skb = skb; |
| 540 | 513 | } else if (timestamp && unmatched && unmatched->skb) { |
| 541 | 514 | unmatched->timestamp = timestamp; |
| 542 | − } else if (unmatched) { | |
| 543 | − /* unmatched holds an older entry of the same type: either an | |
| 544 | − * skb if we are handling skb, or a timestamp if we are handling | |
| 545 | − * timestamp. We can't match that up, so save what we have. | |
| 515 | + } else { | |
| 516 | + /* Either there is no entry to match, or one that is there is | |
| 517 | + * incompatible. | |
| 546 | 518 | */ |
| 547 | − conflict = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key, | |
| 548 | − skb, timestamp); | |
| 549 | − if (IS_ERR(conflict)) { | |
| 550 | − if (skb) | |
| 551 | − mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb, | |
| 552 | − key.local_port, | |
| 553 | − key.ingress, NULL); | |
| 554 | − } else { | |
| 555 | − /* Above, we removed an object with this key from the | |
| 556 | − * hash table, under lock, so conflict can not be a | |
| 557 | − * valid pointer. | |
| 558 | − */ | |
| 559 | − WARN_ON_ONCE(conflict); | |
| 560 | − } | |
| 519 | + if (length < 100) | |
| 520 | + err = mlxsw_sp1_ptp_unmatched_save(mlxsw_sp, key, | |
| 521 | + skb, timestamp); | |
| 522 | + else | |
| 523 | + err = -E2BIG; | |
| 524 | + if (err && skb) | |
| 525 | + mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb, | |
| 526 | + key.local_port, | |
| 527 | + key.ingress, NULL); | |
| 528 | + unmatched = NULL; | |
| 529 | + } | |
| 530 | + | |
| 531 | + if (unmatched) { | |
| 532 | + err = mlxsw_sp1_ptp_unmatched_remove(mlxsw_sp, unmatched); | |
| 533 | + WARN_ON_ONCE(err); | |
| 561 | 534 | } |
| 562 | 535 | |
| 563 | 536 | spin_unlock(&mlxsw_sp->ptp_state->unmatched_lock); |
| @@ -669,9 +642,8 @@ mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp_ptp_state *ptp_state, · 105 unmodified lines | ||
| 669 | 642 | local_bh_disable(); |
| 670 | 643 | |
| 671 | 644 | spin_lock(&ptp_state->unmatched_lock); |
| 672 | − err = rhashtable_remove_fast(&ptp_state->unmatched_ht, | |
| 673 | − &unmatched->ht_node, | |
| 674 | − mlxsw_sp1_ptp_unmatched_ht_params); | |
| 645 | + err = rhltable_remove(&ptp_state->unmatched_ht, &unmatched->ht_node, | |
| 646 | + mlxsw_sp1_ptp_unmatched_ht_params); | |
| 675 | 647 | spin_unlock(&ptp_state->unmatched_lock); |
| 676 | 648 | |
| 677 | 649 | if (err) |
| @@ -702,7 +674,7 @@ static void mlxsw_sp1_ptp_ht_gc(struct work_struct *work) · 24 unmodified lines | ||
| 702 | 674 | ptp_state = container_of(dwork, struct mlxsw_sp_ptp_state, ht_gc_dw); |
| 703 | 675 | gc_cycle = ptp_state->gc_cycle++; |
| 704 | 676 | |
| 705 | − rhashtable_walk_enter(&ptp_state->unmatched_ht, &iter); | |
| 677 | + rhltable_walk_enter(&ptp_state->unmatched_ht, &iter); | |
| 706 | 678 | rhashtable_walk_start(&iter); |
| 707 | 679 | while ((obj = rhashtable_walk_next(&iter))) { |
| 708 | 680 | if (IS_ERR(obj)) |
| @@ -855,8 +827,8 @@ struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp) · 146 unmodified lines | ||
| 855 | 827 | |
| 856 | 828 | spin_lock_init(&ptp_state->unmatched_lock); |
| 857 | 829 | |
| 858 | − err = rhashtable_init(&ptp_state->unmatched_ht, | |
| 859 | − &mlxsw_sp1_ptp_unmatched_ht_params); | |
| 830 | + err = rhltable_init(&ptp_state->unmatched_ht, | |
| 831 | + &mlxsw_sp1_ptp_unmatched_ht_params); | |
| 860 | 832 | if (err) |
| 861 | 833 | goto err_hashtable_init; |
| 862 | 834 | |
| @@ -891,7 +863,7 @@ err_fifo_clr: · 28 unmodified lines | ||
| 891 | 863 | err_mtptpt1_set: |
| 892 | 864 | mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0); |
| 893 | 865 | err_mtptpt_set: |
| 894 | − rhashtable_destroy(&ptp_state->unmatched_ht); | |
| 866 | + rhltable_destroy(&ptp_state->unmatched_ht); | |
| 895 | 867 | err_hashtable_init: |
| 896 | 868 | kfree(ptp_state); |
| 897 | 869 | return ERR_PTR(err); |
| @@ -906,8 +878,8 @@ void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state) · 8 unmodified lines | ||
| 906 | 878 | mlxsw_sp1_ptp_set_fifo_clr_on_trap(mlxsw_sp, false); |
| 907 | 879 | mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1, 0); |
| 908 | 880 | mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP0, 0); |
| 909 | − rhashtable_free_and_destroy(&ptp_state->unmatched_ht, | |
| 910 | − &mlxsw_sp1_ptp_unmatched_free_fn, NULL); | |
| 881 | + rhltable_free_and_destroy(&ptp_state->unmatched_ht, | |
| 882 | + &mlxsw_sp1_ptp_unmatched_free_fn, NULL); | |
| 911 | 883 | kfree(ptp_state); |
| 912 | 884 | } |
| 913 | 885 | |
| @@ -13,12 +13,6 @@ struct ocelot_port_block { · 12 unmodified lines | ||
| 13 | 13 | struct ocelot_port *port; |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | −static u16 get_prio(u32 prio) | |
| 17 | −{ | |
| 18 | − /* prio starts from 0x1000 while the ids starts from 0 */ | |
| 19 | − return prio >> 16; | |
| 20 | −} | |
| 21 | − | |
| 22 | 16 | static int ocelot_flower_parse_action(struct flow_cls_offload *f, |
| 23 | 17 | struct ocelot_ace_rule *rule) |
| 24 | 18 | { |
| @@ -168,7 +162,7 @@ static int ocelot_flower_parse(struct flow_cls_offload *f, · 143 unmodified lines | ||
| 168 | 162 | } |
| 169 | 163 | |
| 170 | 164 | finished_key_parsing: |
| 171 | − ocelot_rule->prio = get_prio(f->common.prio); | |
| 165 | + ocelot_rule->prio = f->common.prio; | |
| 172 | 166 | ocelot_rule->id = f->cookie; |
| 173 | 167 | return ocelot_flower_parse_action(f, ocelot_rule); |
| 174 | 168 | } |
| @@ -218,7 +212,7 @@ static int ocelot_flower_destroy(struct flow_cls_offload *f, · 43 unmodified lines | ||
| 218 | 212 | struct ocelot_ace_rule rule; |
| 219 | 213 | int ret; |
| 220 | 214 | |
| 221 | − rule.prio = get_prio(f->common.prio); | |
| 215 | + rule.prio = f->common.prio; | |
| 222 | 216 | rule.port = port_block->port; |
| 223 | 217 | rule.id = f->cookie; |
| 224 | 218 | |
| @@ -236,7 +230,7 @@ static int ocelot_flower_stats_update(struct flow_cls_offload *f, · 11 unmodified lines | ||
| 236 | 230 | struct ocelot_ace_rule rule; |
| 237 | 231 | int ret; |
| 238 | 232 | |
| 239 | − rule.prio = get_prio(f->common.prio); | |
| 233 | + rule.prio = f->common.prio; | |
| 240 | 234 | rule.port = port_block->port; |
| 241 | 235 | rule.id = f->cookie; |
| 242 | 236 | ret = ocelot_ace_rule_stats_update(&rule); |
| @@ -3918,7 +3918,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 3917 unmodified lines | ||
| 3918 | 3918 | * setup (if available). */ |
| 3919 | 3919 | status = myri10ge_request_irq(mgp); |
| 3920 | 3920 | if (status != 0) |
| 3921 | − goto abort_with_firmware; | |
| 3921 | + goto abort_with_slices; | |
| 3922 | 3922 | myri10ge_free_irq(mgp); |
| 3923 | 3923 | |
| 3924 | 3924 | /* Save configuration space to be restored if the |
| @@ -93,7 +93,7 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev, · 92 unmodified lines | ||
| 93 | 93 | return -EOPNOTSUPP; |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | − if (flow->common.prio != (1 << 16)) { | |
| 96 | + if (flow->common.prio != 1) { | |
| 97 | 97 | NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload requires highest priority"); |
| 98 | 98 | return -EOPNOTSUPP; |
| 99 | 99 | } |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* Renesas Ethernet AVB device driver |
| 3 | 3 | * |
| 4 | − * Copyright (C) 2014-2015 Renesas Electronics Corporation | |
| 4 | + * Copyright (C) 2014-2019 Renesas Electronics Corporation | |
| 5 | 5 | * Copyright (C) 2015 Renesas Solutions Corp. |
| 6 | 6 | * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com> |
| 7 | 7 | * |
| @@ -513,7 +513,10 @@ static void ravb_get_tx_tstamp(struct net_device *ndev) · 505 unmodified lines | ||
| 513 | 513 | kfree(ts_skb); |
| 514 | 514 | if (tag == tfa_tag) { |
| 515 | 515 | skb_tstamp_tx(skb, &shhwtstamps); |
| 516 | + dev_consume_skb_any(skb); | |
| 516 | 517 | break; |
| 518 | + } else { | |
| 519 | + dev_kfree_skb_any(skb); | |
| 517 | 520 | } |
| 518 | 521 | } |
| 519 | 522 | ravb_modify(ndev, TCCR, TCCR_TFR, TCCR_TFR); |
| @@ -1564,7 +1567,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1044 unmodified lines | ||
| 1564 | 1567 | } |
| 1565 | 1568 | goto unmap; |
| 1566 | 1569 | } |
| 1567 | − ts_skb->skb = skb; | |
| 1570 | + ts_skb->skb = skb_get(skb); | |
| 1568 | 1571 | ts_skb->tag = priv->ts_skb_tag++; |
| 1569 | 1572 | priv->ts_skb_tag &= 0x3ff; |
| 1570 | 1573 | list_add_tail(&ts_skb->list, &priv->ts_skb_list); |
| @@ -1693,6 +1696,7 @@ static int ravb_close(struct net_device *ndev) · 122 unmodified lines | ||
| 1693 | 1696 | /* Clear the timestamp list */ |
| 1694 | 1697 | list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { |
| 1695 | 1698 | list_del(&ts_skb->list); |
| 1699 | + kfree_skb(ts_skb->skb); | |
| 1696 | 1700 | kfree(ts_skb); |
| 1697 | 1701 | } |
| 1698 | 1702 | |
| @@ -94,7 +94,7 @@ static int tc_fill_entry(struct stmmac_priv *priv, · 93 unmodified lines | ||
| 94 | 94 | struct stmmac_tc_entry *entry, *frag = NULL; |
| 95 | 95 | struct tc_u32_sel *sel = cls->knode.sel; |
| 96 | 96 | u32 off, data, mask, real_off, rem; |
| 97 | − u32 prio = cls->common.prio; | |
| 97 | + u32 prio = cls->common.prio << 16; | |
| 98 | 98 | int ret; |
| 99 | 99 | |
| 100 | 100 | /* Only 1 match per entry */ |
| @@ -1504,7 +1504,7 @@ tc35815_rx(struct net_device *dev, int limit) · 1503 unmodified lines | ||
| 1504 | 1504 | pci_unmap_single(lp->pci_dev, |
| 1505 | 1505 | lp->rx_skbs[cur_bd].skb_dma, |
| 1506 | 1506 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
| 1507 | − if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN) | |
| 1507 | + if (!HAVE_DMA_RXALIGN(lp) && NET_IP_ALIGN != 0) | |
| 1508 | 1508 | memmove(skb->data, skb->data - NET_IP_ALIGN, |
| 1509 | 1509 | pkt_len); |
| 1510 | 1510 | data = skb_put(skb, pkt_len); |
| @@ -371,9 +371,10 @@ tsi108_stat_carry_one(int carry, int carry_bit, int carry_shift, · 370 unmodified lines | ||
| 371 | 371 | static void tsi108_stat_carry(struct net_device *dev) |
| 372 | 372 | { |
| 373 | 373 | struct tsi108_prv_data *data = netdev_priv(dev); |
| 374 | + unsigned long flags; | |
| 374 | 375 | u32 carry1, carry2; |
| 375 | 376 | |
| 376 | − spin_lock_irq(&data->misclock); | |
| 377 | + spin_lock_irqsave(&data->misclock, flags); | |
| 377 | 378 | |
| 378 | 379 | carry1 = TSI_READ(TSI108_STAT_CARRY1); |
| 379 | 380 | carry2 = TSI_READ(TSI108_STAT_CARRY2); |
| @@ -441,7 +442,7 @@ static void tsi108_stat_carry(struct net_device *dev) · 61 unmodified lines | ||
| 441 | 442 | TSI108_STAT_TXPAUSEDROP_CARRY, |
| 442 | 443 | &data->tx_pause_drop); |
| 443 | 444 | |
| 444 | − spin_unlock_irq(&data->misclock); | |
| 445 | + spin_unlock_irqrestore(&data->misclock, flags); | |
| 445 | 446 | } |
| 446 | 447 | |
| 447 | 448 | /* Read a stat counter atomically with respect to carries. |
| @@ -1239,12 +1239,15 @@ static void netvsc_get_stats64(struct net_device *net, · 1238 unmodified lines | ||
| 1239 | 1239 | struct rtnl_link_stats64 *t) |
| 1240 | 1240 | { |
| 1241 | 1241 | struct net_device_context *ndev_ctx = netdev_priv(net); |
| 1242 | − struct netvsc_device *nvdev = rcu_dereference_rtnl(ndev_ctx->nvdev); | |
| 1242 | + struct netvsc_device *nvdev; | |
| 1243 | 1243 | struct netvsc_vf_pcpu_stats vf_tot; |
| 1244 | 1244 | int i; |
| 1245 | 1245 | |
| 1246 | + rcu_read_lock(); | |
| 1247 | + | |
| 1248 | + nvdev = rcu_dereference(ndev_ctx->nvdev); | |
| 1246 | 1249 | if (!nvdev) |
| 1247 | − return; | |
| 1250 | + goto out; | |
| 1248 | 1251 | |
| 1249 | 1252 | netdev_stats_to_stats64(t, &net->stats); |
| 1250 | 1253 | |
| @@ -1283,6 +1286,8 @@ static void netvsc_get_stats64(struct net_device *net, · 32 unmodified lines | ||
| 1283 | 1286 | t->rx_packets += packets; |
| 1284 | 1287 | t->multicast += multicast; |
| 1285 | 1288 | } |
| 1289 | +out: | |
| 1290 | + rcu_read_unlock(); | |
| 1286 | 1291 | } |
| 1287 | 1292 | |
| 1288 | 1293 | static int netvsc_set_mac_addr(struct net_device *ndev, void *p) |
| @@ -123,46 +123,47 @@ static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port) · 122 unmodified lines | ||
| 123 | 123 | debugfs_remove_recursive(nsim_dev_port->ddir); |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | +static struct net *nsim_devlink_net(struct devlink *devlink) | |
| 127 | +{ | |
| 128 | + return &init_net; | |
| 129 | +} | |
| 130 | + | |
| 126 | 131 | static u64 nsim_dev_ipv4_fib_resource_occ_get(void *priv) |
| 127 | 132 | { |
| 128 | − struct nsim_dev *nsim_dev = priv; | |
| 133 | + struct net *net = priv; | |
| 129 | 134 | |
| 130 | − return nsim_fib_get_val(nsim_dev->fib_data, | |
| 131 | − NSIM_RESOURCE_IPV4_FIB, false); | |
| 135 | + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false); | |
| 132 | 136 | } |
| 133 | 137 | |
| 134 | 138 | static u64 nsim_dev_ipv4_fib_rules_res_occ_get(void *priv) |
| 135 | 139 | { |
| 136 | − struct nsim_dev *nsim_dev = priv; | |
| 140 | + struct net *net = priv; | |
| 137 | 141 | |
| 138 | − return nsim_fib_get_val(nsim_dev->fib_data, | |
| 139 | − NSIM_RESOURCE_IPV4_FIB_RULES, false); | |
| 142 | + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false); | |
| 140 | 143 | } |
| 141 | 144 | |
| 142 | 145 | static u64 nsim_dev_ipv6_fib_resource_occ_get(void *priv) |
| 143 | 146 | { |
| 144 | − struct nsim_dev *nsim_dev = priv; | |
| 147 | + struct net *net = priv; | |
| 145 | 148 | |
| 146 | − return nsim_fib_get_val(nsim_dev->fib_data, | |
| 147 | − NSIM_RESOURCE_IPV6_FIB, false); | |
| 149 | + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false); | |
| 148 | 150 | } |
| 149 | 151 | |
| 150 | 152 | static u64 nsim_dev_ipv6_fib_rules_res_occ_get(void *priv) |
| 151 | 153 | { |
| 152 | − struct nsim_dev *nsim_dev = priv; | |
| 154 | + struct net *net = priv; | |
| 153 | 155 | |
| 154 | − return nsim_fib_get_val(nsim_dev->fib_data, | |
| 155 | − NSIM_RESOURCE_IPV6_FIB_RULES, false); | |
| 156 | + return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false); | |
| 156 | 157 | } |
| 157 | 158 | |
| 158 | 159 | static int nsim_dev_resources_register(struct devlink *devlink) |
| 159 | 160 | { |
| 160 | − struct nsim_dev *nsim_dev = devlink_priv(devlink); | |
| 161 | 161 | struct devlink_resource_size_params params = { |
| 162 | 162 | .size_max = (u64)-1, |
| 163 | 163 | .size_granularity = 1, |
| 164 | 164 | .unit = DEVLINK_RESOURCE_UNIT_ENTRY |
| 165 | 165 | }; |
| 166 | + struct net *net = nsim_devlink_net(devlink); | |
| 166 | 167 | int err; |
| 167 | 168 | u64 n; |
| 168 | 169 | |
| @@ -176,8 +177,7 @@ static int nsim_dev_resources_register(struct devlink *devlink) · 7 unmodified lines | ||
| 176 | 177 | goto out; |
| 177 | 178 | } |
| 178 | 179 | |
| 179 | − n = nsim_fib_get_val(nsim_dev->fib_data, | |
| 180 | − NSIM_RESOURCE_IPV4_FIB, true); | |
| 180 | + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true); | |
| 181 | 181 | err = devlink_resource_register(devlink, "fib", n, |
| 182 | 182 | NSIM_RESOURCE_IPV4_FIB, |
| 183 | 183 | NSIM_RESOURCE_IPV4, ¶ms); |
| @@ -186,8 +186,7 @@ static int nsim_dev_resources_register(struct devlink *devlink) · 2 unmodified lines | ||
| 186 | 186 | return err; |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | − n = nsim_fib_get_val(nsim_dev->fib_data, | |
| 190 | − NSIM_RESOURCE_IPV4_FIB_RULES, true); | |
| 189 | + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true); | |
| 191 | 190 | err = devlink_resource_register(devlink, "fib-rules", n, |
| 192 | 191 | NSIM_RESOURCE_IPV4_FIB_RULES, |
| 193 | 192 | NSIM_RESOURCE_IPV4, ¶ms); |
| @@ -206,8 +205,7 @@ static int nsim_dev_resources_register(struct devlink *devlink) · 12 unmodified lines | ||
| 206 | 205 | goto out; |
| 207 | 206 | } |
| 208 | 207 | |
| 209 | − n = nsim_fib_get_val(nsim_dev->fib_data, | |
| 210 | − NSIM_RESOURCE_IPV6_FIB, true); | |
| 208 | + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true); | |
| 211 | 209 | err = devlink_resource_register(devlink, "fib", n, |
| 212 | 210 | NSIM_RESOURCE_IPV6_FIB, |
| 213 | 211 | NSIM_RESOURCE_IPV6, ¶ms); |
| @@ -216,8 +214,7 @@ static int nsim_dev_resources_register(struct devlink *devlink) · 2 unmodified lines | ||
| 216 | 214 | return err; |
| 217 | 215 | } |
| 218 | 216 | |
| 219 | − n = nsim_fib_get_val(nsim_dev->fib_data, | |
| 220 | − NSIM_RESOURCE_IPV6_FIB_RULES, true); | |
| 217 | + n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true); | |
| 221 | 218 | err = devlink_resource_register(devlink, "fib-rules", n, |
| 222 | 219 | NSIM_RESOURCE_IPV6_FIB_RULES, |
| 223 | 220 | NSIM_RESOURCE_IPV6, ¶ms); |
| @@ -229,19 +226,19 @@ static int nsim_dev_resources_register(struct devlink *devlink) · 5 unmodified lines | ||
| 229 | 226 | devlink_resource_occ_get_register(devlink, |
| 230 | 227 | NSIM_RESOURCE_IPV4_FIB, |
| 231 | 228 | nsim_dev_ipv4_fib_resource_occ_get, |
| 232 | − nsim_dev); | |
| 229 | + net); | |
| 233 | 230 | devlink_resource_occ_get_register(devlink, |
| 234 | 231 | NSIM_RESOURCE_IPV4_FIB_RULES, |
| 235 | 232 | nsim_dev_ipv4_fib_rules_res_occ_get, |
| 236 | − nsim_dev); | |
| 233 | + net); | |
| 237 | 234 | devlink_resource_occ_get_register(devlink, |
| 238 | 235 | NSIM_RESOURCE_IPV6_FIB, |
| 239 | 236 | nsim_dev_ipv6_fib_resource_occ_get, |
| 240 | − nsim_dev); | |
| 237 | + net); | |
| 241 | 238 | devlink_resource_occ_get_register(devlink, |
| 242 | 239 | NSIM_RESOURCE_IPV6_FIB_RULES, |
| 243 | 240 | nsim_dev_ipv6_fib_rules_res_occ_get, |
| 244 | − nsim_dev); | |
| 241 | + net); | |
| 245 | 242 | out: |
| 246 | 243 | return err; |
| 247 | 244 | } |
| @@ -526,11 +523,11 @@ static void nsim_dev_traps_exit(struct devlink *devlink) · 278 unmodified lines | ||
| 526 | 523 | static int nsim_dev_reload(struct devlink *devlink, |
| 527 | 524 | struct netlink_ext_ack *extack) |
| 528 | 525 | { |
| 529 | − struct nsim_dev *nsim_dev = devlink_priv(devlink); | |
| 530 | 526 | enum nsim_resource_id res_ids[] = { |
| 531 | 527 | NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, |
| 532 | 528 | NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES |
| 533 | 529 | }; |
| 530 | + struct net *net = nsim_devlink_net(devlink); | |
| 534 | 531 | int i; |
| 535 | 532 | |
| 536 | 533 | for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { |
| @@ -539,8 +536,7 @@ static int nsim_dev_reload(struct devlink *devlink, · 2 unmodified lines | ||
| 539 | 536 | |
| 540 | 537 | err = devlink_resource_size_get(devlink, res_ids[i], &val); |
| 541 | 538 | if (!err) { |
| 542 | − err = nsim_fib_set_max(nsim_dev->fib_data, | |
| 543 | − res_ids[i], val, extack); | |
| 539 | + err = nsim_fib_set_max(net, res_ids[i], val, extack); | |
| 544 | 540 | if (err) |
| 545 | 541 | return err; |
| 546 | 542 | } |
| @@ -670,15 +666,9 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count) · 123 unmodified lines | ||
| 670 | 666 | nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; |
| 671 | 667 | nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT; |
| 672 | 668 | |
| 673 | − nsim_dev->fib_data = nsim_fib_create(); | |
| 674 | − if (IS_ERR(nsim_dev->fib_data)) { | |
| 675 | − err = PTR_ERR(nsim_dev->fib_data); | |
| 676 | − goto err_devlink_free; | |
| 677 | − } | |
| 678 | − | |
| 679 | 669 | err = nsim_dev_resources_register(devlink); |
| 680 | 670 | if (err) |
| 681 | − goto err_fib_destroy; | |
| 671 | + goto err_devlink_free; | |
| 682 | 672 | |
| 683 | 673 | err = devlink_register(devlink, &nsim_bus_dev->dev); |
| 684 | 674 | if (err) |
| @@ -722,8 +712,6 @@ err_dl_unregister: · 37 unmodified lines | ||
| 722 | 712 | devlink_unregister(devlink); |
| 723 | 713 | err_resources_unregister: |
| 724 | 714 | devlink_resources_unregister(devlink, NULL); |
| 725 | −err_fib_destroy: | |
| 726 | − nsim_fib_destroy(nsim_dev->fib_data); | |
| 727 | 715 | err_devlink_free: |
| 728 | 716 | devlink_free(devlink); |
| 729 | 717 | return ERR_PTR(err); |
| @@ -741,7 +729,6 @@ static void nsim_dev_destroy(struct nsim_dev *nsim_dev) · 11 unmodified lines | ||
| 741 | 729 | ARRAY_SIZE(nsim_devlink_params)); |
| 742 | 730 | devlink_unregister(devlink); |
| 743 | 731 | devlink_resources_unregister(devlink, NULL); |
| 744 | − nsim_fib_destroy(nsim_dev->fib_data); | |
| 745 | 732 | mutex_destroy(&nsim_dev->port_list_lock); |
| 746 | 733 | devlink_free(devlink); |
| 747 | 734 | } |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <net/ip_fib.h> |
| 19 | 19 | #include <net/ip6_fib.h> |
| 20 | 20 | #include <net/fib_rules.h> |
| 21 | +#include <net/netns/generic.h> | |
| 21 | 22 | |
| 22 | 23 | #include "netdevsim.h" |
| 23 | 24 | |
| @@ -32,14 +33,15 @@ struct nsim_per_fib_data { · 8 unmodified lines | ||
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | struct nsim_fib_data { |
| 35 | − struct notifier_block fib_nb; | |
| 36 | 36 | struct nsim_per_fib_data ipv4; |
| 37 | 37 | struct nsim_per_fib_data ipv6; |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | −u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, | |
| 41 | − enum nsim_resource_id res_id, bool max) | |
| 40 | +static unsigned int nsim_fib_net_id; | |
| 41 | + | |
| 42 | +u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max) | |
| 42 | 43 | { |
| 44 | + struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); | |
| 43 | 45 | struct nsim_fib_entry *entry; |
| 44 | 46 | |
| 45 | 47 | switch (res_id) { |
| @@ -62,10 +64,10 @@ u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, · 16 unmodified lines | ||
| 62 | 64 | return max ? entry->max : entry->num; |
| 63 | 65 | } |
| 64 | 66 | |
| 65 | −int nsim_fib_set_max(struct nsim_fib_data *fib_data, | |
| 66 | − enum nsim_resource_id res_id, u64 val, | |
| 67 | +int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, | |
| 67 | 68 | struct netlink_ext_ack *extack) |
| 68 | 69 | { |
| 70 | + struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); | |
| 69 | 71 | struct nsim_fib_entry *entry; |
| 70 | 72 | int err = 0; |
| 71 | 73 | |
| @@ -118,9 +120,9 @@ static int nsim_fib_rule_account(struct nsim_fib_entry *entry, bool add, · 46 unmodified lines | ||
| 118 | 120 | return err; |
| 119 | 121 | } |
| 120 | 122 | |
| 121 | −static int nsim_fib_rule_event(struct nsim_fib_data *data, | |
| 122 | − struct fib_notifier_info *info, bool add) | |
| 123 | +static int nsim_fib_rule_event(struct fib_notifier_info *info, bool add) | |
| 123 | 124 | { |
| 125 | + struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); | |
| 124 | 126 | struct netlink_ext_ack *extack = info->extack; |
| 125 | 127 | int err = 0; |
| 126 | 128 | |
| @@ -155,9 +157,9 @@ static int nsim_fib_account(struct nsim_fib_entry *entry, bool add, · 28 unmodified lines | ||
| 155 | 157 | return err; |
| 156 | 158 | } |
| 157 | 159 | |
| 158 | −static int nsim_fib_event(struct nsim_fib_data *data, | |
| 159 | − struct fib_notifier_info *info, bool add) | |
| 160 | +static int nsim_fib_event(struct fib_notifier_info *info, bool add) | |
| 160 | 161 | { |
| 162 | + struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id); | |
| 161 | 163 | struct netlink_ext_ack *extack = info->extack; |
| 162 | 164 | int err = 0; |
| 163 | 165 | |
| @@ -176,22 +178,18 @@ static int nsim_fib_event(struct nsim_fib_data *data, · 12 unmodified lines | ||
| 176 | 178 | static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, |
| 177 | 179 | void *ptr) |
| 178 | 180 | { |
| 179 | − struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data, | |
| 180 | − fib_nb); | |
| 181 | 181 | struct fib_notifier_info *info = ptr; |
| 182 | 182 | int err = 0; |
| 183 | 183 | |
| 184 | 184 | switch (event) { |
| 185 | 185 | case FIB_EVENT_RULE_ADD: /* fall through */ |
| 186 | 186 | case FIB_EVENT_RULE_DEL: |
| 187 | − err = nsim_fib_rule_event(data, info, | |
| 188 | − event == FIB_EVENT_RULE_ADD); | |
| 187 | + err = nsim_fib_rule_event(info, event == FIB_EVENT_RULE_ADD); | |
| 189 | 188 | break; |
| 190 | 189 | |
| 191 | 190 | case FIB_EVENT_ENTRY_ADD: /* fall through */ |
| 192 | 191 | case FIB_EVENT_ENTRY_DEL: |
| 193 | − err = nsim_fib_event(data, info, | |
| 194 | − event == FIB_EVENT_ENTRY_ADD); | |
| 192 | + err = nsim_fib_event(info, event == FIB_EVENT_ENTRY_ADD); | |
| 195 | 193 | break; |
| 196 | 194 | } |
| 197 | 195 | |
| @@ -201,23 +199,30 @@ static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event, · 3 unmodified lines | ||
| 201 | 199 | /* inconsistent dump, trying again */ |
| 202 | 200 | static void nsim_fib_dump_inconsistent(struct notifier_block *nb) |
| 203 | 201 | { |
| 204 | − struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data, | |
| 205 | − fib_nb); | |
| 202 | + struct nsim_fib_data *data; | |
| 203 | + struct net *net; | |
| 204 | + | |
| 205 | + rcu_read_lock(); | |
| 206 | + for_each_net_rcu(net) { | |
| 207 | + data = net_generic(net, nsim_fib_net_id); | |
| 208 | + | |
| 209 | + data->ipv4.fib.num = 0ULL; | |
| 210 | + data->ipv4.rules.num = 0ULL; | |
| 206 | 211 | |
| 207 | − data->ipv4.fib.num = 0ULL; | |
| 208 | − data->ipv4.rules.num = 0ULL; | |
| 209 | − data->ipv6.fib.num = 0ULL; | |
| 210 | − data->ipv6.rules.num = 0ULL; | |
| 212 | + data->ipv6.fib.num = 0ULL; | |
| 213 | + data->ipv6.rules.num = 0ULL; | |
| 214 | + } | |
| 215 | + rcu_read_unlock(); | |
| 211 | 216 | } |
| 212 | 217 | |
| 213 | −struct nsim_fib_data *nsim_fib_create(void) | |
| 214 | −{ | |
| 215 | − struct nsim_fib_data *data; | |
| 216 | − int err; | |
| 218 | +static struct notifier_block nsim_fib_nb = { | |
| 219 | + .notifier_call = nsim_fib_event_nb, | |
| 220 | +}; | |
| 217 | 221 | |
| 218 | − data = kzalloc(sizeof(*data), GFP_KERNEL); | |
| 219 | − if (!data) | |
| 220 | − return ERR_PTR(-ENOMEM); | |
| 222 | +/* Initialize per network namespace state */ | |
| 223 | +static int __net_init nsim_fib_netns_init(struct net *net) | |
| 224 | +{ | |
| 225 | + struct nsim_fib_data *data = net_generic(net, nsim_fib_net_id); | |
| 221 | 226 | |
| 222 | 227 | data->ipv4.fib.max = (u64)-1; |
| 223 | 228 | data->ipv4.rules.max = (u64)-1; |
| @@ -225,22 +230,37 @@ struct nsim_fib_data *nsim_fib_create(void) · 1 unmodified line | ||
| 225 | 230 | data->ipv6.fib.max = (u64)-1; |
| 226 | 231 | data->ipv6.rules.max = (u64)-1; |
| 227 | 232 | |
| 228 | − data->fib_nb.notifier_call = nsim_fib_event_nb; | |
| 229 | − err = register_fib_notifier(&data->fib_nb, nsim_fib_dump_inconsistent); | |
| 230 | − if (err) { | |
| 231 | − pr_err("Failed to register fib notifier\n"); | |
| 232 | − goto err_out; | |
| 233 | − } | |
| 233 | + return 0; | |
| 234 | +} | |
| 234 | 235 | |
| 235 | − return data; | |
| 236 | +static struct pernet_operations nsim_fib_net_ops = { | |
| 237 | + .init = nsim_fib_netns_init, | |
| 238 | + .id = &nsim_fib_net_id, | |
| 239 | + .size = sizeof(struct nsim_fib_data), | |
| 240 | +}; | |
| 236 | 241 | |
| 237 | −err_out: | |
| 238 | − kfree(data); | |
| 239 | − return ERR_PTR(err); | |
| 242 | +void nsim_fib_exit(void) | |
| 243 | +{ | |
| 244 | + unregister_pernet_subsys(&nsim_fib_net_ops); | |
| 245 | + unregister_fib_notifier(&nsim_fib_nb); | |
| 240 | 246 | } |
| 241 | 247 | |
| 242 | −void nsim_fib_destroy(struct nsim_fib_data *data) | |
| 248 | +int nsim_fib_init(void) | |
| 243 | 249 | { |
| 244 | − unregister_fib_notifier(&data->fib_nb); | |
| 245 | − kfree(data); | |
| 250 | + int err; | |
| 251 | + | |
| 252 | + err = register_pernet_subsys(&nsim_fib_net_ops); | |
| 253 | + if (err < 0) { | |
| 254 | + pr_err("Failed to register pernet subsystem\n"); | |
| 255 | + goto err_out; | |
| 256 | + } | |
| 257 | + | |
| 258 | + err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent); | |
| 259 | + if (err < 0) { | |
| 260 | + pr_err("Failed to register fib notifier\n"); | |
| 261 | + goto err_out; | |
| 262 | + } | |
| 263 | + | |
| 264 | +err_out: | |
| 265 | + return err; | |
| 246 | 266 | } |
| @@ -357,12 +357,18 @@ static int __init nsim_module_init(void) · 356 unmodified lines | ||
| 357 | 357 | if (err) |
| 358 | 358 | goto err_dev_exit; |
| 359 | 359 | |
| 360 | − err = rtnl_link_register(&nsim_link_ops); | |
| 360 | + err = nsim_fib_init(); | |
| 361 | 361 | if (err) |
| 362 | 362 | goto err_bus_exit; |
| 363 | 363 | |
| 364 | + err = rtnl_link_register(&nsim_link_ops); | |
| 365 | + if (err) | |
| 366 | + goto err_fib_exit; | |
| 367 | + | |
| 364 | 368 | return 0; |
| 365 | 369 | |
| 370 | +err_fib_exit: | |
| 371 | + nsim_fib_exit(); | |
| 366 | 372 | err_bus_exit: |
| 367 | 373 | nsim_bus_exit(); |
| 368 | 374 | err_dev_exit: |
| @@ -373,6 +379,7 @@ err_dev_exit: · 4 unmodified lines | ||
| 373 | 379 | static void __exit nsim_module_exit(void) |
| 374 | 380 | { |
| 375 | 381 | rtnl_link_unregister(&nsim_link_ops); |
| 382 | + nsim_fib_exit(); | |
| 376 | 383 | nsim_bus_exit(); |
| 377 | 384 | nsim_dev_exit(); |
| 378 | 385 | } |
| @@ -173,12 +173,10 @@ int nsim_dev_port_add(struct nsim_bus_dev *nsim_bus_dev, · 172 unmodified lines | ||
| 173 | 173 | int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev, |
| 174 | 174 | unsigned int port_index); |
| 175 | 175 | |
| 176 | −struct nsim_fib_data *nsim_fib_create(void); | |
| 177 | −void nsim_fib_destroy(struct nsim_fib_data *fib_data); | |
| 178 | −u64 nsim_fib_get_val(struct nsim_fib_data *fib_data, | |
| 179 | − enum nsim_resource_id res_id, bool max); | |
| 180 | −int nsim_fib_set_max(struct nsim_fib_data *fib_data, | |
| 181 | − enum nsim_resource_id res_id, u64 val, | |
| 176 | +int nsim_fib_init(void); | |
| 177 | +void nsim_fib_exit(void); | |
| 178 | +u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); | |
| 179 | +int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, | |
| 182 | 180 | struct netlink_ext_ack *extack); |
| 183 | 181 | |
| 184 | 182 | #if IS_ENABLED(CONFIG_XFRM_OFFLOAD) |
| @@ -253,36 +253,20 @@ static int at803x_config_init(struct phy_device *phydev) · 252 unmodified lines | ||
| 253 | 253 | * after HW reset: RX delay enabled and TX delay disabled |
| 254 | 254 | * after SW reset: RX delay enabled, while TX delay retains the |
| 255 | 255 | * value before reset. |
| 256 | − * | |
| 257 | − * So let's first disable the RX and TX delays in PHY and enable | |
| 258 | − * them based on the mode selected (this also takes care of RGMII | |
| 259 | − * mode where we expect delays to be disabled) | |
| 260 | 256 | */ |
| 261 | − | |
| 262 | − ret = at803x_disable_rx_delay(phydev); | |
| 263 | − if (ret < 0) | |
| 264 | − return ret; | |
| 265 | − ret = at803x_disable_tx_delay(phydev); | |
| 266 | − if (ret < 0) | |
| 267 | − return ret; | |
| 268 | − | |
| 269 | 257 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
| 270 | − phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { | |
| 271 | − /* If RGMII_ID or RGMII_RXID are specified enable RX delay, | |
| 272 | − * otherwise keep it disabled | |
| 273 | − */ | |
| 258 | + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) | |
| 274 | 259 | ret = at803x_enable_rx_delay(phydev); |
| 275 | − if (ret < 0) | |
| 276 | − return ret; | |
| 277 | − } | |
| 260 | + else | |
| 261 | + ret = at803x_disable_rx_delay(phydev); | |
| 262 | + if (ret < 0) | |
| 263 | + return ret; | |
| 278 | 264 | |
| 279 | 265 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
| 280 | − phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { | |
| 281 | − /* If RGMII_ID or RGMII_TXID are specified enable TX delay, | |
| 282 | − * otherwise keep it disabled | |
| 283 | − */ | |
| 266 | + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) | |
| 284 | 267 | ret = at803x_enable_tx_delay(phydev); |
| 285 | − } | |
| 268 | + else | |
| 269 | + ret = at803x_disable_tx_delay(phydev); | |
| 286 | 270 | |
| 287 | 271 | return ret; |
| 288 | 272 | } |
| @@ -219,6 +219,20 @@ int genphy_c45_read_link(struct phy_device *phydev) · 218 unmodified lines | ||
| 219 | 219 | int val, devad; |
| 220 | 220 | bool link = true; |
| 221 | 221 | |
| 222 | + if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) { | |
| 223 | + val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); | |
| 224 | + if (val < 0) | |
| 225 | + return val; | |
| 226 | + | |
| 227 | + /* Autoneg is being started, therefore disregard current | |
| 228 | + * link status and report link as down. | |
| 229 | + */ | |
| 230 | + if (val & MDIO_AN_CTRL1_RESTART) { | |
| 231 | + phydev->link = 0; | |
| 232 | + return 0; | |
| 233 | + } | |
| 234 | + } | |
| 235 | + | |
| 222 | 236 | while (mmd_mask && link) { |
| 223 | 237 | devad = __ffs(mmd_mask); |
| 224 | 238 | mmd_mask &= ~BIT(devad); |
| @@ -1741,7 +1741,17 @@ EXPORT_SYMBOL(genphy_aneg_done); · 1740 unmodified lines | ||
| 1741 | 1741 | */ |
| 1742 | 1742 | int genphy_update_link(struct phy_device *phydev) |
| 1743 | 1743 | { |
| 1744 | − int status; | |
| 1744 | + int status = 0, bmcr; | |
| 1745 | + | |
| 1746 | + bmcr = phy_read(phydev, MII_BMCR); | |
| 1747 | + if (bmcr < 0) | |
| 1748 | + return bmcr; | |
| 1749 | + | |
| 1750 | + /* Autoneg is being started, therefore disregard BMSR value and | |
| 1751 | + * report link as down. | |
| 1752 | + */ | |
| 1753 | + if (bmcr & BMCR_ANRESTART) | |
| 1754 | + goto done; | |
| 1745 | 1755 | |
| 1746 | 1756 | /* The link state is latched low so that momentary link |
| 1747 | 1757 | * drops can be detected. Do not double-read the status |
| @@ -1004,6 +1004,8 @@ static void __team_compute_features(struct team *team) · 1003 unmodified lines | ||
| 1004 | 1004 | |
| 1005 | 1005 | team->dev->vlan_features = vlan_features; |
| 1006 | 1006 | team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | |
| 1007 | + NETIF_F_HW_VLAN_CTAG_TX | | |
| 1008 | + NETIF_F_HW_VLAN_STAG_TX | | |
| 1007 | 1009 | NETIF_F_GSO_UDP_L4; |
| 1008 | 1010 | team->dev->hard_header_len = max_hard_header_len; |
| 1009 | 1011 | |
| @@ -163,7 +163,8 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) · 162 unmodified lines | ||
| 163 | 163 | } |
| 164 | 164 | if (!timeout) { |
| 165 | 165 | dev_err(&udev->dev, "firmware not ready in time\n"); |
| 166 | − return -ETIMEDOUT; | |
| 166 | + ret = -ETIMEDOUT; | |
| 167 | + goto err; | |
| 167 | 168 | } |
| 168 | 169 | |
| 169 | 170 | /* enable ethernet mode (?) */ |
| @@ -113,16 +113,16 @@ kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) · 112 unmodified lines | ||
| 113 | 113 | status = kalmia_send_init_packet(dev, usb_buf, ARRAY_SIZE(init_msg_1), |
| 114 | 114 | usb_buf, 24); |
| 115 | 115 | if (status != 0) |
| 116 | − return status; | |
| 116 | + goto out; | |
| 117 | 117 | |
| 118 | 118 | memcpy(usb_buf, init_msg_2, 12); |
| 119 | 119 | status = kalmia_send_init_packet(dev, usb_buf, ARRAY_SIZE(init_msg_2), |
| 120 | 120 | usb_buf, 28); |
| 121 | 121 | if (status != 0) |
| 122 | − return status; | |
| 122 | + goto out; | |
| 123 | 123 | |
| 124 | 124 | memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN); |
| 125 | − | |
| 125 | +out: | |
| 126 | 126 | kfree(usb_buf); |
| 127 | 127 | return status; |
| 128 | 128 | } |
| @@ -3785,7 +3785,7 @@ static int lan78xx_probe(struct usb_interface *intf, · 3784 unmodified lines | ||
| 3785 | 3785 | ret = register_netdev(netdev); |
| 3786 | 3786 | if (ret != 0) { |
| 3787 | 3787 | netif_err(dev, probe, netdev, "couldn't register the device\n"); |
| 3788 | − goto out3; | |
| 3788 | + goto out4; | |
| 3789 | 3789 | } |
| 3790 | 3790 | |
| 3791 | 3791 | usb_set_intfdata(intf, dev); |
| @@ -3800,12 +3800,14 @@ static int lan78xx_probe(struct usb_interface *intf, · 8 unmodified lines | ||
| 3800 | 3800 | |
| 3801 | 3801 | ret = lan78xx_phy_init(dev); |
| 3802 | 3802 | if (ret < 0) |
| 3803 | − goto out4; | |
| 3803 | + goto out5; | |
| 3804 | 3804 | |
| 3805 | 3805 | return 0; |
| 3806 | 3806 | |
| 3807 | −out4: | |
| 3807 | +out5: | |
| 3808 | 3808 | unregister_netdev(netdev); |
| 3809 | +out4: | |
| 3810 | + usb_free_urb(dev->urb_intr); | |
| 3809 | 3811 | out3: |
| 3810 | 3812 | lan78xx_unbind(dev, intf); |
| 3811 | 3813 | out2: |
| @@ -351,13 +351,15 @@ int i2400m_barker_db_init(const char *_options) · 350 unmodified lines | ||
| 351 | 351 | } |
| 352 | 352 | result = i2400m_barker_db_add(barker); |
| 353 | 353 | if (result < 0) |
| 354 | − goto error_add; | |
| 354 | + goto error_parse_add; | |
| 355 | 355 | } |
| 356 | 356 | kfree(options_orig); |
| 357 | 357 | } |
| 358 | 358 | return 0; |
| 359 | 359 | |
| 360 | +error_parse_add: | |
| 360 | 361 | error_parse: |
| 362 | + kfree(options_orig); | |
| 361 | 363 | error_add: |
| 362 | 364 | kfree(i2400m_barker_db); |
| 363 | 365 | return result; |
| @@ -925,6 +925,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 924 unmodified lines | ||
| 925 | 925 | skb_shinfo(skb)->nr_frags = MAX_SKB_FRAGS; |
| 926 | 926 | nskb = xenvif_alloc_skb(0); |
| 927 | 927 | if (unlikely(nskb == NULL)) { |
| 928 | + skb_shinfo(skb)->nr_frags = 0; | |
| 928 | 929 | kfree_skb(skb); |
| 929 | 930 | xenvif_tx_err(queue, &txreq, extra_count, idx); |
| 930 | 931 | if (net_ratelimit()) |
| @@ -940,6 +941,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, · 9 unmodified lines | ||
| 940 | 941 | |
| 941 | 942 | if (xenvif_set_skb_gso(queue->vif, skb, gso)) { |
| 942 | 943 | /* Failure in xenvif_set_skb_gso is fatal. */ |
| 944 | + skb_shinfo(skb)->nr_frags = 0; | |
| 943 | 945 | kfree_skb(skb); |
| 944 | 946 | kfree_skb(nskb); |
| 945 | 947 | break; |
| @@ -6,11 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/msi.h> |
| 7 | 7 | #include <linux/pci.h> |
| 8 | 8 | |
| 9 | −MODULE_LICENSE("Dual BSD/GPL"); | |
| 10 | −MODULE_VERSION("0.1"); | |
| 11 | −MODULE_AUTHOR("Logan Gunthorpe <logang@deltatee.com>"); | |
| 12 | −MODULE_DESCRIPTION("NTB MSI Interrupt Library"); | |
| 13 | − | |
| 14 | 9 | struct ntb_msi { |
| 15 | 10 | u64 base_addr; |
| 16 | 11 | u64 end_addr; |
| @@ -1286,6 +1286,9 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, · 1285 unmodified lines | ||
| 1286 | 1286 | */ |
| 1287 | 1287 | if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { |
| 1288 | 1288 | mutex_lock(&ctrl->scan_lock); |
| 1289 | + mutex_lock(&ctrl->subsys->lock); | |
| 1290 | + nvme_mpath_start_freeze(ctrl->subsys); | |
| 1291 | + nvme_mpath_wait_freeze(ctrl->subsys); | |
| 1289 | 1292 | nvme_start_freeze(ctrl); |
| 1290 | 1293 | nvme_wait_freeze(ctrl); |
| 1291 | 1294 | } |
| @@ -1316,6 +1319,8 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) · 24 unmodified lines | ||
| 1316 | 1319 | nvme_update_formats(ctrl); |
| 1317 | 1320 | if (effects & (NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK)) { |
| 1318 | 1321 | nvme_unfreeze(ctrl); |
| 1322 | + nvme_mpath_unfreeze(ctrl->subsys); | |
| 1323 | + mutex_unlock(&ctrl->subsys->lock); | |
| 1319 | 1324 | mutex_unlock(&ctrl->scan_lock); |
| 1320 | 1325 | } |
| 1321 | 1326 | if (effects & NVME_CMD_EFFECTS_CCC) |
| @@ -1715,6 +1720,7 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id) · 393 unmodified lines | ||
| 1715 | 1720 | if (ns->head->disk) { |
| 1716 | 1721 | nvme_update_disk_info(ns->head->disk, ns, id); |
| 1717 | 1722 | blk_queue_stack_limits(ns->head->disk->queue, ns->queue); |
| 1723 | + revalidate_disk(ns->head->disk); | |
| 1718 | 1724 | } |
| 1719 | 1725 | #endif |
| 1720 | 1726 | } |
| @@ -2487,6 +2493,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) · 766 unmodified lines | ||
| 2487 | 2493 | if (ret) { |
| 2488 | 2494 | dev_err(ctrl->device, |
| 2489 | 2495 | "failed to register subsystem device.\n"); |
| 2496 | + put_device(&subsys->dev); | |
| 2490 | 2497 | goto out_unlock; |
| 2491 | 2498 | } |
| 2492 | 2499 | ida_init(&subsys->ns_ida); |
| @@ -2509,7 +2516,6 @@ out_put_subsystem: · 16 unmodified lines | ||
| 2509 | 2516 | nvme_put_subsystem(subsys); |
| 2510 | 2517 | out_unlock: |
| 2511 | 2518 | mutex_unlock(&nvme_subsystems_lock); |
| 2512 | − put_device(&subsys->dev); | |
| 2513 | 2519 | return ret; |
| 2514 | 2520 | } |
| 2515 | 2521 | |
| @@ -3571,6 +3577,13 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl) · 1055 unmodified lines | ||
| 3571 | 3577 | struct nvme_ns *ns, *next; |
| 3572 | 3578 | LIST_HEAD(ns_list); |
| 3573 | 3579 | |
| 3580 | + /* | |
| 3581 | + * make sure to requeue I/O to all namespaces as these | |
| 3582 | + * might result from the scan itself and must complete | |
| 3583 | + * for the scan_work to make progress | |
| 3584 | + */ | |
| 3585 | + nvme_mpath_clear_ctrl_paths(ctrl); | |
| 3586 | + | |
| 3574 | 3587 | /* prevent racing with ns scanning */ |
| 3575 | 3588 | flush_work(&ctrl->scan_work); |
| 3576 | 3589 | |
| @@ -12,6 +12,36 @@ module_param(multipath, bool, 0444); · 11 unmodified lines | ||
| 12 | 12 | MODULE_PARM_DESC(multipath, |
| 13 | 13 | "turn on native support for multiple controllers per subsystem"); |
| 14 | 14 | |
| 15 | +void nvme_mpath_unfreeze(struct nvme_subsystem *subsys) | |
| 16 | +{ | |
| 17 | + struct nvme_ns_head *h; | |
| 18 | + | |
| 19 | + lockdep_assert_held(&subsys->lock); | |
| 20 | + list_for_each_entry(h, &subsys->nsheads, entry) | |
| 21 | + if (h->disk) | |
| 22 | + blk_mq_unfreeze_queue(h->disk->queue); | |
| 23 | +} | |
| 24 | + | |
| 25 | +void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys) | |
| 26 | +{ | |
| 27 | + struct nvme_ns_head *h; | |
| 28 | + | |
| 29 | + lockdep_assert_held(&subsys->lock); | |
| 30 | + list_for_each_entry(h, &subsys->nsheads, entry) | |
| 31 | + if (h->disk) | |
| 32 | + blk_mq_freeze_queue_wait(h->disk->queue); | |
| 33 | +} | |
| 34 | + | |
| 35 | +void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) | |
| 36 | +{ | |
| 37 | + struct nvme_ns_head *h; | |
| 38 | + | |
| 39 | + lockdep_assert_held(&subsys->lock); | |
| 40 | + list_for_each_entry(h, &subsys->nsheads, entry) | |
| 41 | + if (h->disk) | |
| 42 | + blk_freeze_queue_start(h->disk->queue); | |
| 43 | +} | |
| 44 | + | |
| 15 | 45 | /* |
| 16 | 46 | * If multipathing is enabled we need to always use the subsystem instance |
| 17 | 47 | * number for numbering our devices to avoid conflicts between subsystems that |
| @@ -104,18 +134,34 @@ static const char *nvme_ana_state_names[] = { · 86 unmodified lines | ||
| 104 | 134 | [NVME_ANA_CHANGE] = "change", |
| 105 | 135 | }; |
| 106 | 136 | |
| 107 | −void nvme_mpath_clear_current_path(struct nvme_ns *ns) | |
| 137 | +bool nvme_mpath_clear_current_path(struct nvme_ns *ns) | |
| 108 | 138 | { |
| 109 | 139 | struct nvme_ns_head *head = ns->head; |
| 140 | + bool changed = false; | |
| 110 | 141 | int node; |
| 111 | 142 | |
| 112 | 143 | if (!head) |
| 113 | − return; | |
| 144 | + goto out; | |
| 114 | 145 | |
| 115 | 146 | for_each_node(node) { |
| 116 | − if (ns == rcu_access_pointer(head->current_path[node])) | |
| 147 | + if (ns == rcu_access_pointer(head->current_path[node])) { | |
| 117 | 148 | rcu_assign_pointer(head->current_path[node], NULL); |
| 149 | + changed = true; | |
| 150 | + } | |
| 118 | 151 | } |
| 152 | +out: | |
| 153 | + return changed; | |
| 154 | +} | |
| 155 | + | |
| 156 | +void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) | |
| 157 | +{ | |
| 158 | + struct nvme_ns *ns; | |
| 159 | + | |
| 160 | + mutex_lock(&ctrl->scan_lock); | |
| 161 | + list_for_each_entry(ns, &ctrl->namespaces, list) | |
| 162 | + if (nvme_mpath_clear_current_path(ns)) | |
| 163 | + kblockd_schedule_work(&ns->head->requeue_work); | |
| 164 | + mutex_unlock(&ctrl->scan_lock); | |
| 119 | 165 | } |
| 120 | 166 | |
| 121 | 167 | static bool nvme_path_is_disabled(struct nvme_ns *ns) |
| @@ -226,6 +272,24 @@ inline struct nvme_ns *nvme_find_path(struct nvme_ns_head *head) · 104 unmodified lines | ||
| 226 | 272 | return ns; |
| 227 | 273 | } |
| 228 | 274 | |
| 275 | +static bool nvme_available_path(struct nvme_ns_head *head) | |
| 276 | +{ | |
| 277 | + struct nvme_ns *ns; | |
| 278 | + | |
| 279 | + list_for_each_entry_rcu(ns, &head->list, siblings) { | |
| 280 | + switch (ns->ctrl->state) { | |
| 281 | + case NVME_CTRL_LIVE: | |
| 282 | + case NVME_CTRL_RESETTING: | |
| 283 | + case NVME_CTRL_CONNECTING: | |
| 284 | + /* fallthru */ | |
| 285 | + return true; | |
| 286 | + default: | |
| 287 | + break; | |
| 288 | + } | |
| 289 | + } | |
| 290 | + return false; | |
| 291 | +} | |
| 292 | + | |
| 229 | 293 | static blk_qc_t nvme_ns_head_make_request(struct request_queue *q, |
| 230 | 294 | struct bio *bio) |
| 231 | 295 | { |
| @@ -252,14 +316,14 @@ static blk_qc_t nvme_ns_head_make_request(struct request_queue *q, · 20 unmodified lines | ||
| 252 | 316 | disk_devt(ns->head->disk), |
| 253 | 317 | bio->bi_iter.bi_sector); |
| 254 | 318 | ret = direct_make_request(bio); |
| 255 | − } else if (!list_empty_careful(&head->list)) { | |
| 256 | − dev_warn_ratelimited(dev, "no path available - requeuing I/O\n"); | |
| 319 | + } else if (nvme_available_path(head)) { | |
| 320 | + dev_warn_ratelimited(dev, "no usable path - requeuing I/O\n"); | |
| 257 | 321 | |
| 258 | 322 | spin_lock_irq(&head->requeue_lock); |
| 259 | 323 | bio_list_add(&head->requeue_list, bio); |
| 260 | 324 | spin_unlock_irq(&head->requeue_lock); |
| 261 | 325 | } else { |
| 262 | − dev_warn_ratelimited(dev, "no path - failing I/O\n"); | |
| 326 | + dev_warn_ratelimited(dev, "no available path - failing I/O\n"); | |
| 263 | 327 | |
| 264 | 328 | bio->bi_status = BLK_STS_IOERR; |
| 265 | 329 | bio_endio(bio); |
| @@ -490,6 +490,9 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl) · 489 unmodified lines | ||
| 490 | 490 | return ctrl->ana_log_buf != NULL; |
| 491 | 491 | } |
| 492 | 492 | |
| 493 | +void nvme_mpath_unfreeze(struct nvme_subsystem *subsys); | |
| 494 | +void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys); | |
| 495 | +void nvme_mpath_start_freeze(struct nvme_subsystem *subsys); | |
| 493 | 496 | void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, |
| 494 | 497 | struct nvme_ctrl *ctrl, int *flags); |
| 495 | 498 | void nvme_failover_req(struct request *req); |
| @@ -500,7 +503,8 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head); · 4 unmodified lines | ||
| 500 | 503 | int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); |
| 501 | 504 | void nvme_mpath_uninit(struct nvme_ctrl *ctrl); |
| 502 | 505 | void nvme_mpath_stop(struct nvme_ctrl *ctrl); |
| 503 | −void nvme_mpath_clear_current_path(struct nvme_ns *ns); | |
| 506 | +bool nvme_mpath_clear_current_path(struct nvme_ns *ns); | |
| 507 | +void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl); | |
| 504 | 508 | struct nvme_ns *nvme_find_path(struct nvme_ns_head *head); |
| 505 | 509 | |
| 506 | 510 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) |
| @@ -548,7 +552,11 @@ static inline void nvme_mpath_add_disk(struct nvme_ns *ns, · 41 unmodified lines | ||
| 548 | 552 | static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) |
| 549 | 553 | { |
| 550 | 554 | } |
| 551 | −static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) | |
| 555 | +static inline bool nvme_mpath_clear_current_path(struct nvme_ns *ns) | |
| 556 | +{ | |
| 557 | + return false; | |
| 558 | +} | |
| 559 | +static inline void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) | |
| 552 | 560 | { |
| 553 | 561 | } |
| 554 | 562 | static inline void nvme_mpath_check_last_path(struct nvme_ns *ns) |
| @@ -568,6 +576,15 @@ static inline void nvme_mpath_uninit(struct nvme_ctrl *ctrl) · 13 unmodified lines | ||
| 568 | 576 | static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl) |
| 569 | 577 | { |
| 570 | 578 | } |
| 579 | +static inline void nvme_mpath_unfreeze(struct nvme_subsystem *subsys) | |
| 580 | +{ | |
| 581 | +} | |
| 582 | +static inline void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys) | |
| 583 | +{ | |
| 584 | +} | |
| 585 | +static inline void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) | |
| 586 | +{ | |
| 587 | +} | |
| 571 | 588 | #endif /* CONFIG_NVME_MULTIPATH */ |
| 572 | 589 | |
| 573 | 590 | #ifdef CONFIG_NVM |
| @@ -2695,7 +2695,7 @@ static void nvme_async_probe(void *data, async_cookie_t cookie) · 2694 unmodified lines | ||
| 2695 | 2695 | { |
| 2696 | 2696 | struct nvme_dev *dev = data; |
| 2697 | 2697 | |
| 2698 | − nvme_reset_ctrl_sync(&dev->ctrl); | |
| 2698 | + flush_work(&dev->ctrl.reset_work); | |
| 2699 | 2699 | flush_work(&dev->ctrl.scan_work); |
| 2700 | 2700 | nvme_put_ctrl(&dev->ctrl); |
| 2701 | 2701 | } |
| @@ -2761,6 +2761,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 59 unmodified lines | ||
| 2761 | 2761 | |
| 2762 | 2762 | dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); |
| 2763 | 2763 | |
| 2764 | + nvme_reset_ctrl(&dev->ctrl); | |
| 2764 | 2765 | nvme_get_ctrl(&dev->ctrl); |
| 2765 | 2766 | async_schedule(nvme_async_probe, dev); |
| 2766 | 2767 | |
| @@ -2846,7 +2847,7 @@ static int nvme_resume(struct device *dev) · 79 unmodified lines | ||
| 2846 | 2847 | struct nvme_dev *ndev = pci_get_drvdata(to_pci_dev(dev)); |
| 2847 | 2848 | struct nvme_ctrl *ctrl = &ndev->ctrl; |
| 2848 | 2849 | |
| 2849 | − if (pm_resume_via_firmware() || !ctrl->npss || | |
| 2850 | + if (ndev->last_ps == U32_MAX || | |
| 2850 | 2851 | nvme_set_power_state(ctrl, ndev->last_ps) != 0) |
| 2851 | 2852 | nvme_reset_ctrl(ctrl); |
| 2852 | 2853 | return 0; |
| @@ -2859,6 +2860,8 @@ static int nvme_suspend(struct device *dev) · 6 unmodified lines | ||
| 2859 | 2860 | struct nvme_ctrl *ctrl = &ndev->ctrl; |
| 2860 | 2861 | int ret = -EBUSY; |
| 2861 | 2862 | |
| 2863 | + ndev->last_ps = U32_MAX; | |
| 2864 | + | |
| 2862 | 2865 | /* |
| 2863 | 2866 | * The platform does not remove power for a kernel managed suspend so |
| 2864 | 2867 | * use host managed nvme power settings for lowest idle power if |
| @@ -2866,8 +2869,14 @@ static int nvme_suspend(struct device *dev) · 1 unmodified line | ||
| 2866 | 2869 | * shutdown. But if the firmware is involved after the suspend or the |
| 2867 | 2870 | * device does not support any non-default power states, shut down the |
| 2868 | 2871 | * device fully. |
| 2872 | + * | |
| 2873 | + * If ASPM is not enabled for the device, shut down the device and allow | |
| 2874 | + * the PCI bus layer to put it into D3 in order to take the PCIe link | |
| 2875 | + * down, so as to allow the platform to achieve its minimum low-power | |
| 2876 | + * state (which may not be possible if the link is up). | |
| 2869 | 2877 | */ |
| 2870 | − if (pm_suspend_via_firmware() || !ctrl->npss) { | |
| 2878 | + if (pm_suspend_via_firmware() || !ctrl->npss || | |
| 2879 | + !pcie_aspm_enabled(pdev)) { | |
| 2871 | 2880 | nvme_dev_disable(ndev, true); |
| 2872 | 2881 | return 0; |
| 2873 | 2882 | } |
| @@ -2880,7 +2889,6 @@ static int nvme_suspend(struct device *dev) · 6 unmodified lines | ||
| 2880 | 2889 | ctrl->state != NVME_CTRL_ADMIN_ONLY) |
| 2881 | 2890 | goto unfreeze; |
| 2882 | 2891 | |
| 2883 | − ndev->last_ps = 0; | |
| 2884 | 2892 | ret = nvme_get_power_state(ctrl, &ndev->last_ps); |
| 2885 | 2893 | if (ret < 0) |
| 2886 | 2894 | goto unfreeze; |
| @@ -562,13 +562,17 @@ out_destroy_cm_id: · 561 unmodified lines | ||
| 562 | 562 | return ret; |
| 563 | 563 | } |
| 564 | 564 | |
| 565 | +static void __nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) | |
| 566 | +{ | |
| 567 | + rdma_disconnect(queue->cm_id); | |
| 568 | + ib_drain_qp(queue->qp); | |
| 569 | +} | |
| 570 | + | |
| 565 | 571 | static void nvme_rdma_stop_queue(struct nvme_rdma_queue *queue) |
| 566 | 572 | { |
| 567 | 573 | if (!test_and_clear_bit(NVME_RDMA_Q_LIVE, &queue->flags)) |
| 568 | 574 | return; |
| 569 | − | |
| 570 | − rdma_disconnect(queue->cm_id); | |
| 571 | − ib_drain_qp(queue->qp); | |
| 575 | + __nvme_rdma_stop_queue(queue); | |
| 572 | 576 | } |
| 573 | 577 | |
| 574 | 578 | static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue) |
| @@ -607,11 +611,13 @@ static int nvme_rdma_start_queue(struct nvme_rdma_ctrl *ctrl, int idx) · 32 unmodified lines | ||
| 607 | 611 | else |
| 608 | 612 | ret = nvmf_connect_admin_queue(&ctrl->ctrl); |
| 609 | 613 | |
| 610 | − if (!ret) | |
| 614 | + if (!ret) { | |
| 611 | 615 | set_bit(NVME_RDMA_Q_LIVE, &queue->flags); |
| 612 | − else | |
| 616 | + } else { | |
| 617 | + __nvme_rdma_stop_queue(queue); | |
| 613 | 618 | dev_info(ctrl->ctrl.device, |
| 614 | 619 | "failed to connect queue: %d ret=%d\n", idx, ret); |
| 620 | + } | |
| 615 | 621 | return ret; |
| 616 | 622 | } |
| 617 | 623 | |
| @@ -675,6 +675,7 @@ static void nvmet_port_subsys_drop_link(struct config_item *parent, · 674 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | found: |
| 677 | 677 | list_del(&p->entry); |
| 678 | + nvmet_port_del_ctrls(port, subsys); | |
| 678 | 679 | nvmet_port_disc_changed(port, subsys); |
| 679 | 680 | |
| 680 | 681 | if (list_empty(&port->subsystems)) |
| @@ -46,6 +46,9 @@ inline u16 errno_to_nvme_status(struct nvmet_req *req, int errno) · 45 unmodified lines | ||
| 46 | 46 | u16 status; |
| 47 | 47 | |
| 48 | 48 | switch (errno) { |
| 49 | + case 0: | |
| 50 | + status = NVME_SC_SUCCESS; | |
| 51 | + break; | |
| 49 | 52 | case -ENOSPC: |
| 50 | 53 | req->error_loc = offsetof(struct nvme_rw_command, length); |
| 51 | 54 | status = NVME_SC_CAP_EXCEEDED | NVME_SC_DNR; |
| @@ -280,6 +283,18 @@ void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops) · 228 unmodified lines | ||
| 280 | 283 | } |
| 281 | 284 | EXPORT_SYMBOL_GPL(nvmet_unregister_transport); |
| 282 | 285 | |
| 286 | +void nvmet_port_del_ctrls(struct nvmet_port *port, struct nvmet_subsys *subsys) | |
| 287 | +{ | |
| 288 | + struct nvmet_ctrl *ctrl; | |
| 289 | + | |
| 290 | + mutex_lock(&subsys->lock); | |
| 291 | + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { | |
| 292 | + if (ctrl->port == port) | |
| 293 | + ctrl->ops->delete_ctrl(ctrl); | |
| 294 | + } | |
| 295 | + mutex_unlock(&subsys->lock); | |
| 296 | +} | |
| 297 | + | |
| 283 | 298 | int nvmet_enable_port(struct nvmet_port *port) |
| 284 | 299 | { |
| 285 | 300 | const struct nvmet_fabrics_ops *ops; |
| @@ -654,6 +654,14 @@ static void nvme_loop_remove_port(struct nvmet_port *port) · 653 unmodified lines | ||
| 654 | 654 | mutex_lock(&nvme_loop_ports_mutex); |
| 655 | 655 | list_del_init(&port->entry); |
| 656 | 656 | mutex_unlock(&nvme_loop_ports_mutex); |
| 657 | + | |
| 658 | + /* | |
| 659 | + * Ensure any ctrls that are in the process of being | |
| 660 | + * deleted are in fact deleted before we return | |
| 661 | + * and free the port. This is to prevent active | |
| 662 | + * ctrls from using a port after it's freed. | |
| 663 | + */ | |
| 664 | + flush_workqueue(nvme_delete_wq); | |
| 657 | 665 | } |
| 658 | 666 | |
| 659 | 667 | static const struct nvmet_fabrics_ops nvme_loop_ops = { |
| @@ -418,6 +418,9 @@ void nvmet_port_send_ana_event(struct nvmet_port *port); · 417 unmodified lines | ||
| 418 | 418 | int nvmet_register_transport(const struct nvmet_fabrics_ops *ops); |
| 419 | 419 | void nvmet_unregister_transport(const struct nvmet_fabrics_ops *ops); |
| 420 | 420 | |
| 421 | +void nvmet_port_del_ctrls(struct nvmet_port *port, | |
| 422 | + struct nvmet_subsys *subsys); | |
| 423 | + | |
| 421 | 424 | int nvmet_enable_port(struct nvmet_port *port); |
| 422 | 425 | void nvmet_disable_port(struct nvmet_port *port); |
| 423 | 426 | |
| @@ -224,10 +224,17 @@ int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, · 223 unmodified lines | ||
| 224 | 224 | if (!config->base_dev) |
| 225 | 225 | return -EINVAL; |
| 226 | 226 | |
| 227 | − if (nvmem->read_only) | |
| 228 | − nvmem->eeprom = bin_attr_ro_root_nvmem; | |
| 229 | − else | |
| 230 | − nvmem->eeprom = bin_attr_rw_root_nvmem; | |
| 227 | + if (nvmem->read_only) { | |
| 228 | + if (config->root_only) | |
| 229 | + nvmem->eeprom = bin_attr_ro_root_nvmem; | |
| 230 | + else | |
| 231 | + nvmem->eeprom = bin_attr_ro_nvmem; | |
| 232 | + } else { | |
| 233 | + if (config->root_only) | |
| 234 | + nvmem->eeprom = bin_attr_rw_root_nvmem; | |
| 235 | + else | |
| 236 | + nvmem->eeprom = bin_attr_rw_nvmem; | |
| 237 | + } | |
| 231 | 238 | nvmem->eeprom.attr.name = "eeprom"; |
| 232 | 239 | nvmem->eeprom.size = nvmem->size; |
| 233 | 240 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| @@ -277,7 +277,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); · 276 unmodified lines | ||
| 277 | 277 | * of_irq_parse_one - Resolve an interrupt for a device |
| 278 | 278 | * @device: the device whose interrupt is to be resolved |
| 279 | 279 | * @index: index of the interrupt to resolve |
| 280 | − * @out_irq: structure of_irq filled by this function | |
| 280 | + * @out_irq: structure of_phandle_args filled by this function | |
| 281 | 281 | * |
| 282 | 282 | * This function resolves an interrupt for a node by walking the interrupt tree, |
| 283 | 283 | * finding which interrupt controller node it is attached to, and returning the |
| @@ -206,16 +206,22 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, · 205 unmodified lines | ||
| 206 | 206 | for_each_child_of_node(local_fixups, child) { |
| 207 | 207 | |
| 208 | 208 | for_each_child_of_node(overlay, overlay_child) |
| 209 | − if (!node_name_cmp(child, overlay_child)) | |
| 209 | + if (!node_name_cmp(child, overlay_child)) { | |
| 210 | + of_node_put(overlay_child); | |
| 210 | 211 | break; |
| 212 | + } | |
| 211 | 213 | |
| 212 | − if (!overlay_child) | |
| 214 | + if (!overlay_child) { | |
| 215 | + of_node_put(child); | |
| 213 | 216 | return -EINVAL; |
| 217 | + } | |
| 214 | 218 | |
| 215 | 219 | err = adjust_local_phandle_references(child, overlay_child, |
| 216 | 220 | phandle_delta); |
| 217 | − if (err) | |
| 221 | + if (err) { | |
| 222 | + of_node_put(child); | |
| 218 | 223 | return err; |
| 224 | + } | |
| 219 | 225 | } |
| 220 | 226 | |
| 221 | 227 | return 0; |
| @@ -1025,10 +1025,15 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) · 1024 unmodified lines | ||
| 1025 | 1025 | if (state == PCI_D0) { |
| 1026 | 1026 | pci_platform_power_transition(dev, PCI_D0); |
| 1027 | 1027 | /* |
| 1028 | − * Mandatory power management transition delays are | |
| 1029 | − * handled in the PCIe portdrv resume hooks. | |
| 1028 | + * Mandatory power management transition delays, see | |
| 1029 | + * PCI Express Base Specification Revision 2.0 Section | |
| 1030 | + * 6.6.1: Conventional Reset. Do not delay for | |
| 1031 | + * devices powered on/off by corresponding bridge, | |
| 1032 | + * because have already delayed for the bridge. | |
| 1030 | 1033 | */ |
| 1031 | 1034 | if (dev->runtime_d3cold) { |
| 1035 | + if (dev->d3cold_delay && !dev->imm_ready) | |
| 1036 | + msleep(dev->d3cold_delay); | |
| 1032 | 1037 | /* |
| 1033 | 1038 | * When powering on a bridge from D3cold, the |
| 1034 | 1039 | * whole hierarchy may be powered on into |
| @@ -4602,16 +4607,14 @@ static int pci_pm_reset(struct pci_dev *dev, int probe) · 3567 unmodified lines | ||
| 4602 | 4607 | |
| 4603 | 4608 | return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS); |
| 4604 | 4609 | } |
| 4605 | − | |
| 4606 | 4610 | /** |
| 4607 | − * pcie_wait_for_link_delay - Wait until link is active or inactive | |
| 4611 | + * pcie_wait_for_link - Wait until link is active or inactive | |
| 4608 | 4612 | * @pdev: Bridge device |
| 4609 | 4613 | * @active: waiting for active or inactive? |
| 4610 | − * @delay: Delay to wait after link has become active (in ms) | |
| 4611 | 4614 | * |
| 4612 | 4615 | * Use this to wait till link becomes active or inactive. |
| 4613 | 4616 | */ |
| 4614 | −bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, int delay) | |
| 4617 | +bool pcie_wait_for_link(struct pci_dev *pdev, bool active) | |
| 4615 | 4618 | { |
| 4616 | 4619 | int timeout = 1000; |
| 4617 | 4620 | bool ret; |
| @@ -4648,25 +4651,13 @@ bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, int delay) · 30 unmodified lines | ||
| 4648 | 4651 | timeout -= 10; |
| 4649 | 4652 | } |
| 4650 | 4653 | if (active && ret) |
| 4651 | − msleep(delay); | |
| 4654 | + msleep(100); | |
| 4652 | 4655 | else if (ret != active) |
| 4653 | 4656 | pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", |
| 4654 | 4657 | active ? "set" : "cleared"); |
| 4655 | 4658 | return ret == active; |
| 4656 | 4659 | } |
| 4657 | 4660 | |
| 4658 | −/** | |
| 4659 | − * pcie_wait_for_link - Wait until link is active or inactive | |
| 4660 | − * @pdev: Bridge device | |
| 4661 | − * @active: waiting for active or inactive? | |
| 4662 | − * | |
| 4663 | − * Use this to wait till link becomes active or inactive. | |
| 4664 | − */ | |
| 4665 | −bool pcie_wait_for_link(struct pci_dev *pdev, bool active) | |
| 4666 | −{ | |
| 4667 | − return pcie_wait_for_link_delay(pdev, active, 100); | |
| 4668 | −} | |
| 4669 | − | |
| 4670 | 4661 | void pci_reset_secondary_bus(struct pci_dev *dev) |
| 4671 | 4662 | { |
| 4672 | 4663 | u16 ctrl; |
| @@ -497,7 +497,6 @@ static inline int pci_dev_specific_disable_acs_redir(struct pci_dev *dev) · 496 unmodified lines | ||
| 497 | 497 | void pcie_do_recovery(struct pci_dev *dev, enum pci_channel_state state, |
| 498 | 498 | u32 service); |
| 499 | 499 | |
| 500 | −bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, int delay); | |
| 501 | 500 | bool pcie_wait_for_link(struct pci_dev *pdev, bool active); |
| 502 | 501 | #ifdef CONFIG_PCIEASPM |
| 503 | 502 | void pcie_aspm_init_link_state(struct pci_dev *pdev); |
| @@ -1170,6 +1170,26 @@ static int pcie_aspm_get_policy(char *buffer, const struct kernel_param *kp) · 1169 unmodified lines | ||
| 1170 | 1170 | module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy, |
| 1171 | 1171 | NULL, 0644); |
| 1172 | 1172 | |
| 1173 | +/** | |
| 1174 | + * pcie_aspm_enabled - Check if PCIe ASPM has been enabled for a device. | |
| 1175 | + * @pdev: Target device. | |
| 1176 | + */ | |
| 1177 | +bool pcie_aspm_enabled(struct pci_dev *pdev) | |
| 1178 | +{ | |
| 1179 | + struct pci_dev *bridge = pci_upstream_bridge(pdev); | |
| 1180 | + bool ret; | |
| 1181 | + | |
| 1182 | + if (!bridge) | |
| 1183 | + return false; | |
| 1184 | + | |
| 1185 | + mutex_lock(&aspm_lock); | |
| 1186 | + ret = bridge->link_state ? !!bridge->link_state->aspm_enabled : false; | |
| 1187 | + mutex_unlock(&aspm_lock); | |
| 1188 | + | |
| 1189 | + return ret; | |
| 1190 | +} | |
| 1191 | +EXPORT_SYMBOL_GPL(pcie_aspm_enabled); | |
| 1192 | + | |
| 1173 | 1193 | #ifdef CONFIG_PCIEASPM_DEBUG |
| 1174 | 1194 | static ssize_t link_state_show(struct device *dev, |
| 1175 | 1195 | struct device_attribute *attr, |
| @@ -9,7 +9,6 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | #include <linux/pci.h> |
| 11 | 11 | #include <linux/kernel.h> |
| 12 | −#include <linux/delay.h> | |
| 13 | 12 | #include <linux/errno.h> |
| 14 | 13 | #include <linux/pm.h> |
| 15 | 14 | #include <linux/pm_runtime.h> |
| @@ -379,67 +378,6 @@ static int pm_iter(struct device *dev, void *data) · 363 unmodified lines | ||
| 379 | 378 | return 0; |
| 380 | 379 | } |
| 381 | 380 | |
| 382 | −static int get_downstream_delay(struct pci_bus *bus) | |
| 383 | −{ | |
| 384 | − struct pci_dev *pdev; | |
| 385 | − int min_delay = 100; | |
| 386 | − int max_delay = 0; | |
| 387 | − | |
| 388 | − list_for_each_entry(pdev, &bus->devices, bus_list) { | |
| 389 | − if (!pdev->imm_ready) | |
| 390 | − min_delay = 0; | |
| 391 | − else if (pdev->d3cold_delay < min_delay) | |
| 392 | − min_delay = pdev->d3cold_delay; | |
| 393 | − if (pdev->d3cold_delay > max_delay) | |
| 394 | − max_delay = pdev->d3cold_delay; | |
| 395 | − } | |
| 396 | − | |
| 397 | − return max(min_delay, max_delay); | |
| 398 | −} | |
| 399 | − | |
| 400 | −/* | |
| 401 | − * wait_for_downstream_link - Wait for downstream link to establish | |
| 402 | − * @pdev: PCIe port whose downstream link is waited | |
| 403 | − * | |
| 404 | − * Handle delays according to PCIe 4.0 section 6.6.1 before configuration | |
| 405 | − * access to the downstream component is permitted. | |
| 406 | − * | |
| 407 | − * This blocks PCI core resume of the hierarchy below this port until the | |
| 408 | − * link is trained. Should be called before resuming port services to | |
| 409 | − * prevent pciehp from starting to tear-down the hierarchy too soon. | |
| 410 | − */ | |
| 411 | −static void wait_for_downstream_link(struct pci_dev *pdev) | |
| 412 | −{ | |
| 413 | − int delay; | |
| 414 | − | |
| 415 | − if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && | |
| 416 | − pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) | |
| 417 | − return; | |
| 418 | − | |
| 419 | − if (pci_dev_is_disconnected(pdev)) | |
| 420 | − return; | |
| 421 | − | |
| 422 | − if (!pdev->subordinate || list_empty(&pdev->subordinate->devices) || | |
| 423 | − !pdev->bridge_d3) | |
| 424 | − return; | |
| 425 | − | |
| 426 | − delay = get_downstream_delay(pdev->subordinate); | |
| 427 | − if (!delay) | |
| 428 | − return; | |
| 429 | − | |
| 430 | − dev_dbg(&pdev->dev, "waiting downstream link for %d ms\n", delay); | |
| 431 | − | |
| 432 | − /* | |
| 433 | − * If downstream port does not support speeds greater than 5 GT/s | |
| 434 | − * need to wait 100ms. For higher speeds (gen3) we need to wait | |
| 435 | − * first for the data link layer to become active. | |
| 436 | − */ | |
| 437 | − if (pcie_get_speed_cap(pdev) <= PCIE_SPEED_5_0GT) | |
| 438 | − msleep(delay); | |
| 439 | − else | |
| 440 | − pcie_wait_for_link_delay(pdev, true, delay); | |
| 441 | −} | |
| 442 | − | |
| 443 | 381 | /** |
| 444 | 382 | * pcie_port_device_suspend - suspend port services associated with a PCIe port |
| 445 | 383 | * @dev: PCI Express port to handle |
| @@ -453,8 +391,6 @@ int pcie_port_device_suspend(struct device *dev) · 7 unmodified lines | ||
| 453 | 391 | int pcie_port_device_resume_noirq(struct device *dev) |
| 454 | 392 | { |
| 455 | 393 | size_t off = offsetof(struct pcie_port_service_driver, resume_noirq); |
| 456 | − | |
| 457 | − wait_for_downstream_link(to_pci_dev(dev)); | |
| 458 | 394 | return device_for_each_child(dev, &off, pm_iter); |
| 459 | 395 | } |
| 460 | 396 | |
| @@ -485,8 +421,6 @@ int pcie_port_device_runtime_suspend(struct device *dev) · 24 unmodified lines | ||
| 485 | 421 | int pcie_port_device_runtime_resume(struct device *dev) |
| 486 | 422 | { |
| 487 | 423 | size_t off = offsetof(struct pcie_port_service_driver, runtime_resume); |
| 488 | − | |
| 489 | − wait_for_downstream_link(to_pci_dev(dev)); | |
| 490 | 424 | return device_for_each_child(dev, &off, pm_iter); |
| 491 | 425 | } |
| 492 | 426 | #endif /* PM */ |
| @@ -255,8 +255,10 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, · 254 unmodified lines | ||
| 255 | 255 | switch (state->Vcc) { |
| 256 | 256 | case 50: |
| 257 | 257 | ++v; |
| 258 | + /* fall through */ | |
| 258 | 259 | case 33: |
| 259 | 260 | ++v; |
| 261 | + /* fall through */ | |
| 260 | 262 | case 0: |
| 261 | 263 | break; |
| 262 | 264 | default: |
| @@ -267,9 +269,11 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, · 4 unmodified lines | ||
| 267 | 269 | switch (state->Vpp) { |
| 268 | 270 | case 12: |
| 269 | 271 | ++p; |
| 272 | + /* fall through */ | |
| 270 | 273 | case 33: |
| 271 | 274 | case 50: |
| 272 | 275 | ++p; |
| 276 | + /* fall through */ | |
| 273 | 277 | case 0: |
| 274 | 278 | break; |
| 275 | 279 | default: |
| @@ -2412,7 +2412,7 @@ static const struct aspeed_pin_config aspeed_g4_configs[] = { · 2411 unmodified lines | ||
| 2412 | 2412 | { PIN_CONFIG_INPUT_DEBOUNCE, { C14, B14 }, SCUA8, 27 }, |
| 2413 | 2413 | }; |
| 2414 | 2414 | |
| 2415 | −static int aspeed_g4_sig_expr_set(const struct aspeed_pinmux_data *ctx, | |
| 2415 | +static int aspeed_g4_sig_expr_set(struct aspeed_pinmux_data *ctx, | |
| 2416 | 2416 | const struct aspeed_sig_expr *expr, |
| 2417 | 2417 | bool enable) |
| 2418 | 2418 | { |
| @@ -2507,6 +2507,61 @@ static struct aspeed_pin_config aspeed_g5_configs[] = { · 2506 unmodified lines | ||
| 2507 | 2507 | { PIN_CONFIG_INPUT_DEBOUNCE, { A20, B19 }, SCUA8, 27 }, |
| 2508 | 2508 | }; |
| 2509 | 2509 | |
| 2510 | +static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx, | |
| 2511 | + int ip) | |
| 2512 | +{ | |
| 2513 | + if (ip == ASPEED_IP_SCU) { | |
| 2514 | + WARN(!ctx->maps[ip], "Missing SCU syscon!"); | |
| 2515 | + return ctx->maps[ip]; | |
| 2516 | + } | |
| 2517 | + | |
| 2518 | + if (ip >= ASPEED_NR_PINMUX_IPS) | |
| 2519 | + return ERR_PTR(-EINVAL); | |
| 2520 | + | |
| 2521 | + if (likely(ctx->maps[ip])) | |
| 2522 | + return ctx->maps[ip]; | |
| 2523 | + | |
| 2524 | + if (ip == ASPEED_IP_GFX) { | |
| 2525 | + struct device_node *node; | |
| 2526 | + struct regmap *map; | |
| 2527 | + | |
| 2528 | + node = of_parse_phandle(ctx->dev->of_node, | |
| 2529 | + "aspeed,external-nodes", 0); | |
| 2530 | + if (node) { | |
| 2531 | + map = syscon_node_to_regmap(node); | |
| 2532 | + of_node_put(node); | |
| 2533 | + if (IS_ERR(map)) | |
| 2534 | + return map; | |
| 2535 | + } else | |
| 2536 | + return ERR_PTR(-ENODEV); | |
| 2537 | + | |
| 2538 | + ctx->maps[ASPEED_IP_GFX] = map; | |
| 2539 | + dev_dbg(ctx->dev, "Acquired GFX regmap"); | |
| 2540 | + return map; | |
| 2541 | + } | |
| 2542 | + | |
| 2543 | + if (ip == ASPEED_IP_LPC) { | |
| 2544 | + struct device_node *node; | |
| 2545 | + struct regmap *map; | |
| 2546 | + | |
| 2547 | + node = of_parse_phandle(ctx->dev->of_node, | |
| 2548 | + "aspeed,external-nodes", 1); | |
| 2549 | + if (node) { | |
| 2550 | + map = syscon_node_to_regmap(node->parent); | |
| 2551 | + of_node_put(node); | |
| 2552 | + if (IS_ERR(map)) | |
| 2553 | + return map; | |
| 2554 | + } else | |
| 2555 | + map = ERR_PTR(-ENODEV); | |
| 2556 | + | |
| 2557 | + ctx->maps[ASPEED_IP_LPC] = map; | |
| 2558 | + dev_dbg(ctx->dev, "Acquired LPC regmap"); | |
| 2559 | + return map; | |
| 2560 | + } | |
| 2561 | + | |
| 2562 | + return ERR_PTR(-EINVAL); | |
| 2563 | +} | |
| 2564 | + | |
| 2510 | 2565 | /** |
| 2511 | 2566 | * Configure a pin's signal by applying an expression's descriptor state for |
| 2512 | 2567 | * all descriptors in the expression. |
| @@ -2520,7 +2575,7 @@ static struct aspeed_pin_config aspeed_g5_configs[] = { · 7 unmodified lines | ||
| 2520 | 2575 | * Return: 0 if the expression is configured as requested and a negative error |
| 2521 | 2576 | * code otherwise |
| 2522 | 2577 | */ |
| 2523 | −static int aspeed_g5_sig_expr_set(const struct aspeed_pinmux_data *ctx, | |
| 2578 | +static int aspeed_g5_sig_expr_set(struct aspeed_pinmux_data *ctx, | |
| 2524 | 2579 | const struct aspeed_sig_expr *expr, |
| 2525 | 2580 | bool enable) |
| 2526 | 2581 | { |
| @@ -2531,9 +2586,15 @@ static int aspeed_g5_sig_expr_set(const struct aspeed_pinmux_data *ctx, · 4 unmodified lines | ||
| 2531 | 2586 | const struct aspeed_sig_desc *desc = &expr->descs[i]; |
| 2532 | 2587 | u32 pattern = enable ? desc->enable : desc->disable; |
| 2533 | 2588 | u32 val = (pattern << __ffs(desc->mask)); |
| 2589 | + struct regmap *map; | |
| 2534 | 2590 | |
| 2535 | − if (!ctx->maps[desc->ip]) | |
| 2536 | − return -ENODEV; | |
| 2591 | + map = aspeed_g5_acquire_regmap(ctx, desc->ip); | |
| 2592 | + if (IS_ERR(map)) { | |
| 2593 | + dev_err(ctx->dev, | |
| 2594 | + "Failed to acquire regmap for IP block %d\n", | |
| 2595 | + desc->ip); | |
| 2596 | + return PTR_ERR(map); | |
| 2597 | + } | |
| 2537 | 2598 | |
| 2538 | 2599 | /* |
| 2539 | 2600 | * Strap registers are configured in hardware or by early-boot |
| @@ -2641,34 +2702,11 @@ static struct pinctrl_desc aspeed_g5_pinctrl_desc = { · 101 unmodified lines | ||
| 2641 | 2702 | static int aspeed_g5_pinctrl_probe(struct platform_device *pdev) |
| 2642 | 2703 | { |
| 2643 | 2704 | int i; |
| 2644 | − struct regmap *map; | |
| 2645 | − struct device_node *node; | |
| 2646 | 2705 | |
| 2647 | 2706 | for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++) |
| 2648 | 2707 | aspeed_g5_pins[i].number = i; |
| 2649 | 2708 | |
| 2650 | − node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 0); | |
| 2651 | − map = syscon_node_to_regmap(node); | |
| 2652 | − of_node_put(node); | |
| 2653 | − if (IS_ERR(map)) { | |
| 2654 | − dev_warn(&pdev->dev, "No GFX phandle found, some mux configurations may fail\n"); | |
| 2655 | − map = NULL; | |
| 2656 | − } | |
| 2657 | − aspeed_g5_pinctrl_data.pinmux.maps[ASPEED_IP_GFX] = map; | |
| 2658 | − | |
| 2659 | − node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 1); | |
| 2660 | − if (node) { | |
| 2661 | − map = syscon_node_to_regmap(node->parent); | |
| 2662 | − if (IS_ERR(map)) { | |
| 2663 | − dev_warn(&pdev->dev, "LHC parent is not a syscon, some mux configurations may fail\n"); | |
| 2664 | − map = NULL; | |
| 2665 | − } | |
| 2666 | − } else { | |
| 2667 | − dev_warn(&pdev->dev, "No LHC phandle found, some mux configurations may fail\n"); | |
| 2668 | − map = NULL; | |
| 2669 | − } | |
| 2670 | − of_node_put(node); | |
| 2671 | − aspeed_g5_pinctrl_data.pinmux.maps[ASPEED_IP_LPC] = map; | |
| 2709 | + aspeed_g5_pinctrl_data.pinmux.dev = &pdev->dev; | |
| 2672 | 2710 | |
| 2673 | 2711 | return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc, |
| 2674 | 2712 | &aspeed_g5_pinctrl_data); |
| @@ -71,7 +71,7 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev, · 70 unmodified lines | ||
| 71 | 71 | return 0; |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | −static int aspeed_sig_expr_enable(const struct aspeed_pinmux_data *ctx, | |
| 74 | +static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx, | |
| 75 | 75 | const struct aspeed_sig_expr *expr) |
| 76 | 76 | { |
| 77 | 77 | int ret; |
| @@ -86,7 +86,7 @@ static int aspeed_sig_expr_enable(const struct aspeed_pinmux_data *ctx, · 8 unmodified lines | ||
| 86 | 86 | return 0; |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | −static int aspeed_sig_expr_disable(const struct aspeed_pinmux_data *ctx, | |
| 89 | +static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx, | |
| 90 | 90 | const struct aspeed_sig_expr *expr) |
| 91 | 91 | { |
| 92 | 92 | int ret; |
| @@ -109,7 +109,7 @@ static int aspeed_sig_expr_disable(const struct aspeed_pinmux_data *ctx, · 16 unmodified lines | ||
| 109 | 109 | * |
| 110 | 110 | * Return: 0 if all expressions are disabled, otherwise a negative error code |
| 111 | 111 | */ |
| 112 | −static int aspeed_disable_sig(const struct aspeed_pinmux_data *ctx, | |
| 112 | +static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx, | |
| 113 | 113 | const struct aspeed_sig_expr **exprs) |
| 114 | 114 | { |
| 115 | 115 | int ret = 0; |
| @@ -217,8 +217,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, · 101 unmodified lines | ||
| 217 | 217 | { |
| 218 | 218 | int i; |
| 219 | 219 | int ret; |
| 220 | − const struct aspeed_pinctrl_data *pdata = | |
| 221 | − pinctrl_dev_get_drvdata(pctldev); | |
| 220 | + struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | |
| 222 | 221 | const struct aspeed_pin_group *pgroup = &pdata->pinmux.groups[group]; |
| 223 | 222 | const struct aspeed_pin_function *pfunc = |
| 224 | 223 | &pdata->pinmux.functions[function]; |
| @@ -306,8 +305,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, · 81 unmodified lines | ||
| 306 | 305 | unsigned int offset) |
| 307 | 306 | { |
| 308 | 307 | int ret; |
| 309 | − const struct aspeed_pinctrl_data *pdata = | |
| 310 | − pinctrl_dev_get_drvdata(pctldev); | |
| 308 | + struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | |
| 311 | 309 | const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data; |
| 312 | 310 | const struct aspeed_sig_expr ***prios, **funcs, *expr; |
| 313 | 311 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include "pinmux-aspeed.h" |
| 7 | 7 | |
| 8 | −const char *const aspeed_pinmux_ips[] = { | |
| 8 | +static const char *const aspeed_pinmux_ips[] = { | |
| 9 | 9 | [ASPEED_IP_SCU] = "SCU", |
| 10 | 10 | [ASPEED_IP_GFX] = "GFX", |
| 11 | 11 | [ASPEED_IP_LPC] = "LPC", |
| @@ -702,11 +702,12 @@ struct aspeed_pin_function { · 701 unmodified lines | ||
| 702 | 702 | struct aspeed_pinmux_data; |
| 703 | 703 | |
| 704 | 704 | struct aspeed_pinmux_ops { |
| 705 | − int (*set)(const struct aspeed_pinmux_data *ctx, | |
| 705 | + int (*set)(struct aspeed_pinmux_data *ctx, | |
| 706 | 706 | const struct aspeed_sig_expr *expr, bool enabled); |
| 707 | 707 | }; |
| 708 | 708 | |
| 709 | 709 | struct aspeed_pinmux_data { |
| 710 | + struct device *dev; | |
| 710 | 711 | struct regmap *maps[ASPEED_NR_PINMUX_IPS]; |
| 711 | 712 | |
| 712 | 713 | const struct aspeed_pinmux_ops *ops; |
| @@ -725,7 +726,7 @@ int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx, · 12 unmodified lines | ||
| 725 | 726 | const struct aspeed_sig_expr *expr, |
| 726 | 727 | bool enabled); |
| 727 | 728 | |
| 728 | −static inline int aspeed_sig_expr_set(const struct aspeed_pinmux_data *ctx, | |
| 729 | +static inline int aspeed_sig_expr_set(struct aspeed_pinmux_data *ctx, | |
| 729 | 730 | const struct aspeed_sig_expr *expr, |
| 730 | 731 | bool enabled) |
| 731 | 732 | { |
| @@ -882,8 +882,11 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id) · 881 unmodified lines | ||
| 882 | 882 | return of_pwm_get(dev, dev->of_node, con_id); |
| 883 | 883 | |
| 884 | 884 | /* then lookup via ACPI */ |
| 885 | − if (dev && is_acpi_node(dev->fwnode)) | |
| 886 | − return acpi_pwm_get(dev->fwnode); | |
| 885 | + if (dev && is_acpi_node(dev->fwnode)) { | |
| 886 | + pwm = acpi_pwm_get(dev->fwnode); | |
| 887 | + if (!IS_ERR(pwm) || PTR_ERR(pwm) != -ENOENT) | |
| 888 | + return pwm; | |
| 889 | + } | |
| 887 | 890 | |
| 888 | 891 | /* |
| 889 | 892 | * We look up the provider in the static table typically provided by |
| @@ -1704,6 +1704,7 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg) · 1703 unmodified lines | ||
| 1704 | 1704 | grp->changed_side = 2; |
| 1705 | 1705 | break; |
| 1706 | 1706 | } |
| 1707 | + /* Else, fall through */ | |
| 1707 | 1708 | case MPCG_STATE_XID0IOWAIX: |
| 1708 | 1709 | case MPCG_STATE_XID7INITW: |
| 1709 | 1710 | case MPCG_STATE_XID7INITX: |
| @@ -357,6 +357,7 @@ int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int)) · 356 unmodified lines | ||
| 357 | 357 | /*fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);*/ |
| 358 | 358 | if (callback) |
| 359 | 359 | grp->send_qllc_disc = 1; |
| 360 | + /* Else, fall through */ | |
| 360 | 361 | case MPCG_STATE_XID0IOWAIT: |
| 361 | 362 | fsm_deltimer(&grp->timer); |
| 362 | 363 | grp->outstanding_xid2 = 0; |
| @@ -1469,6 +1470,7 @@ static void mpc_action_timeout(fsm_instance *fi, int event, void *arg) · 1106 unmodified lines | ||
| 1469 | 1470 | if ((fsm_getstate(rch->fsm) == CH_XID0_PENDING) && |
| 1470 | 1471 | (fsm_getstate(wch->fsm) == CH_XID0_PENDING)) |
| 1471 | 1472 | break; |
| 1473 | + /* Else, fall through */ | |
| 1472 | 1474 | default: |
| 1473 | 1475 | fsm_event(grp->fsm, MPCG_EVENT_INOP, dev); |
| 1474 | 1476 | } |
| @@ -2089,6 +2091,7 @@ static int mpc_send_qllc_discontact(struct net_device *dev) · 614 unmodified lines | ||
| 2089 | 2091 | grp->estconnfunc = NULL; |
| 2090 | 2092 | break; |
| 2091 | 2093 | } |
| 2094 | + /* Else, fall through */ | |
| 2092 | 2095 | case MPCG_STATE_FLOWC: |
| 2093 | 2096 | case MPCG_STATE_READY: |
| 2094 | 2097 | grp->send_qllc_disc = 2; |
| @@ -629,6 +629,7 @@ struct qeth_seqno { · 628 unmodified lines | ||
| 629 | 629 | struct qeth_reply { |
| 630 | 630 | struct list_head list; |
| 631 | 631 | struct completion received; |
| 632 | + spinlock_t lock; | |
| 632 | 633 | int (*callback)(struct qeth_card *, struct qeth_reply *, |
| 633 | 634 | unsigned long); |
| 634 | 635 | u32 seqno; |
| @@ -544,6 +544,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) · 543 unmodified lines | ||
| 544 | 544 | if (reply) { |
| 545 | 545 | refcount_set(&reply->refcnt, 1); |
| 546 | 546 | init_completion(&reply->received); |
| 547 | + spin_lock_init(&reply->lock); | |
| 547 | 548 | } |
| 548 | 549 | return reply; |
| 549 | 550 | } |
| @@ -799,6 +800,13 @@ static void qeth_issue_next_read_cb(struct qeth_card *card, · 249 unmodified lines | ||
| 799 | 800 | |
| 800 | 801 | if (!reply->callback) { |
| 801 | 802 | rc = 0; |
| 803 | + goto no_callback; | |
| 804 | + } | |
| 805 | + | |
| 806 | + spin_lock_irqsave(&reply->lock, flags); | |
| 807 | + if (reply->rc) { | |
| 808 | + /* Bail out when the requestor has already left: */ | |
| 809 | + rc = reply->rc; | |
| 802 | 810 | } else { |
| 803 | 811 | if (cmd) { |
| 804 | 812 | reply->offset = (u16)((char *)cmd - (char *)iob->data); |
| @@ -807,7 +815,9 @@ static void qeth_issue_next_read_cb(struct qeth_card *card, · 2 unmodified lines | ||
| 807 | 815 | rc = reply->callback(card, reply, (unsigned long)iob); |
| 808 | 816 | } |
| 809 | 817 | } |
| 818 | + spin_unlock_irqrestore(&reply->lock, flags); | |
| 810 | 819 | |
| 820 | +no_callback: | |
| 811 | 821 | if (rc <= 0) |
| 812 | 822 | qeth_notify_reply(reply, rc); |
| 813 | 823 | qeth_put_reply(reply); |
| @@ -1749,6 +1759,16 @@ static int qeth_send_control_data(struct qeth_card *card, · 935 unmodified lines | ||
| 1749 | 1759 | rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; |
| 1750 | 1760 | |
| 1751 | 1761 | qeth_dequeue_reply(card, reply); |
| 1762 | + | |
| 1763 | + if (reply_cb) { | |
| 1764 | + /* Wait until the callback for a late reply has completed: */ | |
| 1765 | + spin_lock_irq(&reply->lock); | |
| 1766 | + if (rc) | |
| 1767 | + /* Zap any callback that's still pending: */ | |
| 1768 | + reply->rc = rc; | |
| 1769 | + spin_unlock_irq(&reply->lock); | |
| 1770 | + } | |
| 1771 | + | |
| 1752 | 1772 | if (!rc) |
| 1753 | 1773 | rc = reply->rc; |
| 1754 | 1774 | qeth_put_reply(reply); |
| @@ -333,7 +333,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card, · 332 unmodified lines | ||
| 333 | 333 | card->osn_info.data_cb(skb); |
| 334 | 334 | break; |
| 335 | 335 | } |
| 336 | − /* else unknown */ | |
| 336 | + /* Else, fall through */ | |
| 337 | 337 | default: |
| 338 | 338 | dev_kfree_skb_any(skb); |
| 339 | 339 | QETH_CARD_TEXT(card, 3, "inbunkno"); |
| @@ -603,6 +603,7 @@ static void fas216_handlesync(FAS216_Info *info, char *msg) · 602 unmodified lines | ||
| 603 | 603 | msgqueue_flush(&info->scsi.msgs); |
| 604 | 604 | msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT); |
| 605 | 605 | info->scsi.phase = PHASE_MSGOUT_EXPECT; |
| 606 | + /* fall through */ | |
| 606 | 607 | |
| 607 | 608 | case async: |
| 608 | 609 | dev->period = info->ifcfg.asyncperiod / 4; |
| @@ -915,6 +916,7 @@ static void fas216_disconnect_intr(FAS216_Info *info) · 306 unmodified lines | ||
| 915 | 916 | fas216_done(info, DID_ABORT); |
| 916 | 917 | break; |
| 917 | 918 | } |
| 919 | + /* else, fall through */ | |
| 918 | 920 | |
| 919 | 921 | default: /* huh? */ |
| 920 | 922 | printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n", |
| @@ -1411,6 +1413,8 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne · 490 unmodified lines | ||
| 1411 | 1413 | case STATE(STAT_STATUS, PHASE_DATAOUT): /* Data Out -> Status */ |
| 1412 | 1414 | case STATE(STAT_STATUS, PHASE_DATAIN): /* Data In -> Status */ |
| 1413 | 1415 | fas216_stoptransfer(info); |
| 1416 | + /* fall through */ | |
| 1417 | + | |
| 1414 | 1418 | case STATE(STAT_STATUS, PHASE_SELSTEPS):/* Sel w/ steps -> Status */ |
| 1415 | 1419 | case STATE(STAT_STATUS, PHASE_MSGOUT): /* Message Out -> Status */ |
| 1416 | 1420 | case STATE(STAT_STATUS, PHASE_COMMAND): /* Command -> Status */ |
| @@ -1422,6 +1426,8 @@ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigne · 5 unmodified lines | ||
| 1422 | 1426 | case STATE(STAT_MESGIN, PHASE_DATAOUT): /* Data Out -> Message In */ |
| 1423 | 1427 | case STATE(STAT_MESGIN, PHASE_DATAIN): /* Data In -> Message In */ |
| 1424 | 1428 | fas216_stoptransfer(info); |
| 1429 | + /* fall through */ | |
| 1430 | + | |
| 1425 | 1431 | case STATE(STAT_MESGIN, PHASE_COMMAND): /* Command -> Message In */ |
| 1426 | 1432 | case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In */ |
| 1427 | 1433 | case STATE(STAT_MESGIN, PHASE_MSGOUT): /* Message Out -> Message In */ |
| @@ -1575,6 +1581,7 @@ static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned · 147 unmodified lines | ||
| 1575 | 1581 | fas216_message(info); |
| 1576 | 1582 | break; |
| 1577 | 1583 | } |
| 1584 | + /* else, fall through */ | |
| 1578 | 1585 | |
| 1579 | 1586 | default: |
| 1580 | 1587 | fas216_log(info, 0, "internal phase %s for function done?" |
| @@ -1957,6 +1964,7 @@ static void fas216_kick(FAS216_Info *info) · 376 unmodified lines | ||
| 1957 | 1964 | switch (where_from) { |
| 1958 | 1965 | case TYPE_QUEUE: |
| 1959 | 1966 | fas216_allocate_tag(info, SCpnt); |
| 1967 | + /* fall through */ | |
| 1960 | 1968 | case TYPE_OTHER: |
| 1961 | 1969 | fas216_start_command(info, SCpnt); |
| 1962 | 1970 | break; |
| @@ -10776,12 +10776,31 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors) · 10775 unmodified lines | ||
| 10776 | 10776 | /* This loop sets up all CPUs that are affinitized with a |
| 10777 | 10777 | * irq vector assigned to the driver. All affinitized CPUs |
| 10778 | 10778 | * will get a link to that vectors IRQ and EQ. |
| 10779 | + * | |
| 10780 | + * NULL affinity mask handling: | |
| 10781 | + * If irq count is greater than one, log an error message. | |
| 10782 | + * If the null mask is received for the first irq, find the | |
| 10783 | + * first present cpu, and assign the eq index to ensure at | |
| 10784 | + * least one EQ is assigned. | |
| 10779 | 10785 | */ |
| 10780 | 10786 | for (idx = 0; idx < phba->cfg_irq_chann; idx++) { |
| 10781 | 10787 | /* Get a CPU mask for all CPUs affinitized to this vector */ |
| 10782 | 10788 | maskp = pci_irq_get_affinity(phba->pcidev, idx); |
| 10783 | − if (!maskp) | |
| 10784 | − continue; | |
| 10789 | + if (!maskp) { | |
| 10790 | + if (phba->cfg_irq_chann > 1) | |
| 10791 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
| 10792 | + "3329 No affinity mask found " | |
| 10793 | + "for vector %d (%d)\n", | |
| 10794 | + idx, phba->cfg_irq_chann); | |
| 10795 | + if (!idx) { | |
| 10796 | + cpu = cpumask_first(cpu_present_mask); | |
| 10797 | + cpup = &phba->sli4_hba.cpu_map[cpu]; | |
| 10798 | + cpup->eq = idx; | |
| 10799 | + cpup->irq = pci_irq_vector(phba->pcidev, idx); | |
| 10800 | + cpup->flag |= LPFC_CPU_FIRST_IRQ; | |
| 10801 | + } | |
| 10802 | + break; | |
| 10803 | + } | |
| 10785 | 10804 | |
| 10786 | 10805 | i = 0; |
| 10787 | 10806 | /* Loop through all CPUs associated with vector idx */ |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | # |
| 5 | 5 | |
| 6 | 6 | menuconfig SOUNDWIRE |
| 7 | − bool "SoundWire support" | |
| 7 | + tristate "SoundWire support" | |
| 8 | 8 | help |
| 9 | 9 | SoundWire is a 2-Pin interface with data and clock line ratified |
| 10 | 10 | by the MIPI Alliance. SoundWire is used for transporting data |
| @@ -17,17 +17,12 @@ if SOUNDWIRE · 6 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | comment "SoundWire Devices" |
| 19 | 19 | |
| 20 | −config SOUNDWIRE_BUS | |
| 21 | − tristate | |
| 22 | − select REGMAP_SOUNDWIRE | |
| 23 | − | |
| 24 | 20 | config SOUNDWIRE_CADENCE |
| 25 | 21 | tristate |
| 26 | 22 | |
| 27 | 23 | config SOUNDWIRE_INTEL |
| 28 | 24 | tristate "Intel SoundWire Master driver" |
| 29 | 25 | select SOUNDWIRE_CADENCE |
| 30 | − select SOUNDWIRE_BUS | |
| 31 | 26 | depends on X86 && ACPI && SND_SOC |
| 32 | 27 | help |
| 33 | 28 | SoundWire Intel Master driver. |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #Bus Objs |
| 7 | 7 | soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o |
| 8 | −obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o | |
| 8 | +obj-$(CONFIG_SOUNDWIRE) += soundwire-bus.o | |
| 9 | 9 | |
| 10 | 10 | #Cadence Objs |
| 11 | 11 | soundwire-cadence-objs := cadence_master.o |
| @@ -81,8 +81,8 @@ · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | #define CDNS_MCP_INTSET 0x4C |
| 83 | 83 | |
| 84 | −#define CDNS_SDW_SLAVE_STAT 0x50 | |
| 85 | −#define CDNS_MCP_SLAVE_STAT_MASK BIT(1, 0) | |
| 84 | +#define CDNS_MCP_SLAVE_STAT 0x50 | |
| 85 | +#define CDNS_MCP_SLAVE_STAT_MASK GENMASK(1, 0) | |
| 86 | 86 | |
| 87 | 87 | #define CDNS_MCP_SLAVE_INTSTAT0 0x54 |
| 88 | 88 | #define CDNS_MCP_SLAVE_INTSTAT1 0x58 |
| @@ -96,8 +96,8 @@ · 7 unmodified lines | ||
| 96 | 96 | #define CDNS_MCP_SLAVE_INTMASK0 0x5C |
| 97 | 97 | #define CDNS_MCP_SLAVE_INTMASK1 0x60 |
| 98 | 98 | |
| 99 | −#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(30, 0) | |
| 100 | −#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(16, 0) | |
| 99 | +#define CDNS_MCP_SLAVE_INTMASK0_MASK GENMASK(31, 0) | |
| 100 | +#define CDNS_MCP_SLAVE_INTMASK1_MASK GENMASK(15, 0) | |
| 101 | 101 | |
| 102 | 102 | #define CDNS_MCP_PORT_INTSTAT 0x64 |
| 103 | 103 | #define CDNS_MCP_PDI_STAT 0x6C |
| @@ -8,11 +8,14 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/list.h> |
| 9 | 9 | #include <linux/slab.h> |
| 10 | 10 | #include <linux/swap.h> |
| 11 | +#include <linux/sched/signal.h> | |
| 11 | 12 | |
| 12 | 13 | #include "ion.h" |
| 13 | 14 | |
| 14 | 15 | static inline struct page *ion_page_pool_alloc_pages(struct ion_page_pool *pool) |
| 15 | 16 | { |
| 17 | + if (fatal_signal_pending(current)) | |
| 18 | + return NULL; | |
| 16 | 19 | return alloc_pages(pool->gfp_mask, pool->order); |
| 17 | 20 | } |
| 18 | 21 | |
| @@ -342,9 +342,9 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) · 341 unmodified lines | ||
| 342 | 342 | static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, |
| 343 | 343 | unsigned int flags) |
| 344 | 344 | { |
| 345 | − int divider, base, prescale; | |
| 345 | + unsigned int divider, base, prescale; | |
| 346 | 346 | |
| 347 | − /* This function needs improvment */ | |
| 347 | + /* This function needs improvement */ | |
| 348 | 348 | /* Don't know if divider==0 works. */ |
| 349 | 349 | |
| 350 | 350 | for (prescale = 0; prescale < 16; prescale++) { |
| @@ -358,7 +358,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, · 7 unmodified lines | ||
| 358 | 358 | divider = (*nanosec) / base; |
| 359 | 359 | break; |
| 360 | 360 | case CMDF_ROUND_UP: |
| 361 | − divider = (*nanosec) / base; | |
| 361 | + divider = DIV_ROUND_UP(*nanosec, base); | |
| 362 | 362 | break; |
| 363 | 363 | } |
| 364 | 364 | if (divider < 65536) { |
| @@ -368,7 +368,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, · 3 unmodified lines | ||
| 368 | 368 | } |
| 369 | 369 | |
| 370 | 370 | prescale = 15; |
| 371 | − base = timer_base * (1 << prescale); | |
| 371 | + base = timer_base * (prescale + 1); | |
| 372 | 372 | divider = 65535; |
| 373 | 373 | *nanosec = divider * base; |
| 374 | 374 | return (prescale << 16) | (divider); |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | static int init_display(struct fbtft_par *par) |
| 26 | 26 | { |
| 27 | − if (!par->gpio.cs) | |
| 27 | + if (par->gpio.cs) | |
| 28 | 28 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 29 | 29 | |
| 30 | 30 | par->fbtftops.reset(par); |
| @@ -77,7 +77,7 @@ static int init_display(struct fbtft_par *par) · 76 unmodified lines | ||
| 77 | 77 | { |
| 78 | 78 | par->fbtftops.reset(par); |
| 79 | 79 | |
| 80 | − if (!par->gpio.cs) | |
| 80 | + if (par->gpio.cs) | |
| 81 | 81 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 82 | 82 | |
| 83 | 83 | write_reg(par, MIPI_DCS_SOFT_RESET); /* software reset */ |
| @@ -85,7 +85,7 @@ static int init_display(struct fbtft_par *par) · 84 unmodified lines | ||
| 85 | 85 | { |
| 86 | 86 | par->fbtftops.reset(par); |
| 87 | 87 | |
| 88 | − if (!par->gpio.cs) | |
| 88 | + if (par->gpio.cs) | |
| 89 | 89 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 90 | 90 | |
| 91 | 91 | bt &= 0x07; |
| @@ -29,7 +29,7 @@ static int init_display(struct fbtft_par *par) · 28 unmodified lines | ||
| 29 | 29 | { |
| 30 | 30 | par->fbtftops.reset(par); |
| 31 | 31 | |
| 32 | − if (!par->gpio.cs) | |
| 32 | + if (par->gpio.cs) | |
| 33 | 33 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 34 | 34 | |
| 35 | 35 | /* Initialization sequence from Lib_UTFT */ |
| @@ -28,7 +28,7 @@ static int init_display(struct fbtft_par *par) · 27 unmodified lines | ||
| 28 | 28 | { |
| 29 | 29 | par->fbtftops.reset(par); |
| 30 | 30 | |
| 31 | − if (!par->gpio.cs) | |
| 31 | + if (par->gpio.cs) | |
| 32 | 32 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 33 | 33 | |
| 34 | 34 | write_reg(par, 0x00, 0x0001); |
| @@ -81,7 +81,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) · 80 unmodified lines | ||
| 81 | 81 | va_start(args, len); |
| 82 | 82 | |
| 83 | 83 | *buf = (u8)va_arg(args, unsigned int); |
| 84 | − if (!par->gpio.dc) | |
| 84 | + if (par->gpio.dc) | |
| 85 | 85 | gpiod_set_value(par->gpio.dc, 0); |
| 86 | 86 | ret = par->fbtftops.write(par, par->buf, sizeof(u8)); |
| 87 | 87 | if (ret < 0) { |
| @@ -104,7 +104,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) · 16 unmodified lines | ||
| 104 | 104 | return; |
| 105 | 105 | } |
| 106 | 106 | } |
| 107 | − if (!par->gpio.dc) | |
| 107 | + if (par->gpio.dc) | |
| 108 | 108 | gpiod_set_value(par->gpio.dc, 1); |
| 109 | 109 | va_end(args); |
| 110 | 110 | } |
| @@ -26,7 +26,7 @@ static int init_display(struct fbtft_par *par) · 25 unmodified lines | ||
| 26 | 26 | { |
| 27 | 27 | par->fbtftops.reset(par); |
| 28 | 28 | |
| 29 | − if (!par->gpio.cs) | |
| 29 | + if (par->gpio.cs) | |
| 30 | 30 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 31 | 31 | |
| 32 | 32 | /* Initialization sequence from Lib_UTFT */ |
| @@ -135,7 +135,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) · 134 unmodified lines | ||
| 135 | 135 | remain = len / 2; |
| 136 | 136 | vmem16 = (u16 *)(par->info->screen_buffer + offset); |
| 137 | 137 | |
| 138 | − if (!par->gpio.dc) | |
| 138 | + if (par->gpio.dc) | |
| 139 | 139 | gpiod_set_value(par->gpio.dc, 1); |
| 140 | 140 | |
| 141 | 141 | /* non buffered write */ |
| @@ -76,21 +76,18 @@ static int fbtft_request_one_gpio(struct fbtft_par *par, · 75 unmodified lines | ||
| 76 | 76 | struct gpio_desc **gpiop) |
| 77 | 77 | { |
| 78 | 78 | struct device *dev = par->info->device; |
| 79 | − struct device_node *node = dev->of_node; | |
| 80 | 79 | int ret = 0; |
| 81 | 80 | |
| 82 | − if (of_find_property(node, name, NULL)) { | |
| 83 | − *gpiop = devm_gpiod_get_index(dev, dev->driver->name, index, | |
| 84 | − GPIOD_OUT_HIGH); | |
| 85 | − if (IS_ERR(*gpiop)) { | |
| 86 | − ret = PTR_ERR(*gpiop); | |
| 87 | − dev_err(dev, | |
| 88 | − "Failed to request %s GPIO:%d\n", name, ret); | |
| 89 | − return ret; | |
| 90 | − } | |
| 91 | − fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n", | |
| 92 | − __func__, name); | |
| 81 | + *gpiop = devm_gpiod_get_index_optional(dev, name, index, | |
| 82 | + GPIOD_OUT_HIGH); | |
| 83 | + if (IS_ERR(*gpiop)) { | |
| 84 | + ret = PTR_ERR(*gpiop); | |
| 85 | + dev_err(dev, | |
| 86 | + "Failed to request %s GPIO: %d\n", name, ret); | |
| 87 | + return ret; | |
| 93 | 88 | } |
| 89 | + fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n", | |
| 90 | + __func__, name); | |
| 94 | 91 | |
| 95 | 92 | return ret; |
| 96 | 93 | } |
| @@ -103,34 +100,34 @@ static int fbtft_request_gpios_dt(struct fbtft_par *par) · 6 unmodified lines | ||
| 103 | 100 | if (!par->info->device->of_node) |
| 104 | 101 | return -EINVAL; |
| 105 | 102 | |
| 106 | − ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset); | |
| 103 | + ret = fbtft_request_one_gpio(par, "reset", 0, &par->gpio.reset); | |
| 107 | 104 | if (ret) |
| 108 | 105 | return ret; |
| 109 | − ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc); | |
| 106 | + ret = fbtft_request_one_gpio(par, "dc", 0, &par->gpio.dc); | |
| 110 | 107 | if (ret) |
| 111 | 108 | return ret; |
| 112 | − ret = fbtft_request_one_gpio(par, "rd-gpios", 0, &par->gpio.rd); | |
| 109 | + ret = fbtft_request_one_gpio(par, "rd", 0, &par->gpio.rd); | |
| 113 | 110 | if (ret) |
| 114 | 111 | return ret; |
| 115 | − ret = fbtft_request_one_gpio(par, "wr-gpios", 0, &par->gpio.wr); | |
| 112 | + ret = fbtft_request_one_gpio(par, "wr", 0, &par->gpio.wr); | |
| 116 | 113 | if (ret) |
| 117 | 114 | return ret; |
| 118 | − ret = fbtft_request_one_gpio(par, "cs-gpios", 0, &par->gpio.cs); | |
| 115 | + ret = fbtft_request_one_gpio(par, "cs", 0, &par->gpio.cs); | |
| 119 | 116 | if (ret) |
| 120 | 117 | return ret; |
| 121 | − ret = fbtft_request_one_gpio(par, "latch-gpios", 0, &par->gpio.latch); | |
| 118 | + ret = fbtft_request_one_gpio(par, "latch", 0, &par->gpio.latch); | |
| 122 | 119 | if (ret) |
| 123 | 120 | return ret; |
| 124 | 121 | for (i = 0; i < 16; i++) { |
| 125 | − ret = fbtft_request_one_gpio(par, "db-gpios", i, | |
| 122 | + ret = fbtft_request_one_gpio(par, "db", i, | |
| 126 | 123 | &par->gpio.db[i]); |
| 127 | 124 | if (ret) |
| 128 | 125 | return ret; |
| 129 | − ret = fbtft_request_one_gpio(par, "led-gpios", i, | |
| 126 | + ret = fbtft_request_one_gpio(par, "led", i, | |
| 130 | 127 | &par->gpio.led[i]); |
| 131 | 128 | if (ret) |
| 132 | 129 | return ret; |
| 133 | − ret = fbtft_request_one_gpio(par, "aux-gpios", i, | |
| 130 | + ret = fbtft_request_one_gpio(par, "aux", i, | |
| 134 | 131 | &par->gpio.aux[i]); |
| 135 | 132 | if (ret) |
| 136 | 133 | return ret; |
| @@ -234,9 +231,9 @@ static void fbtft_reset(struct fbtft_par *par) · 97 unmodified lines | ||
| 234 | 231 | if (!par->gpio.reset) |
| 235 | 232 | return; |
| 236 | 233 | fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__); |
| 237 | − gpiod_set_value_cansleep(par->gpio.reset, 0); | |
| 238 | − usleep_range(20, 40); | |
| 239 | 234 | gpiod_set_value_cansleep(par->gpio.reset, 1); |
| 235 | + usleep_range(20, 40); | |
| 236 | + gpiod_set_value_cansleep(par->gpio.reset, 0); | |
| 240 | 237 | msleep(120); |
| 241 | 238 | } |
| 242 | 239 | |
| @@ -921,7 +918,7 @@ static int fbtft_init_display_dt(struct fbtft_par *par) · 678 unmodified lines | ||
| 921 | 918 | return -EINVAL; |
| 922 | 919 | |
| 923 | 920 | par->fbtftops.reset(par); |
| 924 | − if (!par->gpio.cs) | |
| 921 | + if (par->gpio.cs) | |
| 925 | 922 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 926 | 923 | |
| 927 | 924 | while (p) { |
| @@ -1012,7 +1009,7 @@ int fbtft_init_display(struct fbtft_par *par) · 84 unmodified lines | ||
| 1012 | 1009 | } |
| 1013 | 1010 | |
| 1014 | 1011 | par->fbtftops.reset(par); |
| 1015 | − if (!par->gpio.cs) | |
| 1012 | + if (par->gpio.cs) | |
| 1016 | 1013 | gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ |
| 1017 | 1014 | |
| 1018 | 1015 | i = 0; |
| @@ -532,7 +532,7 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr, · 531 unmodified lines | ||
| 532 | 532 | break; |
| 533 | 533 | case ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE: |
| 534 | 534 | ret = scnprintf(buf, PAGE_SIZE, "%u\n", |
| 535 | − gasket_page_table_num_entries( | |
| 535 | + gasket_page_table_num_simple_entries( | |
| 536 | 536 | gasket_dev->page_table[0])); |
| 537 | 537 | break; |
| 538 | 538 | case ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES: |
| @@ -1750,7 +1750,8 @@ static int visornic_poll(struct napi_struct *napi, int budget) · 1749 unmodified lines | ||
| 1750 | 1750 | } |
| 1751 | 1751 | |
| 1752 | 1752 | /* poll_for_irq - checks the status of the response queue |
| 1753 | − * @v: Void pointer to the visronic devdata struct. | |
| 1753 | + * @t: pointer to the 'struct timer_list' from which we can retrieve the | |
| 1754 | + * the visornic devdata struct. | |
| 1754 | 1755 | * |
| 1755 | 1756 | * Main function of the vnic_incoming thread. Periodically check the response |
| 1756 | 1757 | * queue and drain it if needed. |
| @@ -1969,6 +1969,7 @@ void wilc_deinit_host_int(struct net_device *net) · 1968 unmodified lines | ||
| 1969 | 1969 | |
| 1970 | 1970 | priv->p2p_listen_state = false; |
| 1971 | 1971 | |
| 1972 | + flush_workqueue(vif->wilc->hif_workqueue); | |
| 1972 | 1973 | mutex_destroy(&priv->scan_req_lock); |
| 1973 | 1974 | ret = wilc_deinit(vif); |
| 1974 | 1975 | |
| @@ -277,10 +277,14 @@ static void kgdboc_pre_exp_handler(void) · 276 unmodified lines | ||
| 277 | 277 | /* Increment the module count when the debugger is active */ |
| 278 | 278 | if (!kgdb_connected) |
| 279 | 279 | try_module_get(THIS_MODULE); |
| 280 | + | |
| 281 | + atomic_inc(&ignore_console_lock_warning); | |
| 280 | 282 | } |
| 281 | 283 | |
| 282 | 284 | static void kgdboc_post_exp_handler(void) |
| 283 | 285 | { |
| 286 | + atomic_dec(&ignore_console_lock_warning); | |
| 287 | + | |
| 284 | 288 | /* decrement the module count when the debugger detaches */ |
| 285 | 289 | if (!kgdb_connected) |
| 286 | 290 | module_put(THIS_MODULE); |
| @@ -454,9 +454,11 @@ err_clk: · 453 unmodified lines | ||
| 454 | 454 | imx_disable_unprepare_clks(dev); |
| 455 | 455 | disable_hsic_regulator: |
| 456 | 456 | if (data->hsic_pad_regulator) |
| 457 | − ret = regulator_disable(data->hsic_pad_regulator); | |
| 457 | + /* don't overwrite original ret (cf. EPROBE_DEFER) */ | |
| 458 | + regulator_disable(data->hsic_pad_regulator); | |
| 458 | 459 | if (pdata.flags & CI_HDRC_PMQOS) |
| 459 | 460 | pm_qos_remove_request(&data->pm_qos_req); |
| 461 | + data->ci_pdev = NULL; | |
| 460 | 462 | return ret; |
| 461 | 463 | } |
| 462 | 464 | |
| @@ -469,14 +471,17 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) · 6 unmodified lines | ||
| 469 | 471 | pm_runtime_disable(&pdev->dev); |
| 470 | 472 | pm_runtime_put_noidle(&pdev->dev); |
| 471 | 473 | } |
| 472 | − ci_hdrc_remove_device(data->ci_pdev); | |
| 474 | + if (data->ci_pdev) | |
| 475 | + ci_hdrc_remove_device(data->ci_pdev); | |
| 473 | 476 | if (data->override_phy_control) |
| 474 | 477 | usb_phy_shutdown(data->phy); |
| 475 | − imx_disable_unprepare_clks(&pdev->dev); | |
| 476 | − if (data->plat_data->flags & CI_HDRC_PMQOS) | |
| 477 | − pm_qos_remove_request(&data->pm_qos_req); | |
| 478 | − if (data->hsic_pad_regulator) | |
| 479 | − regulator_disable(data->hsic_pad_regulator); | |
| 478 | + if (data->ci_pdev) { | |
| 479 | + imx_disable_unprepare_clks(&pdev->dev); | |
| 480 | + if (data->plat_data->flags & CI_HDRC_PMQOS) | |
| 481 | + pm_qos_remove_request(&data->pm_qos_req); | |
| 482 | + if (data->hsic_pad_regulator) | |
| 483 | + regulator_disable(data->hsic_pad_regulator); | |
| 484 | + } | |
| 480 | 485 | |
| 481 | 486 | return 0; |
| 482 | 487 | } |
| @@ -1301,10 +1301,6 @@ made_compressed_probe: · 1300 unmodified lines | ||
| 1301 | 1301 | tty_port_init(&acm->port); |
| 1302 | 1302 | acm->port.ops = &acm_port_ops; |
| 1303 | 1303 | |
| 1304 | − minor = acm_alloc_minor(acm); | |
| 1305 | − if (minor < 0) | |
| 1306 | − goto alloc_fail1; | |
| 1307 | − | |
| 1308 | 1304 | ctrlsize = usb_endpoint_maxp(epctrl); |
| 1309 | 1305 | readsize = usb_endpoint_maxp(epread) * |
| 1310 | 1306 | (quirks == SINGLE_RX_URB ? 1 : 2); |
| @@ -1312,6 +1308,13 @@ made_compressed_probe: · 1 unmodified line | ||
| 1312 | 1308 | acm->writesize = usb_endpoint_maxp(epwrite) * 20; |
| 1313 | 1309 | acm->control = control_interface; |
| 1314 | 1310 | acm->data = data_interface; |
| 1311 | + | |
| 1312 | + usb_get_intf(acm->control); /* undone in destruct() */ | |
| 1313 | + | |
| 1314 | + minor = acm_alloc_minor(acm); | |
| 1315 | + if (minor < 0) | |
| 1316 | + goto alloc_fail1; | |
| 1317 | + | |
| 1315 | 1318 | acm->minor = minor; |
| 1316 | 1319 | acm->dev = usb_dev; |
| 1317 | 1320 | if (h.usb_cdc_acm_descriptor) |
| @@ -1458,7 +1461,6 @@ skip_countries: · 140 unmodified lines | ||
| 1458 | 1461 | usb_driver_claim_interface(&acm_driver, data_interface, acm); |
| 1459 | 1462 | usb_set_intfdata(data_interface, acm); |
| 1460 | 1463 | |
| 1461 | − usb_get_intf(control_interface); | |
| 1462 | 1464 | tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, |
| 1463 | 1465 | &control_interface->dev); |
| 1464 | 1466 | if (IS_ERR(tty_dev)) { |
| @@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) · 65 unmodified lines | ||
| 66 | 66 | char name[16]; |
| 67 | 67 | int i, size; |
| 68 | 68 | |
| 69 | − if (!IS_ENABLED(CONFIG_HAS_DMA) || | |
| 70 | − (!is_device_dma_capable(hcd->self.sysdev) && | |
| 71 | − !hcd->localmem_pool)) | |
| 69 | + if (hcd->localmem_pool || !hcd_uses_dma(hcd)) | |
| 72 | 70 | return 0; |
| 73 | 71 | |
| 74 | 72 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
| @@ -129,8 +127,7 @@ void *hcd_buffer_alloc( · 54 unmodified lines | ||
| 129 | 127 | return gen_pool_dma_alloc(hcd->localmem_pool, size, dma); |
| 130 | 128 | |
| 131 | 129 | /* some USB hosts just use PIO */ |
| 132 | − if (!IS_ENABLED(CONFIG_HAS_DMA) || | |
| 133 | − !is_device_dma_capable(bus->sysdev)) { | |
| 130 | + if (!hcd_uses_dma(hcd)) { | |
| 134 | 131 | *dma = ~(dma_addr_t) 0; |
| 135 | 132 | return kmalloc(size, mem_flags); |
| 136 | 133 | } |
| @@ -160,8 +157,7 @@ void hcd_buffer_free( · 23 unmodified lines | ||
| 160 | 157 | return; |
| 161 | 158 | } |
| 162 | 159 | |
| 163 | − if (!IS_ENABLED(CONFIG_HAS_DMA) || | |
| 164 | − !is_device_dma_capable(bus->sysdev)) { | |
| 160 | + if (!hcd_uses_dma(hcd)) { | |
| 165 | 161 | kfree(addr); |
| 166 | 162 | return; |
| 167 | 163 | } |
| @@ -1812,8 +1812,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb · 1811 unmodified lines | ||
| 1812 | 1812 | return 0; |
| 1813 | 1813 | |
| 1814 | 1814 | error: |
| 1815 | − if (as && as->usbm) | |
| 1816 | − dec_usb_memory_use_count(as->usbm, &as->usbm->urb_use_count); | |
| 1817 | 1815 | kfree(isopkt); |
| 1818 | 1816 | kfree(dr); |
| 1819 | 1817 | if (as) |
| @@ -193,9 +193,10 @@ int usb_register_dev(struct usb_interface *intf, · 192 unmodified lines | ||
| 193 | 193 | intf->minor = minor; |
| 194 | 194 | break; |
| 195 | 195 | } |
| 196 | − up_write(&minor_rwsem); | |
| 197 | − if (intf->minor < 0) | |
| 196 | + if (intf->minor < 0) { | |
| 197 | + up_write(&minor_rwsem); | |
| 198 | 198 | return -EXFULL; |
| 199 | + } | |
| 199 | 200 | |
| 200 | 201 | /* create a usb class device for this usb interface */ |
| 201 | 202 | snprintf(name, sizeof(name), class_driver->name, minor - minor_base); |
| @@ -203,12 +204,11 @@ int usb_register_dev(struct usb_interface *intf, · 1 unmodified line | ||
| 203 | 204 | MKDEV(USB_MAJOR, minor), class_driver, |
| 204 | 205 | "%s", kbasename(name)); |
| 205 | 206 | if (IS_ERR(intf->usb_dev)) { |
| 206 | − down_write(&minor_rwsem); | |
| 207 | 207 | usb_minors[minor] = NULL; |
| 208 | 208 | intf->minor = -1; |
| 209 | − up_write(&minor_rwsem); | |
| 210 | 209 | retval = PTR_ERR(intf->usb_dev); |
| 211 | 210 | } |
| 211 | + up_write(&minor_rwsem); | |
| 212 | 212 | return retval; |
| 213 | 213 | } |
| 214 | 214 | EXPORT_SYMBOL_GPL(usb_register_dev); |
| @@ -234,12 +234,12 @@ void usb_deregister_dev(struct usb_interface *intf, · 19 unmodified lines | ||
| 234 | 234 | return; |
| 235 | 235 | |
| 236 | 236 | dev_dbg(&intf->dev, "removing %d minor\n", intf->minor); |
| 237 | + device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | |
| 237 | 238 | |
| 238 | 239 | down_write(&minor_rwsem); |
| 239 | 240 | usb_minors[intf->minor] = NULL; |
| 240 | 241 | up_write(&minor_rwsem); |
| 241 | 242 | |
| 242 | − device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | |
| 243 | 243 | intf->usb_dev = NULL; |
| 244 | 244 | intf->minor = -1; |
| 245 | 245 | destroy_usb_class(); |
| @@ -103,11 +103,6 @@ static DEFINE_SPINLOCK(hcd_urb_unlink_lock); · 102 unmodified lines | ||
| 103 | 103 | /* wait queue for synchronous unlinks */ |
| 104 | 104 | DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); |
| 105 | 105 | |
| 106 | −static inline int is_root_hub(struct usb_device *udev) | |
| 107 | −{ | |
| 108 | − return (udev->parent == NULL); | |
| 109 | −} | |
| 110 | − | |
| 111 | 106 | /*-------------------------------------------------------------------------*/ |
| 112 | 107 | |
| 113 | 108 | /* |
| @@ -880,101 +875,6 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 766 unmodified lines | ||
| 880 | 875 | } |
| 881 | 876 | |
| 882 | 877 | |
| 883 | − | |
| 884 | −/* | |
| 885 | − * Show & store the current value of authorized_default | |
| 886 | − */ | |
| 887 | −static ssize_t authorized_default_show(struct device *dev, | |
| 888 | − struct device_attribute *attr, char *buf) | |
| 889 | −{ | |
| 890 | − struct usb_device *rh_usb_dev = to_usb_device(dev); | |
| 891 | − struct usb_bus *usb_bus = rh_usb_dev->bus; | |
| 892 | − struct usb_hcd *hcd; | |
| 893 | − | |
| 894 | − hcd = bus_to_hcd(usb_bus); | |
| 895 | − return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy); | |
| 896 | −} | |
| 897 | − | |
| 898 | −static ssize_t authorized_default_store(struct device *dev, | |
| 899 | − struct device_attribute *attr, | |
| 900 | − const char *buf, size_t size) | |
| 901 | −{ | |
| 902 | − ssize_t result; | |
| 903 | − unsigned val; | |
| 904 | − struct usb_device *rh_usb_dev = to_usb_device(dev); | |
| 905 | − struct usb_bus *usb_bus = rh_usb_dev->bus; | |
| 906 | − struct usb_hcd *hcd; | |
| 907 | − | |
| 908 | − hcd = bus_to_hcd(usb_bus); | |
| 909 | − result = sscanf(buf, "%u\n", &val); | |
| 910 | − if (result == 1) { | |
| 911 | − hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ? | |
| 912 | − val : USB_DEVICE_AUTHORIZE_ALL; | |
| 913 | − result = size; | |
| 914 | − } else { | |
| 915 | − result = -EINVAL; | |
| 916 | − } | |
| 917 | − return result; | |
| 918 | −} | |
| 919 | −static DEVICE_ATTR_RW(authorized_default); | |
| 920 | − | |
| 921 | −/* | |
| 922 | − * interface_authorized_default_show - show default authorization status | |
| 923 | − * for USB interfaces | |
| 924 | − * | |
| 925 | − * note: interface_authorized_default is the default value | |
| 926 | − * for initializing the authorized attribute of interfaces | |
| 927 | − */ | |
| 928 | −static ssize_t interface_authorized_default_show(struct device *dev, | |
| 929 | − struct device_attribute *attr, char *buf) | |
| 930 | −{ | |
| 931 | − struct usb_device *usb_dev = to_usb_device(dev); | |
| 932 | − struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); | |
| 933 | − | |
| 934 | − return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd)); | |
| 935 | −} | |
| 936 | − | |
| 937 | −/* | |
| 938 | − * interface_authorized_default_store - store default authorization status | |
| 939 | − * for USB interfaces | |
| 940 | − * | |
| 941 | − * note: interface_authorized_default is the default value | |
| 942 | − * for initializing the authorized attribute of interfaces | |
| 943 | − */ | |
| 944 | −static ssize_t interface_authorized_default_store(struct device *dev, | |
| 945 | − struct device_attribute *attr, const char *buf, size_t count) | |
| 946 | −{ | |
| 947 | − struct usb_device *usb_dev = to_usb_device(dev); | |
| 948 | − struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); | |
| 949 | − int rc = count; | |
| 950 | − bool val; | |
| 951 | − | |
| 952 | − if (strtobool(buf, &val) != 0) | |
| 953 | − return -EINVAL; | |
| 954 | − | |
| 955 | − if (val) | |
| 956 | − set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); | |
| 957 | − else | |
| 958 | − clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); | |
| 959 | − | |
| 960 | − return rc; | |
| 961 | −} | |
| 962 | −static DEVICE_ATTR_RW(interface_authorized_default); | |
| 963 | − | |
| 964 | −/* Group all the USB bus attributes */ | |
| 965 | −static struct attribute *usb_bus_attrs[] = { | |
| 966 | − &dev_attr_authorized_default.attr, | |
| 967 | − &dev_attr_interface_authorized_default.attr, | |
| 968 | − NULL, | |
| 969 | −}; | |
| 970 | − | |
| 971 | −static const struct attribute_group usb_bus_attr_group = { | |
| 972 | − .name = NULL, /* we want them in the same directory */ | |
| 973 | − .attrs = usb_bus_attrs, | |
| 974 | −}; | |
| 975 | − | |
| 976 | − | |
| 977 | − | |
| 978 | 878 | /*-------------------------------------------------------------------------*/ |
| 979 | 879 | |
| 980 | 880 | /** |
| @@ -1512,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, · 531 unmodified lines | ||
| 1512 | 1412 | if (usb_endpoint_xfer_control(&urb->ep->desc)) { |
| 1513 | 1413 | if (hcd->self.uses_pio_for_control) |
| 1514 | 1414 | return ret; |
| 1515 | − if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { | |
| 1415 | + if (hcd_uses_dma(hcd)) { | |
| 1516 | 1416 | if (is_vmalloc_addr(urb->setup_packet)) { |
| 1517 | 1417 | WARN_ONCE(1, "setup packet is not dma capable\n"); |
| 1518 | 1418 | return -EAGAIN; |
| @@ -1546,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, · 27 unmodified lines | ||
| 1546 | 1446 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
| 1547 | 1447 | if (urb->transfer_buffer_length != 0 |
| 1548 | 1448 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { |
| 1549 | − if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { | |
| 1449 | + if (hcd_uses_dma(hcd)) { | |
| 1550 | 1450 | if (urb->num_sgs) { |
| 1551 | 1451 | int n; |
| 1552 | 1452 | |
| @@ -2894,32 +2794,11 @@ int usb_add_hcd(struct usb_hcd *hcd, · 1341 unmodified lines | ||
| 2894 | 2794 | if (retval != 0) |
| 2895 | 2795 | goto err_register_root_hub; |
| 2896 | 2796 | |
| 2897 | − retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group); | |
| 2898 | − if (retval < 0) { | |
| 2899 | − printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n", | |
| 2900 | − retval); | |
| 2901 | − goto error_create_attr_group; | |
| 2902 | − } | |
| 2903 | 2797 | if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) |
| 2904 | 2798 | usb_hcd_poll_rh_status(hcd); |
| 2905 | 2799 | |
| 2906 | 2800 | return retval; |
| 2907 | 2801 | |
| 2908 | −error_create_attr_group: | |
| 2909 | − clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); | |
| 2910 | − if (HC_IS_RUNNING(hcd->state)) | |
| 2911 | − hcd->state = HC_STATE_QUIESCING; | |
| 2912 | − spin_lock_irq(&hcd_root_hub_lock); | |
| 2913 | − hcd->rh_registered = 0; | |
| 2914 | − spin_unlock_irq(&hcd_root_hub_lock); | |
| 2915 | − | |
| 2916 | −#ifdef CONFIG_PM | |
| 2917 | − cancel_work_sync(&hcd->wakeup_work); | |
| 2918 | −#endif | |
| 2919 | − cancel_work_sync(&hcd->died_work); | |
| 2920 | − mutex_lock(&usb_bus_idr_lock); | |
| 2921 | − usb_disconnect(&rhdev); /* Sets rhdev to NULL */ | |
| 2922 | − mutex_unlock(&usb_bus_idr_lock); | |
| 2923 | 2802 | err_register_root_hub: |
| 2924 | 2803 | hcd->rh_pollable = 0; |
| 2925 | 2804 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); |
| @@ -2963,8 +2842,6 @@ void usb_remove_hcd(struct usb_hcd *hcd) · 37 unmodified lines | ||
| 2963 | 2842 | dev_info(hcd->self.controller, "remove, state %x\n", hcd->state); |
| 2964 | 2843 | |
| 2965 | 2844 | usb_get_dev(rhdev); |
| 2966 | − sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); | |
| 2967 | − | |
| 2968 | 2845 | clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); |
| 2969 | 2846 | if (HC_IS_RUNNING (hcd->state)) |
| 2970 | 2847 | hcd->state = HC_STATE_QUIESCING; |
| @@ -2218,14 +2218,14 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, · 2217 unmodified lines | ||
| 2218 | 2218 | (struct usb_cdc_dmm_desc *)buffer; |
| 2219 | 2219 | break; |
| 2220 | 2220 | case USB_CDC_MDLM_TYPE: |
| 2221 | − if (elength < sizeof(struct usb_cdc_mdlm_desc *)) | |
| 2221 | + if (elength < sizeof(struct usb_cdc_mdlm_desc)) | |
| 2222 | 2222 | goto next_desc; |
| 2223 | 2223 | if (desc) |
| 2224 | 2224 | return -EINVAL; |
| 2225 | 2225 | desc = (struct usb_cdc_mdlm_desc *)buffer; |
| 2226 | 2226 | break; |
| 2227 | 2227 | case USB_CDC_MDLM_DETAIL_TYPE: |
| 2228 | − if (elength < sizeof(struct usb_cdc_mdlm_detail_desc *)) | |
| 2228 | + if (elength < sizeof(struct usb_cdc_mdlm_detail_desc)) | |
| 2229 | 2229 | goto next_desc; |
| 2230 | 2230 | if (detail) |
| 2231 | 2231 | return -EINVAL; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/kernel.h> |
| 16 | 16 | #include <linux/string.h> |
| 17 | 17 | #include <linux/usb.h> |
| 18 | +#include <linux/usb/hcd.h> | |
| 18 | 19 | #include <linux/usb/quirks.h> |
| 19 | 20 | #include <linux/of.h> |
| 20 | 21 | #include "usb.h" |
| @@ -922,6 +923,116 @@ static struct bin_attribute dev_bin_attr_descriptors = { · 901 unmodified lines | ||
| 922 | 923 | .size = 18 + 65535, /* dev descr + max-size raw descriptor */ |
| 923 | 924 | }; |
| 924 | 925 | |
| 926 | +/* | |
| 927 | + * Show & store the current value of authorized_default | |
| 928 | + */ | |
| 929 | +static ssize_t authorized_default_show(struct device *dev, | |
| 930 | + struct device_attribute *attr, char *buf) | |
| 931 | +{ | |
| 932 | + struct usb_device *rh_usb_dev = to_usb_device(dev); | |
| 933 | + struct usb_bus *usb_bus = rh_usb_dev->bus; | |
| 934 | + struct usb_hcd *hcd; | |
| 935 | + | |
| 936 | + hcd = bus_to_hcd(usb_bus); | |
| 937 | + return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy); | |
| 938 | +} | |
| 939 | + | |
| 940 | +static ssize_t authorized_default_store(struct device *dev, | |
| 941 | + struct device_attribute *attr, | |
| 942 | + const char *buf, size_t size) | |
| 943 | +{ | |
| 944 | + ssize_t result; | |
| 945 | + unsigned int val; | |
| 946 | + struct usb_device *rh_usb_dev = to_usb_device(dev); | |
| 947 | + struct usb_bus *usb_bus = rh_usb_dev->bus; | |
| 948 | + struct usb_hcd *hcd; | |
| 949 | + | |
| 950 | + hcd = bus_to_hcd(usb_bus); | |
| 951 | + result = sscanf(buf, "%u\n", &val); | |
| 952 | + if (result == 1) { | |
| 953 | + hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ? | |
| 954 | + val : USB_DEVICE_AUTHORIZE_ALL; | |
| 955 | + result = size; | |
| 956 | + } else { | |
| 957 | + result = -EINVAL; | |
| 958 | + } | |
| 959 | + return result; | |
| 960 | +} | |
| 961 | +static DEVICE_ATTR_RW(authorized_default); | |
| 962 | + | |
| 963 | +/* | |
| 964 | + * interface_authorized_default_show - show default authorization status | |
| 965 | + * for USB interfaces | |
| 966 | + * | |
| 967 | + * note: interface_authorized_default is the default value | |
| 968 | + * for initializing the authorized attribute of interfaces | |
| 969 | + */ | |
| 970 | +static ssize_t interface_authorized_default_show(struct device *dev, | |
| 971 | + struct device_attribute *attr, char *buf) | |
| 972 | +{ | |
| 973 | + struct usb_device *usb_dev = to_usb_device(dev); | |
| 974 | + struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); | |
| 975 | + | |
| 976 | + return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd)); | |
| 977 | +} | |
| 978 | + | |
| 979 | +/* | |
| 980 | + * interface_authorized_default_store - store default authorization status | |
| 981 | + * for USB interfaces | |
| 982 | + * | |
| 983 | + * note: interface_authorized_default is the default value | |
| 984 | + * for initializing the authorized attribute of interfaces | |
| 985 | + */ | |
| 986 | +static ssize_t interface_authorized_default_store(struct device *dev, | |
| 987 | + struct device_attribute *attr, const char *buf, size_t count) | |
| 988 | +{ | |
| 989 | + struct usb_device *usb_dev = to_usb_device(dev); | |
| 990 | + struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus); | |
| 991 | + int rc = count; | |
| 992 | + bool val; | |
| 993 | + | |
| 994 | + if (strtobool(buf, &val) != 0) | |
| 995 | + return -EINVAL; | |
| 996 | + | |
| 997 | + if (val) | |
| 998 | + set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); | |
| 999 | + else | |
| 1000 | + clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags); | |
| 1001 | + | |
| 1002 | + return rc; | |
| 1003 | +} | |
| 1004 | +static DEVICE_ATTR_RW(interface_authorized_default); | |
| 1005 | + | |
| 1006 | +/* Group all the USB bus attributes */ | |
| 1007 | +static struct attribute *usb_bus_attrs[] = { | |
| 1008 | + &dev_attr_authorized_default.attr, | |
| 1009 | + &dev_attr_interface_authorized_default.attr, | |
| 1010 | + NULL, | |
| 1011 | +}; | |
| 1012 | + | |
| 1013 | +static const struct attribute_group usb_bus_attr_group = { | |
| 1014 | + .name = NULL, /* we want them in the same directory */ | |
| 1015 | + .attrs = usb_bus_attrs, | |
| 1016 | +}; | |
| 1017 | + | |
| 1018 | + | |
| 1019 | +static int add_default_authorized_attributes(struct device *dev) | |
| 1020 | +{ | |
| 1021 | + int rc = 0; | |
| 1022 | + | |
| 1023 | + if (is_usb_device(dev)) | |
| 1024 | + rc = sysfs_create_group(&dev->kobj, &usb_bus_attr_group); | |
| 1025 | + | |
| 1026 | + return rc; | |
| 1027 | +} | |
| 1028 | + | |
| 1029 | +static void remove_default_authorized_attributes(struct device *dev) | |
| 1030 | +{ | |
| 1031 | + if (is_usb_device(dev)) { | |
| 1032 | + sysfs_remove_group(&dev->kobj, &usb_bus_attr_group); | |
| 1033 | + } | |
| 1034 | +} | |
| 1035 | + | |
| 925 | 1036 | int usb_create_sysfs_dev_files(struct usb_device *udev) |
| 926 | 1037 | { |
| 927 | 1038 | struct device *dev = &udev->dev; |
| @@ -938,7 +1049,14 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) · 10 unmodified lines | ||
| 938 | 1049 | retval = add_power_attributes(dev); |
| 939 | 1050 | if (retval) |
| 940 | 1051 | goto error; |
| 1052 | + | |
| 1053 | + if (is_root_hub(udev)) { | |
| 1054 | + retval = add_default_authorized_attributes(dev); | |
| 1055 | + if (retval) | |
| 1056 | + goto error; | |
| 1057 | + } | |
| 941 | 1058 | return retval; |
| 1059 | + | |
| 942 | 1060 | error: |
| 943 | 1061 | usb_remove_sysfs_dev_files(udev); |
| 944 | 1062 | return retval; |
| @@ -948,6 +1066,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) · 3 unmodified lines | ||
| 948 | 1066 | { |
| 949 | 1067 | struct device *dev = &udev->dev; |
| 950 | 1068 | |
| 1069 | + if (is_root_hub(udev)) | |
| 1070 | + remove_default_authorized_attributes(dev); | |
| 1071 | + | |
| 951 | 1072 | remove_power_attributes(dev); |
| 952 | 1073 | remove_persist_attributes(dev); |
| 953 | 1074 | device_remove_bin_file(dev, &dev_bin_attr_descriptors); |
| @@ -153,6 +153,11 @@ static inline int is_usb_port(const struct device *dev) · 152 unmodified lines | ||
| 153 | 153 | return dev->type == &usb_port_device_type; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | +static inline int is_root_hub(struct usb_device *udev) | |
| 157 | +{ | |
| 158 | + return (udev->parent == NULL); | |
| 159 | +} | |
| 160 | + | |
| 156 | 161 | /* Do the same for device drivers and interface drivers. */ |
| 157 | 162 | |
| 158 | 163 | static inline int is_usb_device_driver(struct device_driver *drv) |
| @@ -4608,7 +4608,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, · 4607 unmodified lines | ||
| 4608 | 4608 | |
| 4609 | 4609 | buf = urb->transfer_buffer; |
| 4610 | 4610 | |
| 4611 | − if (hcd->self.uses_dma) { | |
| 4611 | + if (hcd_uses_dma(hcd)) { | |
| 4612 | 4612 | if (!buf && (urb->transfer_dma & 3)) { |
| 4613 | 4613 | dev_err(hsotg->dev, |
| 4614 | 4614 | "%s: unaligned transfer with no transfer_buffer", |
| @@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget) · 1975 unmodified lines | ||
| 1976 | 1976 | * disconnect callbacks? |
| 1977 | 1977 | */ |
| 1978 | 1978 | spin_lock_irqsave(&cdev->lock, flags); |
| 1979 | + cdev->suspended = 0; | |
| 1979 | 1980 | if (cdev->config) |
| 1980 | 1981 | reset_config(cdev); |
| 1981 | 1982 | if (cdev->driver->disconnect) |
| @@ -261,7 +261,7 @@ struct fsg_common; · 260 unmodified lines | ||
| 261 | 261 | struct fsg_common { |
| 262 | 262 | struct usb_gadget *gadget; |
| 263 | 263 | struct usb_composite_dev *cdev; |
| 264 | − struct fsg_dev *fsg, *new_fsg; | |
| 264 | + struct fsg_dev *fsg; | |
| 265 | 265 | wait_queue_head_t io_wait; |
| 266 | 266 | wait_queue_head_t fsg_wait; |
| 267 | 267 | |
| @@ -290,6 +290,7 @@ struct fsg_common { · 22 unmodified lines | ||
| 290 | 290 | unsigned int bulk_out_maxpacket; |
| 291 | 291 | enum fsg_state state; /* For exception handling */ |
| 292 | 292 | unsigned int exception_req_tag; |
| 293 | + void *exception_arg; | |
| 293 | 294 | |
| 294 | 295 | enum data_direction data_dir; |
| 295 | 296 | u32 data_size; |
| @@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) · 95 unmodified lines | ||
| 391 | 392 | |
| 392 | 393 | /* These routines may be called in process context or in_irq */ |
| 393 | 394 | |
| 394 | −static void raise_exception(struct fsg_common *common, enum fsg_state new_state) | |
| 395 | +static void __raise_exception(struct fsg_common *common, enum fsg_state new_state, | |
| 396 | + void *arg) | |
| 395 | 397 | { |
| 396 | 398 | unsigned long flags; |
| 397 | 399 | |
| @@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) · 6 unmodified lines | ||
| 404 | 406 | if (common->state <= new_state) { |
| 405 | 407 | common->exception_req_tag = common->ep0_req_tag; |
| 406 | 408 | common->state = new_state; |
| 409 | + common->exception_arg = arg; | |
| 407 | 410 | if (common->thread_task) |
| 408 | 411 | send_sig_info(SIGUSR1, SEND_SIG_PRIV, |
| 409 | 412 | common->thread_task); |
| @@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) · 1 unmodified line | ||
| 411 | 414 | spin_unlock_irqrestore(&common->lock, flags); |
| 412 | 415 | } |
| 413 | 416 | |
| 417 | +static void raise_exception(struct fsg_common *common, enum fsg_state new_state) | |
| 418 | +{ | |
| 419 | + __raise_exception(common, new_state, NULL); | |
| 420 | +} | |
| 414 | 421 | |
| 415 | 422 | /*-------------------------------------------------------------------------*/ |
| 416 | 423 | |
| @@ -2285,16 +2292,16 @@ reset: · 1868 unmodified lines | ||
| 2285 | 2292 | static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) |
| 2286 | 2293 | { |
| 2287 | 2294 | struct fsg_dev *fsg = fsg_from_func(f); |
| 2288 | − fsg->common->new_fsg = fsg; | |
| 2289 | − raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); | |
| 2295 | + | |
| 2296 | + __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg); | |
| 2290 | 2297 | return USB_GADGET_DELAYED_STATUS; |
| 2291 | 2298 | } |
| 2292 | 2299 | |
| 2293 | 2300 | static void fsg_disable(struct usb_function *f) |
| 2294 | 2301 | { |
| 2295 | 2302 | struct fsg_dev *fsg = fsg_from_func(f); |
| 2296 | − fsg->common->new_fsg = NULL; | |
| 2297 | − raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); | |
| 2303 | + | |
| 2304 | + __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); | |
| 2298 | 2305 | } |
| 2299 | 2306 | |
| 2300 | 2307 | |
| @@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common) · 6 unmodified lines | ||
| 2307 | 2314 | enum fsg_state old_state; |
| 2308 | 2315 | struct fsg_lun *curlun; |
| 2309 | 2316 | unsigned int exception_req_tag; |
| 2317 | + struct fsg_dev *new_fsg; | |
| 2310 | 2318 | |
| 2311 | 2319 | /* |
| 2312 | 2320 | * Clear the existing signals. Anything but SIGUSR1 is converted |
| @@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common) · 47 unmodified lines | ||
| 2360 | 2368 | common->next_buffhd_to_fill = &common->buffhds[0]; |
| 2361 | 2369 | common->next_buffhd_to_drain = &common->buffhds[0]; |
| 2362 | 2370 | exception_req_tag = common->exception_req_tag; |
| 2371 | + new_fsg = common->exception_arg; | |
| 2363 | 2372 | old_state = common->state; |
| 2364 | 2373 | common->state = FSG_STATE_NORMAL; |
| 2365 | 2374 | |
| @@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common) · 47 unmodified lines | ||
| 2413 | 2422 | break; |
| 2414 | 2423 | |
| 2415 | 2424 | case FSG_STATE_CONFIG_CHANGE: |
| 2416 | − do_set_interface(common, common->new_fsg); | |
| 2417 | − if (common->new_fsg) | |
| 2425 | + do_set_interface(common, new_fsg); | |
| 2426 | + if (new_fsg) | |
| 2418 | 2427 | usb_composite_setup_continue(common->cdev); |
| 2419 | 2428 | break; |
| 2420 | 2429 | |
| @@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) · 568 unmodified lines | ||
| 2989 | 2998 | |
| 2990 | 2999 | DBG(fsg, "unbind\n"); |
| 2991 | 3000 | if (fsg->common->fsg == fsg) { |
| 2992 | − fsg->common->new_fsg = NULL; | |
| 2993 | − raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); | |
| 3001 | + __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); | |
| 2994 | 3002 | /* FIXME: make interruptible or killable somehow? */ |
| 2995 | 3003 | wait_event(common->fsg_wait, common->fsg != fsg); |
| 2996 | 3004 | } |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/pm_runtime.h> |
| 20 | 20 | #include <linux/sizes.h> |
| 21 | 21 | #include <linux/slab.h> |
| 22 | +#include <linux/string.h> | |
| 22 | 23 | #include <linux/sys_soc.h> |
| 23 | 24 | #include <linux/uaccess.h> |
| 24 | 25 | #include <linux/usb/ch9.h> |
| @@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, · 2425 unmodified lines | ||
| 2450 | 2451 | if (usb3->forced_b_device) |
| 2451 | 2452 | return -EBUSY; |
| 2452 | 2453 | |
| 2453 | − if (!strncmp(buf, "host", strlen("host"))) | |
| 2454 | + if (sysfs_streq(buf, "host")) | |
| 2454 | 2455 | new_mode_is_host = true; |
| 2455 | − else if (!strncmp(buf, "peripheral", strlen("peripheral"))) | |
| 2456 | + else if (sysfs_streq(buf, "peripheral")) | |
| 2456 | 2457 | new_mode_is_host = false; |
| 2457 | 2458 | else |
| 2458 | 2459 | return -EINVAL; |
| @@ -1629,6 +1629,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 1628 unmodified lines | ||
| 1629 | 1629 | /* see what we found out */ |
| 1630 | 1630 | temp = check_reset_complete(fotg210, wIndex, status_reg, |
| 1631 | 1631 | fotg210_readl(fotg210, status_reg)); |
| 1632 | + | |
| 1633 | + /* restart schedule */ | |
| 1634 | + fotg210->command |= CMD_RUN; | |
| 1635 | + fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command); | |
| 1632 | 1636 | } |
| 1633 | 1637 | |
| 1634 | 1638 | if (!(temp & (PORT_RESUME|PORT_RESET))) { |
| @@ -238,10 +238,15 @@ int xhci_rcar_init_quirk(struct usb_hcd *hcd) · 237 unmodified lines | ||
| 238 | 238 | * pointers. So, this driver clears the AC64 bit of xhci->hcc_params |
| 239 | 239 | * to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in |
| 240 | 240 | * xhci_gen_setup(). |
| 241 | + * | |
| 242 | + * And, since the firmware/internal CPU control the USBSTS.STS_HALT | |
| 243 | + * and the process speed is down when the roothub port enters U3, | |
| 244 | + * long delay for the handshake of STS_HALT is neeed in xhci_suspend(). | |
| 241 | 245 | */ |
| 242 | 246 | if (xhci_rcar_is_gen2(hcd->self.controller) || |
| 243 | − xhci_rcar_is_gen3(hcd->self.controller)) | |
| 244 | − xhci->quirks |= XHCI_NO_64BIT_SUPPORT; | |
| 247 | + xhci_rcar_is_gen3(hcd->self.controller)) { | |
| 248 | + xhci->quirks |= XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND; | |
| 249 | + } | |
| 245 | 250 | |
| 246 | 251 | if (!xhci_rcar_wait_for_pll_active(hcd)) |
| 247 | 252 | return -ETIMEDOUT; |
| @@ -3089,8 +3089,18 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd, · 3088 unmodified lines | ||
| 3089 | 3089 | return; |
| 3090 | 3090 | udev = (struct usb_device *) host_ep->hcpriv; |
| 3091 | 3091 | vdev = xhci->devs[udev->slot_id]; |
| 3092 | + | |
| 3093 | + /* | |
| 3094 | + * vdev may be lost due to xHC restore error and re-initialization | |
| 3095 | + * during S3/S4 resume. A new vdev will be allocated later by | |
| 3096 | + * xhci_discover_or_reset_device() | |
| 3097 | + */ | |
| 3098 | + if (!udev->slot_id || !vdev) | |
| 3099 | + return; | |
| 3092 | 3100 | ep_index = xhci_get_endpoint_index(&host_ep->desc); |
| 3093 | 3101 | ep = &vdev->eps[ep_index]; |
| 3102 | + if (!ep) | |
| 3103 | + return; | |
| 3094 | 3104 | |
| 3095 | 3105 | /* Bail out if toggle is already being cleared by a endpoint reset */ |
| 3096 | 3106 | if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) { |
| @@ -866,19 +866,20 @@ static void iowarrior_disconnect(struct usb_interface *interface) · 865 unmodified lines | ||
| 866 | 866 | dev = usb_get_intfdata(interface); |
| 867 | 867 | mutex_lock(&iowarrior_open_disc_lock); |
| 868 | 868 | usb_set_intfdata(interface, NULL); |
| 869 | + /* prevent device read, write and ioctl */ | |
| 870 | + dev->present = 0; | |
| 869 | 871 | |
| 870 | 872 | minor = dev->minor; |
| 873 | + mutex_unlock(&iowarrior_open_disc_lock); | |
| 874 | + /* give back our minor - this will call close() locks need to be dropped at this point*/ | |
| 871 | 875 | |
| 872 | − /* give back our minor */ | |
| 873 | 876 | usb_deregister_dev(interface, &iowarrior_class); |
| 874 | 877 | |
| 875 | 878 | mutex_lock(&dev->mutex); |
| 876 | 879 | |
| 877 | 880 | /* prevent device read, write and ioctl */ |
| 878 | − dev->present = 0; | |
| 879 | 881 | |
| 880 | 882 | mutex_unlock(&dev->mutex); |
| 881 | − mutex_unlock(&iowarrior_open_disc_lock); | |
| 882 | 883 | |
| 883 | 884 | if (dev->opened) { |
| 884 | 885 | /* There is a process that holds a filedescriptor to the device , |
| @@ -51,6 +51,7 @@ struct rio_usb_data { · 50 unmodified lines | ||
| 51 | 51 | char *obuf, *ibuf; /* transfer buffers */ |
| 52 | 52 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ |
| 53 | 53 | wait_queue_head_t wait_q; /* for timeouts */ |
| 54 | + struct mutex lock; /* general race avoidance */ | |
| 54 | 55 | }; |
| 55 | 56 | |
| 56 | 57 | static DEFINE_MUTEX(rio500_mutex); |
| @@ -62,8 +63,10 @@ static int open_rio(struct inode *inode, struct file *file) · 5 unmodified lines | ||
| 62 | 63 | |
| 63 | 64 | /* against disconnect() */ |
| 64 | 65 | mutex_lock(&rio500_mutex); |
| 66 | + mutex_lock(&(rio->lock)); | |
| 65 | 67 | |
| 66 | 68 | if (rio->isopen || !rio->present) { |
| 69 | + mutex_unlock(&(rio->lock)); | |
| 67 | 70 | mutex_unlock(&rio500_mutex); |
| 68 | 71 | return -EBUSY; |
| 69 | 72 | } |
| @@ -71,6 +74,7 @@ static int open_rio(struct inode *inode, struct file *file) · 1 unmodified line | ||
| 71 | 74 | |
| 72 | 75 | init_waitqueue_head(&rio->wait_q); |
| 73 | 76 | |
| 77 | + mutex_unlock(&(rio->lock)); | |
| 74 | 78 | |
| 75 | 79 | dev_info(&rio->rio_dev->dev, "Rio opened.\n"); |
| 76 | 80 | mutex_unlock(&rio500_mutex); |
| @@ -84,6 +88,7 @@ static int close_rio(struct inode *inode, struct file *file) · 7 unmodified lines | ||
| 84 | 88 | |
| 85 | 89 | /* against disconnect() */ |
| 86 | 90 | mutex_lock(&rio500_mutex); |
| 91 | + mutex_lock(&(rio->lock)); | |
| 87 | 92 | |
| 88 | 93 | rio->isopen = 0; |
| 89 | 94 | if (!rio->present) { |
| @@ -95,6 +100,7 @@ static int close_rio(struct inode *inode, struct file *file) · 5 unmodified lines | ||
| 95 | 100 | } else { |
| 96 | 101 | dev_info(&rio->rio_dev->dev, "Rio closed.\n"); |
| 97 | 102 | } |
| 103 | + mutex_unlock(&(rio->lock)); | |
| 98 | 104 | mutex_unlock(&rio500_mutex); |
| 99 | 105 | return 0; |
| 100 | 106 | } |
| @@ -109,7 +115,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) · 8 unmodified lines | ||
| 109 | 115 | int retries; |
| 110 | 116 | int retval=0; |
| 111 | 117 | |
| 112 | − mutex_lock(&rio500_mutex); | |
| 118 | + mutex_lock(&(rio->lock)); | |
| 113 | 119 | /* Sanity check to make sure rio is connected, powered, etc */ |
| 114 | 120 | if (rio->present == 0 || rio->rio_dev == NULL) { |
| 115 | 121 | retval = -ENODEV; |
| @@ -253,7 +259,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) · 137 unmodified lines | ||
| 253 | 259 | |
| 254 | 260 | |
| 255 | 261 | err_out: |
| 256 | − mutex_unlock(&rio500_mutex); | |
| 262 | + mutex_unlock(&(rio->lock)); | |
| 257 | 263 | return retval; |
| 258 | 264 | } |
| 259 | 265 | |
| @@ -273,12 +279,12 @@ write_rio(struct file *file, const char __user *buffer, · 13 unmodified lines | ||
| 273 | 279 | int errn = 0; |
| 274 | 280 | int intr; |
| 275 | 281 | |
| 276 | − intr = mutex_lock_interruptible(&rio500_mutex); | |
| 282 | + intr = mutex_lock_interruptible(&(rio->lock)); | |
| 277 | 283 | if (intr) |
| 278 | 284 | return -EINTR; |
| 279 | 285 | /* Sanity check to make sure rio is connected, powered, etc */ |
| 280 | 286 | if (rio->present == 0 || rio->rio_dev == NULL) { |
| 281 | − mutex_unlock(&rio500_mutex); | |
| 287 | + mutex_unlock(&(rio->lock)); | |
| 282 | 288 | return -ENODEV; |
| 283 | 289 | } |
| 284 | 290 | |
| @@ -301,7 +307,7 @@ write_rio(struct file *file, const char __user *buffer, · 16 unmodified lines | ||
| 301 | 307 | goto error; |
| 302 | 308 | } |
| 303 | 309 | if (signal_pending(current)) { |
| 304 | − mutex_unlock(&rio500_mutex); | |
| 310 | + mutex_unlock(&(rio->lock)); | |
| 305 | 311 | return bytes_written ? bytes_written : -EINTR; |
| 306 | 312 | } |
| 307 | 313 | |
| @@ -339,12 +345,12 @@ write_rio(struct file *file, const char __user *buffer, · 31 unmodified lines | ||
| 339 | 345 | buffer += copy_size; |
| 340 | 346 | } while (count > 0); |
| 341 | 347 | |
| 342 | − mutex_unlock(&rio500_mutex); | |
| 348 | + mutex_unlock(&(rio->lock)); | |
| 343 | 349 | |
| 344 | 350 | return bytes_written ? bytes_written : -EIO; |
| 345 | 351 | |
| 346 | 352 | error: |
| 347 | − mutex_unlock(&rio500_mutex); | |
| 353 | + mutex_unlock(&(rio->lock)); | |
| 348 | 354 | return errn; |
| 349 | 355 | } |
| 350 | 356 | |
| @@ -361,12 +367,12 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) · 10 unmodified lines | ||
| 361 | 367 | char *ibuf; |
| 362 | 368 | int intr; |
| 363 | 369 | |
| 364 | − intr = mutex_lock_interruptible(&rio500_mutex); | |
| 370 | + intr = mutex_lock_interruptible(&(rio->lock)); | |
| 365 | 371 | if (intr) |
| 366 | 372 | return -EINTR; |
| 367 | 373 | /* Sanity check to make sure rio is connected, powered, etc */ |
| 368 | 374 | if (rio->present == 0 || rio->rio_dev == NULL) { |
| 369 | − mutex_unlock(&rio500_mutex); | |
| 375 | + mutex_unlock(&(rio->lock)); | |
| 370 | 376 | return -ENODEV; |
| 371 | 377 | } |
| 372 | 378 | |
| @@ -377,11 +383,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) · 4 unmodified lines | ||
| 377 | 383 | |
| 378 | 384 | while (count > 0) { |
| 379 | 385 | if (signal_pending(current)) { |
| 380 | − mutex_unlock(&rio500_mutex); | |
| 386 | + mutex_unlock(&(rio->lock)); | |
| 381 | 387 | return read_count ? read_count : -EINTR; |
| 382 | 388 | } |
| 383 | 389 | if (!rio->rio_dev) { |
| 384 | − mutex_unlock(&rio500_mutex); | |
| 390 | + mutex_unlock(&(rio->lock)); | |
| 385 | 391 | return -ENODEV; |
| 386 | 392 | } |
| 387 | 393 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; |
| @@ -399,7 +405,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) · 11 unmodified lines | ||
| 399 | 405 | count = this_read = partial; |
| 400 | 406 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ |
| 401 | 407 | if (!maxretry--) { |
| 402 | − mutex_unlock(&rio500_mutex); | |
| 408 | + mutex_unlock(&(rio->lock)); | |
| 403 | 409 | dev_err(&rio->rio_dev->dev, |
| 404 | 410 | "read_rio: maxretry timeout\n"); |
| 405 | 411 | return -ETIME; |
| @@ -409,19 +415,19 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) · 3 unmodified lines | ||
| 409 | 415 | finish_wait(&rio->wait_q, &wait); |
| 410 | 416 | continue; |
| 411 | 417 | } else if (result != -EREMOTEIO) { |
| 412 | − mutex_unlock(&rio500_mutex); | |
| 418 | + mutex_unlock(&(rio->lock)); | |
| 413 | 419 | dev_err(&rio->rio_dev->dev, |
| 414 | 420 | "Read Whoops - result:%d partial:%u this_read:%u\n", |
| 415 | 421 | result, partial, this_read); |
| 416 | 422 | return -EIO; |
| 417 | 423 | } else { |
| 418 | − mutex_unlock(&rio500_mutex); | |
| 424 | + mutex_unlock(&(rio->lock)); | |
| 419 | 425 | return (0); |
| 420 | 426 | } |
| 421 | 427 | |
| 422 | 428 | if (this_read) { |
| 423 | 429 | if (copy_to_user(buffer, ibuf, this_read)) { |
| 424 | − mutex_unlock(&rio500_mutex); | |
| 430 | + mutex_unlock(&(rio->lock)); | |
| 425 | 431 | return -EFAULT; |
| 426 | 432 | } |
| 427 | 433 | count -= this_read; |
| @@ -429,7 +435,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) · 1 unmodified line | ||
| 429 | 435 | buffer += this_read; |
| 430 | 436 | } |
| 431 | 437 | } |
| 432 | − mutex_unlock(&rio500_mutex); | |
| 438 | + mutex_unlock(&(rio->lock)); | |
| 433 | 439 | return read_count; |
| 434 | 440 | } |
| 435 | 441 | |
| @@ -494,6 +500,8 @@ static int probe_rio(struct usb_interface *intf, · 58 unmodified lines | ||
| 494 | 500 | } |
| 495 | 501 | dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); |
| 496 | 502 | |
| 503 | + mutex_init(&(rio->lock)); | |
| 504 | + | |
| 497 | 505 | usb_set_intfdata (intf, rio); |
| 498 | 506 | rio->present = 1; |
| 499 | 507 | bail_out: |
| @@ -511,10 +519,12 @@ static void disconnect_rio(struct usb_interface *intf) · 11 unmodified lines | ||
| 511 | 519 | if (rio) { |
| 512 | 520 | usb_deregister_dev(intf, &usb_rio_class); |
| 513 | 521 | |
| 522 | + mutex_lock(&(rio->lock)); | |
| 514 | 523 | if (rio->isopen) { |
| 515 | 524 | rio->isopen = 0; |
| 516 | 525 | /* better let it finish - the release will do whats needed */ |
| 517 | 526 | rio->rio_dev = NULL; |
| 527 | + mutex_unlock(&(rio->lock)); | |
| 518 | 528 | mutex_unlock(&rio500_mutex); |
| 519 | 529 | return; |
| 520 | 530 | } |
| @@ -524,6 +534,7 @@ static void disconnect_rio(struct usb_interface *intf) · 3 unmodified lines | ||
| 524 | 534 | dev_info(&intf->dev, "USB Rio disconnected.\n"); |
| 525 | 535 | |
| 526 | 536 | rio->present = 0; |
| 537 | + mutex_unlock(&(rio->lock)); | |
| 527 | 538 | } |
| 528 | 539 | mutex_unlock(&rio500_mutex); |
| 529 | 540 | } |
| @@ -92,7 +92,6 @@ static void yurex_delete(struct kref *kref) · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | dev_dbg(&dev->interface->dev, "%s\n", __func__); |
| 94 | 94 | |
| 95 | − usb_put_dev(dev->udev); | |
| 96 | 95 | if (dev->cntl_urb) { |
| 97 | 96 | usb_kill_urb(dev->cntl_urb); |
| 98 | 97 | kfree(dev->cntl_req); |
| @@ -108,6 +107,7 @@ static void yurex_delete(struct kref *kref) · 9 unmodified lines | ||
| 108 | 107 | dev->int_buffer, dev->urb->transfer_dma); |
| 109 | 108 | usb_free_urb(dev->urb); |
| 110 | 109 | } |
| 110 | + usb_put_dev(dev->udev); | |
| 111 | 111 | kfree(dev); |
| 112 | 112 | } |
| 113 | 113 | |
| @@ -968,6 +968,11 @@ static const struct usb_device_id option_ids[] = { · 967 unmodified lines | ||
| 968 | 968 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) }, |
| 969 | 969 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) }, |
| 970 | 970 | |
| 971 | + /* Motorola devices */ | |
| 972 | + { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2a70, 0xff, 0xff, 0xff) }, /* mdm6600 */ | |
| 973 | + { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2e0a, 0xff, 0xff, 0xff) }, /* mdm9600 */ | |
| 974 | + { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x4281, 0x0a, 0x00, 0xfc) }, /* mdm ram dl */ | |
| 975 | + { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x900e, 0xff, 0xff, 0xff) }, /* mdm qc dl */ | |
| 971 | 976 | |
| 972 | 977 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
| 973 | 978 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
| @@ -1549,6 +1554,7 @@ static const struct usb_device_id option_ids[] = { · 575 unmodified lines | ||
| 1549 | 1554 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ |
| 1550 | 1555 | .driver_info = RSVD(2) }, |
| 1551 | 1556 | { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */ |
| 1557 | + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0x00, 0x00) }, /* ZTE MF871A */ | |
| 1552 | 1558 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, |
| 1553 | 1559 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, |
| 1554 | 1560 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, |
| @@ -1952,11 +1958,15 @@ static const struct usb_device_id option_ids[] = { · 397 unmodified lines | ||
| 1952 | 1958 | .driver_info = RSVD(4) }, |
| 1953 | 1959 | { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ |
| 1954 | 1960 | .driver_info = RSVD(4) }, |
| 1961 | + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e3d, 0xff), /* D-Link DWM-222 A2 */ | |
| 1962 | + .driver_info = RSVD(4) }, | |
| 1955 | 1963 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ |
| 1956 | 1964 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ |
| 1957 | 1965 | { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ |
| 1958 | 1966 | { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff), /* Olicard 600 */ |
| 1959 | 1967 | .driver_info = RSVD(4) }, |
| 1968 | + { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2060, 0xff), /* BroadMobi BM818 */ | |
| 1969 | + .driver_info = RSVD(4) }, | |
| 1960 | 1970 | { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ |
| 1961 | 1971 | { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, |
| 1962 | 1972 | { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, |
| @@ -379,7 +379,8 @@ static enum tcpm_state tcpm_default_state(struct tcpm_port *port) · 378 unmodified lines | ||
| 379 | 379 | return SNK_UNATTACHED; |
| 380 | 380 | else if (port->try_role == TYPEC_SOURCE) |
| 381 | 381 | return SRC_UNATTACHED; |
| 382 | − else if (port->tcpc->config->default_role == TYPEC_SINK) | |
| 382 | + else if (port->tcpc->config && | |
| 383 | + port->tcpc->config->default_role == TYPEC_SINK) | |
| 383 | 384 | return SNK_UNATTACHED; |
| 384 | 385 | /* Fall through to return SRC_UNATTACHED */ |
| 385 | 386 | } else if (port->port_type == TYPEC_PORT_SNK) { |
| @@ -586,7 +587,20 @@ static void tcpm_debugfs_init(struct tcpm_port *port) · 200 unmodified lines | ||
| 586 | 587 | |
| 587 | 588 | static void tcpm_debugfs_exit(struct tcpm_port *port) |
| 588 | 589 | { |
| 590 | + int i; | |
| 591 | + | |
| 592 | + mutex_lock(&port->logbuffer_lock); | |
| 593 | + for (i = 0; i < LOG_BUFFER_ENTRIES; i++) { | |
| 594 | + kfree(port->logbuffer[i]); | |
| 595 | + port->logbuffer[i] = NULL; | |
| 596 | + } | |
| 597 | + mutex_unlock(&port->logbuffer_lock); | |
| 598 | + | |
| 589 | 599 | debugfs_remove(port->dentry); |
| 600 | + if (list_empty(&rootdir->d_subdirs)) { | |
| 601 | + debugfs_remove(rootdir); | |
| 602 | + rootdir = NULL; | |
| 603 | + } | |
| 590 | 604 | } |
| 591 | 605 | |
| 592 | 606 | #else |
| @@ -1095,7 +1109,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, · 502 unmodified lines | ||
| 1095 | 1109 | break; |
| 1096 | 1110 | case CMD_ATTENTION: |
| 1097 | 1111 | /* Attention command does not have response */ |
| 1098 | − typec_altmode_attention(adev, p[1]); | |
| 1112 | + if (adev) | |
| 1113 | + typec_altmode_attention(adev, p[1]); | |
| 1099 | 1114 | return 0; |
| 1100 | 1115 | default: |
| 1101 | 1116 | break; |
| @@ -1147,20 +1162,26 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, · 45 unmodified lines | ||
| 1147 | 1162 | } |
| 1148 | 1163 | break; |
| 1149 | 1164 | case CMD_ENTER_MODE: |
| 1150 | − typec_altmode_update_active(pdev, true); | |
| 1151 | − | |
| 1152 | − if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) { | |
| 1153 | − response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE); | |
| 1154 | − response[0] |= VDO_OPOS(adev->mode); | |
| 1155 | − return 1; | |
| 1165 | + if (adev && pdev) { | |
| 1166 | + typec_altmode_update_active(pdev, true); | |
| 1167 | + | |
| 1168 | + if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) { | |
| 1169 | + response[0] = VDO(adev->svid, 1, | |
| 1170 | + CMD_EXIT_MODE); | |
| 1171 | + response[0] |= VDO_OPOS(adev->mode); | |
| 1172 | + return 1; | |
| 1173 | + } | |
| 1156 | 1174 | } |
| 1157 | 1175 | return 0; |
| 1158 | 1176 | case CMD_EXIT_MODE: |
| 1159 | − typec_altmode_update_active(pdev, false); | |
| 1177 | + if (adev && pdev) { | |
| 1178 | + typec_altmode_update_active(pdev, false); | |
| 1160 | 1179 | |
| 1161 | − /* Back to USB Operation */ | |
| 1162 | − WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, | |
| 1163 | − NULL)); | |
| 1180 | + /* Back to USB Operation */ | |
| 1181 | + WARN_ON(typec_altmode_notify(adev, | |
| 1182 | + TYPEC_STATE_USB, | |
| 1183 | + NULL)); | |
| 1184 | + } | |
| 1164 | 1185 | break; |
| 1165 | 1186 | default: |
| 1166 | 1187 | break; |
| @@ -1170,8 +1191,10 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, · 3 unmodified lines | ||
| 1170 | 1191 | switch (cmd) { |
| 1171 | 1192 | case CMD_ENTER_MODE: |
| 1172 | 1193 | /* Back to USB Operation */ |
| 1173 | − WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, | |
| 1174 | − NULL)); | |
| 1194 | + if (adev) | |
| 1195 | + WARN_ON(typec_altmode_notify(adev, | |
| 1196 | + TYPEC_STATE_USB, | |
| 1197 | + NULL)); | |
| 1175 | 1198 | break; |
| 1176 | 1199 | default: |
| 1177 | 1200 | break; |
| @@ -1182,7 +1205,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, · 4 unmodified lines | ||
| 1182 | 1205 | } |
| 1183 | 1206 | |
| 1184 | 1207 | /* Informing the alternate mode drivers about everything */ |
| 1185 | − typec_altmode_vdm(adev, p[0], &p[1], cnt); | |
| 1208 | + if (adev) | |
| 1209 | + typec_altmode_vdm(adev, p[0], &p[1], cnt); | |
| 1186 | 1210 | |
| 1187 | 1211 | return rlen; |
| 1188 | 1212 | } |
| @@ -4114,7 +4138,7 @@ static int tcpm_try_role(const struct typec_capability *cap, int role) · 2925 unmodified lines | ||
| 4114 | 4138 | mutex_lock(&port->lock); |
| 4115 | 4139 | if (tcpc->try_role) |
| 4116 | 4140 | ret = tcpc->try_role(tcpc, role); |
| 4117 | − if (!ret && !tcpc->config->try_role_hw) | |
| 4141 | + if (!ret && (!tcpc->config || !tcpc->config->try_role_hw)) | |
| 4118 | 4142 | port->try_role = role; |
| 4119 | 4143 | port->try_src_count = 0; |
| 4120 | 4144 | port->try_snk_count = 0; |
| @@ -4701,7 +4725,7 @@ static int tcpm_copy_caps(struct tcpm_port *port, · 580 unmodified lines | ||
| 4701 | 4725 | port->typec_caps.prefer_role = tcfg->default_role; |
| 4702 | 4726 | port->typec_caps.type = tcfg->type; |
| 4703 | 4727 | port->typec_caps.data = tcfg->data; |
| 4704 | − port->self_powered = port->tcpc->config->self_powered; | |
| 4728 | + port->self_powered = tcfg->self_powered; | |
| 4705 | 4729 | |
| 4706 | 4730 | return 0; |
| 4707 | 4731 | } |
| @@ -1018,7 +1018,7 @@ release_fw: · 1017 unmodified lines | ||
| 1018 | 1018 | ******************************************************************************/ |
| 1019 | 1019 | static int ccg_fw_update(struct ucsi_ccg *uc, enum enum_flash_mode flash_mode) |
| 1020 | 1020 | { |
| 1021 | − int err; | |
| 1021 | + int err = 0; | |
| 1022 | 1022 | |
| 1023 | 1023 | while (flash_mode != FLASH_NOT_NEEDED) { |
| 1024 | 1024 | err = do_flash(uc, flash_mode); |
| @@ -447,6 +447,7 @@ static int set_color_mode(struct omapfb_plane_struct *plane, · 446 unmodified lines | ||
| 447 | 447 | return 0; |
| 448 | 448 | case 12: |
| 449 | 449 | var->bits_per_pixel = 16; |
| 450 | + /* fall through */ | |
| 450 | 451 | case 16: |
| 451 | 452 | if (plane->fbdev->panel->bpp == 12) |
| 452 | 453 | plane->color_mode = OMAPFB_COLOR_RGB444; |
| @@ -1534,20 +1535,27 @@ static void omapfb_free_resources(struct omapfb_device *fbdev, int state) · 1081 unmodified lines | ||
| 1534 | 1535 | case OMAPFB_ACTIVE: |
| 1535 | 1536 | for (i = 0; i < fbdev->mem_desc.region_cnt; i++) |
| 1536 | 1537 | unregister_framebuffer(fbdev->fb_info[i]); |
| 1538 | + /* fall through */ | |
| 1537 | 1539 | case 7: |
| 1538 | 1540 | omapfb_unregister_sysfs(fbdev); |
| 1541 | + /* fall through */ | |
| 1539 | 1542 | case 6: |
| 1540 | 1543 | if (fbdev->panel->disable) |
| 1541 | 1544 | fbdev->panel->disable(fbdev->panel); |
| 1545 | + /* fall through */ | |
| 1542 | 1546 | case 5: |
| 1543 | 1547 | omapfb_set_update_mode(fbdev, OMAPFB_UPDATE_DISABLED); |
| 1548 | + /* fall through */ | |
| 1544 | 1549 | case 4: |
| 1545 | 1550 | planes_cleanup(fbdev); |
| 1551 | + /* fall through */ | |
| 1546 | 1552 | case 3: |
| 1547 | 1553 | ctrl_cleanup(fbdev); |
| 1554 | + /* fall through */ | |
| 1548 | 1555 | case 2: |
| 1549 | 1556 | if (fbdev->panel->cleanup) |
| 1550 | 1557 | fbdev->panel->cleanup(fbdev->panel); |
| 1558 | + /* fall through */ | |
| 1551 | 1559 | case 1: |
| 1552 | 1560 | dev_set_drvdata(fbdev->dev, NULL); |
| 1553 | 1561 | kfree(fbdev); |
| @@ -235,6 +235,7 @@ static long ar7_wdt_ioctl(struct file *file, · 234 unmodified lines | ||
| 235 | 235 | ar7_wdt_update_margin(new_margin); |
| 236 | 236 | ar7_wdt_kick(1); |
| 237 | 237 | spin_unlock(&wdt_lock); |
| 238 | + /* Fall through */ | |
| 238 | 239 | |
| 239 | 240 | case WDIOC_GETTIMEOUT: |
| 240 | 241 | if (put_user(margin, (int *)arg)) |
| @@ -651,7 +651,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 650 unmodified lines | ||
| 651 | 651 | return -EINVAL; |
| 652 | 652 | |
| 653 | 653 | pcwd_keepalive(); |
| 654 | − /* Fall */ | |
| 654 | + /* Fall through */ | |
| 655 | 655 | |
| 656 | 656 | case WDIOC_GETTIMEOUT: |
| 657 | 657 | return put_user(heartbeat, argp); |
| @@ -134,7 +134,7 @@ static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 133 unmodified lines | ||
| 134 | 134 | return -EINVAL; |
| 135 | 135 | riowd_timeout = (new_margin + 59) / 60; |
| 136 | 136 | riowd_writereg(p, riowd_timeout, WDTO_INDEX); |
| 137 | − /* Fall */ | |
| 137 | + /* Fall through */ | |
| 138 | 138 | |
| 139 | 139 | case WDIOC_GETTIMEOUT: |
| 140 | 140 | return put_user(riowd_timeout * 60, (int __user *)argp); |
| @@ -202,6 +202,7 @@ static long sbwdog_ioctl(struct file *file, unsigned int cmd, · 201 unmodified lines | ||
| 202 | 202 | timeout = time; |
| 203 | 203 | sbwdog_set(user_dog, timeout); |
| 204 | 204 | sbwdog_pet(user_dog); |
| 205 | + /* Fall through */ | |
| 205 | 206 | |
| 206 | 207 | case WDIOC_GETTIMEOUT: |
| 207 | 208 | /* |
| @@ -186,6 +186,7 @@ static long scx200_wdt_ioctl(struct file *file, unsigned int cmd, · 185 unmodified lines | ||
| 186 | 186 | margin = new_margin; |
| 187 | 187 | scx200_wdt_update_margin(); |
| 188 | 188 | scx200_wdt_ping(); |
| 189 | + /* Fall through */ | |
| 189 | 190 | case WDIOC_GETTIMEOUT: |
| 190 | 191 | if (put_user(margin, p)) |
| 191 | 192 | return -EFAULT; |
| @@ -389,7 +389,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 388 unmodified lines | ||
| 389 | 389 | if (wdt_set_heartbeat(new_heartbeat)) |
| 390 | 390 | return -EINVAL; |
| 391 | 391 | wdt_ping(); |
| 392 | − /* Fall */ | |
| 392 | + /* Fall through */ | |
| 393 | 393 | case WDIOC_GETTIMEOUT: |
| 394 | 394 | return put_user(heartbeat, p); |
| 395 | 395 | default: |
| @@ -398,7 +398,7 @@ static long wdt977_ioctl(struct file *file, unsigned int cmd, · 397 unmodified lines | ||
| 398 | 398 | return -EINVAL; |
| 399 | 399 | |
| 400 | 400 | wdt977_keepalive(); |
| 401 | − /* Fall */ | |
| 401 | + /* Fall through */ | |
| 402 | 402 | |
| 403 | 403 | case WDIOC_GETTIMEOUT: |
| 404 | 404 | return put_user(timeout, uarg.i); |
| @@ -505,18 +505,14 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work) · 504 unmodified lines | ||
| 505 | 505 | struct afs_call *call = container_of(work, struct afs_call, work); |
| 506 | 506 | struct afs_uuid *r = call->request; |
| 507 | 507 | |
| 508 | − struct { | |
| 509 | − __be32 match; | |
| 510 | − } reply; | |
| 511 | − | |
| 512 | 508 | _enter(""); |
| 513 | 509 | |
| 514 | 510 | if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) |
| 515 | − reply.match = htonl(0); | |
| 511 | + afs_send_empty_reply(call); | |
| 516 | 512 | else |
| 517 | − reply.match = htonl(1); | |
| 513 | + rxrpc_kernel_abort_call(call->net->socket, call->rxcall, | |
| 514 | + 1, 1, "K-1"); | |
| 518 | 515 | |
| 519 | − afs_send_simple_reply(call, &reply, sizeof(reply)); | |
| 520 | 516 | afs_put_call(call); |
| 521 | 517 | _leave(""); |
| 522 | 518 | } |
| @@ -440,7 +440,7 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode, · 439 unmodified lines | ||
| 440 | 440 | * iterate through the data blob that lists the contents of an AFS directory |
| 441 | 441 | */ |
| 442 | 442 | static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, |
| 443 | − struct key *key) | |
| 443 | + struct key *key, afs_dataversion_t *_dir_version) | |
| 444 | 444 | { |
| 445 | 445 | struct afs_vnode *dvnode = AFS_FS_I(dir); |
| 446 | 446 | struct afs_xdr_dir_page *dbuf; |
| @@ -460,6 +460,7 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, · 13 unmodified lines | ||
| 460 | 460 | req = afs_read_dir(dvnode, key); |
| 461 | 461 | if (IS_ERR(req)) |
| 462 | 462 | return PTR_ERR(req); |
| 463 | + *_dir_version = req->data_version; | |
| 463 | 464 | |
| 464 | 465 | /* round the file position up to the next entry boundary */ |
| 465 | 466 | ctx->pos += sizeof(union afs_xdr_dirent) - 1; |
| @@ -514,7 +515,10 @@ out: · 48 unmodified lines | ||
| 514 | 515 | */ |
| 515 | 516 | static int afs_readdir(struct file *file, struct dir_context *ctx) |
| 516 | 517 | { |
| 517 | − return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file)); | |
| 518 | + afs_dataversion_t dir_version; | |
| 519 | + | |
| 520 | + return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file), | |
| 521 | + &dir_version); | |
| 518 | 522 | } |
| 519 | 523 | |
| 520 | 524 | /* |
| @@ -555,7 +559,8 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, · 34 unmodified lines | ||
| 555 | 559 | * - just returns the FID the dentry name maps to if found |
| 556 | 560 | */ |
| 557 | 561 | static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, |
| 558 | − struct afs_fid *fid, struct key *key) | |
| 562 | + struct afs_fid *fid, struct key *key, | |
| 563 | + afs_dataversion_t *_dir_version) | |
| 559 | 564 | { |
| 560 | 565 | struct afs_super_info *as = dir->i_sb->s_fs_info; |
| 561 | 566 | struct afs_lookup_one_cookie cookie = { |
| @@ -568,7 +573,7 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, · 6 unmodified lines | ||
| 568 | 573 | _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); |
| 569 | 574 | |
| 570 | 575 | /* search the directory */ |
| 571 | − ret = afs_dir_iterate(dir, &cookie.ctx, key); | |
| 576 | + ret = afs_dir_iterate(dir, &cookie.ctx, key, _dir_version); | |
| 572 | 577 | if (ret < 0) { |
| 573 | 578 | _leave(" = %d [iter]", ret); |
| 574 | 579 | return ret; |
| @@ -642,6 +647,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 67 unmodified lines | ||
| 642 | 647 | struct afs_server *server; |
| 643 | 648 | struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; |
| 644 | 649 | struct inode *inode = NULL, *ti; |
| 650 | + afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version); | |
| 645 | 651 | int ret, i; |
| 646 | 652 | |
| 647 | 653 | _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); |
| @@ -669,12 +675,14 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, · 21 unmodified lines | ||
| 669 | 675 | cookie->fids[i].vid = as->volume->vid; |
| 670 | 676 | |
| 671 | 677 | /* search the directory */ |
| 672 | − ret = afs_dir_iterate(dir, &cookie->ctx, key); | |
| 678 | + ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version); | |
| 673 | 679 | if (ret < 0) { |
| 674 | 680 | inode = ERR_PTR(ret); |
| 675 | 681 | goto out; |
| 676 | 682 | } |
| 677 | 683 | |
| 684 | + dentry->d_fsdata = (void *)(unsigned long)data_version; | |
| 685 | + | |
| 678 | 686 | inode = ERR_PTR(-ENOENT); |
| 679 | 687 | if (!cookie->found) |
| 680 | 688 | goto out; |
| @@ -968,7 +976,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) · 287 unmodified lines | ||
| 968 | 976 | struct dentry *parent; |
| 969 | 977 | struct inode *inode; |
| 970 | 978 | struct key *key; |
| 971 | − long dir_version, de_version; | |
| 979 | + afs_dataversion_t dir_version; | |
| 980 | + long de_version; | |
| 972 | 981 | int ret; |
| 973 | 982 | |
| 974 | 983 | if (flags & LOOKUP_RCU) |
| @@ -1014,20 +1023,20 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) · 39 unmodified lines | ||
| 1014 | 1023 | * on a 32-bit system, we only have 32 bits in the dentry to store the |
| 1015 | 1024 | * version. |
| 1016 | 1025 | */ |
| 1017 | − dir_version = (long)dir->status.data_version; | |
| 1026 | + dir_version = dir->status.data_version; | |
| 1018 | 1027 | de_version = (long)dentry->d_fsdata; |
| 1019 | − if (de_version == dir_version) | |
| 1020 | − goto out_valid; | |
| 1028 | + if (de_version == (long)dir_version) | |
| 1029 | + goto out_valid_noupdate; | |
| 1021 | 1030 | |
| 1022 | − dir_version = (long)dir->invalid_before; | |
| 1023 | − if (de_version - dir_version >= 0) | |
| 1031 | + dir_version = dir->invalid_before; | |
| 1032 | + if (de_version - (long)dir_version >= 0) | |
| 1024 | 1033 | goto out_valid; |
| 1025 | 1034 | |
| 1026 | 1035 | _debug("dir modified"); |
| 1027 | 1036 | afs_stat_v(dir, n_reval); |
| 1028 | 1037 | |
| 1029 | 1038 | /* search the directory for this vnode */ |
| 1030 | − ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key); | |
| 1039 | + ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version); | |
| 1031 | 1040 | switch (ret) { |
| 1032 | 1041 | case 0: |
| 1033 | 1042 | /* the filename maps to something */ |
| @@ -1080,7 +1089,8 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) · 46 unmodified lines | ||
| 1080 | 1089 | } |
| 1081 | 1090 | |
| 1082 | 1091 | out_valid: |
| 1083 | − dentry->d_fsdata = (void *)dir_version; | |
| 1092 | + dentry->d_fsdata = (void *)(unsigned long)dir_version; | |
| 1093 | +out_valid_noupdate: | |
| 1084 | 1094 | dput(parent); |
| 1085 | 1095 | key_put(key); |
| 1086 | 1096 | _leave(" = 1 [valid]"); |
| @@ -1185,6 +1195,20 @@ static void afs_prep_for_new_inode(struct afs_fs_cursor *fc, · 98 unmodified lines | ||
| 1185 | 1195 | iget_data->cb_s_break = fc->cbi->server->cb_s_break; |
| 1186 | 1196 | } |
| 1187 | 1197 | |
| 1198 | +/* | |
| 1199 | + * Note that a dentry got changed. We need to set d_fsdata to the data version | |
| 1200 | + * number derived from the result of the operation. It doesn't matter if | |
| 1201 | + * d_fsdata goes backwards as we'll just revalidate. | |
| 1202 | + */ | |
| 1203 | +static void afs_update_dentry_version(struct afs_fs_cursor *fc, | |
| 1204 | + struct dentry *dentry, | |
| 1205 | + struct afs_status_cb *scb) | |
| 1206 | +{ | |
| 1207 | + if (fc->ac.error == 0) | |
| 1208 | + dentry->d_fsdata = | |
| 1209 | + (void *)(unsigned long)scb->status.data_version; | |
| 1210 | +} | |
| 1211 | + | |
| 1188 | 1212 | /* |
| 1189 | 1213 | * create a directory on an AFS filesystem |
| 1190 | 1214 | */ |
| @@ -1227,6 +1251,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) · 36 unmodified lines | ||
| 1227 | 1251 | afs_check_for_remote_deletion(&fc, dvnode); |
| 1228 | 1252 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
| 1229 | 1253 | &data_version, &scb[0]); |
| 1254 | + afs_update_dentry_version(&fc, dentry, &scb[0]); | |
| 1230 | 1255 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
| 1231 | 1256 | ret = afs_end_vnode_operation(&fc); |
| 1232 | 1257 | if (ret < 0) |
| @@ -1319,6 +1344,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) · 86 unmodified lines | ||
| 1319 | 1344 | |
| 1320 | 1345 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
| 1321 | 1346 | &data_version, scb); |
| 1347 | + afs_update_dentry_version(&fc, dentry, scb); | |
| 1322 | 1348 | ret = afs_end_vnode_operation(&fc); |
| 1323 | 1349 | if (ret == 0) { |
| 1324 | 1350 | afs_dir_remove_subdir(dentry); |
| @@ -1458,6 +1484,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) · 133 unmodified lines | ||
| 1458 | 1484 | &data_version, &scb[0]); |
| 1459 | 1485 | afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, |
| 1460 | 1486 | &data_version_2, &scb[1]); |
| 1487 | + afs_update_dentry_version(&fc, dentry, &scb[0]); | |
| 1461 | 1488 | ret = afs_end_vnode_operation(&fc); |
| 1462 | 1489 | if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) |
| 1463 | 1490 | ret = afs_dir_remove_link(dvnode, dentry, key); |
| @@ -1526,6 +1553,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, · 62 unmodified lines | ||
| 1526 | 1553 | afs_check_for_remote_deletion(&fc, dvnode); |
| 1527 | 1554 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
| 1528 | 1555 | &data_version, &scb[0]); |
| 1556 | + afs_update_dentry_version(&fc, dentry, &scb[0]); | |
| 1529 | 1557 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
| 1530 | 1558 | ret = afs_end_vnode_operation(&fc); |
| 1531 | 1559 | if (ret < 0) |
| @@ -1607,6 +1635,7 @@ static int afs_link(struct dentry *from, struct inode *dir, · 75 unmodified lines | ||
| 1607 | 1635 | afs_vnode_commit_status(&fc, vnode, fc.cb_break_2, |
| 1608 | 1636 | NULL, &scb[1]); |
| 1609 | 1637 | ihold(&vnode->vfs_inode); |
| 1638 | + afs_update_dentry_version(&fc, dentry, &scb[0]); | |
| 1610 | 1639 | d_instantiate(dentry, &vnode->vfs_inode); |
| 1611 | 1640 | |
| 1612 | 1641 | mutex_unlock(&vnode->io_lock); |
| @@ -1686,6 +1715,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry, · 73 unmodified lines | ||
| 1686 | 1715 | afs_check_for_remote_deletion(&fc, dvnode); |
| 1687 | 1716 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break, |
| 1688 | 1717 | &data_version, &scb[0]); |
| 1718 | + afs_update_dentry_version(&fc, dentry, &scb[0]); | |
| 1689 | 1719 | afs_vnode_new_inode(&fc, dentry, &iget_data, &scb[1]); |
| 1690 | 1720 | ret = afs_end_vnode_operation(&fc); |
| 1691 | 1721 | if (ret < 0) |
| @@ -1791,6 +1821,17 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 99 unmodified lines | ||
| 1791 | 1821 | } |
| 1792 | 1822 | } |
| 1793 | 1823 | |
| 1824 | + /* This bit is potentially nasty as there's a potential race with | |
| 1825 | + * afs_d_revalidate{,_rcu}(). We have to change d_fsdata on the dentry | |
| 1826 | + * to reflect it's new parent's new data_version after the op, but | |
| 1827 | + * d_revalidate may see old_dentry between the op having taken place | |
| 1828 | + * and the version being updated. | |
| 1829 | + * | |
| 1830 | + * So drop the old_dentry for now to make other threads go through | |
| 1831 | + * lookup instead - which we hold a lock against. | |
| 1832 | + */ | |
| 1833 | + d_drop(old_dentry); | |
| 1834 | + | |
| 1794 | 1835 | ret = -ERESTARTSYS; |
| 1795 | 1836 | if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { |
| 1796 | 1837 | afs_dataversion_t orig_data_version; |
| @@ -1802,9 +1843,9 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 5 unmodified lines | ||
| 1802 | 1843 | if (orig_dvnode != new_dvnode) { |
| 1803 | 1844 | if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { |
| 1804 | 1845 | afs_end_vnode_operation(&fc); |
| 1805 | − goto error_rehash; | |
| 1846 | + goto error_rehash_old; | |
| 1806 | 1847 | } |
| 1807 | − new_data_version = new_dvnode->status.data_version; | |
| 1848 | + new_data_version = new_dvnode->status.data_version + 1; | |
| 1808 | 1849 | } else { |
| 1809 | 1850 | new_data_version = orig_data_version; |
| 1810 | 1851 | new_scb = &scb[0]; |
| @@ -1827,7 +1868,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 16 unmodified lines | ||
| 1827 | 1868 | } |
| 1828 | 1869 | ret = afs_end_vnode_operation(&fc); |
| 1829 | 1870 | if (ret < 0) |
| 1830 | − goto error_rehash; | |
| 1871 | + goto error_rehash_old; | |
| 1831 | 1872 | } |
| 1832 | 1873 | |
| 1833 | 1874 | if (ret == 0) { |
| @@ -1853,10 +1894,26 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, · 19 unmodified lines | ||
| 1853 | 1894 | drop_nlink(new_inode); |
| 1854 | 1895 | spin_unlock(&new_inode->i_lock); |
| 1855 | 1896 | } |
| 1897 | + | |
| 1898 | + /* Now we can update d_fsdata on the dentries to reflect their | |
| 1899 | + * new parent's data_version. | |
| 1900 | + * | |
| 1901 | + * Note that if we ever implement RENAME_EXCHANGE, we'll have | |
| 1902 | + * to update both dentries with opposing dir versions. | |
| 1903 | + */ | |
| 1904 | + if (new_dvnode != orig_dvnode) { | |
| 1905 | + afs_update_dentry_version(&fc, old_dentry, &scb[1]); | |
| 1906 | + afs_update_dentry_version(&fc, new_dentry, &scb[1]); | |
| 1907 | + } else { | |
| 1908 | + afs_update_dentry_version(&fc, old_dentry, &scb[0]); | |
| 1909 | + afs_update_dentry_version(&fc, new_dentry, &scb[0]); | |
| 1910 | + } | |
| 1856 | 1911 | d_move(old_dentry, new_dentry); |
| 1857 | 1912 | goto error_tmp; |
| 1858 | 1913 | } |
| 1859 | 1914 | |
| 1915 | +error_rehash_old: | |
| 1916 | + d_rehash(new_dentry); | |
| 1860 | 1917 | error_rehash: |
| 1861 | 1918 | if (rehash) |
| 1862 | 1919 | d_rehash(rehash); |
| @@ -191,11 +191,13 @@ void afs_put_read(struct afs_read *req) · 190 unmodified lines | ||
| 191 | 191 | int i; |
| 192 | 192 | |
| 193 | 193 | if (refcount_dec_and_test(&req->usage)) { |
| 194 | − for (i = 0; i < req->nr_pages; i++) | |
| 195 | − if (req->pages[i]) | |
| 196 | − put_page(req->pages[i]); | |
| 197 | − if (req->pages != req->array) | |
| 198 | − kfree(req->pages); | |
| 194 | + if (req->pages) { | |
| 195 | + for (i = 0; i < req->nr_pages; i++) | |
| 196 | + if (req->pages[i]) | |
| 197 | + put_page(req->pages[i]); | |
| 198 | + if (req->pages != req->array) | |
| 199 | + kfree(req->pages); | |
| 200 | + } | |
| 199 | 201 | kfree(req); |
| 200 | 202 | } |
| 201 | 203 | } |
| @@ -56,23 +56,24 @@ static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call) · 55 unmodified lines | ||
| 56 | 56 | struct afs_uuid__xdr *xdr; |
| 57 | 57 | struct afs_uuid *uuid; |
| 58 | 58 | int j; |
| 59 | + int n = entry->nr_servers; | |
| 59 | 60 | |
| 60 | 61 | tmp = ntohl(uvldb->serverFlags[i]); |
| 61 | 62 | if (tmp & AFS_VLSF_DONTUSE || |
| 62 | 63 | (new_only && !(tmp & AFS_VLSF_NEWREPSITE))) |
| 63 | 64 | continue; |
| 64 | 65 | if (tmp & AFS_VLSF_RWVOL) { |
| 65 | − entry->fs_mask[i] |= AFS_VOL_VTM_RW; | |
| 66 | + entry->fs_mask[n] |= AFS_VOL_VTM_RW; | |
| 66 | 67 | if (vlflags & AFS_VLF_BACKEXISTS) |
| 67 | − entry->fs_mask[i] |= AFS_VOL_VTM_BAK; | |
| 68 | + entry->fs_mask[n] |= AFS_VOL_VTM_BAK; | |
| 68 | 69 | } |
| 69 | 70 | if (tmp & AFS_VLSF_ROVOL) |
| 70 | − entry->fs_mask[i] |= AFS_VOL_VTM_RO; | |
| 71 | − if (!entry->fs_mask[i]) | |
| 71 | + entry->fs_mask[n] |= AFS_VOL_VTM_RO; | |
| 72 | + if (!entry->fs_mask[n]) | |
| 72 | 73 | continue; |
| 73 | 74 | |
| 74 | 75 | xdr = &uvldb->serverNumber[i]; |
| 75 | − uuid = (struct afs_uuid *)&entry->fs_server[i]; | |
| 76 | + uuid = (struct afs_uuid *)&entry->fs_server[n]; | |
| 76 | 77 | uuid->time_low = xdr->time_low; |
| 77 | 78 | uuid->time_mid = htons(ntohl(xdr->time_mid)); |
| 78 | 79 | uuid->time_hi_and_version = htons(ntohl(xdr->time_hi_and_version)); |
| @@ -345,24 +345,15 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 344 unmodified lines | ||
| 345 | 345 | struct bio *bio; |
| 346 | 346 | bool is_poll = (iocb->ki_flags & IOCB_HIPRI) != 0; |
| 347 | 347 | bool is_read = (iov_iter_rw(iter) == READ), is_sync; |
| 348 | − bool nowait = (iocb->ki_flags & IOCB_NOWAIT) != 0; | |
| 349 | 348 | loff_t pos = iocb->ki_pos; |
| 350 | 349 | blk_qc_t qc = BLK_QC_T_NONE; |
| 351 | − gfp_t gfp; | |
| 352 | − ssize_t ret; | |
| 350 | + int ret = 0; | |
| 353 | 351 | |
| 354 | 352 | if ((pos | iov_iter_alignment(iter)) & |
| 355 | 353 | (bdev_logical_block_size(bdev) - 1)) |
| 356 | 354 | return -EINVAL; |
| 357 | 355 | |
| 358 | − if (nowait) | |
| 359 | − gfp = GFP_NOWAIT; | |
| 360 | − else | |
| 361 | − gfp = GFP_KERNEL; | |
| 362 | − | |
| 363 | − bio = bio_alloc_bioset(gfp, nr_pages, &blkdev_dio_pool); | |
| 364 | − if (!bio) | |
| 365 | − return -EAGAIN; | |
| 356 | + bio = bio_alloc_bioset(GFP_KERNEL, nr_pages, &blkdev_dio_pool); | |
| 366 | 357 | |
| 367 | 358 | dio = container_of(bio, struct blkdev_dio, bio); |
| 368 | 359 | dio->is_sync = is_sync = is_sync_kiocb(iocb); |
| @@ -384,10 +375,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 15 unmodified lines | ||
| 384 | 375 | if (!is_poll) |
| 385 | 376 | blk_start_plug(&plug); |
| 386 | 377 | |
| 387 | − ret = 0; | |
| 388 | 378 | for (;;) { |
| 389 | − int err; | |
| 390 | − | |
| 391 | 379 | bio_set_dev(bio, bdev); |
| 392 | 380 | bio->bi_iter.bi_sector = pos >> 9; |
| 393 | 381 | bio->bi_write_hint = iocb->ki_hint; |
| @@ -395,10 +383,8 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 1 unmodified line | ||
| 395 | 383 | bio->bi_end_io = blkdev_bio_end_io; |
| 396 | 384 | bio->bi_ioprio = iocb->ki_ioprio; |
| 397 | 385 | |
| 398 | − err = bio_iov_iter_get_pages(bio, iter); | |
| 399 | − if (unlikely(err)) { | |
| 400 | − if (!ret) | |
| 401 | − ret = err; | |
| 386 | + ret = bio_iov_iter_get_pages(bio, iter); | |
| 387 | + if (unlikely(ret)) { | |
| 402 | 388 | bio->bi_status = BLK_STS_IOERR; |
| 403 | 389 | bio_endio(bio); |
| 404 | 390 | break; |
| @@ -413,14 +399,6 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 8 unmodified lines | ||
| 413 | 399 | task_io_account_write(bio->bi_iter.bi_size); |
| 414 | 400 | } |
| 415 | 401 | |
| 416 | − /* | |
| 417 | − * Tell underlying layer to not block for resource shortage. | |
| 418 | − * And if we would have blocked, return error inline instead | |
| 419 | − * of through the bio->bi_end_io() callback. | |
| 420 | − */ | |
| 421 | − if (nowait) | |
| 422 | − bio->bi_opf |= (REQ_NOWAIT | REQ_NOWAIT_INLINE); | |
| 423 | − | |
| 424 | 402 | dio->size += bio->bi_iter.bi_size; |
| 425 | 403 | pos += bio->bi_iter.bi_size; |
| 426 | 404 | |
| @@ -434,12 +412,6 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 7 unmodified lines | ||
| 434 | 412 | } |
| 435 | 413 | |
| 436 | 414 | qc = submit_bio(bio); |
| 437 | − if (qc == BLK_QC_T_EAGAIN) { | |
| 438 | − if (!ret) | |
| 439 | − ret = -EAGAIN; | |
| 440 | − goto error; | |
| 441 | − } | |
| 442 | − ret = dio->size; | |
| 443 | 415 | |
| 444 | 416 | if (polled) |
| 445 | 417 | WRITE_ONCE(iocb->ki_cookie, qc); |
| @@ -460,20 +432,8 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 14 unmodified lines | ||
| 460 | 432 | atomic_inc(&dio->ref); |
| 461 | 433 | } |
| 462 | 434 | |
| 463 | − qc = submit_bio(bio); | |
| 464 | − if (qc == BLK_QC_T_EAGAIN) { | |
| 465 | − if (!ret) | |
| 466 | − ret = -EAGAIN; | |
| 467 | − goto error; | |
| 468 | − } | |
| 469 | − ret = dio->size; | |
| 470 | − | |
| 471 | − bio = bio_alloc(gfp, nr_pages); | |
| 472 | − if (!bio) { | |
| 473 | − if (!ret) | |
| 474 | − ret = -EAGAIN; | |
| 475 | − goto error; | |
| 476 | − } | |
| 435 | + submit_bio(bio); | |
| 436 | + bio = bio_alloc(GFP_KERNEL, nr_pages); | |
| 477 | 437 | } |
| 478 | 438 | |
| 479 | 439 | if (!is_poll) |
| @@ -493,16 +453,13 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages) · 13 unmodified lines | ||
| 493 | 453 | } |
| 494 | 454 | __set_current_state(TASK_RUNNING); |
| 495 | 455 | |
| 496 | −out: | |
| 497 | 456 | if (!ret) |
| 498 | 457 | ret = blk_status_to_errno(dio->bio.bi_status); |
| 458 | + if (likely(!ret)) | |
| 459 | + ret = dio->size; | |
| 499 | 460 | |
| 500 | 461 | bio_put(&dio->bio); |
| 501 | 462 | return ret; |
| 502 | −error: | |
| 503 | − if (!is_poll) | |
| 504 | − blk_finish_plug(&plug); | |
| 505 | − goto out; | |
| 506 | 463 | } |
| 507 | 464 | |
| 508 | 465 | static ssize_t |
| @@ -1754,7 +1711,10 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) · 1245 unmodified lines | ||
| 1754 | 1711 | |
| 1755 | 1712 | /* finish claiming */ |
| 1756 | 1713 | mutex_lock(&bdev->bd_mutex); |
| 1757 | − bd_finish_claiming(bdev, whole, holder); | |
| 1714 | + if (!res) | |
| 1715 | + bd_finish_claiming(bdev, whole, holder); | |
| 1716 | + else | |
| 1717 | + bd_abort_claiming(bdev, whole, holder); | |
| 1758 | 1718 | /* |
| 1759 | 1719 | * Block event polling for write claims if requested. Any |
| 1760 | 1720 | * write holder makes the write_holder state stick until |
| @@ -401,7 +401,6 @@ struct btrfs_dev_replace { · 400 unmodified lines | ||
| 401 | 401 | struct raid_kobject { |
| 402 | 402 | u64 flags; |
| 403 | 403 | struct kobject kobj; |
| 404 | − struct list_head list; | |
| 405 | 404 | }; |
| 406 | 405 | |
| 407 | 406 | /* |
| @@ -915,8 +914,6 @@ struct btrfs_fs_info { · 507 unmodified lines | ||
| 915 | 914 | u32 thread_pool_size; |
| 916 | 915 | |
| 917 | 916 | struct kobject *space_info_kobj; |
| 918 | − struct list_head pending_raid_kobjs; | |
| 919 | − spinlock_t pending_raid_kobjs_lock; /* uncontended */ | |
| 920 | 917 | |
| 921 | 918 | u64 total_pinned; |
| 922 | 919 | |
| @@ -2698,7 +2695,6 @@ int btrfs_can_relocate(struct btrfs_fs_info *fs_info, u64 bytenr); · 1775 unmodified lines | ||
| 2698 | 2695 | int btrfs_make_block_group(struct btrfs_trans_handle *trans, |
| 2699 | 2696 | u64 bytes_used, u64 type, u64 chunk_offset, |
| 2700 | 2697 | u64 size); |
| 2701 | −void btrfs_add_raid_kobjects(struct btrfs_fs_info *fs_info); | |
| 2702 | 2698 | struct btrfs_trans_handle *btrfs_start_trans_remove_block_group( |
| 2703 | 2699 | struct btrfs_fs_info *fs_info, |
| 2704 | 2700 | const u64 chunk_offset); |
| @@ -2683,8 +2683,6 @@ int open_ctree(struct super_block *sb, · 2682 unmodified lines | ||
| 2683 | 2683 | INIT_LIST_HEAD(&fs_info->delayed_iputs); |
| 2684 | 2684 | INIT_LIST_HEAD(&fs_info->delalloc_roots); |
| 2685 | 2685 | INIT_LIST_HEAD(&fs_info->caching_block_groups); |
| 2686 | − INIT_LIST_HEAD(&fs_info->pending_raid_kobjs); | |
| 2687 | − spin_lock_init(&fs_info->pending_raid_kobjs_lock); | |
| 2688 | 2686 | spin_lock_init(&fs_info->delalloc_root_lock); |
| 2689 | 2687 | spin_lock_init(&fs_info->trans_lock); |
| 2690 | 2688 | spin_lock_init(&fs_info->fs_roots_radix_lock); |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/sched.h> |
| 7 | +#include <linux/sched/mm.h> | |
| 7 | 8 | #include <linux/sched/signal.h> |
| 8 | 9 | #include <linux/pagemap.h> |
| 9 | 10 | #include <linux/writeback.h> |
| @@ -7888,33 +7889,6 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) · 7878 unmodified lines | ||
| 7888 | 7889 | return 0; |
| 7889 | 7890 | } |
| 7890 | 7891 | |
| 7891 | −/* link_block_group will queue up kobjects to add when we're reclaim-safe */ | |
| 7892 | −void btrfs_add_raid_kobjects(struct btrfs_fs_info *fs_info) | |
| 7893 | −{ | |
| 7894 | − struct btrfs_space_info *space_info; | |
| 7895 | − struct raid_kobject *rkobj; | |
| 7896 | − LIST_HEAD(list); | |
| 7897 | − int ret = 0; | |
| 7898 | − | |
| 7899 | − spin_lock(&fs_info->pending_raid_kobjs_lock); | |
| 7900 | − list_splice_init(&fs_info->pending_raid_kobjs, &list); | |
| 7901 | − spin_unlock(&fs_info->pending_raid_kobjs_lock); | |
| 7902 | − | |
| 7903 | − list_for_each_entry(rkobj, &list, list) { | |
| 7904 | − space_info = btrfs_find_space_info(fs_info, rkobj->flags); | |
| 7905 | − | |
| 7906 | − ret = kobject_add(&rkobj->kobj, &space_info->kobj, | |
| 7907 | − "%s", btrfs_bg_type_to_raid_name(rkobj->flags)); | |
| 7908 | − if (ret) { | |
| 7909 | − kobject_put(&rkobj->kobj); | |
| 7910 | − break; | |
| 7911 | − } | |
| 7912 | − } | |
| 7913 | − if (ret) | |
| 7914 | − btrfs_warn(fs_info, | |
| 7915 | − "failed to add kobject for block cache, ignoring"); | |
| 7916 | −} | |
| 7917 | − | |
| 7918 | 7892 | static void link_block_group(struct btrfs_block_group_cache *cache) |
| 7919 | 7893 | { |
| 7920 | 7894 | struct btrfs_space_info *space_info = cache->space_info; |
| @@ -7929,18 +7903,36 @@ static void link_block_group(struct btrfs_block_group_cache *cache) · 8 unmodified lines | ||
| 7929 | 7903 | up_write(&space_info->groups_sem); |
| 7930 | 7904 | |
| 7931 | 7905 | if (first) { |
| 7932 | − struct raid_kobject *rkobj = kzalloc(sizeof(*rkobj), GFP_NOFS); | |
| 7906 | + struct raid_kobject *rkobj; | |
| 7907 | + unsigned int nofs_flag; | |
| 7908 | + int ret; | |
| 7909 | + | |
| 7910 | + /* | |
| 7911 | + * Setup a NOFS context because kobject_add(), deep in its call | |
| 7912 | + * chain, does GFP_KERNEL allocations, and we are often called | |
| 7913 | + * in a context where if reclaim is triggered we can deadlock | |
| 7914 | + * (we are either holding a transaction handle or some lock | |
| 7915 | + * required for a transaction commit). | |
| 7916 | + */ | |
| 7917 | + nofs_flag = memalloc_nofs_save(); | |
| 7918 | + rkobj = kzalloc(sizeof(*rkobj), GFP_KERNEL); | |
| 7933 | 7919 | if (!rkobj) { |
| 7920 | + memalloc_nofs_restore(nofs_flag); | |
| 7934 | 7921 | btrfs_warn(cache->fs_info, |
| 7935 | 7922 | "couldn't alloc memory for raid level kobject"); |
| 7936 | 7923 | return; |
| 7937 | 7924 | } |
| 7938 | 7925 | rkobj->flags = cache->flags; |
| 7939 | 7926 | kobject_init(&rkobj->kobj, &btrfs_raid_ktype); |
| 7940 | − | |
| 7941 | − spin_lock(&fs_info->pending_raid_kobjs_lock); | |
| 7942 | − list_add_tail(&rkobj->list, &fs_info->pending_raid_kobjs); | |
| 7943 | − spin_unlock(&fs_info->pending_raid_kobjs_lock); | |
| 7927 | + ret = kobject_add(&rkobj->kobj, &space_info->kobj, "%s", | |
| 7928 | + btrfs_bg_type_to_raid_name(rkobj->flags)); | |
| 7929 | + memalloc_nofs_restore(nofs_flag); | |
| 7930 | + if (ret) { | |
| 7931 | + kobject_put(&rkobj->kobj); | |
| 7932 | + btrfs_warn(fs_info, | |
| 7933 | + "failed to add kobject for block cache, ignoring"); | |
| 7934 | + return; | |
| 7935 | + } | |
| 7944 | 7936 | space_info->block_group_kobjs[index] = &rkobj->kobj; |
| 7945 | 7937 | } |
| 7946 | 7938 | } |
| @@ -8206,7 +8198,6 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) · 259 unmodified lines | ||
| 8206 | 8198 | inc_block_group_ro(cache, 1); |
| 8207 | 8199 | } |
| 8208 | 8200 | |
| 8209 | − btrfs_add_raid_kobjects(info); | |
| 8210 | 8201 | btrfs_init_global_block_rsv(info); |
| 8211 | 8202 | ret = check_chunk_block_group_mappings(info); |
| 8212 | 8203 | error: |
| @@ -8975,6 +8966,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) · 762 unmodified lines | ||
| 8975 | 8966 | struct btrfs_device *device; |
| 8976 | 8967 | struct list_head *devices; |
| 8977 | 8968 | u64 group_trimmed; |
| 8969 | + u64 range_end = U64_MAX; | |
| 8978 | 8970 | u64 start; |
| 8979 | 8971 | u64 end; |
| 8980 | 8972 | u64 trimmed = 0; |
| @@ -8984,16 +8976,23 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) · 3 unmodified lines | ||
| 8984 | 8976 | int dev_ret = 0; |
| 8985 | 8977 | int ret = 0; |
| 8986 | 8978 | |
| 8979 | + /* | |
| 8980 | + * Check range overflow if range->len is set. | |
| 8981 | + * The default range->len is U64_MAX. | |
| 8982 | + */ | |
| 8983 | + if (range->len != U64_MAX && | |
| 8984 | + check_add_overflow(range->start, range->len, &range_end)) | |
| 8985 | + return -EINVAL; | |
| 8986 | + | |
| 8987 | 8987 | cache = btrfs_lookup_first_block_group(fs_info, range->start); |
| 8988 | 8988 | for (; cache; cache = next_block_group(cache)) { |
| 8989 | − if (cache->key.objectid >= (range->start + range->len)) { | |
| 8989 | + if (cache->key.objectid >= range_end) { | |
| 8990 | 8990 | btrfs_put_block_group(cache); |
| 8991 | 8991 | break; |
| 8992 | 8992 | } |
| 8993 | 8993 | |
| 8994 | 8994 | start = max(range->start, cache->key.objectid); |
| 8995 | − end = min(range->start + range->len, | |
| 8996 | − cache->key.objectid + cache->key.offset); | |
| 8995 | + end = min(range_end, cache->key.objectid + cache->key.offset); | |
| 8997 | 8996 | |
| 8998 | 8997 | if (end - start >= range->minlen) { |
| 8999 | 8998 | if (!block_group_cache_done(cache)) { |
| @@ -3087,16 +3087,6 @@ static int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset) · 3086 unmodified lines | ||
| 3087 | 3087 | if (ret) |
| 3088 | 3088 | return ret; |
| 3089 | 3089 | |
| 3090 | − /* | |
| 3091 | − * We add the kobjects here (and after forcing data chunk creation) | |
| 3092 | − * since relocation is the only place we'll create chunks of a new | |
| 3093 | − * type at runtime. The only place where we'll remove the last | |
| 3094 | − * chunk of a type is the call immediately below this one. Even | |
| 3095 | − * so, we're protected against races with the cleaner thread since | |
| 3096 | − * we're covered by the delete_unused_bgs_mutex. | |
| 3097 | − */ | |
| 3098 | − btrfs_add_raid_kobjects(fs_info); | |
| 3099 | − | |
| 3100 | 3090 | trans = btrfs_start_trans_remove_block_group(root->fs_info, |
| 3101 | 3091 | chunk_offset); |
| 3102 | 3092 | if (IS_ERR(trans)) { |
| @@ -3223,9 +3213,6 @@ static int btrfs_may_alloc_data_chunk(struct btrfs_fs_info *fs_info, · 120 unmodified lines | ||
| 3223 | 3213 | btrfs_end_transaction(trans); |
| 3224 | 3214 | if (ret < 0) |
| 3225 | 3215 | return ret; |
| 3226 | − | |
| 3227 | − btrfs_add_raid_kobjects(fs_info); | |
| 3228 | − | |
| 3229 | 3216 | return 1; |
| 3230 | 3217 | } |
| 3231 | 3218 | } |
| @@ -1113,6 +1113,7 @@ cifs_demultiplex_thread(void *p) · 1112 unmodified lines | ||
| 1113 | 1113 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv); |
| 1114 | 1114 | |
| 1115 | 1115 | set_freezable(); |
| 1116 | + allow_signal(SIGKILL); | |
| 1116 | 1117 | while (server->tcpStatus != CifsExiting) { |
| 1117 | 1118 | if (try_to_freeze()) |
| 1118 | 1119 | continue; |
| @@ -3489,7 +3489,15 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len, · 3488 unmodified lines | ||
| 3489 | 3489 | static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf, |
| 3490 | 3490 | unsigned int buflen) |
| 3491 | 3491 | { |
| 3492 | − sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); | |
| 3492 | + void *addr; | |
| 3493 | + /* | |
| 3494 | + * VMAP_STACK (at least) puts stack into the vmalloc address space | |
| 3495 | + */ | |
| 3496 | + if (is_vmalloc_addr(buf)) | |
| 3497 | + addr = vmalloc_to_page(buf); | |
| 3498 | + else | |
| 3499 | + addr = virt_to_page(buf); | |
| 3500 | + sg_set_page(sg, addr, buflen, offset_in_page(buf)); | |
| 3493 | 3501 | } |
| 3494 | 3502 | |
| 3495 | 3503 | /* Assumes the first rqst has a transform header as the first iov. |
| @@ -4070,7 +4078,6 @@ receive_encrypted_standard(struct TCP_Server_Info *server, · 574 unmodified lines | ||
| 4070 | 4078 | { |
| 4071 | 4079 | int ret, length; |
| 4072 | 4080 | char *buf = server->smallbuf; |
| 4073 | − char *tmpbuf; | |
| 4074 | 4081 | struct smb2_sync_hdr *shdr; |
| 4075 | 4082 | unsigned int pdu_length = server->pdu_size; |
| 4076 | 4083 | unsigned int buf_size; |
| @@ -4100,18 +4107,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server, · 23 unmodified lines | ||
| 4100 | 4107 | return length; |
| 4101 | 4108 | |
| 4102 | 4109 | next_is_large = server->large_buf; |
| 4103 | − one_more: | |
| 4110 | +one_more: | |
| 4104 | 4111 | shdr = (struct smb2_sync_hdr *)buf; |
| 4105 | 4112 | if (shdr->NextCommand) { |
| 4106 | − if (next_is_large) { | |
| 4107 | − tmpbuf = server->bigbuf; | |
| 4113 | + if (next_is_large) | |
| 4108 | 4114 | next_buffer = (char *)cifs_buf_get(); |
| 4109 | − } else { | |
| 4110 | − tmpbuf = server->smallbuf; | |
| 4115 | + else | |
| 4111 | 4116 | next_buffer = (char *)cifs_small_buf_get(); |
| 4112 | − } | |
| 4113 | 4117 | memcpy(next_buffer, |
| 4114 | − tmpbuf + le32_to_cpu(shdr->NextCommand), | |
| 4118 | + buf + le32_to_cpu(shdr->NextCommand), | |
| 4115 | 4119 | pdu_length - le32_to_cpu(shdr->NextCommand)); |
| 4116 | 4120 | } |
| 4117 | 4121 | |
| @@ -4140,12 +4144,21 @@ receive_encrypted_standard(struct TCP_Server_Info *server, · 22 unmodified lines | ||
| 4140 | 4144 | pdu_length -= le32_to_cpu(shdr->NextCommand); |
| 4141 | 4145 | server->large_buf = next_is_large; |
| 4142 | 4146 | if (next_is_large) |
| 4143 | − server->bigbuf = next_buffer; | |
| 4147 | + server->bigbuf = buf = next_buffer; | |
| 4144 | 4148 | else |
| 4145 | − server->smallbuf = next_buffer; | |
| 4146 | − | |
| 4147 | − buf += le32_to_cpu(shdr->NextCommand); | |
| 4149 | + server->smallbuf = buf = next_buffer; | |
| 4148 | 4150 | goto one_more; |
| 4151 | + } else if (ret != 0) { | |
| 4152 | + /* | |
| 4153 | + * ret != 0 here means that we didn't get to handle_mid() thus | |
| 4154 | + * server->smallbuf and server->bigbuf are still valid. We need | |
| 4155 | + * to free next_buffer because it is not going to be used | |
| 4156 | + * anywhere. | |
| 4157 | + */ | |
| 4158 | + if (next_is_large) | |
| 4159 | + free_rsp_buf(CIFS_LARGE_BUFFER, next_buffer); | |
| 4160 | + else | |
| 4161 | + free_rsp_buf(CIFS_SMALL_BUFFER, next_buffer); | |
| 4149 | 4162 | } |
| 4150 | 4163 | |
| 4151 | 4164 | return ret; |
| @@ -252,7 +252,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) · 251 unmodified lines | ||
| 252 | 252 | if (tcon == NULL) |
| 253 | 253 | return 0; |
| 254 | 254 | |
| 255 | − if (smb2_command == SMB2_TREE_CONNECT) | |
| 255 | + if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL) | |
| 256 | 256 | return 0; |
| 257 | 257 | |
| 258 | 258 | if (tcon->tidStatus == CifsExiting) { |
| @@ -1196,7 +1196,12 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data) · 937 unmodified lines | ||
| 1196 | 1196 | else |
| 1197 | 1197 | req->SecurityMode = 0; |
| 1198 | 1198 | |
| 1199 | +#ifdef CONFIG_CIFS_DFS_UPCALL | |
| 1200 | + req->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS); | |
| 1201 | +#else | |
| 1199 | 1202 | req->Capabilities = 0; |
| 1203 | +#endif /* DFS_UPCALL */ | |
| 1204 | + | |
| 1200 | 1205 | req->Channel = 0; /* MBZ */ |
| 1201 | 1206 | |
| 1202 | 1207 | sess_data->iov[0].iov_base = (char *)req; |
| @@ -600,7 +600,7 @@ struct page *dax_layout_busy_page(struct address_space *mapping) · 599 unmodified lines | ||
| 600 | 600 | * guaranteed to either see new references or prevent new |
| 601 | 601 | * references from being established. |
| 602 | 602 | */ |
| 603 | − unmap_mapping_range(mapping, 0, 0, 1); | |
| 603 | + unmap_mapping_range(mapping, 0, 0, 0); | |
| 604 | 604 | |
| 605 | 605 | xas_lock_irq(&xas); |
| 606 | 606 | xas_for_each(&xas, entry, ULONG_MAX) { |
| @@ -390,6 +390,19 @@ static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h) · 389 unmodified lines | ||
| 390 | 390 | return mp->mp_aheight - x - 1; |
| 391 | 391 | } |
| 392 | 392 | |
| 393 | +static sector_t metapath_to_block(struct gfs2_sbd *sdp, struct metapath *mp) | |
| 394 | +{ | |
| 395 | + sector_t factor = 1, block = 0; | |
| 396 | + int hgt; | |
| 397 | + | |
| 398 | + for (hgt = mp->mp_fheight - 1; hgt >= 0; hgt--) { | |
| 399 | + if (hgt < mp->mp_aheight) | |
| 400 | + block += mp->mp_list[hgt] * factor; | |
| 401 | + factor *= sdp->sd_inptrs; | |
| 402 | + } | |
| 403 | + return block; | |
| 404 | +} | |
| 405 | + | |
| 393 | 406 | static void release_metapath(struct metapath *mp) |
| 394 | 407 | { |
| 395 | 408 | int i; |
| @@ -430,60 +443,84 @@ static inline unsigned int gfs2_extent_length(struct buffer_head *bh, __be64 *pt · 34 unmodified lines | ||
| 430 | 443 | return ptr - first; |
| 431 | 444 | } |
| 432 | 445 | |
| 433 | −typedef const __be64 *(*gfs2_metadata_walker)( | |
| 434 | − struct metapath *mp, | |
| 435 | − const __be64 *start, const __be64 *end, | |
| 436 | − u64 factor, void *data); | |
| 446 | +enum walker_status { WALK_STOP, WALK_FOLLOW, WALK_CONTINUE }; | |
| 437 | 447 | |
| 438 | −#define WALK_STOP ((__be64 *)0) | |
| 439 | −#define WALK_NEXT ((__be64 *)1) | |
| 448 | +/* | |
| 449 | + * gfs2_metadata_walker - walk an indirect block | |
| 450 | + * @mp: Metapath to indirect block | |
| 451 | + * @ptrs: Number of pointers to look at | |
| 452 | + * | |
| 453 | + * When returning WALK_FOLLOW, the walker must update @mp to point at the right | |
| 454 | + * indirect block to follow. | |
| 455 | + */ | |
| 456 | +typedef enum walker_status (*gfs2_metadata_walker)(struct metapath *mp, | |
| 457 | + unsigned int ptrs); | |
| 440 | 458 | |
| 441 | −static int gfs2_walk_metadata(struct inode *inode, sector_t lblock, | |
| 442 | − u64 len, struct metapath *mp, gfs2_metadata_walker walker, | |
| 443 | − void *data) | |
| 459 | +/* | |
| 460 | + * gfs2_walk_metadata - walk a tree of indirect blocks | |
| 461 | + * @inode: The inode | |
| 462 | + * @mp: Starting point of walk | |
| 463 | + * @max_len: Maximum number of blocks to walk | |
| 464 | + * @walker: Called during the walk | |
| 465 | + * | |
| 466 | + * Returns 1 if the walk was stopped by @walker, 0 if we went past @max_len or | |
| 467 | + * past the end of metadata, and a negative error code otherwise. | |
| 468 | + */ | |
| 469 | + | |
| 470 | +static int gfs2_walk_metadata(struct inode *inode, struct metapath *mp, | |
| 471 | + u64 max_len, gfs2_metadata_walker walker) | |
| 444 | 472 | { |
| 445 | − struct metapath clone; | |
| 446 | 473 | struct gfs2_inode *ip = GFS2_I(inode); |
| 447 | 474 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
| 448 | − const __be64 *start, *end, *ptr; | |
| 449 | 475 | u64 factor = 1; |
| 450 | 476 | unsigned int hgt; |
| 451 | − int ret = 0; | |
| 477 | + int ret; | |
| 452 | 478 | |
| 453 | − for (hgt = ip->i_height - 1; hgt >= mp->mp_aheight; hgt--) | |
| 479 | + /* | |
| 480 | + * The walk starts in the lowest allocated indirect block, which may be | |
| 481 | + * before the position indicated by @mp. Adjust @max_len accordingly | |
| 482 | + * to avoid a short walk. | |
| 483 | + */ | |
| 484 | + for (hgt = mp->mp_fheight - 1; hgt >= mp->mp_aheight; hgt--) { | |
| 485 | + max_len += mp->mp_list[hgt] * factor; | |
| 486 | + mp->mp_list[hgt] = 0; | |
| 454 | 487 | factor *= sdp->sd_inptrs; |
| 488 | + } | |
| 455 | 489 | |
| 456 | 490 | for (;;) { |
| 457 | − u64 step; | |
| 491 | + u16 start = mp->mp_list[hgt]; | |
| 492 | + enum walker_status status; | |
| 493 | + unsigned int ptrs; | |
| 494 | + u64 len; | |
| 458 | 495 | |
| 459 | 496 | /* Walk indirect block. */ |
| 460 | − start = metapointer(hgt, mp); | |
| 461 | − end = metaend(hgt, mp); | |
| 462 | − | |
| 463 | − step = (end - start) * factor; | |
| 464 | − if (step > len) | |
| 465 | − end = start + DIV_ROUND_UP_ULL(len, factor); | |
| 466 | − | |
| 467 | − ptr = walker(mp, start, end, factor, data); | |
| 468 | − if (ptr == WALK_STOP) | |
| 497 | + ptrs = (hgt >= 1 ? sdp->sd_inptrs : sdp->sd_diptrs) - start; | |
| 498 | + len = ptrs * factor; | |
| 499 | + if (len > max_len) | |
| 500 | + ptrs = DIV_ROUND_UP_ULL(max_len, factor); | |
| 501 | + status = walker(mp, ptrs); | |
| 502 | + switch (status) { | |
| 503 | + case WALK_STOP: | |
| 504 | + return 1; | |
| 505 | + case WALK_FOLLOW: | |
| 506 | + BUG_ON(mp->mp_aheight == mp->mp_fheight); | |
| 507 | + ptrs = mp->mp_list[hgt] - start; | |
| 508 | + len = ptrs * factor; | |
| 469 | 509 | break; |
| 470 | − if (step >= len) | |
| 510 | + case WALK_CONTINUE: | |
| 471 | 511 | break; |
| 472 | − len -= step; | |
| 473 | − if (ptr != WALK_NEXT) { | |
| 474 | − BUG_ON(!*ptr); | |
| 475 | − mp->mp_list[hgt] += ptr - start; | |
| 476 | − goto fill_up_metapath; | |
| 477 | 512 | } |
| 513 | + if (len >= max_len) | |
| 514 | + break; | |
| 515 | + max_len -= len; | |
| 516 | + if (status == WALK_FOLLOW) | |
| 517 | + goto fill_up_metapath; | |
| 478 | 518 | |
| 479 | 519 | lower_metapath: |
| 480 | 520 | /* Decrease height of metapath. */ |
| 481 | − if (mp != &clone) { | |
| 482 | − clone_metapath(&clone, mp); | |
| 483 | − mp = &clone; | |
| 484 | − } | |
| 485 | 521 | brelse(mp->mp_bh[hgt]); |
| 486 | 522 | mp->mp_bh[hgt] = NULL; |
| 523 | + mp->mp_list[hgt] = 0; | |
| 487 | 524 | if (!hgt) |
| 488 | 525 | break; |
| 489 | 526 | hgt--; |
| @@ -491,10 +528,7 @@ lower_metapath: · 1 unmodified line | ||
| 491 | 528 | |
| 492 | 529 | /* Advance in metadata tree. */ |
| 493 | 530 | (mp->mp_list[hgt])++; |
| 494 | − start = metapointer(hgt, mp); | |
| 495 | − end = metaend(hgt, mp); | |
| 496 | − if (start >= end) { | |
| 497 | − mp->mp_list[hgt] = 0; | |
| 531 | + if (mp->mp_list[hgt] >= sdp->sd_inptrs) { | |
| 498 | 532 | if (!hgt) |
| 499 | 533 | break; |
| 500 | 534 | goto lower_metapath; |
| @@ -502,44 +536,36 @@ lower_metapath: · 1 unmodified line | ||
| 502 | 536 | |
| 503 | 537 | fill_up_metapath: |
| 504 | 538 | /* Increase height of metapath. */ |
| 505 | − if (mp != &clone) { | |
| 506 | − clone_metapath(&clone, mp); | |
| 507 | − mp = &clone; | |
| 508 | − } | |
| 509 | 539 | ret = fillup_metapath(ip, mp, ip->i_height - 1); |
| 510 | 540 | if (ret < 0) |
| 511 | − break; | |
| 541 | + return ret; | |
| 512 | 542 | hgt += ret; |
| 513 | 543 | for (; ret; ret--) |
| 514 | 544 | do_div(factor, sdp->sd_inptrs); |
| 515 | 545 | mp->mp_aheight = hgt + 1; |
| 516 | 546 | } |
| 517 | − if (mp == &clone) | |
| 518 | − release_metapath(mp); | |
| 519 | − return ret; | |
| 547 | + return 0; | |
| 520 | 548 | } |
| 521 | 549 | |
| 522 | −struct gfs2_hole_walker_args { | |
| 523 | − u64 blocks; | |
| 524 | −}; | |
| 525 | − | |
| 526 | −static const __be64 *gfs2_hole_walker(struct metapath *mp, | |
| 527 | − const __be64 *start, const __be64 *end, | |
| 528 | − u64 factor, void *data) | |
| 550 | +static enum walker_status gfs2_hole_walker(struct metapath *mp, | |
| 551 | + unsigned int ptrs) | |
| 529 | 552 | { |
| 530 | − struct gfs2_hole_walker_args *args = data; | |
| 531 | − const __be64 *ptr; | |
| 553 | + const __be64 *start, *ptr, *end; | |
| 554 | + unsigned int hgt; | |
| 555 | + | |
| 556 | + hgt = mp->mp_aheight - 1; | |
| 557 | + start = metapointer(hgt, mp); | |
| 558 | + end = start + ptrs; | |
| 532 | 559 | |
| 533 | 560 | for (ptr = start; ptr < end; ptr++) { |
| 534 | 561 | if (*ptr) { |
| 535 | − args->blocks += (ptr - start) * factor; | |
| 562 | + mp->mp_list[hgt] += ptr - start; | |
| 536 | 563 | if (mp->mp_aheight == mp->mp_fheight) |
| 537 | 564 | return WALK_STOP; |
| 538 | − return ptr; /* increase height */ | |
| 565 | + return WALK_FOLLOW; | |
| 539 | 566 | } |
| 540 | 567 | } |
| 541 | − args->blocks += (end - start) * factor; | |
| 542 | − return WALK_NEXT; | |
| 568 | + return WALK_CONTINUE; | |
| 543 | 569 | } |
| 544 | 570 | |
| 545 | 571 | /** |
| @@ -557,12 +583,24 @@ static const __be64 *gfs2_hole_walker(struct metapath *mp, · 11 unmodified lines | ||
| 557 | 583 | static int gfs2_hole_size(struct inode *inode, sector_t lblock, u64 len, |
| 558 | 584 | struct metapath *mp, struct iomap *iomap) |
| 559 | 585 | { |
| 560 | − struct gfs2_hole_walker_args args = { }; | |
| 561 | − int ret = 0; | |
| 586 | + struct metapath clone; | |
| 587 | + u64 hole_size; | |
| 588 | + int ret; | |
| 562 | 589 | |
| 563 | − ret = gfs2_walk_metadata(inode, lblock, len, mp, gfs2_hole_walker, &args); | |
| 564 | − if (!ret) | |
| 565 | − iomap->length = args.blocks << inode->i_blkbits; | |
| 590 | + clone_metapath(&clone, mp); | |
| 591 | + ret = gfs2_walk_metadata(inode, &clone, len, gfs2_hole_walker); | |
| 592 | + if (ret < 0) | |
| 593 | + goto out; | |
| 594 | + | |
| 595 | + if (ret == 1) | |
| 596 | + hole_size = metapath_to_block(GFS2_SB(inode), &clone) - lblock; | |
| 597 | + else | |
| 598 | + hole_size = len; | |
| 599 | + iomap->length = hole_size << inode->i_blkbits; | |
| 600 | + ret = 0; | |
| 601 | + | |
| 602 | +out: | |
| 603 | + release_metapath(&clone); | |
| 566 | 604 | return ret; |
| 567 | 605 | } |
| 568 | 606 | |
| @@ -1097,10 +1097,8 @@ static int io_import_fixed(struct io_ring_ctx *ctx, int rw, · 1096 unmodified lines | ||
| 1097 | 1097 | |
| 1098 | 1098 | iter->bvec = bvec + seg_skip; |
| 1099 | 1099 | iter->nr_segs -= seg_skip; |
| 1100 | − iter->count -= (seg_skip << PAGE_SHIFT); | |
| 1100 | + iter->count -= bvec->bv_len + offset; | |
| 1101 | 1101 | iter->iov_offset = offset & ~PAGE_MASK; |
| 1102 | − if (iter->iov_offset) | |
| 1103 | − iter->count -= iter->iov_offset; | |
| 1104 | 1102 | } |
| 1105 | 1103 | } |
| 1106 | 1104 | |
| @@ -2025,6 +2023,15 @@ static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 918 unmodified lines | ||
| 2025 | 2023 | { |
| 2026 | 2024 | int ret; |
| 2027 | 2025 | |
| 2026 | + ret = io_req_defer(ctx, req, s->sqe); | |
| 2027 | + if (ret) { | |
| 2028 | + if (ret != -EIOCBQUEUED) { | |
| 2029 | + io_free_req(req); | |
| 2030 | + io_cqring_add_event(ctx, s->sqe->user_data, ret); | |
| 2031 | + } | |
| 2032 | + return 0; | |
| 2033 | + } | |
| 2034 | + | |
| 2028 | 2035 | ret = __io_submit_sqe(ctx, req, s, true); |
| 2029 | 2036 | if (ret == -EAGAIN && !(req->flags & REQ_F_NOWAIT)) { |
| 2030 | 2037 | struct io_uring_sqe *sqe_copy; |
| @@ -2097,13 +2104,6 @@ err: · 66 unmodified lines | ||
| 2097 | 2104 | return; |
| 2098 | 2105 | } |
| 2099 | 2106 | |
| 2100 | − ret = io_req_defer(ctx, req, s->sqe); | |
| 2101 | − if (ret) { | |
| 2102 | − if (ret != -EIOCBQUEUED) | |
| 2103 | − goto err_req; | |
| 2104 | − return; | |
| 2105 | − } | |
| 2106 | − | |
| 2107 | 2107 | /* |
| 2108 | 2108 | * If we already have a head request, queue this one for async |
| 2109 | 2109 | * submittal once the head completes. If we don't have a head but |
| @@ -153,7 +153,7 @@ again: · 152 unmodified lines | ||
| 153 | 153 | /* Block nfs4_proc_unlck */ |
| 154 | 154 | mutex_lock(&sp->so_delegreturn_mutex); |
| 155 | 155 | seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); |
| 156 | − err = nfs4_open_delegation_recall(ctx, state, stateid, type); | |
| 156 | + err = nfs4_open_delegation_recall(ctx, state, stateid); | |
| 157 | 157 | if (!err) |
| 158 | 158 | err = nfs_delegation_claim_locks(state, stateid); |
| 159 | 159 | if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) |
| @@ -1046,6 +1046,22 @@ void nfs_test_expired_all_delegations(struct nfs_client *clp) · 886 unmodified lines | ||
| 1046 | 1046 | nfs4_schedule_state_manager(clp); |
| 1047 | 1047 | } |
| 1048 | 1048 | |
| 1049 | +static void | |
| 1050 | +nfs_delegation_test_free_expired(struct inode *inode, | |
| 1051 | + nfs4_stateid *stateid, | |
| 1052 | + const struct cred *cred) | |
| 1053 | +{ | |
| 1054 | + struct nfs_server *server = NFS_SERVER(inode); | |
| 1055 | + const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops; | |
| 1056 | + int status; | |
| 1057 | + | |
| 1058 | + if (!cred) | |
| 1059 | + return; | |
| 1060 | + status = ops->test_and_free_expired(server, stateid, cred); | |
| 1061 | + if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) | |
| 1062 | + nfs_remove_bad_delegation(inode, stateid); | |
| 1063 | +} | |
| 1064 | + | |
| 1049 | 1065 | /** |
| 1050 | 1066 | * nfs_reap_expired_delegations - reap expired delegations |
| 1051 | 1067 | * @clp: nfs_client to process |
| @@ -1057,7 +1073,6 @@ void nfs_test_expired_all_delegations(struct nfs_client *clp) · 5 unmodified lines | ||
| 1057 | 1073 | */ |
| 1058 | 1074 | void nfs_reap_expired_delegations(struct nfs_client *clp) |
| 1059 | 1075 | { |
| 1060 | − const struct nfs4_minor_version_ops *ops = clp->cl_mvops; | |
| 1061 | 1076 | struct nfs_delegation *delegation; |
| 1062 | 1077 | struct nfs_server *server; |
| 1063 | 1078 | struct inode *inode; |
| @@ -1088,11 +1103,7 @@ restart: · 24 unmodified lines | ||
| 1088 | 1103 | nfs4_stateid_copy(&stateid, &delegation->stateid); |
| 1089 | 1104 | clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags); |
| 1090 | 1105 | rcu_read_unlock(); |
| 1091 | − if (cred != NULL && | |
| 1092 | − ops->test_and_free_expired(server, &stateid, cred) < 0) { | |
| 1093 | − nfs_revoke_delegation(inode, &stateid); | |
| 1094 | − nfs_inode_find_state_and_recover(inode, &stateid); | |
| 1095 | − } | |
| 1106 | + nfs_delegation_test_free_expired(inode, &stateid, cred); | |
| 1096 | 1107 | put_cred(cred); |
| 1097 | 1108 | if (nfs4_server_rebooted(clp)) { |
| 1098 | 1109 | nfs_inode_mark_test_expired_delegation(server,inode); |
| @@ -63,7 +63,7 @@ void nfs_reap_expired_delegations(struct nfs_client *clp); · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | /* NFSv4 delegation-related procedures */ |
| 65 | 65 | int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync); |
| 66 | −int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid, fmode_t type); | |
| 66 | +int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); | |
| 67 | 67 | int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid); |
| 68 | 68 | bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, const struct cred **cred); |
| 69 | 69 | bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode); |
| @@ -114,6 +114,10 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int · 113 unmodified lines | ||
| 114 | 114 | struct rb_node **p, *parent; |
| 115 | 115 | int diff; |
| 116 | 116 | |
| 117 | + nfss->fscache_key = NULL; | |
| 118 | + nfss->fscache = NULL; | |
| 119 | + if (!(nfss->options & NFS_OPTION_FSCACHE)) | |
| 120 | + return; | |
| 117 | 121 | if (!uniq) { |
| 118 | 122 | uniq = ""; |
| 119 | 123 | ulen = 1; |
| @@ -226,10 +230,11 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) · 106 unmodified lines | ||
| 226 | 230 | void nfs_fscache_init_inode(struct inode *inode) |
| 227 | 231 | { |
| 228 | 232 | struct nfs_fscache_inode_auxdata auxdata; |
| 233 | + struct nfs_server *nfss = NFS_SERVER(inode); | |
| 229 | 234 | struct nfs_inode *nfsi = NFS_I(inode); |
| 230 | 235 | |
| 231 | 236 | nfsi->fscache = NULL; |
| 232 | − if (!S_ISREG(inode->i_mode)) | |
| 237 | + if (!(nfss->fscache && S_ISREG(inode->i_mode))) | |
| 233 | 238 | return; |
| 234 | 239 | |
| 235 | 240 | memset(&auxdata, 0, sizeof(auxdata)); |
| @@ -182,7 +182,7 @@ static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) · 181 unmodified lines | ||
| 182 | 182 | */ |
| 183 | 183 | static inline const char *nfs_server_fscache_state(struct nfs_server *server) |
| 184 | 184 | { |
| 185 | − if (server->fscache && (server->options & NFS_OPTION_FSCACHE)) | |
| 185 | + if (server->fscache) | |
| 186 | 186 | return "yes"; |
| 187 | 187 | return "no "; |
| 188 | 188 | } |
| @@ -465,7 +465,8 @@ static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, · 464 unmodified lines | ||
| 465 | 465 | |
| 466 | 466 | extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, const struct cred *, gfp_t); |
| 467 | 467 | extern void nfs4_put_state_owner(struct nfs4_state_owner *); |
| 468 | −extern void nfs4_purge_state_owners(struct nfs_server *); | |
| 468 | +extern void nfs4_purge_state_owners(struct nfs_server *, struct list_head *); | |
| 469 | +extern void nfs4_free_state_owners(struct list_head *head); | |
| 469 | 470 | extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *); |
| 470 | 471 | extern void nfs4_put_open_state(struct nfs4_state *); |
| 471 | 472 | extern void nfs4_close_state(struct nfs4_state *, fmode_t); |
| @@ -758,9 +758,12 @@ out: · 757 unmodified lines | ||
| 758 | 758 | |
| 759 | 759 | static void nfs4_destroy_server(struct nfs_server *server) |
| 760 | 760 | { |
| 761 | + LIST_HEAD(freeme); | |
| 762 | + | |
| 761 | 763 | nfs_server_return_all_delegations(server); |
| 762 | 764 | unset_pnfs_layoutdriver(server); |
| 763 | − nfs4_purge_state_owners(server); | |
| 765 | + nfs4_purge_state_owners(server, &freeme); | |
| 766 | + nfs4_free_state_owners(&freeme); | |
| 764 | 767 | } |
| 765 | 768 | |
| 766 | 769 | /* |
| @@ -1683,6 +1683,14 @@ static void nfs_state_set_open_stateid(struct nfs4_state *state, · 1682 unmodified lines | ||
| 1683 | 1683 | write_sequnlock(&state->seqlock); |
| 1684 | 1684 | } |
| 1685 | 1685 | |
| 1686 | +static void nfs_state_clear_open_state_flags(struct nfs4_state *state) | |
| 1687 | +{ | |
| 1688 | + clear_bit(NFS_O_RDWR_STATE, &state->flags); | |
| 1689 | + clear_bit(NFS_O_WRONLY_STATE, &state->flags); | |
| 1690 | + clear_bit(NFS_O_RDONLY_STATE, &state->flags); | |
| 1691 | + clear_bit(NFS_OPEN_STATE, &state->flags); | |
| 1692 | +} | |
| 1693 | + | |
| 1686 | 1694 | static void nfs_state_set_delegation(struct nfs4_state *state, |
| 1687 | 1695 | const nfs4_stateid *deleg_stateid, |
| 1688 | 1696 | fmode_t fmode) |
| @@ -1907,8 +1915,9 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data) · 218 unmodified lines | ||
| 1907 | 1915 | if (data->o_res.delegation_type != 0) |
| 1908 | 1916 | nfs4_opendata_check_deleg(data, state); |
| 1909 | 1917 | update: |
| 1910 | − update_open_stateid(state, &data->o_res.stateid, NULL, | |
| 1911 | − data->o_arg.fmode); | |
| 1918 | + if (!update_open_stateid(state, &data->o_res.stateid, | |
| 1919 | + NULL, data->o_arg.fmode)) | |
| 1920 | + return ERR_PTR(-EAGAIN); | |
| 1912 | 1921 | refcount_inc(&state->count); |
| 1913 | 1922 | |
| 1914 | 1923 | return state; |
| @@ -1973,8 +1982,11 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) · 58 unmodified lines | ||
| 1973 | 1982 | |
| 1974 | 1983 | if (data->o_res.delegation_type != 0) |
| 1975 | 1984 | nfs4_opendata_check_deleg(data, state); |
| 1976 | − update_open_stateid(state, &data->o_res.stateid, NULL, | |
| 1977 | − data->o_arg.fmode); | |
| 1985 | + if (!update_open_stateid(state, &data->o_res.stateid, | |
| 1986 | + NULL, data->o_arg.fmode)) { | |
| 1987 | + nfs4_put_open_state(state); | |
| 1988 | + state = ERR_PTR(-EAGAIN); | |
| 1989 | + } | |
| 1978 | 1990 | out: |
| 1979 | 1991 | nfs_release_seqid(data->o_arg.seqid); |
| 1980 | 1992 | return state; |
| @@ -2074,13 +2086,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state * · 93 unmodified lines | ||
| 2074 | 2086 | { |
| 2075 | 2087 | int ret; |
| 2076 | 2088 | |
| 2077 | − /* Don't trigger recovery in nfs_test_and_clear_all_open_stateid */ | |
| 2078 | − clear_bit(NFS_O_RDWR_STATE, &state->flags); | |
| 2079 | − clear_bit(NFS_O_WRONLY_STATE, &state->flags); | |
| 2080 | − clear_bit(NFS_O_RDONLY_STATE, &state->flags); | |
| 2081 | 2089 | /* memory barrier prior to reading state->n_* */ |
| 2082 | − clear_bit(NFS_DELEGATED_STATE, &state->flags); | |
| 2083 | − clear_bit(NFS_OPEN_STATE, &state->flags); | |
| 2084 | 2090 | smp_rmb(); |
| 2085 | 2091 | ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE); |
| 2086 | 2092 | if (ret != 0) |
| @@ -2156,6 +2162,8 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta · 69 unmodified lines | ||
| 2156 | 2162 | ctx = nfs4_state_find_open_context(state); |
| 2157 | 2163 | if (IS_ERR(ctx)) |
| 2158 | 2164 | return -EAGAIN; |
| 2165 | + clear_bit(NFS_DELEGATED_STATE, &state->flags); | |
| 2166 | + nfs_state_clear_open_state_flags(state); | |
| 2159 | 2167 | ret = nfs4_do_open_reclaim(ctx, state); |
| 2160 | 2168 | put_nfs_open_context(ctx); |
| 2161 | 2169 | return ret; |
| @@ -2171,18 +2179,17 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct · 9 unmodified lines | ||
| 2171 | 2179 | case -ENOENT: |
| 2172 | 2180 | case -EAGAIN: |
| 2173 | 2181 | case -ESTALE: |
| 2182 | + case -ETIMEDOUT: | |
| 2174 | 2183 | break; |
| 2175 | 2184 | case -NFS4ERR_BADSESSION: |
| 2176 | 2185 | case -NFS4ERR_BADSLOT: |
| 2177 | 2186 | case -NFS4ERR_BAD_HIGH_SLOT: |
| 2178 | 2187 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: |
| 2179 | 2188 | case -NFS4ERR_DEADSESSION: |
| 2180 | − set_bit(NFS_DELEGATED_STATE, &state->flags); | |
| 2181 | 2189 | nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); |
| 2182 | 2190 | return -EAGAIN; |
| 2183 | 2191 | case -NFS4ERR_STALE_CLIENTID: |
| 2184 | 2192 | case -NFS4ERR_STALE_STATEID: |
| 2185 | − set_bit(NFS_DELEGATED_STATE, &state->flags); | |
| 2186 | 2193 | /* Don't recall a delegation if it was lost */ |
| 2187 | 2194 | nfs4_schedule_lease_recovery(server->nfs_client); |
| 2188 | 2195 | return -EAGAIN; |
| @@ -2203,7 +2210,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct · 14 unmodified lines | ||
| 2203 | 2210 | return -EAGAIN; |
| 2204 | 2211 | case -NFS4ERR_DELAY: |
| 2205 | 2212 | case -NFS4ERR_GRACE: |
| 2206 | − set_bit(NFS_DELEGATED_STATE, &state->flags); | |
| 2207 | 2213 | ssleep(1); |
| 2208 | 2214 | return -EAGAIN; |
| 2209 | 2215 | case -ENOMEM: |
| @@ -2219,8 +2225,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct · 9 unmodified lines | ||
| 2219 | 2225 | } |
| 2220 | 2226 | |
| 2221 | 2227 | int nfs4_open_delegation_recall(struct nfs_open_context *ctx, |
| 2222 | − struct nfs4_state *state, const nfs4_stateid *stateid, | |
| 2223 | − fmode_t type) | |
| 2228 | + struct nfs4_state *state, const nfs4_stateid *stateid) | |
| 2224 | 2229 | { |
| 2225 | 2230 | struct nfs_server *server = NFS_SERVER(state->inode); |
| 2226 | 2231 | struct nfs4_opendata *opendata; |
| @@ -2231,20 +2236,23 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, · 4 unmodified lines | ||
| 2231 | 2236 | if (IS_ERR(opendata)) |
| 2232 | 2237 | return PTR_ERR(opendata); |
| 2233 | 2238 | nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); |
| 2234 | − nfs_state_clear_delegation(state); | |
| 2235 | − switch (type & (FMODE_READ|FMODE_WRITE)) { | |
| 2236 | − case FMODE_READ|FMODE_WRITE: | |
| 2237 | − case FMODE_WRITE: | |
| 2239 | + if (!test_bit(NFS_O_RDWR_STATE, &state->flags)) { | |
| 2238 | 2240 | err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE); |
| 2239 | 2241 | if (err) |
| 2240 | − break; | |
| 2242 | + goto out; | |
| 2243 | + } | |
| 2244 | + if (!test_bit(NFS_O_WRONLY_STATE, &state->flags)) { | |
| 2241 | 2245 | err = nfs4_open_recover_helper(opendata, FMODE_WRITE); |
| 2242 | 2246 | if (err) |
| 2243 | − break; | |
| 2244 | − /* Fall through */ | |
| 2245 | − case FMODE_READ: | |
| 2247 | + goto out; | |
| 2248 | + } | |
| 2249 | + if (!test_bit(NFS_O_RDONLY_STATE, &state->flags)) { | |
| 2246 | 2250 | err = nfs4_open_recover_helper(opendata, FMODE_READ); |
| 2251 | + if (err) | |
| 2252 | + goto out; | |
| 2247 | 2253 | } |
| 2254 | + nfs_state_clear_delegation(state); | |
| 2255 | +out: | |
| 2248 | 2256 | nfs4_opendata_put(opendata); |
| 2249 | 2257 | return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err); |
| 2250 | 2258 | } |
| @@ -2492,6 +2500,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, · 241 unmodified lines | ||
| 2492 | 2500 | if (!ctx) { |
| 2493 | 2501 | nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1); |
| 2494 | 2502 | data->is_recover = true; |
| 2503 | + task_setup_data.flags |= RPC_TASK_TIMEOUT; | |
| 2495 | 2504 | } else { |
| 2496 | 2505 | nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0); |
| 2497 | 2506 | pnfs_lgopen_prepare(data, ctx); |
| @@ -2698,6 +2707,7 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st · 200 unmodified lines | ||
| 2698 | 2707 | { |
| 2699 | 2708 | /* NFSv4.0 doesn't allow for delegation recovery on open expire */ |
| 2700 | 2709 | nfs40_clear_delegation_stateid(state); |
| 2710 | + nfs_state_clear_open_state_flags(state); | |
| 2701 | 2711 | return nfs4_open_expired(sp, state); |
| 2702 | 2712 | } |
| 2703 | 2713 | |
| @@ -2740,13 +2750,13 @@ out_free: · 36 unmodified lines | ||
| 2740 | 2750 | return -NFS4ERR_EXPIRED; |
| 2741 | 2751 | } |
| 2742 | 2752 | |
| 2743 | −static void nfs41_check_delegation_stateid(struct nfs4_state *state) | |
| 2753 | +static int nfs41_check_delegation_stateid(struct nfs4_state *state) | |
| 2744 | 2754 | { |
| 2745 | 2755 | struct nfs_server *server = NFS_SERVER(state->inode); |
| 2746 | 2756 | nfs4_stateid stateid; |
| 2747 | 2757 | struct nfs_delegation *delegation; |
| 2748 | 2758 | const struct cred *cred = NULL; |
| 2749 | − int status; | |
| 2759 | + int status, ret = NFS_OK; | |
| 2750 | 2760 | |
| 2751 | 2761 | /* Get the delegation credential for use by test/free_stateid */ |
| 2752 | 2762 | rcu_read_lock(); |
| @@ -2754,20 +2764,15 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state) · 1 unmodified line | ||
| 2754 | 2764 | if (delegation == NULL) { |
| 2755 | 2765 | rcu_read_unlock(); |
| 2756 | 2766 | nfs_state_clear_delegation(state); |
| 2757 | − return; | |
| 2767 | + return NFS_OK; | |
| 2758 | 2768 | } |
| 2759 | 2769 | |
| 2760 | 2770 | nfs4_stateid_copy(&stateid, &delegation->stateid); |
| 2761 | − if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { | |
| 2762 | − rcu_read_unlock(); | |
| 2763 | − nfs_state_clear_delegation(state); | |
| 2764 | − return; | |
| 2765 | − } | |
| 2766 | 2771 | |
| 2767 | 2772 | if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, |
| 2768 | 2773 | &delegation->flags)) { |
| 2769 | 2774 | rcu_read_unlock(); |
| 2770 | − return; | |
| 2775 | + return NFS_OK; | |
| 2771 | 2776 | } |
| 2772 | 2777 | |
| 2773 | 2778 | if (delegation->cred) |
| @@ -2777,9 +2782,24 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state) · 3 unmodified lines | ||
| 2777 | 2782 | trace_nfs4_test_delegation_stateid(state, NULL, status); |
| 2778 | 2783 | if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) |
| 2779 | 2784 | nfs_finish_clear_delegation_stateid(state, &stateid); |
| 2785 | + else | |
| 2786 | + ret = status; | |
| 2780 | 2787 | |
| 2781 | − if (delegation->cred) | |
| 2782 | − put_cred(cred); | |
| 2788 | + put_cred(cred); | |
| 2789 | + return ret; | |
| 2790 | +} | |
| 2791 | + | |
| 2792 | +static void nfs41_delegation_recover_stateid(struct nfs4_state *state) | |
| 2793 | +{ | |
| 2794 | + nfs4_stateid tmp; | |
| 2795 | + | |
| 2796 | + if (test_bit(NFS_DELEGATED_STATE, &state->flags) && | |
| 2797 | + nfs4_copy_delegation_stateid(state->inode, state->state, | |
| 2798 | + &tmp, NULL) && | |
| 2799 | + nfs4_stateid_match_other(&state->stateid, &tmp)) | |
| 2800 | + nfs_state_set_delegation(state, &tmp, state->state); | |
| 2801 | + else | |
| 2802 | + nfs_state_clear_delegation(state); | |
| 2783 | 2803 | } |
| 2784 | 2804 | |
| 2785 | 2805 | /** |
| @@ -2849,21 +2869,12 @@ static int nfs41_check_open_stateid(struct nfs4_state *state) · 63 unmodified lines | ||
| 2849 | 2869 | const struct cred *cred = state->owner->so_cred; |
| 2850 | 2870 | int status; |
| 2851 | 2871 | |
| 2852 | − if (test_bit(NFS_OPEN_STATE, &state->flags) == 0) { | |
| 2853 | − if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) { | |
| 2854 | − if (nfs4_have_delegation(state->inode, state->state)) | |
| 2855 | − return NFS_OK; | |
| 2856 | − return -NFS4ERR_OPENMODE; | |
| 2857 | − } | |
| 2872 | + if (test_bit(NFS_OPEN_STATE, &state->flags) == 0) | |
| 2858 | 2873 | return -NFS4ERR_BAD_STATEID; |
| 2859 | − } | |
| 2860 | 2874 | status = nfs41_test_and_free_expired_stateid(server, stateid, cred); |
| 2861 | 2875 | trace_nfs4_test_open_stateid(state, NULL, status); |
| 2862 | 2876 | if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) { |
| 2863 | − clear_bit(NFS_O_RDONLY_STATE, &state->flags); | |
| 2864 | − clear_bit(NFS_O_WRONLY_STATE, &state->flags); | |
| 2865 | − clear_bit(NFS_O_RDWR_STATE, &state->flags); | |
| 2866 | − clear_bit(NFS_OPEN_STATE, &state->flags); | |
| 2877 | + nfs_state_clear_open_state_flags(state); | |
| 2867 | 2878 | stateid->type = NFS4_INVALID_STATEID_TYPE; |
| 2868 | 2879 | return status; |
| 2869 | 2880 | } |
| @@ -2876,7 +2887,11 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st · 6 unmodified lines | ||
| 2876 | 2887 | { |
| 2877 | 2888 | int status; |
| 2878 | 2889 | |
| 2879 | − nfs41_check_delegation_stateid(state); | |
| 2890 | + status = nfs41_check_delegation_stateid(state); | |
| 2891 | + if (status != NFS_OK) | |
| 2892 | + return status; | |
| 2893 | + nfs41_delegation_recover_stateid(state); | |
| 2894 | + | |
| 2880 | 2895 | status = nfs41_check_expired_locks(state); |
| 2881 | 2896 | if (status != NFS_OK) |
| 2882 | 2897 | return status; |
| @@ -3201,7 +3216,7 @@ static int _nfs4_do_setattr(struct inode *inode, · 318 unmodified lines | ||
| 3201 | 3216 | |
| 3202 | 3217 | if (nfs4_copy_delegation_stateid(inode, FMODE_WRITE, &arg->stateid, &delegation_cred)) { |
| 3203 | 3218 | /* Use that stateid */ |
| 3204 | − } else if (ctx != NULL) { | |
| 3219 | + } else if (ctx != NULL && ctx->state) { | |
| 3205 | 3220 | struct nfs_lock_context *l_ctx; |
| 3206 | 3221 | if (!nfs4_valid_open_stateid(ctx->state)) |
| 3207 | 3222 | return -EBADF; |
| @@ -624,24 +624,39 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp) · 623 unmodified lines | ||
| 624 | 624 | /** |
| 625 | 625 | * nfs4_purge_state_owners - Release all cached state owners |
| 626 | 626 | * @server: nfs_server with cached state owners to release |
| 627 | + * @head: resulting list of state owners | |
| 627 | 628 | * |
| 628 | 629 | * Called at umount time. Remaining state owners will be on |
| 629 | 630 | * the LRU with ref count of zero. |
| 631 | + * Note that the state owners are not freed, but are added | |
| 632 | + * to the list @head, which can later be used as an argument | |
| 633 | + * to nfs4_free_state_owners. | |
| 630 | 634 | */ |
| 631 | −void nfs4_purge_state_owners(struct nfs_server *server) | |
| 635 | +void nfs4_purge_state_owners(struct nfs_server *server, struct list_head *head) | |
| 632 | 636 | { |
| 633 | 637 | struct nfs_client *clp = server->nfs_client; |
| 634 | 638 | struct nfs4_state_owner *sp, *tmp; |
| 635 | − LIST_HEAD(doomed); | |
| 636 | 639 | |
| 637 | 640 | spin_lock(&clp->cl_lock); |
| 638 | 641 | list_for_each_entry_safe(sp, tmp, &server->state_owners_lru, so_lru) { |
| 639 | − list_move(&sp->so_lru, &doomed); | |
| 642 | + list_move(&sp->so_lru, head); | |
| 640 | 643 | nfs4_remove_state_owner_locked(sp); |
| 641 | 644 | } |
| 642 | 645 | spin_unlock(&clp->cl_lock); |
| 646 | +} | |
| 643 | 647 | |
| 644 | − list_for_each_entry_safe(sp, tmp, &doomed, so_lru) { | |
| 648 | +/** | |
| 649 | + * nfs4_purge_state_owners - Release all cached state owners | |
| 650 | + * @head: resulting list of state owners | |
| 651 | + * | |
| 652 | + * Frees a list of state owners that was generated by | |
| 653 | + * nfs4_purge_state_owners | |
| 654 | + */ | |
| 655 | +void nfs4_free_state_owners(struct list_head *head) | |
| 656 | +{ | |
| 657 | + struct nfs4_state_owner *sp, *tmp; | |
| 658 | + | |
| 659 | + list_for_each_entry_safe(sp, tmp, head, so_lru) { | |
| 645 | 660 | list_del(&sp->so_lru); |
| 646 | 661 | nfs4_free_state_owner(sp); |
| 647 | 662 | } |
| @@ -1463,7 +1478,7 @@ void nfs_inode_find_state_and_recover(struct inode *inode, · 815 unmodified lines | ||
| 1463 | 1478 | nfs4_schedule_state_manager(clp); |
| 1464 | 1479 | } |
| 1465 | 1480 | |
| 1466 | −static void nfs4_state_mark_open_context_bad(struct nfs4_state *state) | |
| 1481 | +static void nfs4_state_mark_open_context_bad(struct nfs4_state *state, int err) | |
| 1467 | 1482 | { |
| 1468 | 1483 | struct inode *inode = state->inode; |
| 1469 | 1484 | struct nfs_inode *nfsi = NFS_I(inode); |
| @@ -1474,6 +1489,8 @@ static void nfs4_state_mark_open_context_bad(struct nfs4_state *state) · 4 unmodified lines | ||
| 1474 | 1489 | if (ctx->state != state) |
| 1475 | 1490 | continue; |
| 1476 | 1491 | set_bit(NFS_CONTEXT_BAD, &ctx->flags); |
| 1492 | + pr_warn("NFSv4: state recovery failed for open file %pd2, " | |
| 1493 | + "error = %d\n", ctx->dentry, err); | |
| 1477 | 1494 | } |
| 1478 | 1495 | rcu_read_unlock(); |
| 1479 | 1496 | } |
| @@ -1481,7 +1498,7 @@ static void nfs4_state_mark_open_context_bad(struct nfs4_state *state) · 1 unmodified line | ||
| 1481 | 1498 | static void nfs4_state_mark_recovery_failed(struct nfs4_state *state, int error) |
| 1482 | 1499 | { |
| 1483 | 1500 | set_bit(NFS_STATE_RECOVERY_FAILED, &state->flags); |
| 1484 | − nfs4_state_mark_open_context_bad(state); | |
| 1501 | + nfs4_state_mark_open_context_bad(state, error); | |
| 1485 | 1502 | } |
| 1486 | 1503 | |
| 1487 | 1504 | |
| @@ -1512,6 +1529,7 @@ restart: · 24 unmodified lines | ||
| 1512 | 1529 | switch (status) { |
| 1513 | 1530 | case 0: |
| 1514 | 1531 | break; |
| 1532 | + case -ETIMEDOUT: | |
| 1515 | 1533 | case -ESTALE: |
| 1516 | 1534 | case -NFS4ERR_ADMIN_REVOKED: |
| 1517 | 1535 | case -NFS4ERR_STALE_STATEID: |
| @@ -1605,6 +1623,7 @@ static int __nfs4_reclaim_open_state(struct nfs4_state_owner *sp, struct nfs4_st · 87 unmodified lines | ||
| 1605 | 1623 | static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops) |
| 1606 | 1624 | { |
| 1607 | 1625 | struct nfs4_state *state; |
| 1626 | + unsigned int loop = 0; | |
| 1608 | 1627 | int status = 0; |
| 1609 | 1628 | |
| 1610 | 1629 | /* Note: we rely on the sp->so_states list being ordered |
| @@ -1631,8 +1650,10 @@ restart: · 20 unmodified lines | ||
| 1631 | 1650 | |
| 1632 | 1651 | switch (status) { |
| 1633 | 1652 | default: |
| 1634 | − if (status >= 0) | |
| 1653 | + if (status >= 0) { | |
| 1654 | + loop = 0; | |
| 1635 | 1655 | break; |
| 1656 | + } | |
| 1636 | 1657 | printk(KERN_ERR "NFS: %s: unhandled error %d\n", __func__, status); |
| 1637 | 1658 | /* Fall through */ |
| 1638 | 1659 | case -ENOENT: |
| @@ -1646,6 +1667,10 @@ restart: · 7 unmodified lines | ||
| 1646 | 1667 | break; |
| 1647 | 1668 | case -EAGAIN: |
| 1648 | 1669 | ssleep(1); |
| 1670 | + if (loop++ < 10) { | |
| 1671 | + set_bit(ops->state_flag_bit, &state->flags); | |
| 1672 | + break; | |
| 1673 | + } | |
| 1649 | 1674 | /* Fall through */ |
| 1650 | 1675 | case -NFS4ERR_ADMIN_REVOKED: |
| 1651 | 1676 | case -NFS4ERR_STALE_STATEID: |
| @@ -1658,11 +1683,13 @@ restart: · 6 unmodified lines | ||
| 1658 | 1683 | case -NFS4ERR_EXPIRED: |
| 1659 | 1684 | case -NFS4ERR_NO_GRACE: |
| 1660 | 1685 | nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state); |
| 1686 | + /* Fall through */ | |
| 1661 | 1687 | case -NFS4ERR_STALE_CLIENTID: |
| 1662 | 1688 | case -NFS4ERR_BADSESSION: |
| 1663 | 1689 | case -NFS4ERR_BADSLOT: |
| 1664 | 1690 | case -NFS4ERR_BAD_HIGH_SLOT: |
| 1665 | 1691 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: |
| 1692 | + case -ETIMEDOUT: | |
| 1666 | 1693 | goto out_err; |
| 1667 | 1694 | } |
| 1668 | 1695 | nfs4_put_open_state(state); |
| @@ -1856,12 +1883,13 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov · 187 unmodified lines | ||
| 1856 | 1883 | struct nfs4_state_owner *sp; |
| 1857 | 1884 | struct nfs_server *server; |
| 1858 | 1885 | struct rb_node *pos; |
| 1886 | + LIST_HEAD(freeme); | |
| 1859 | 1887 | int status = 0; |
| 1860 | 1888 | |
| 1861 | 1889 | restart: |
| 1862 | 1890 | rcu_read_lock(); |
| 1863 | 1891 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { |
| 1864 | − nfs4_purge_state_owners(server); | |
| 1892 | + nfs4_purge_state_owners(server, &freeme); | |
| 1865 | 1893 | spin_lock(&clp->cl_lock); |
| 1866 | 1894 | for (pos = rb_first(&server->state_owners); |
| 1867 | 1895 | pos != NULL; |
| @@ -1890,6 +1918,7 @@ restart: · 22 unmodified lines | ||
| 1890 | 1918 | spin_unlock(&clp->cl_lock); |
| 1891 | 1919 | } |
| 1892 | 1920 | rcu_read_unlock(); |
| 1921 | + nfs4_free_state_owners(&freeme); | |
| 1893 | 1922 | return 0; |
| 1894 | 1923 | } |
| 1895 | 1924 | |
| @@ -1945,7 +1974,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status) · 49 unmodified lines | ||
| 1945 | 1974 | return -EPERM; |
| 1946 | 1975 | case -EACCES: |
| 1947 | 1976 | case -NFS4ERR_DELAY: |
| 1948 | − case -ETIMEDOUT: | |
| 1949 | 1977 | case -EAGAIN: |
| 1950 | 1978 | ssleep(1); |
| 1951 | 1979 | break; |
| @@ -2574,7 +2602,7 @@ static void nfs4_state_manager(struct nfs_client *clp) · 622 unmodified lines | ||
| 2574 | 2602 | } |
| 2575 | 2603 | |
| 2576 | 2604 | /* Now recover expired state... */ |
| 2577 | − if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { | |
| 2605 | + if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) { | |
| 2578 | 2606 | section = "reclaim nograce"; |
| 2579 | 2607 | status = nfs4_do_reclaim(clp, |
| 2580 | 2608 | clp->cl_mvops->nograce_recovery_ops); |
| @@ -2582,6 +2610,7 @@ static void nfs4_state_manager(struct nfs_client *clp) · 1 unmodified line | ||
| 2582 | 2610 | continue; |
| 2583 | 2611 | if (status < 0) |
| 2584 | 2612 | goto out_error; |
| 2613 | + clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); | |
| 2585 | 2614 | } |
| 2586 | 2615 | |
| 2587 | 2616 | nfs4_end_drain_session(clp); |
| @@ -1903,12 +1903,6 @@ lookup_again: · 1902 unmodified lines | ||
| 1903 | 1903 | goto out_unlock; |
| 1904 | 1904 | } |
| 1905 | 1905 | |
| 1906 | − if (!nfs4_valid_open_stateid(ctx->state)) { | |
| 1907 | − trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, | |
| 1908 | − PNFS_UPDATE_LAYOUT_INVALID_OPEN); | |
| 1909 | − goto out_unlock; | |
| 1910 | − } | |
| 1911 | − | |
| 1912 | 1906 | /* |
| 1913 | 1907 | * Choose a stateid for the LAYOUTGET. If we don't have a layout |
| 1914 | 1908 | * stateid, or it has been invalidated, then we must use the open |
| @@ -1939,6 +1933,7 @@ lookup_again: · 24 unmodified lines | ||
| 1939 | 1933 | iomode == IOMODE_RW ? FMODE_WRITE : FMODE_READ, |
| 1940 | 1934 | NULL, &stateid, NULL); |
| 1941 | 1935 | if (status != 0) { |
| 1936 | + lseg = ERR_PTR(status); | |
| 1942 | 1937 | trace_pnfs_update_layout(ino, pos, count, |
| 1943 | 1938 | iomode, lo, lseg, |
| 1944 | 1939 | PNFS_UPDATE_LAYOUT_INVALID_OPEN); |
| @@ -2260,6 +2260,7 @@ nfs_compare_remount_data(struct nfs_server *nfss, · 2259 unmodified lines | ||
| 2260 | 2260 | data->acdirmin != nfss->acdirmin / HZ || |
| 2261 | 2261 | data->acdirmax != nfss->acdirmax / HZ || |
| 2262 | 2262 | data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || |
| 2263 | + (data->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) || | |
| 2263 | 2264 | data->nfs_server.port != nfss->port || |
| 2264 | 2265 | data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || |
| 2265 | 2266 | !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address, |
| @@ -119,6 +119,7 @@ static int traverse(struct seq_file *m, loff_t offset) · 118 unmodified lines | ||
| 119 | 119 | } |
| 120 | 120 | if (seq_has_overflowed(m)) |
| 121 | 121 | goto Eoverflow; |
| 122 | + p = m->op->next(m, p, &m->index); | |
| 122 | 123 | if (pos + m->count > offset) { |
| 123 | 124 | m->from = offset - pos; |
| 124 | 125 | m->count -= m->from; |
| @@ -126,7 +127,6 @@ static int traverse(struct seq_file *m, loff_t offset) · 1 unmodified line | ||
| 126 | 127 | } |
| 127 | 128 | pos += m->count; |
| 128 | 129 | m->count = 0; |
| 129 | − p = m->op->next(m, p, &m->index); | |
| 130 | 130 | if (pos == offset) |
| 131 | 131 | break; |
| 132 | 132 | } |
| @@ -3835,15 +3835,28 @@ xfs_bmapi_read( · 3834 unmodified lines | ||
| 3835 | 3835 | XFS_STATS_INC(mp, xs_blk_mapr); |
| 3836 | 3836 | |
| 3837 | 3837 | ifp = XFS_IFORK_PTR(ip, whichfork); |
| 3838 | + if (!ifp) { | |
| 3839 | + /* No CoW fork? Return a hole. */ | |
| 3840 | + if (whichfork == XFS_COW_FORK) { | |
| 3841 | + mval->br_startoff = bno; | |
| 3842 | + mval->br_startblock = HOLESTARTBLOCK; | |
| 3843 | + mval->br_blockcount = len; | |
| 3844 | + mval->br_state = XFS_EXT_NORM; | |
| 3845 | + *nmap = 1; | |
| 3846 | + return 0; | |
| 3847 | + } | |
| 3838 | 3848 | |
| 3839 | − /* No CoW fork? Return a hole. */ | |
| 3840 | − if (whichfork == XFS_COW_FORK && !ifp) { | |
| 3841 | − mval->br_startoff = bno; | |
| 3842 | − mval->br_startblock = HOLESTARTBLOCK; | |
| 3843 | − mval->br_blockcount = len; | |
| 3844 | − mval->br_state = XFS_EXT_NORM; | |
| 3845 | − *nmap = 1; | |
| 3846 | − return 0; | |
| 3849 | + /* | |
| 3850 | + * A missing attr ifork implies that the inode says we're in | |
| 3851 | + * extents or btree format but failed to pass the inode fork | |
| 3852 | + * verifier while trying to load it. Treat that as a file | |
| 3853 | + * corruption too. | |
| 3854 | + */ | |
| 3855 | +#ifdef DEBUG | |
| 3856 | + xfs_alert(mp, "%s: inode %llu missing fork %d", | |
| 3857 | + __func__, ip->i_ino, whichfork); | |
| 3858 | +#endif /* DEBUG */ | |
| 3859 | + return -EFSCORRUPTED; | |
| 3847 | 3860 | } |
| 3848 | 3861 | |
| 3849 | 3862 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { |
| @@ -487,10 +487,8 @@ xfs_da3_split( · 486 unmodified lines | ||
| 487 | 487 | ASSERT(state->path.active == 0); |
| 488 | 488 | oldblk = &state->path.blk[0]; |
| 489 | 489 | error = xfs_da3_root_split(state, oldblk, addblk); |
| 490 | − if (error) { | |
| 491 | − addblk->bp = NULL; | |
| 492 | − return error; /* GROT: dir is inconsistent */ | |
| 493 | − } | |
| 490 | + if (error) | |
| 491 | + goto out; | |
| 494 | 492 | |
| 495 | 493 | /* |
| 496 | 494 | * Update pointers to the node which used to be block 0 and just got |
| @@ -505,7 +503,10 @@ xfs_da3_split( · 8 unmodified lines | ||
| 505 | 503 | */ |
| 506 | 504 | node = oldblk->bp->b_addr; |
| 507 | 505 | if (node->hdr.info.forw) { |
| 508 | − ASSERT(be32_to_cpu(node->hdr.info.forw) == addblk->blkno); | |
| 506 | + if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) { | |
| 507 | + error = -EFSCORRUPTED; | |
| 508 | + goto out; | |
| 509 | + } | |
| 509 | 510 | node = addblk->bp->b_addr; |
| 510 | 511 | node->hdr.info.back = cpu_to_be32(oldblk->blkno); |
| 511 | 512 | xfs_trans_log_buf(state->args->trans, addblk->bp, |
| @@ -514,15 +515,19 @@ xfs_da3_split( · 2 unmodified lines | ||
| 514 | 515 | } |
| 515 | 516 | node = oldblk->bp->b_addr; |
| 516 | 517 | if (node->hdr.info.back) { |
| 517 | − ASSERT(be32_to_cpu(node->hdr.info.back) == addblk->blkno); | |
| 518 | + if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) { | |
| 519 | + error = -EFSCORRUPTED; | |
| 520 | + goto out; | |
| 521 | + } | |
| 518 | 522 | node = addblk->bp->b_addr; |
| 519 | 523 | node->hdr.info.forw = cpu_to_be32(oldblk->blkno); |
| 520 | 524 | xfs_trans_log_buf(state->args->trans, addblk->bp, |
| 521 | 525 | XFS_DA_LOGRANGE(node, &node->hdr.info, |
| 522 | 526 | sizeof(node->hdr.info))); |
| 523 | 527 | } |
| 528 | +out: | |
| 524 | 529 | addblk->bp = NULL; |
| 525 | − return 0; | |
| 530 | + return error; | |
| 526 | 531 | } |
| 527 | 532 | |
| 528 | 533 | /* |
| @@ -741,7 +741,8 @@ xfs_dir2_leafn_lookup_for_entry( · 740 unmodified lines | ||
| 741 | 741 | ents = dp->d_ops->leaf_ents_p(leaf); |
| 742 | 742 | |
| 743 | 743 | xfs_dir3_leaf_check(dp, bp); |
| 744 | − ASSERT(leafhdr.count > 0); | |
| 744 | + if (leafhdr.count <= 0) | |
| 745 | + return -EFSCORRUPTED; | |
| 745 | 746 | |
| 746 | 747 | /* |
| 747 | 748 | * Look up the hash value in the leaf entries. |
| @@ -429,10 +429,7 @@ xfs_log_reserve( · 428 unmodified lines | ||
| 429 | 429 | |
| 430 | 430 | ASSERT(*ticp == NULL); |
| 431 | 431 | tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent, |
| 432 | − KM_SLEEP | KM_MAYFAIL); | |
| 433 | − if (!tic) | |
| 434 | − return -ENOMEM; | |
| 435 | − | |
| 432 | + KM_SLEEP); | |
| 436 | 433 | *ticp = tic; |
| 437 | 434 | |
| 438 | 435 | xlog_grant_push_ail(log, tic->t_cnt ? tic->t_unit_res * tic->t_cnt |
| @@ -19,9 +19,24 @@ · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | #define p4d_alloc(mm, pgd, address) (pgd) |
| 21 | 21 | #define p4d_offset(pgd, start) (pgd) |
| 22 | −#define p4d_none(p4d) 0 | |
| 23 | −#define p4d_bad(p4d) 0 | |
| 24 | −#define p4d_present(p4d) 1 | |
| 22 | + | |
| 23 | +#ifndef __ASSEMBLY__ | |
| 24 | +static inline int p4d_none(p4d_t p4d) | |
| 25 | +{ | |
| 26 | + return 0; | |
| 27 | +} | |
| 28 | + | |
| 29 | +static inline int p4d_bad(p4d_t p4d) | |
| 30 | +{ | |
| 31 | + return 0; | |
| 32 | +} | |
| 33 | + | |
| 34 | +static inline int p4d_present(p4d_t p4d) | |
| 35 | +{ | |
| 36 | + return 1; | |
| 37 | +} | |
| 38 | +#endif | |
| 39 | + | |
| 25 | 40 | #define p4d_ERROR(p4d) do { } while (0) |
| 26 | 41 | #define p4d_clear(p4d) pgd_clear(p4d) |
| 27 | 42 | #define p4d_val(p4d) pgd_val(p4d) |
| @@ -34,6 +34,7 @@ struct kvm_pmu { · 33 unmodified lines | ||
| 34 | 34 | u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx); |
| 35 | 35 | void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val); |
| 36 | 36 | u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu); |
| 37 | +void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu); | |
| 37 | 38 | void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu); |
| 38 | 39 | void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu); |
| 39 | 40 | void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val); |
| @@ -71,6 +72,7 @@ static inline u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu) · 31 unmodified lines | ||
| 71 | 72 | { |
| 72 | 73 | return 0; |
| 73 | 74 | } |
| 75 | +static inline void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu) {} | |
| 74 | 76 | static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {} |
| 75 | 77 | static inline void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) {} |
| 76 | 78 | static inline void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val) {} |
| @@ -350,6 +350,7 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | void kvm_vgic_load(struct kvm_vcpu *vcpu); |
| 352 | 352 | void kvm_vgic_put(struct kvm_vcpu *vcpu); |
| 353 | +void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu); | |
| 353 | 354 | |
| 354 | 355 | #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) |
| 355 | 356 | #define vgic_initialized(k) ((k)->arch.vgic.initialized) |
| @@ -311,7 +311,6 @@ enum req_flag_bits { · 310 unmodified lines | ||
| 311 | 311 | __REQ_RAHEAD, /* read ahead, can fail anytime */ |
| 312 | 312 | __REQ_BACKGROUND, /* background IO */ |
| 313 | 313 | __REQ_NOWAIT, /* Don't wait if request will block */ |
| 314 | − __REQ_NOWAIT_INLINE, /* Return would-block error inline */ | |
| 315 | 314 | /* |
| 316 | 315 | * When a shared kthread needs to issue a bio for a cgroup, doing |
| 317 | 316 | * so synchronously can lead to priority inversions as the kthread |
| @@ -346,7 +345,6 @@ enum req_flag_bits { · 28 unmodified lines | ||
| 346 | 345 | #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) |
| 347 | 346 | #define REQ_BACKGROUND (1ULL << __REQ_BACKGROUND) |
| 348 | 347 | #define REQ_NOWAIT (1ULL << __REQ_NOWAIT) |
| 349 | −#define REQ_NOWAIT_INLINE (1ULL << __REQ_NOWAIT_INLINE) | |
| 350 | 348 | #define REQ_CGROUP_PUNT (1ULL << __REQ_CGROUP_PUNT) |
| 351 | 349 | |
| 352 | 350 | #define REQ_NOUNMAP (1ULL << __REQ_NOUNMAP) |
| @@ -420,13 +418,12 @@ static inline int op_stat_group(unsigned int op) · 67 unmodified lines | ||
| 420 | 418 | |
| 421 | 419 | typedef unsigned int blk_qc_t; |
| 422 | 420 | #define BLK_QC_T_NONE -1U |
| 423 | −#define BLK_QC_T_EAGAIN -2U | |
| 424 | 421 | #define BLK_QC_T_SHIFT 16 |
| 425 | 422 | #define BLK_QC_T_INTERNAL (1U << 31) |
| 426 | 423 | |
| 427 | 424 | static inline bool blk_qc_t_valid(blk_qc_t cookie) |
| 428 | 425 | { |
| 429 | − return cookie != BLK_QC_T_NONE && cookie != BLK_QC_T_EAGAIN; | |
| 426 | + return cookie != BLK_QC_T_NONE; | |
| 430 | 427 | } |
| 431 | 428 | |
| 432 | 429 | static inline unsigned int blk_qc_t_to_queue_num(blk_qc_t cookie) |
| @@ -170,6 +170,8 @@ struct ccp_aes_engine { · 169 unmodified lines | ||
| 170 | 170 | enum ccp_aes_mode mode; |
| 171 | 171 | enum ccp_aes_action action; |
| 172 | 172 | |
| 173 | + u32 authsize; | |
| 174 | + | |
| 173 | 175 | struct scatterlist *key; |
| 174 | 176 | u32 key_len; /* In bytes */ |
| 175 | 177 | |
| @@ -42,13 +42,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, · 41 unmodified lines | ||
| 42 | 42 | dma_addr_t dma_addr, unsigned long attrs); |
| 43 | 43 | long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr, |
| 44 | 44 | dma_addr_t dma_addr); |
| 45 | − | |
| 46 | −#ifdef CONFIG_ARCH_HAS_DMA_MMAP_PGPROT | |
| 47 | 45 | pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, |
| 48 | 46 | unsigned long attrs); |
| 47 | + | |
| 48 | +#ifdef CONFIG_MMU | |
| 49 | +pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs); | |
| 49 | 50 | #else |
| 50 | −# define arch_dma_mmap_pgprot(dev, prot, attrs) pgprot_noncached(prot) | |
| 51 | −#endif | |
| 51 | +static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, | |
| 52 | + unsigned long attrs) | |
| 53 | +{ | |
| 54 | + return prot; /* no protection bits supported without page tables */ | |
| 55 | +} | |
| 56 | +#endif /* CONFIG_MMU */ | |
| 52 | 57 | |
| 53 | 58 | #ifdef CONFIG_DMA_NONCOHERENT_CACHE_SYNC |
| 54 | 59 | void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| @@ -510,22 +510,18 @@ alloc_pages(gfp_t gfp_mask, unsigned int order) · 509 unmodified lines | ||
| 510 | 510 | } |
| 511 | 511 | extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order, |
| 512 | 512 | struct vm_area_struct *vma, unsigned long addr, |
| 513 | − int node, bool hugepage); | |
| 514 | −#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ | |
| 515 | − alloc_pages_vma(gfp_mask, order, vma, addr, numa_node_id(), true) | |
| 513 | + int node); | |
| 516 | 514 | #else |
| 517 | 515 | #define alloc_pages(gfp_mask, order) \ |
| 518 | 516 | alloc_pages_node(numa_node_id(), gfp_mask, order) |
| 519 | −#define alloc_pages_vma(gfp_mask, order, vma, addr, node, false)\ | |
| 520 | − alloc_pages(gfp_mask, order) | |
| 521 | −#define alloc_hugepage_vma(gfp_mask, vma, addr, order) \ | |
| 517 | +#define alloc_pages_vma(gfp_mask, order, vma, addr, node)\ | |
| 522 | 518 | alloc_pages(gfp_mask, order) |
| 523 | 519 | #endif |
| 524 | 520 | #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) |
| 525 | 521 | #define alloc_page_vma(gfp_mask, vma, addr) \ |
| 526 | − alloc_pages_vma(gfp_mask, 0, vma, addr, numa_node_id(), false) | |
| 522 | + alloc_pages_vma(gfp_mask, 0, vma, addr, numa_node_id()) | |
| 527 | 523 | #define alloc_page_vma_node(gfp_mask, vma, addr, node) \ |
| 528 | − alloc_pages_vma(gfp_mask, 0, vma, addr, node, false) | |
| 524 | + alloc_pages_vma(gfp_mask, 0, vma, addr, node) | |
| 529 | 525 | |
| 530 | 526 | extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order); |
| 531 | 527 | extern unsigned long get_zeroed_page(gfp_t gfp_mask); |
| @@ -94,11 +94,11 @@ struct keyring_index_key { · 93 unmodified lines | ||
| 94 | 94 | union { |
| 95 | 95 | struct { |
| 96 | 96 | #ifdef __LITTLE_ENDIAN /* Put desc_len at the LSB of x */ |
| 97 | − u8 desc_len; | |
| 98 | − char desc[sizeof(long) - 1]; /* First few chars of description */ | |
| 97 | + u16 desc_len; | |
| 98 | + char desc[sizeof(long) - 2]; /* First few chars of description */ | |
| 99 | 99 | #else |
| 100 | − char desc[sizeof(long) - 1]; /* First few chars of description */ | |
| 101 | − u8 desc_len; | |
| 100 | + char desc[sizeof(long) - 2]; /* First few chars of description */ | |
| 101 | + u16 desc_len; | |
| 102 | 102 | #endif |
| 103 | 103 | }; |
| 104 | 104 | unsigned long x; |
| @@ -861,8 +861,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu); · 860 unmodified lines | ||
| 861 | 861 | void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu); |
| 862 | 862 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu); |
| 863 | 863 | |
| 864 | −bool kvm_arch_has_vcpu_debugfs(void); | |
| 865 | −int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu); | |
| 864 | +#ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS | |
| 865 | +void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu); | |
| 866 | +#endif | |
| 866 | 867 | |
| 867 | 868 | int kvm_arch_hardware_enable(void); |
| 868 | 869 | void kvm_arch_hardware_disable(void); |
| @@ -872,6 +873,7 @@ int kvm_arch_check_processor_compat(void); · 3 unmodified lines | ||
| 872 | 873 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu); |
| 873 | 874 | bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu); |
| 874 | 875 | int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu); |
| 876 | +bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu); | |
| 875 | 877 | |
| 876 | 878 | #ifndef __KVM_HAVE_ARCH_VM_ALLOC |
| 877 | 879 | /* |
| @@ -668,6 +668,7 @@ static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec, · 667 unmodified lines | ||
| 668 | 668 | |
| 669 | 669 | void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, |
| 670 | 670 | int val); |
| 671 | +void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val); | |
| 671 | 672 | |
| 672 | 673 | static inline void mod_lruvec_state(struct lruvec *lruvec, |
| 673 | 674 | enum node_stat_item idx, int val) |
| @@ -1072,6 +1073,14 @@ static inline void mod_lruvec_page_state(struct page *page, · 398 unmodified lines | ||
| 1072 | 1073 | mod_node_page_state(page_pgdat(page), idx, val); |
| 1073 | 1074 | } |
| 1074 | 1075 | |
| 1076 | +static inline void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, | |
| 1077 | + int val) | |
| 1078 | +{ | |
| 1079 | + struct page *page = virt_to_head_page(p); | |
| 1080 | + | |
| 1081 | + __mod_node_page_state(page_pgdat(page), idx, val); | |
| 1082 | +} | |
| 1083 | + | |
| 1075 | 1084 | static inline |
| 1076 | 1085 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| 1077 | 1086 | gfp_t gfp_mask, |
| @@ -1159,6 +1168,16 @@ static inline void __dec_lruvec_page_state(struct page *page, · 81 unmodified lines | ||
| 1159 | 1168 | __mod_lruvec_page_state(page, idx, -1); |
| 1160 | 1169 | } |
| 1161 | 1170 | |
| 1171 | +static inline void __inc_lruvec_slab_state(void *p, enum node_stat_item idx) | |
| 1172 | +{ | |
| 1173 | + __mod_lruvec_slab_state(p, idx, 1); | |
| 1174 | +} | |
| 1175 | + | |
| 1176 | +static inline void __dec_lruvec_slab_state(void *p, enum node_stat_item idx) | |
| 1177 | +{ | |
| 1178 | + __mod_lruvec_slab_state(p, idx, -1); | |
| 1179 | +} | |
| 1180 | + | |
| 1162 | 1181 | /* idx can be of type enum memcg_stat_item or node_stat_item */ |
| 1163 | 1182 | static inline void inc_memcg_state(struct mem_cgroup *memcg, |
| 1164 | 1183 | int idx) |
| @@ -139,6 +139,8 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp, · 138 unmodified lines | ||
| 139 | 139 | struct mempolicy *get_task_policy(struct task_struct *p); |
| 140 | 140 | struct mempolicy *__get_vma_policy(struct vm_area_struct *vma, |
| 141 | 141 | unsigned long addr); |
| 142 | +struct mempolicy *get_vma_policy(struct vm_area_struct *vma, | |
| 143 | + unsigned long addr); | |
| 142 | 144 | bool vma_policy_mof(struct vm_area_struct *vma); |
| 143 | 145 | |
| 144 | 146 | extern void numa_default_policy(void); |
| @@ -446,11 +446,11 @@ enum { · 445 unmodified lines | ||
| 446 | 446 | }; |
| 447 | 447 | |
| 448 | 448 | enum { |
| 449 | − MLX5_OPC_MOD_TLS_TIS_STATIC_PARAMS = 0x20, | |
| 449 | + MLX5_OPC_MOD_TLS_TIS_STATIC_PARAMS = 0x1, | |
| 450 | 450 | }; |
| 451 | 451 | |
| 452 | 452 | enum { |
| 453 | − MLX5_OPC_MOD_TLS_TIS_PROGRESS_PARAMS = 0x20, | |
| 453 | + MLX5_OPC_MOD_TLS_TIS_PROGRESS_PARAMS = 0x1, | |
| 454 | 454 | }; |
| 455 | 455 | |
| 456 | 456 | enum { |
| @@ -10078,9 +10078,8 @@ struct mlx5_ifc_tls_static_params_bits { · 10077 unmodified lines | ||
| 10078 | 10078 | }; |
| 10079 | 10079 | |
| 10080 | 10080 | struct mlx5_ifc_tls_progress_params_bits { |
| 10081 | − u8 valid[0x1]; | |
| 10082 | − u8 reserved_at_1[0x7]; | |
| 10083 | − u8 pd[0x18]; | |
| 10081 | + u8 reserved_at_0[0x8]; | |
| 10082 | + u8 tisn[0x18]; | |
| 10084 | 10083 | |
| 10085 | 10084 | u8 next_record_tcp_sn[0x20]; |
| 10086 | 10085 | |
| @@ -159,7 +159,16 @@ struct page { · 158 unmodified lines | ||
| 159 | 159 | /** @pgmap: Points to the hosting device page map. */ |
| 160 | 160 | struct dev_pagemap *pgmap; |
| 161 | 161 | void *zone_device_data; |
| 162 | − unsigned long _zd_pad_1; /* uses mapping */ | |
| 162 | + /* | |
| 163 | + * ZONE_DEVICE private pages are counted as being | |
| 164 | + * mapped so the next 3 words hold the mapping, index, | |
| 165 | + * and private fields from the source anonymous or | |
| 166 | + * page cache page while the page is migrated to device | |
| 167 | + * private memory. | |
| 168 | + * ZONE_DEVICE MEMORY_DEVICE_FS_DAX pages also | |
| 169 | + * use the mapping, index, and private fields when | |
| 170 | + * pmem backed DAX files are mapped. | |
| 171 | + */ | |
| 163 | 172 | }; |
| 164 | 173 | |
| 165 | 174 | /** @rcu_head: You can use this to free a page by RCU. */ |
| @@ -1567,8 +1567,10 @@ extern bool pcie_ports_native; · 1566 unmodified lines | ||
| 1567 | 1567 | |
| 1568 | 1568 | #ifdef CONFIG_PCIEASPM |
| 1569 | 1569 | bool pcie_aspm_support_enabled(void); |
| 1570 | +bool pcie_aspm_enabled(struct pci_dev *pdev); | |
| 1570 | 1571 | #else |
| 1571 | 1572 | static inline bool pcie_aspm_support_enabled(void) { return false; } |
| 1573 | +static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; } | |
| 1572 | 1574 | #endif |
| 1573 | 1575 | |
| 1574 | 1576 | #ifdef CONFIG_PCIEAER |
| @@ -1362,6 +1362,14 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) · 1361 unmodified lines | ||
| 1362 | 1362 | to->l4_hash = from->l4_hash; |
| 1363 | 1363 | }; |
| 1364 | 1364 | |
| 1365 | +static inline void skb_copy_decrypted(struct sk_buff *to, | |
| 1366 | + const struct sk_buff *from) | |
| 1367 | +{ | |
| 1368 | +#ifdef CONFIG_TLS_DEVICE | |
| 1369 | + to->decrypted = from->decrypted; | |
| 1370 | +#endif | |
| 1371 | +} | |
| 1372 | + | |
| 1365 | 1373 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
| 1366 | 1374 | static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) |
| 1367 | 1375 | { |
| @@ -292,6 +292,9 @@ struct ucred { · 291 unmodified lines | ||
| 292 | 292 | #define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */ |
| 293 | 293 | #define MSG_EOF MSG_FIN |
| 294 | 294 | #define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */ |
| 295 | +#define MSG_SENDPAGE_DECRYPTED 0x100000 /* sendpage() internal : page may carry | |
| 296 | + * plain text and require encryption | |
| 297 | + */ | |
| 295 | 298 | |
| 296 | 299 | #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ |
| 297 | 300 | #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */ |
| @@ -1457,7 +1457,7 @@ typedef void (*usb_complete_t)(struct urb *); · 1456 unmodified lines | ||
| 1457 | 1457 | * field rather than determining a dma address themselves. |
| 1458 | 1458 | * |
| 1459 | 1459 | * Note that transfer_buffer must still be set if the controller |
| 1460 | − * does not support DMA (as indicated by bus.uses_dma) and when talking | |
| 1460 | + * does not support DMA (as indicated by hcd_uses_dma()) and when talking | |
| 1461 | 1461 | * to root hub. If you have to trasfer between highmem zone and the device |
| 1462 | 1462 | * on such controller, create a bounce buffer or bail out with an error. |
| 1463 | 1463 | * If transfer_buffer cannot be set (is in highmem) and the controller is DMA |
| @@ -422,6 +422,9 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd, · 421 unmodified lines | ||
| 422 | 422 | return hcd->high_prio_bh.completing_ep == ep; |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | +#define hcd_uses_dma(hcd) \ | |
| 426 | + (IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma) | |
| 427 | + | |
| 425 | 428 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); |
| 426 | 429 | extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, |
| 427 | 430 | int status); |
| @@ -278,6 +278,7 @@ struct hci_dev { · 277 unmodified lines | ||
| 278 | 278 | __u16 conn_info_min_age; |
| 279 | 279 | __u16 conn_info_max_age; |
| 280 | 280 | __u16 auth_payload_timeout; |
| 281 | + __u8 min_enc_key_size; | |
| 281 | 282 | __u8 ssp_debug_mode; |
| 282 | 283 | __u8 hw_error_code; |
| 283 | 284 | __u32 clock; |
| @@ -171,7 +171,7 @@ int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb, · 170 unmodified lines | ||
| 171 | 171 | void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb, |
| 172 | 172 | struct sk_buff *parent); |
| 173 | 173 | void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, |
| 174 | − void *reasm_data); | |
| 174 | + void *reasm_data, bool try_coalesce); | |
| 175 | 175 | struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q); |
| 176 | 176 | |
| 177 | 177 | #endif |
| @@ -61,7 +61,6 @@ struct net { · 60 unmodified lines | ||
| 61 | 61 | spinlock_t rules_mod_lock; |
| 62 | 62 | |
| 63 | 63 | u32 hash_mix; |
| 64 | − atomic64_t cookie_gen; | |
| 65 | 64 | |
| 66 | 65 | struct list_head list; /* list of network namespaces */ |
| 67 | 66 | struct list_head exit_list; /* To linked to call pernet exit |
| @@ -423,8 +423,7 @@ struct nft_set { · 422 unmodified lines | ||
| 423 | 423 | unsigned char *udata; |
| 424 | 424 | /* runtime data below here */ |
| 425 | 425 | const struct nft_set_ops *ops ____cacheline_aligned; |
| 426 | − u16 flags:13, | |
| 427 | − bound:1, | |
| 426 | + u16 flags:14, | |
| 428 | 427 | genmask:2; |
| 429 | 428 | u8 klen; |
| 430 | 429 | u8 dlen; |
| @@ -1360,12 +1359,15 @@ struct nft_trans_rule { · 929 unmodified lines | ||
| 1360 | 1359 | struct nft_trans_set { |
| 1361 | 1360 | struct nft_set *set; |
| 1362 | 1361 | u32 set_id; |
| 1362 | + bool bound; | |
| 1363 | 1363 | }; |
| 1364 | 1364 | |
| 1365 | 1365 | #define nft_trans_set(trans) \ |
| 1366 | 1366 | (((struct nft_trans_set *)trans->data)->set) |
| 1367 | 1367 | #define nft_trans_set_id(trans) \ |
| 1368 | 1368 | (((struct nft_trans_set *)trans->data)->set_id) |
| 1369 | +#define nft_trans_set_bound(trans) \ | |
| 1370 | + (((struct nft_trans_set *)trans->data)->bound) | |
| 1369 | 1371 | |
| 1370 | 1372 | struct nft_trans_chain { |
| 1371 | 1373 | bool update; |
| @@ -1396,12 +1398,15 @@ struct nft_trans_table { · 24 unmodified lines | ||
| 1396 | 1398 | struct nft_trans_elem { |
| 1397 | 1399 | struct nft_set *set; |
| 1398 | 1400 | struct nft_set_elem elem; |
| 1401 | + bool bound; | |
| 1399 | 1402 | }; |
| 1400 | 1403 | |
| 1401 | 1404 | #define nft_trans_elem_set(trans) \ |
| 1402 | 1405 | (((struct nft_trans_elem *)trans->data)->set) |
| 1403 | 1406 | #define nft_trans_elem(trans) \ |
| 1404 | 1407 | (((struct nft_trans_elem *)trans->data)->elem) |
| 1408 | +#define nft_trans_elem_set_bound(trans) \ | |
| 1409 | + (((struct nft_trans_elem *)trans->data)->bound) | |
| 1405 | 1410 | |
| 1406 | 1411 | struct nft_trans_obj { |
| 1407 | 1412 | struct nft_object *obj; |
| @@ -78,4 +78,6 @@ void nft_indr_block_get_and_ing_cmd(struct net_device *dev, · 77 unmodified lines | ||
| 78 | 78 | (__reg)->key = __key; \ |
| 79 | 79 | memset(&(__reg)->mask, 0xff, (__reg)->len); |
| 80 | 80 | |
| 81 | +int nft_chain_offload_priority(struct nft_base_chain *basechain); | |
| 82 | + | |
| 81 | 83 | #endif |
| @@ -684,9 +684,8 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, · 683 unmodified lines | ||
| 684 | 684 | const struct nla_policy *policy, |
| 685 | 685 | struct netlink_ext_ack *extack) |
| 686 | 686 | { |
| 687 | − return __nla_parse(tb, maxtype, nlmsg_attrdata(nlh, hdrlen), | |
| 688 | − nlmsg_attrlen(nlh, hdrlen), policy, | |
| 689 | − NL_VALIDATE_STRICT, extack); | |
| 687 | + return __nlmsg_parse(nlh, hdrlen, tb, maxtype, policy, | |
| 688 | + NL_VALIDATE_STRICT, extack); | |
| 690 | 689 | } |
| 691 | 690 | |
| 692 | 691 | /** |
| @@ -611,7 +611,7 @@ tc_cls_common_offload_init(struct flow_cls_common_offload *cls_common, · 610 unmodified lines | ||
| 611 | 611 | { |
| 612 | 612 | cls_common->chain_index = tp->chain->index; |
| 613 | 613 | cls_common->protocol = tp->protocol; |
| 614 | − cls_common->prio = tp->prio; | |
| 614 | + cls_common->prio = tp->prio >> 16; | |
| 615 | 615 | if (tc_skip_sw(flags) || flags & TCA_CLS_FLAGS_VERBOSE) |
| 616 | 616 | cls_common->extack = extack; |
| 617 | 617 | } |
| @@ -2482,6 +2482,7 @@ static inline bool sk_fullsock(const struct sock *sk) · 2481 unmodified lines | ||
| 2482 | 2482 | |
| 2483 | 2483 | /* Checks if this SKB belongs to an HW offloaded socket |
| 2484 | 2484 | * and whether any SW fallbacks are required based on dev. |
| 2485 | + * Check decrypted mark in case skb_orphan() cleared socket. | |
| 2485 | 2486 | */ |
| 2486 | 2487 | static inline struct sk_buff *sk_validate_xmit_skb(struct sk_buff *skb, |
| 2487 | 2488 | struct net_device *dev) |
| @@ -2489,8 +2490,15 @@ static inline struct sk_buff *sk_validate_xmit_skb(struct sk_buff *skb, · 1 unmodified line | ||
| 2489 | 2490 | #ifdef CONFIG_SOCK_VALIDATE_XMIT |
| 2490 | 2491 | struct sock *sk = skb->sk; |
| 2491 | 2492 | |
| 2492 | − if (sk && sk_fullsock(sk) && sk->sk_validate_xmit_skb) | |
| 2493 | + if (sk && sk_fullsock(sk) && sk->sk_validate_xmit_skb) { | |
| 2493 | 2494 | skb = sk->sk_validate_xmit_skb(sk, dev, skb); |
| 2495 | +#ifdef CONFIG_TLS_DEVICE | |
| 2496 | + } else if (unlikely(skb->decrypted)) { | |
| 2497 | + pr_warn_ratelimited("unencrypted skb with no associated socket - dropping\n"); | |
| 2498 | + kfree_skb(skb); | |
| 2499 | + skb = NULL; | |
| 2500 | +#endif | |
| 2501 | + } | |
| 2494 | 2502 | #endif |
| 2495 | 2503 | |
| 2496 | 2504 | return skb; |
| @@ -141,6 +141,10 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, · 140 unmodified lines | ||
| 141 | 141 | { |
| 142 | 142 | struct device *dev = simple_priv_to_dev(priv); |
| 143 | 143 | |
| 144 | + /* dai might be NULL */ | |
| 145 | + if (!dai) | |
| 146 | + return; | |
| 147 | + | |
| 144 | 148 | if (dai->name) |
| 145 | 149 | dev_dbg(dev, "%s dai name = %s\n", |
| 146 | 150 | name, dai->name); |
| @@ -498,10 +498,10 @@ rxrpc_tx_points; · 497 unmodified lines | ||
| 498 | 498 | #define E_(a, b) { a, b } |
| 499 | 499 | |
| 500 | 500 | TRACE_EVENT(rxrpc_local, |
| 501 | − TP_PROTO(struct rxrpc_local *local, enum rxrpc_local_trace op, | |
| 501 | + TP_PROTO(unsigned int local_debug_id, enum rxrpc_local_trace op, | |
| 502 | 502 | int usage, const void *where), |
| 503 | 503 | |
| 504 | − TP_ARGS(local, op, usage, where), | |
| 504 | + TP_ARGS(local_debug_id, op, usage, where), | |
| 505 | 505 | |
| 506 | 506 | TP_STRUCT__entry( |
| 507 | 507 | __field(unsigned int, local ) |
| @@ -511,7 +511,7 @@ TRACE_EVENT(rxrpc_local, · 3 unmodified lines | ||
| 511 | 511 | ), |
| 512 | 512 | |
| 513 | 513 | TP_fast_assign( |
| 514 | − __entry->local = local->debug_id; | |
| 514 | + __entry->local = local_debug_id; | |
| 515 | 515 | __entry->op = op; |
| 516 | 516 | __entry->usage = usage; |
| 517 | 517 | __entry->where = where; |
| @@ -1467,8 +1467,8 @@ union bpf_attr { · 1466 unmodified lines | ||
| 1467 | 1467 | * If no cookie has been set yet, generate a new cookie. Once |
| 1468 | 1468 | * generated, the socket cookie remains stable for the life of the |
| 1469 | 1469 | * socket. This helper can be useful for monitoring per socket |
| 1470 | − * networking traffic statistics as it provides a unique socket | |
| 1471 | − * identifier per namespace. | |
| 1470 | + * networking traffic statistics as it provides a global socket | |
| 1471 | + * identifier that can be assumed unique. | |
| 1472 | 1472 | * Return |
| 1473 | 1473 | * A 8-byte long non-decreasing number on success, or 0 if the |
| 1474 | 1474 | * socket field is missing inside *skb*. |
| @@ -410,21 +410,6 @@ struct kfd_ioctl_unmap_memory_from_gpu_args { · 409 unmodified lines | ||
| 410 | 410 | __u32 n_success; /* to/from KFD */ |
| 411 | 411 | }; |
| 412 | 412 | |
| 413 | −/* Allocate GWS for specific queue | |
| 414 | − * | |
| 415 | − * @gpu_id: device identifier | |
| 416 | − * @queue_id: queue's id that GWS is allocated for | |
| 417 | − * @num_gws: how many GWS to allocate | |
| 418 | − * @first_gws: index of the first GWS allocated. | |
| 419 | − * only support contiguous GWS allocation | |
| 420 | − */ | |
| 421 | −struct kfd_ioctl_alloc_queue_gws_args { | |
| 422 | − __u32 gpu_id; /* to KFD */ | |
| 423 | − __u32 queue_id; /* to KFD */ | |
| 424 | − __u32 num_gws; /* to KFD */ | |
| 425 | − __u32 first_gws; /* from KFD */ | |
| 426 | −}; | |
| 427 | − | |
| 428 | 413 | struct kfd_ioctl_get_dmabuf_info_args { |
| 429 | 414 | __u64 size; /* from KFD */ |
| 430 | 415 | __u64 metadata_ptr; /* to KFD */ |
| @@ -544,10 +529,7 @@ enum kfd_mmio_remap { · 113 unmodified lines | ||
| 544 | 529 | #define AMDKFD_IOC_IMPORT_DMABUF \ |
| 545 | 530 | AMDKFD_IOWR(0x1D, struct kfd_ioctl_import_dmabuf_args) |
| 546 | 531 | |
| 547 | −#define AMDKFD_IOC_ALLOC_QUEUE_GWS \ | |
| 548 | − AMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args) | |
| 549 | − | |
| 550 | 532 | #define AMDKFD_COMMAND_START 0x01 |
| 551 | −#define AMDKFD_COMMAND_END 0x1F | |
| 533 | +#define AMDKFD_COMMAND_END 0x1E | |
| 552 | 534 | |
| 553 | 535 | #endif |
| @@ -180,6 +180,7 @@ struct siw_cqe { · 179 unmodified lines | ||
| 180 | 180 | * to control CQ arming. |
| 181 | 181 | */ |
| 182 | 182 | struct siw_cq_ctrl { |
| 183 | − __aligned_u64 notify; | |
| 183 | + __u32 flags; | |
| 184 | + __u32 pad; | |
| 184 | 185 | }; |
| 185 | 186 | #endif |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | #ifndef __INCLUDE_UAPI_SOF_FW_H__ |
| 14 | 14 | #define __INCLUDE_UAPI_SOF_FW_H__ |
| 15 | 15 | |
| 16 | +#include <linux/types.h> | |
| 17 | + | |
| 16 | 18 | #define SND_SOF_FW_SIG_SIZE 4 |
| 17 | 19 | #define SND_SOF_FW_ABI 1 |
| 18 | 20 | #define SND_SOF_FW_SIG "Reef" |
| @@ -46,8 +48,8 @@ enum snd_sof_fw_blk_type { · 27 unmodified lines | ||
| 46 | 48 | |
| 47 | 49 | struct snd_sof_blk_hdr { |
| 48 | 50 | enum snd_sof_fw_blk_type type; |
| 49 | − uint32_t size; /* bytes minus this header */ | |
| 50 | − uint32_t offset; /* offset from base */ | |
| 51 | + __u32 size; /* bytes minus this header */ | |
| 52 | + __u32 offset; /* offset from base */ | |
| 51 | 53 | } __packed; |
| 52 | 54 | |
| 53 | 55 | /* |
| @@ -61,8 +63,8 @@ enum snd_sof_fw_mod_type { · 7 unmodified lines | ||
| 61 | 63 | |
| 62 | 64 | struct snd_sof_mod_hdr { |
| 63 | 65 | enum snd_sof_fw_mod_type type; |
| 64 | − uint32_t size; /* bytes minus this header */ | |
| 65 | − uint32_t num_blocks; /* number of blocks */ | |
| 66 | + __u32 size; /* bytes minus this header */ | |
| 67 | + __u32 num_blocks; /* number of blocks */ | |
| 66 | 68 | } __packed; |
| 67 | 69 | |
| 68 | 70 | /* |
| @@ -70,9 +72,9 @@ struct snd_sof_mod_hdr { · 1 unmodified line | ||
| 70 | 72 | */ |
| 71 | 73 | struct snd_sof_fw_header { |
| 72 | 74 | unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */ |
| 73 | − uint32_t file_size; /* size of file minus this header */ | |
| 74 | − uint32_t num_modules; /* number of modules */ | |
| 75 | − uint32_t abi; /* version of header format */ | |
| 75 | + __u32 file_size; /* size of file minus this header */ | |
| 76 | + __u32 num_modules; /* number of modules */ | |
| 77 | + __u32 abi; /* version of header format */ | |
| 76 | 78 | } __packed; |
| 77 | 79 | |
| 78 | 80 | #endif |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | #ifndef __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__ |
| 10 | 10 | #define __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__ |
| 11 | 11 | |
| 12 | +#include <linux/types.h> | |
| 13 | + | |
| 12 | 14 | /* |
| 13 | 15 | * Header for all non IPC ABI data. |
| 14 | 16 | * |
| @@ -16,12 +18,12 @@ · 1 unmodified line | ||
| 16 | 18 | * Used by any bespoke component data structures or binary blobs. |
| 17 | 19 | */ |
| 18 | 20 | struct sof_abi_hdr { |
| 19 | − uint32_t magic; /**< 'S', 'O', 'F', '\0' */ | |
| 20 | − uint32_t type; /**< component specific type */ | |
| 21 | − uint32_t size; /**< size in bytes of data excl. this struct */ | |
| 22 | − uint32_t abi; /**< SOF ABI version */ | |
| 23 | − uint32_t reserved[4]; /**< reserved for future use */ | |
| 24 | − uint32_t data[0]; /**< Component data - opaque to core */ | |
| 21 | + __u32 magic; /**< 'S', 'O', 'F', '\0' */ | |
| 22 | + __u32 type; /**< component specific type */ | |
| 23 | + __u32 size; /**< size in bytes of data excl. this struct */ | |
| 24 | + __u32 abi; /**< SOF ABI version */ | |
| 25 | + __u32 reserved[4]; /**< reserved for future use */ | |
| 26 | + __u32 data[0]; /**< Component data - opaque to core */ | |
| 25 | 27 | } __packed; |
| 26 | 28 | |
| 27 | 29 | #endif |
| @@ -1,3 +1,4 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 1 | 2 | /* |
| 2 | 3 | * kernel/configs.c |
| 3 | 4 | * Echo the kernel .config file used to build the kernel |
| @@ -6,21 +7,6 @@ · 2 unmodified lines | ||
| 6 | 7 | * Copyright (C) 2002 Randy Dunlap <rdunlap@xenotime.net> |
| 7 | 8 | * Copyright (C) 2002 Al Stone <ahs3@fc.hp.com> |
| 8 | 9 | * Copyright (C) 2002 Hewlett-Packard Company |
| 9 | − * | |
| 10 | − * This program is free software; you can redistribute it and/or modify | |
| 11 | − * it under the terms of the GNU General Public License as published by | |
| 12 | − * the Free Software Foundation; either version 2 of the License, or (at | |
| 13 | − * your option) any later version. | |
| 14 | − * | |
| 15 | − * This program is distributed in the hope that it will be useful, but | |
| 16 | − * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 17 | − * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | |
| 18 | − * NON INFRINGEMENT. See the GNU General Public License for more | |
| 19 | − * details. | |
| 20 | − * | |
| 21 | − * You should have received a copy of the GNU General Public License | |
| 22 | − * along with this program; if not, write to the Free Software | |
| 23 | − * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 24 | 10 | */ |
| 25 | 11 | |
| 26 | 12 | #include <linux/kernel.h> |
| @@ -47,9 +47,6 @@ u64 dma_direct_get_required_mask(struct device *dev) · 46 unmodified lines | ||
| 47 | 47 | { |
| 48 | 48 | u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT); |
| 49 | 49 | |
| 50 | − if (dev->bus_dma_mask && dev->bus_dma_mask < max_dma) | |
| 51 | − max_dma = dev->bus_dma_mask; | |
| 52 | − | |
| 53 | 50 | return (1ULL << (fls64(max_dma) - 1)) * 2 - 1; |
| 54 | 51 | } |
| 55 | 52 | |
| @@ -130,10 +127,12 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size, · 74 unmodified lines | ||
| 130 | 127 | if (!page) |
| 131 | 128 | return NULL; |
| 132 | 129 | |
| 133 | − if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | |
| 130 | + if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) && | |
| 131 | + !force_dma_unencrypted(dev)) { | |
| 134 | 132 | /* remove any dirty cache lines on the kernel alias */ |
| 135 | 133 | if (!PageHighMem(page)) |
| 136 | 134 | arch_dma_prep_coherent(page, size); |
| 135 | + *dma_handle = phys_to_dma(dev, page_to_phys(page)); | |
| 137 | 136 | /* return the page pointer as the opaque cookie */ |
| 138 | 137 | return page; |
| 139 | 138 | } |
| @@ -178,7 +177,8 @@ void dma_direct_free_pages(struct device *dev, size_t size, void *cpu_addr, · 38 unmodified lines | ||
| 178 | 177 | { |
| 179 | 178 | unsigned int page_order = get_order(size); |
| 180 | 179 | |
| 181 | − if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) { | |
| 180 | + if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) && | |
| 181 | + !force_dma_unencrypted(dev)) { | |
| 182 | 182 | /* cpu_addr is a struct page cookie, not a kernel address */ |
| 183 | 183 | __dma_direct_free_pages(dev, size, cpu_addr); |
| 184 | 184 | return; |
| @@ -150,6 +150,23 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, · 149 unmodified lines | ||
| 150 | 150 | } |
| 151 | 151 | EXPORT_SYMBOL(dma_get_sgtable_attrs); |
| 152 | 152 | |
| 153 | +#ifdef CONFIG_MMU | |
| 154 | +/* | |
| 155 | + * Return the page attributes used for mapping dma_alloc_* memory, either in | |
| 156 | + * kernel space if remapping is needed, or to userspace through dma_mmap_*. | |
| 157 | + */ | |
| 158 | +pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs) | |
| 159 | +{ | |
| 160 | + if (dev_is_dma_coherent(dev) || | |
| 161 | + (IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) && | |
| 162 | + (attrs & DMA_ATTR_NON_CONSISTENT))) | |
| 163 | + return prot; | |
| 164 | + if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT)) | |
| 165 | + return arch_dma_mmap_pgprot(dev, prot, attrs); | |
| 166 | + return pgprot_noncached(prot); | |
| 167 | +} | |
| 168 | +#endif /* CONFIG_MMU */ | |
| 169 | + | |
| 153 | 170 | /* |
| 154 | 171 | * Create userspace mapping for the DMA-coherent memory. |
| 155 | 172 | */ |
| @@ -164,7 +181,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, · 8 unmodified lines | ||
| 164 | 181 | unsigned long pfn; |
| 165 | 182 | int ret = -ENXIO; |
| 166 | 183 | |
| 167 | − vma->vm_page_prot = arch_dma_mmap_pgprot(dev, vma->vm_page_prot, attrs); | |
| 184 | + vma->vm_page_prot = dma_pgprot(dev, vma->vm_page_prot, attrs); | |
| 168 | 185 | |
| 169 | 186 | if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) |
| 170 | 187 | return ret; |
| @@ -218,7 +218,7 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, · 217 unmodified lines | ||
| 218 | 218 | |
| 219 | 219 | /* create a coherent mapping */ |
| 220 | 220 | ret = dma_common_contiguous_remap(page, size, VM_USERMAP, |
| 221 | − arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs), | |
| 221 | + dma_pgprot(dev, PAGE_KERNEL, attrs), | |
| 222 | 222 | __builtin_return_address(0)); |
| 223 | 223 | if (!ret) { |
| 224 | 224 | __dma_direct_free_pages(dev, size, page); |
| @@ -251,11 +251,9 @@ irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) · 250 unmodified lines | ||
| 251 | 251 | * Determine the number of vectors which need interrupt affinities |
| 252 | 252 | * assigned. If the pre/post request exhausts the available vectors |
| 253 | 253 | * then nothing to do here except for invoking the calc_sets() |
| 254 | − * callback so the device driver can adjust to the situation. If there | |
| 255 | − * is only a single vector, then managing the queue is pointless as | |
| 256 | − * well. | |
| 254 | + * callback so the device driver can adjust to the situation. | |
| 257 | 255 | */ |
| 258 | − if (nvecs > 1 && nvecs > affd->pre_vectors + affd->post_vectors) | |
| 256 | + if (nvecs > affd->pre_vectors + affd->post_vectors) | |
| 259 | 257 | affvecs = nvecs - affd->pre_vectors - affd->post_vectors; |
| 260 | 258 | else |
| 261 | 259 | affvecs = 0; |
| @@ -40,6 +40,7 @@ struct sugov_policy { · 39 unmodified lines | ||
| 40 | 40 | struct task_struct *thread; |
| 41 | 41 | bool work_in_progress; |
| 42 | 42 | |
| 43 | + bool limits_changed; | |
| 43 | 44 | bool need_freq_update; |
| 44 | 45 | }; |
| 45 | 46 | |
| @@ -89,8 +90,11 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) · 43 unmodified lines | ||
| 89 | 90 | !cpufreq_this_cpu_can_update(sg_policy->policy)) |
| 90 | 91 | return false; |
| 91 | 92 | |
| 92 | − if (unlikely(sg_policy->need_freq_update)) | |
| 93 | + if (unlikely(sg_policy->limits_changed)) { | |
| 94 | + sg_policy->limits_changed = false; | |
| 95 | + sg_policy->need_freq_update = true; | |
| 93 | 96 | return true; |
| 97 | + } | |
| 94 | 98 | |
| 95 | 99 | delta_ns = time - sg_policy->last_freq_update_time; |
| 96 | 100 | |
| @@ -437,7 +441,7 @@ static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; } · 340 unmodified lines | ||
| 437 | 441 | static inline void ignore_dl_rate_limit(struct sugov_cpu *sg_cpu, struct sugov_policy *sg_policy) |
| 438 | 442 | { |
| 439 | 443 | if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_dl) |
| 440 | − sg_policy->need_freq_update = true; | |
| 444 | + sg_policy->limits_changed = true; | |
| 441 | 445 | } |
| 442 | 446 | |
| 443 | 447 | static void sugov_update_single(struct update_util_data *hook, u64 time, |
| @@ -457,7 +461,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, · 13 unmodified lines | ||
| 457 | 461 | if (!sugov_should_update_freq(sg_policy, time)) |
| 458 | 462 | return; |
| 459 | 463 | |
| 460 | − busy = sugov_cpu_is_busy(sg_cpu); | |
| 464 | + /* Limits may have changed, don't skip frequency update */ | |
| 465 | + busy = !sg_policy->need_freq_update && sugov_cpu_is_busy(sg_cpu); | |
| 461 | 466 | |
| 462 | 467 | util = sugov_get_util(sg_cpu); |
| 463 | 468 | max = sg_cpu->max; |
| @@ -831,6 +836,7 @@ static int sugov_start(struct cpufreq_policy *policy) · 367 unmodified lines | ||
| 831 | 836 | sg_policy->last_freq_update_time = 0; |
| 832 | 837 | sg_policy->next_freq = 0; |
| 833 | 838 | sg_policy->work_in_progress = false; |
| 839 | + sg_policy->limits_changed = false; | |
| 834 | 840 | sg_policy->need_freq_update = false; |
| 835 | 841 | sg_policy->cached_raw_freq = 0; |
| 836 | 842 | |
| @@ -879,7 +885,7 @@ static void sugov_limits(struct cpufreq_policy *policy) · 42 unmodified lines | ||
| 879 | 885 | mutex_unlock(&sg_policy->work_lock); |
| 880 | 886 | } |
| 881 | 887 | |
| 882 | − sg_policy->need_freq_update = true; | |
| 888 | + sg_policy->limits_changed = true; | |
| 883 | 889 | } |
| 884 | 890 | |
| 885 | 891 | struct cpufreq_governor schedutil_gov = { |
| @@ -2088,17 +2088,13 @@ retry: · 2087 unmodified lines | ||
| 2088 | 2088 | } |
| 2089 | 2089 | |
| 2090 | 2090 | deactivate_task(rq, next_task, 0); |
| 2091 | − sub_running_bw(&next_task->dl, &rq->dl); | |
| 2092 | − sub_rq_bw(&next_task->dl, &rq->dl); | |
| 2093 | 2091 | set_task_cpu(next_task, later_rq->cpu); |
| 2094 | − add_rq_bw(&next_task->dl, &later_rq->dl); | |
| 2095 | 2092 | |
| 2096 | 2093 | /* |
| 2097 | 2094 | * Update the later_rq clock here, because the clock is used |
| 2098 | 2095 | * by the cpufreq_update_util() inside __add_running_bw(). |
| 2099 | 2096 | */ |
| 2100 | 2097 | update_rq_clock(later_rq); |
| 2101 | − add_running_bw(&next_task->dl, &later_rq->dl); | |
| 2102 | 2098 | activate_task(later_rq, next_task, ENQUEUE_NOCLOCK); |
| 2103 | 2099 | ret = 1; |
| 2104 | 2100 | |
| @@ -2186,11 +2182,7 @@ static void pull_dl_task(struct rq *this_rq) · 81 unmodified lines | ||
| 2186 | 2182 | resched = true; |
| 2187 | 2183 | |
| 2188 | 2184 | deactivate_task(src_rq, p, 0); |
| 2189 | − sub_running_bw(&p->dl, &src_rq->dl); | |
| 2190 | − sub_rq_bw(&p->dl, &src_rq->dl); | |
| 2191 | 2185 | set_task_cpu(p, this_cpu); |
| 2192 | − add_rq_bw(&p->dl, &this_rq->dl); | |
| 2193 | − add_running_bw(&p->dl, &this_rq->dl); | |
| 2194 | 2186 | activate_task(this_rq, p, 0); |
| 2195 | 2187 | dmin = p->dl.deadline; |
| 2196 | 2188 | |
| @@ -1051,7 +1051,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, · 1050 unmodified lines | ||
| 1051 | 1051 | |
| 1052 | 1052 | if (!rcu_access_pointer(group->poll_kworker)) { |
| 1053 | 1053 | struct sched_param param = { |
| 1054 | − .sched_priority = MAX_RT_PRIO - 1, | |
| 1054 | + .sched_priority = 1, | |
| 1055 | 1055 | }; |
| 1056 | 1056 | struct kthread_worker *kworker; |
| 1057 | 1057 | |
| @@ -1061,7 +1061,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, · 3 unmodified lines | ||
| 1061 | 1061 | mutex_unlock(&group->trigger_lock); |
| 1062 | 1062 | return ERR_CAST(kworker); |
| 1063 | 1063 | } |
| 1064 | − sched_setscheduler(kworker->task, SCHED_FIFO, ¶m); | |
| 1064 | + sched_setscheduler_nocheck(kworker->task, SCHED_FIFO, ¶m); | |
| 1065 | 1065 | kthread_init_delayed_work(&group->poll_work, |
| 1066 | 1066 | psi_poll_work); |
| 1067 | 1067 | rcu_assign_pointer(group->poll_kworker, kworker); |
| @@ -644,30 +644,40 @@ release: · 643 unmodified lines | ||
| 644 | 644 | * available |
| 645 | 645 | * never: never stall for any thp allocation |
| 646 | 646 | */ |
| 647 | −static inline gfp_t alloc_hugepage_direct_gfpmask(struct vm_area_struct *vma) | |
| 647 | +static inline gfp_t alloc_hugepage_direct_gfpmask(struct vm_area_struct *vma, unsigned long addr) | |
| 648 | 648 | { |
| 649 | 649 | const bool vma_madvised = !!(vma->vm_flags & VM_HUGEPAGE); |
| 650 | + gfp_t this_node = 0; | |
| 651 | + | |
| 652 | +#ifdef CONFIG_NUMA | |
| 653 | + struct mempolicy *pol; | |
| 654 | + /* | |
| 655 | + * __GFP_THISNODE is used only when __GFP_DIRECT_RECLAIM is not | |
| 656 | + * specified, to express a general desire to stay on the current | |
| 657 | + * node for optimistic allocation attempts. If the defrag mode | |
| 658 | + * and/or madvise hint requires the direct reclaim then we prefer | |
| 659 | + * to fallback to other node rather than node reclaim because that | |
| 660 | + * can lead to excessive reclaim even though there is free memory | |
| 661 | + * on other nodes. We expect that NUMA preferences are specified | |
| 662 | + * by memory policies. | |
| 663 | + */ | |
| 664 | + pol = get_vma_policy(vma, addr); | |
| 665 | + if (pol->mode != MPOL_BIND) | |
| 666 | + this_node = __GFP_THISNODE; | |
| 667 | + mpol_cond_put(pol); | |
| 668 | +#endif | |
| 650 | 669 | |
| 651 | − /* Always do synchronous compaction */ | |
| 652 | 670 | if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags)) |
| 653 | 671 | return GFP_TRANSHUGE | (vma_madvised ? 0 : __GFP_NORETRY); |
| 654 | − | |
| 655 | − /* Kick kcompactd and fail quickly */ | |
| 656 | 672 | if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags)) |
| 657 | − return GFP_TRANSHUGE_LIGHT | __GFP_KSWAPD_RECLAIM; | |
| 658 | − | |
| 659 | − /* Synchronous compaction if madvised, otherwise kick kcompactd */ | |
| 673 | + return GFP_TRANSHUGE_LIGHT | __GFP_KSWAPD_RECLAIM | this_node; | |
| 660 | 674 | if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags)) |
| 661 | − return GFP_TRANSHUGE_LIGHT | | |
| 662 | − (vma_madvised ? __GFP_DIRECT_RECLAIM : | |
| 663 | − __GFP_KSWAPD_RECLAIM); | |
| 664 | − | |
| 665 | − /* Only do synchronous compaction if madvised */ | |
| 675 | + return GFP_TRANSHUGE_LIGHT | (vma_madvised ? __GFP_DIRECT_RECLAIM : | |
| 676 | + __GFP_KSWAPD_RECLAIM | this_node); | |
| 666 | 677 | if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags)) |
| 667 | − return GFP_TRANSHUGE_LIGHT | | |
| 668 | − (vma_madvised ? __GFP_DIRECT_RECLAIM : 0); | |
| 669 | − | |
| 670 | − return GFP_TRANSHUGE_LIGHT; | |
| 678 | + return GFP_TRANSHUGE_LIGHT | (vma_madvised ? __GFP_DIRECT_RECLAIM : | |
| 679 | + this_node); | |
| 680 | + return GFP_TRANSHUGE_LIGHT | this_node; | |
| 671 | 681 | } |
| 672 | 682 | |
| 673 | 683 | /* Caller must hold page table lock. */ |
| @@ -739,8 +749,8 @@ vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf) · 65 unmodified lines | ||
| 739 | 749 | pte_free(vma->vm_mm, pgtable); |
| 740 | 750 | return ret; |
| 741 | 751 | } |
| 742 | − gfp = alloc_hugepage_direct_gfpmask(vma); | |
| 743 | − page = alloc_hugepage_vma(gfp, vma, haddr, HPAGE_PMD_ORDER); | |
| 752 | + gfp = alloc_hugepage_direct_gfpmask(vma, haddr); | |
| 753 | + page = alloc_pages_vma(gfp, HPAGE_PMD_ORDER, vma, haddr, numa_node_id()); | |
| 744 | 754 | if (unlikely(!page)) { |
| 745 | 755 | count_vm_event(THP_FAULT_FALLBACK); |
| 746 | 756 | return VM_FAULT_FALLBACK; |
| @@ -1347,8 +1357,9 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) · 600 unmodified lines | ||
| 1347 | 1357 | alloc: |
| 1348 | 1358 | if (__transparent_hugepage_enabled(vma) && |
| 1349 | 1359 | !transparent_hugepage_debug_cow()) { |
| 1350 | − huge_gfp = alloc_hugepage_direct_gfpmask(vma); | |
| 1351 | − new_page = alloc_hugepage_vma(huge_gfp, vma, haddr, HPAGE_PMD_ORDER); | |
| 1360 | + huge_gfp = alloc_hugepage_direct_gfpmask(vma, haddr); | |
| 1361 | + new_page = alloc_pages_vma(huge_gfp, HPAGE_PMD_ORDER, vma, | |
| 1362 | + haddr, numa_node_id()); | |
| 1352 | 1363 | } else |
| 1353 | 1364 | new_page = NULL; |
| 1354 | 1365 | |
| @@ -3856,6 +3856,25 @@ retry: · 3855 unmodified lines | ||
| 3856 | 3856 | |
| 3857 | 3857 | page = alloc_huge_page(vma, haddr, 0); |
| 3858 | 3858 | if (IS_ERR(page)) { |
| 3859 | + /* | |
| 3860 | + * Returning error will result in faulting task being | |
| 3861 | + * sent SIGBUS. The hugetlb fault mutex prevents two | |
| 3862 | + * tasks from racing to fault in the same page which | |
| 3863 | + * could result in false unable to allocate errors. | |
| 3864 | + * Page migration does not take the fault mutex, but | |
| 3865 | + * does a clear then write of pte's under page table | |
| 3866 | + * lock. Page fault code could race with migration, | |
| 3867 | + * notice the clear pte and try to allocate a page | |
| 3868 | + * here. Before returning error, get ptl and make | |
| 3869 | + * sure there really is no pte entry. | |
| 3870 | + */ | |
| 3871 | + ptl = huge_pte_lock(h, mm, ptep); | |
| 3872 | + if (!huge_pte_none(huge_ptep_get(ptep))) { | |
| 3873 | + ret = 0; | |
| 3874 | + spin_unlock(ptl); | |
| 3875 | + goto out; | |
| 3876 | + } | |
| 3877 | + spin_unlock(ptl); | |
| 3859 | 3878 | ret = vmf_error(PTR_ERR(page)); |
| 3860 | 3879 | goto out; |
| 3861 | 3880 | } |
| @@ -1966,6 +1966,7 @@ static void kmemleak_disable(void) · 1965 unmodified lines | ||
| 1966 | 1966 | |
| 1967 | 1967 | /* stop any memory operation tracing */ |
| 1968 | 1968 | kmemleak_enabled = 0; |
| 1969 | + kmemleak_early_log = 0; | |
| 1969 | 1970 | |
| 1970 | 1971 | /* check whether it is too early for a kernel thread */ |
| 1971 | 1972 | if (kmemleak_initialized) |
| @@ -2009,7 +2010,6 @@ void __init kmemleak_init(void) · 37 unmodified lines | ||
| 2009 | 2010 | |
| 2010 | 2011 | #ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF |
| 2011 | 2012 | if (!kmemleak_skip_disable) { |
| 2012 | − kmemleak_early_log = 0; | |
| 2013 | 2013 | kmemleak_disable(); |
| 2014 | 2014 | return; |
| 2015 | 2015 | } |
| @@ -768,6 +768,26 @@ void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, · 767 unmodified lines | ||
| 768 | 768 | __this_cpu_write(pn->lruvec_stat_cpu->count[idx], x); |
| 769 | 769 | } |
| 770 | 770 | |
| 771 | +void __mod_lruvec_slab_state(void *p, enum node_stat_item idx, int val) | |
| 772 | +{ | |
| 773 | + struct page *page = virt_to_head_page(p); | |
| 774 | + pg_data_t *pgdat = page_pgdat(page); | |
| 775 | + struct mem_cgroup *memcg; | |
| 776 | + struct lruvec *lruvec; | |
| 777 | + | |
| 778 | + rcu_read_lock(); | |
| 779 | + memcg = memcg_from_slab_page(page); | |
| 780 | + | |
| 781 | + /* Untracked pages have no memcg, no lruvec. Update only the node */ | |
| 782 | + if (!memcg || memcg == root_mem_cgroup) { | |
| 783 | + __mod_node_page_state(pgdat, idx, val); | |
| 784 | + } else { | |
| 785 | + lruvec = mem_cgroup_lruvec(pgdat, memcg); | |
| 786 | + __mod_lruvec_state(lruvec, idx, val); | |
| 787 | + } | |
| 788 | + rcu_read_unlock(); | |
| 789 | +} | |
| 790 | + | |
| 771 | 791 | /** |
| 772 | 792 | * __count_memcg_events - account VM events in a cgroup |
| 773 | 793 | * @memcg: the memory cgroup |
| @@ -1130,26 +1150,45 @@ void mem_cgroup_iter_break(struct mem_cgroup *root, · 356 unmodified lines | ||
| 1130 | 1150 | css_put(&prev->css); |
| 1131 | 1151 | } |
| 1132 | 1152 | |
| 1133 | −static void invalidate_reclaim_iterators(struct mem_cgroup *dead_memcg) | |
| 1153 | +static void __invalidate_reclaim_iterators(struct mem_cgroup *from, | |
| 1154 | + struct mem_cgroup *dead_memcg) | |
| 1134 | 1155 | { |
| 1135 | − struct mem_cgroup *memcg = dead_memcg; | |
| 1136 | 1156 | struct mem_cgroup_reclaim_iter *iter; |
| 1137 | 1157 | struct mem_cgroup_per_node *mz; |
| 1138 | 1158 | int nid; |
| 1139 | 1159 | int i; |
| 1140 | 1160 | |
| 1141 | − for (; memcg; memcg = parent_mem_cgroup(memcg)) { | |
| 1142 | − for_each_node(nid) { | |
| 1143 | − mz = mem_cgroup_nodeinfo(memcg, nid); | |
| 1144 | − for (i = 0; i <= DEF_PRIORITY; i++) { | |
| 1145 | − iter = &mz->iter[i]; | |
| 1146 | − cmpxchg(&iter->position, | |
| 1147 | − dead_memcg, NULL); | |
| 1148 | − } | |
| 1161 | + for_each_node(nid) { | |
| 1162 | + mz = mem_cgroup_nodeinfo(from, nid); | |
| 1163 | + for (i = 0; i <= DEF_PRIORITY; i++) { | |
| 1164 | + iter = &mz->iter[i]; | |
| 1165 | + cmpxchg(&iter->position, | |
| 1166 | + dead_memcg, NULL); | |
| 1149 | 1167 | } |
| 1150 | 1168 | } |
| 1151 | 1169 | } |
| 1152 | 1170 | |
| 1171 | +static void invalidate_reclaim_iterators(struct mem_cgroup *dead_memcg) | |
| 1172 | +{ | |
| 1173 | + struct mem_cgroup *memcg = dead_memcg; | |
| 1174 | + struct mem_cgroup *last; | |
| 1175 | + | |
| 1176 | + do { | |
| 1177 | + __invalidate_reclaim_iterators(memcg, dead_memcg); | |
| 1178 | + last = memcg; | |
| 1179 | + } while ((memcg = parent_mem_cgroup(memcg))); | |
| 1180 | + | |
| 1181 | + /* | |
| 1182 | + * When cgruop1 non-hierarchy mode is used, | |
| 1183 | + * parent_mem_cgroup() does not walk all the way up to the | |
| 1184 | + * cgroup root (root_mem_cgroup). So we have to handle | |
| 1185 | + * dead_memcg from cgroup root separately. | |
| 1186 | + */ | |
| 1187 | + if (last != root_mem_cgroup) | |
| 1188 | + __invalidate_reclaim_iterators(root_mem_cgroup, | |
| 1189 | + dead_memcg); | |
| 1190 | +} | |
| 1191 | + | |
| 1153 | 1192 | /** |
| 1154 | 1193 | * mem_cgroup_scan_tasks - iterate over tasks of a memory cgroup hierarchy |
| 1155 | 1194 | * @memcg: hierarchy root |
| @@ -403,7 +403,7 @@ static const struct mempolicy_operations mpol_ops[MPOL_MAX] = { · 402 unmodified lines | ||
| 403 | 403 | }, |
| 404 | 404 | }; |
| 405 | 405 | |
| 406 | −static void migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 406 | +static int migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 407 | 407 | unsigned long flags); |
| 408 | 408 | |
| 409 | 409 | struct queue_pages { |
| @@ -429,11 +429,14 @@ static inline bool queue_pages_required(struct page *page, · 19 unmodified lines | ||
| 429 | 429 | } |
| 430 | 430 | |
| 431 | 431 | /* |
| 432 | − * queue_pages_pmd() has three possible return values: | |
| 433 | − * 1 - pages are placed on the right node or queued successfully. | |
| 434 | − * 0 - THP was split. | |
| 435 | − * -EIO - is migration entry or MPOL_MF_STRICT was specified and an existing | |
| 436 | − * page was already on a node that does not follow the policy. | |
| 432 | + * queue_pages_pmd() has four possible return values: | |
| 433 | + * 0 - pages are placed on the right node or queued successfully. | |
| 434 | + * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were | |
| 435 | + * specified. | |
| 436 | + * 2 - THP was split. | |
| 437 | + * -EIO - is migration entry or only MPOL_MF_STRICT was specified and an | |
| 438 | + * existing page was already on a node that does not follow the | |
| 439 | + * policy. | |
| 437 | 440 | */ |
| 438 | 441 | static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, |
| 439 | 442 | unsigned long end, struct mm_walk *walk) |
| @@ -451,23 +454,20 @@ static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, · 11 unmodified lines | ||
| 451 | 454 | if (is_huge_zero_page(page)) { |
| 452 | 455 | spin_unlock(ptl); |
| 453 | 456 | __split_huge_pmd(walk->vma, pmd, addr, false, NULL); |
| 457 | + ret = 2; | |
| 454 | 458 | goto out; |
| 455 | 459 | } |
| 456 | − if (!queue_pages_required(page, qp)) { | |
| 457 | − ret = 1; | |
| 460 | + if (!queue_pages_required(page, qp)) | |
| 458 | 461 | goto unlock; |
| 459 | − } | |
| 460 | 462 | |
| 461 | − ret = 1; | |
| 462 | 463 | flags = qp->flags; |
| 463 | 464 | /* go to thp migration */ |
| 464 | 465 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { |
| 465 | − if (!vma_migratable(walk->vma)) { | |
| 466 | − ret = -EIO; | |
| 466 | + if (!vma_migratable(walk->vma) || | |
| 467 | + migrate_page_add(page, qp->pagelist, flags)) { | |
| 468 | + ret = 1; | |
| 467 | 469 | goto unlock; |
| 468 | 470 | } |
| 469 | − | |
| 470 | − migrate_page_add(page, qp->pagelist, flags); | |
| 471 | 471 | } else |
| 472 | 472 | ret = -EIO; |
| 473 | 473 | unlock: |
| @@ -479,6 +479,13 @@ out: · 5 unmodified lines | ||
| 479 | 479 | /* |
| 480 | 480 | * Scan through pages checking if pages follow certain conditions, |
| 481 | 481 | * and move them to the pagelist if they do. |
| 482 | + * | |
| 483 | + * queue_pages_pte_range() has three possible return values: | |
| 484 | + * 0 - pages are placed on the right node or queued successfully. | |
| 485 | + * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were | |
| 486 | + * specified. | |
| 487 | + * -EIO - only MPOL_MF_STRICT was specified and an existing page was already | |
| 488 | + * on a node that does not follow the policy. | |
| 482 | 489 | */ |
| 483 | 490 | static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, |
| 484 | 491 | unsigned long end, struct mm_walk *walk) |
| @@ -488,17 +495,17 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, · 3 unmodified lines | ||
| 488 | 495 | struct queue_pages *qp = walk->private; |
| 489 | 496 | unsigned long flags = qp->flags; |
| 490 | 497 | int ret; |
| 498 | + bool has_unmovable = false; | |
| 491 | 499 | pte_t *pte; |
| 492 | 500 | spinlock_t *ptl; |
| 493 | 501 | |
| 494 | 502 | ptl = pmd_trans_huge_lock(pmd, vma); |
| 495 | 503 | if (ptl) { |
| 496 | 504 | ret = queue_pages_pmd(pmd, ptl, addr, end, walk); |
| 497 | − if (ret > 0) | |
| 498 | − return 0; | |
| 499 | − else if (ret < 0) | |
| 505 | + if (ret != 2) | |
| 500 | 506 | return ret; |
| 501 | 507 | } |
| 508 | + /* THP was split, fall through to pte walk */ | |
| 502 | 509 | |
| 503 | 510 | if (pmd_trans_unstable(pmd)) |
| 504 | 511 | return 0; |
| @@ -519,14 +526,28 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, · 14 unmodified lines | ||
| 519 | 526 | if (!queue_pages_required(page, qp)) |
| 520 | 527 | continue; |
| 521 | 528 | if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { |
| 522 | − if (!vma_migratable(vma)) | |
| 529 | + /* MPOL_MF_STRICT must be specified if we get here */ | |
| 530 | + if (!vma_migratable(vma)) { | |
| 531 | + has_unmovable = true; | |
| 523 | 532 | break; |
| 524 | − migrate_page_add(page, qp->pagelist, flags); | |
| 533 | + } | |
| 534 | + | |
| 535 | + /* | |
| 536 | + * Do not abort immediately since there may be | |
| 537 | + * temporary off LRU pages in the range. Still | |
| 538 | + * need migrate other LRU pages. | |
| 539 | + */ | |
| 540 | + if (migrate_page_add(page, qp->pagelist, flags)) | |
| 541 | + has_unmovable = true; | |
| 525 | 542 | } else |
| 526 | 543 | break; |
| 527 | 544 | } |
| 528 | 545 | pte_unmap_unlock(pte - 1, ptl); |
| 529 | 546 | cond_resched(); |
| 547 | + | |
| 548 | + if (has_unmovable) | |
| 549 | + return 1; | |
| 550 | + | |
| 530 | 551 | return addr != end ? -EIO : 0; |
| 531 | 552 | } |
| 532 | 553 | |
| @@ -639,7 +660,13 @@ static int queue_pages_test_walk(unsigned long start, unsigned long end, · 106 unmodified lines | ||
| 639 | 660 | * |
| 640 | 661 | * If pages found in a given range are on a set of nodes (determined by |
| 641 | 662 | * @nodes and @flags,) it's isolated and queued to the pagelist which is |
| 642 | − * passed via @private.) | |
| 663 | + * passed via @private. | |
| 664 | + * | |
| 665 | + * queue_pages_range() has three possible return values: | |
| 666 | + * 1 - there is unmovable page, but MPOL_MF_MOVE* & MPOL_MF_STRICT were | |
| 667 | + * specified. | |
| 668 | + * 0 - queue pages successfully or no misplaced page. | |
| 669 | + * -EIO - there is misplaced page and only MPOL_MF_STRICT was specified. | |
| 643 | 670 | */ |
| 644 | 671 | static int |
| 645 | 672 | queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, |
| @@ -940,7 +967,7 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, · 294 unmodified lines | ||
| 940 | 967 | /* |
| 941 | 968 | * page migration, thp tail pages can be passed. |
| 942 | 969 | */ |
| 943 | −static void migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 970 | +static int migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 944 | 971 | unsigned long flags) |
| 945 | 972 | { |
| 946 | 973 | struct page *head = compound_head(page); |
| @@ -953,8 +980,19 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist, · 6 unmodified lines | ||
| 953 | 980 | mod_node_page_state(page_pgdat(head), |
| 954 | 981 | NR_ISOLATED_ANON + page_is_file_cache(head), |
| 955 | 982 | hpage_nr_pages(head)); |
| 983 | + } else if (flags & MPOL_MF_STRICT) { | |
| 984 | + /* | |
| 985 | + * Non-movable page may reach here. And, there may be | |
| 986 | + * temporary off LRU pages or non-LRU movable pages. | |
| 987 | + * Treat them as unmovable pages since they can't be | |
| 988 | + * isolated, so they can't be moved at the moment. It | |
| 989 | + * should return -EIO for this case too. | |
| 990 | + */ | |
| 991 | + return -EIO; | |
| 956 | 992 | } |
| 957 | 993 | } |
| 994 | + | |
| 995 | + return 0; | |
| 958 | 996 | } |
| 959 | 997 | |
| 960 | 998 | /* page allocation callback for NUMA node migration */ |
| @@ -1142,8 +1180,8 @@ static struct page *new_page(struct page *page, unsigned long start) · 181 unmodified lines | ||
| 1142 | 1180 | } else if (PageTransHuge(page)) { |
| 1143 | 1181 | struct page *thp; |
| 1144 | 1182 | |
| 1145 | − thp = alloc_hugepage_vma(GFP_TRANSHUGE, vma, address, | |
| 1146 | − HPAGE_PMD_ORDER); | |
| 1183 | + thp = alloc_pages_vma(GFP_TRANSHUGE, HPAGE_PMD_ORDER, vma, | |
| 1184 | + address, numa_node_id()); | |
| 1147 | 1185 | if (!thp) |
| 1148 | 1186 | return NULL; |
| 1149 | 1187 | prep_transhuge_page(thp); |
| @@ -1157,9 +1195,10 @@ static struct page *new_page(struct page *page, unsigned long start) · 7 unmodified lines | ||
| 1157 | 1195 | } |
| 1158 | 1196 | #else |
| 1159 | 1197 | |
| 1160 | −static void migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 1198 | +static int migrate_page_add(struct page *page, struct list_head *pagelist, | |
| 1161 | 1199 | unsigned long flags) |
| 1162 | 1200 | { |
| 1201 | + return -EIO; | |
| 1163 | 1202 | } |
| 1164 | 1203 | |
| 1165 | 1204 | int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from, |
| @@ -1182,6 +1221,7 @@ static long do_mbind(unsigned long start, unsigned long len, · 16 unmodified lines | ||
| 1182 | 1221 | struct mempolicy *new; |
| 1183 | 1222 | unsigned long end; |
| 1184 | 1223 | int err; |
| 1224 | + int ret; | |
| 1185 | 1225 | LIST_HEAD(pagelist); |
| 1186 | 1226 | |
| 1187 | 1227 | if (flags & ~(unsigned long)MPOL_MF_VALID) |
| @@ -1243,10 +1283,15 @@ static long do_mbind(unsigned long start, unsigned long len, · 55 unmodified lines | ||
| 1243 | 1283 | if (err) |
| 1244 | 1284 | goto mpol_out; |
| 1245 | 1285 | |
| 1246 | − err = queue_pages_range(mm, start, end, nmask, | |
| 1286 | + ret = queue_pages_range(mm, start, end, nmask, | |
| 1247 | 1287 | flags | MPOL_MF_INVERT, &pagelist); |
| 1248 | − if (!err) | |
| 1249 | − err = mbind_range(mm, start, end, new); | |
| 1288 | + | |
| 1289 | + if (ret < 0) { | |
| 1290 | + err = -EIO; | |
| 1291 | + goto up_out; | |
| 1292 | + } | |
| 1293 | + | |
| 1294 | + err = mbind_range(mm, start, end, new); | |
| 1250 | 1295 | |
| 1251 | 1296 | if (!err) { |
| 1252 | 1297 | int nr_failed = 0; |
| @@ -1259,13 +1304,14 @@ static long do_mbind(unsigned long start, unsigned long len, · 6 unmodified lines | ||
| 1259 | 1304 | putback_movable_pages(&pagelist); |
| 1260 | 1305 | } |
| 1261 | 1306 | |
| 1262 | − if (nr_failed && (flags & MPOL_MF_STRICT)) | |
| 1307 | + if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) | |
| 1263 | 1308 | err = -EIO; |
| 1264 | 1309 | } else |
| 1265 | 1310 | putback_movable_pages(&pagelist); |
| 1266 | 1311 | |
| 1312 | +up_out: | |
| 1267 | 1313 | up_write(&mm->mmap_sem); |
| 1268 | − mpol_out: | |
| 1314 | +mpol_out: | |
| 1269 | 1315 | mpol_put(new); |
| 1270 | 1316 | return err; |
| 1271 | 1317 | } |
| @@ -1688,7 +1734,7 @@ struct mempolicy *__get_vma_policy(struct vm_area_struct *vma, · 416 unmodified lines | ||
| 1688 | 1734 | * freeing by another task. It is the caller's responsibility to free the |
| 1689 | 1735 | * extra reference for shared policies. |
| 1690 | 1736 | */ |
| 1691 | −static struct mempolicy *get_vma_policy(struct vm_area_struct *vma, | |
| 1737 | +struct mempolicy *get_vma_policy(struct vm_area_struct *vma, | |
| 1692 | 1738 | unsigned long addr) |
| 1693 | 1739 | { |
| 1694 | 1740 | struct mempolicy *pol = __get_vma_policy(vma, addr); |
| @@ -2037,7 +2083,6 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, · 342 unmodified lines | ||
| 2037 | 2083 | * @vma: Pointer to VMA or NULL if not available. |
| 2038 | 2084 | * @addr: Virtual Address of the allocation. Must be inside the VMA. |
| 2039 | 2085 | * @node: Which node to prefer for allocation (modulo policy). |
| 2040 | − * @hugepage: for hugepages try only the preferred node if possible | |
| 2041 | 2086 | * |
| 2042 | 2087 | * This function allocates a page from the kernel page pool and applies |
| 2043 | 2088 | * a NUMA policy associated with the VMA or the current process. |
| @@ -2048,7 +2093,7 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, · 4 unmodified lines | ||
| 2048 | 2093 | */ |
| 2049 | 2094 | struct page * |
| 2050 | 2095 | alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, |
| 2051 | − unsigned long addr, int node, bool hugepage) | |
| 2096 | + unsigned long addr, int node) | |
| 2052 | 2097 | { |
| 2053 | 2098 | struct mempolicy *pol; |
| 2054 | 2099 | struct page *page; |
| @@ -2066,31 +2111,6 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma, · 11 unmodified lines | ||
| 2066 | 2111 | goto out; |
| 2067 | 2112 | } |
| 2068 | 2113 | |
| 2069 | − if (unlikely(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hugepage)) { | |
| 2070 | − int hpage_node = node; | |
| 2071 | − | |
| 2072 | − /* | |
| 2073 | − * For hugepage allocation and non-interleave policy which | |
| 2074 | − * allows the current node (or other explicitly preferred | |
| 2075 | − * node) we only try to allocate from the current/preferred | |
| 2076 | − * node and don't fall back to other nodes, as the cost of | |
| 2077 | − * remote accesses would likely offset THP benefits. | |
| 2078 | − * | |
| 2079 | − * If the policy is interleave, or does not allow the current | |
| 2080 | − * node in its nodemask, we allocate the standard way. | |
| 2081 | − */ | |
| 2082 | − if (pol->mode == MPOL_PREFERRED && !(pol->flags & MPOL_F_LOCAL)) | |
| 2083 | − hpage_node = pol->v.preferred_node; | |
| 2084 | − | |
| 2085 | − nmask = policy_nodemask(gfp, pol); | |
| 2086 | − if (!nmask || node_isset(hpage_node, *nmask)) { | |
| 2087 | − mpol_cond_put(pol); | |
| 2088 | − page = __alloc_pages_node(hpage_node, | |
| 2089 | − gfp | __GFP_THISNODE, order); | |
| 2090 | − goto out; | |
| 2091 | − } | |
| 2092 | − } | |
| 2093 | − | |
| 2094 | 2114 | nmask = policy_nodemask(gfp, pol); |
| 2095 | 2115 | preferred_nid = policy_node(gfp, pol, node); |
| 2096 | 2116 | page = __alloc_pages_nodemask(gfp, order, preferred_nid, nmask); |
| @@ -91,6 +91,12 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap) · 90 unmodified lines | ||
| 91 | 91 | wait_for_completion(&pgmap->done); |
| 92 | 92 | percpu_ref_exit(pgmap->ref); |
| 93 | 93 | } |
| 94 | + /* | |
| 95 | + * Undo the pgmap ref assignment for the internal case as the | |
| 96 | + * caller may re-enable the same pgmap. | |
| 97 | + */ | |
| 98 | + if (pgmap->ref == &pgmap->internal_ref) | |
| 99 | + pgmap->ref = NULL; | |
| 94 | 100 | } |
| 95 | 101 | |
| 96 | 102 | static void devm_memremap_pages_release(void *data) |
| @@ -397,6 +403,30 @@ void __put_devmap_managed_page(struct page *page) · 300 unmodified lines | ||
| 397 | 403 | |
| 398 | 404 | mem_cgroup_uncharge(page); |
| 399 | 405 | |
| 406 | + /* | |
| 407 | + * When a device_private page is freed, the page->mapping field | |
| 408 | + * may still contain a (stale) mapping value. For example, the | |
| 409 | + * lower bits of page->mapping may still identify the page as | |
| 410 | + * an anonymous page. Ultimately, this entire field is just | |
| 411 | + * stale and wrong, and it will cause errors if not cleared. | |
| 412 | + * One example is: | |
| 413 | + * | |
| 414 | + * migrate_vma_pages() | |
| 415 | + * migrate_vma_insert_page() | |
| 416 | + * page_add_new_anon_rmap() | |
| 417 | + * __page_set_anon_rmap() | |
| 418 | + * ...checks page->mapping, via PageAnon(page) call, | |
| 419 | + * and incorrectly concludes that the page is an | |
| 420 | + * anonymous page. Therefore, it incorrectly, | |
| 421 | + * silently fails to set up the new anon rmap. | |
| 422 | + * | |
| 423 | + * For other types of ZONE_DEVICE pages, migration is either | |
| 424 | + * handled differently or not done at all, so there is no need | |
| 425 | + * to clear page->mapping. | |
| 426 | + */ | |
| 427 | + if (is_device_private_page(page)) | |
| 428 | + page->mapping = NULL; | |
| 429 | + | |
| 400 | 430 | page->pgmap->ops->page_free(page); |
| 401 | 431 | } else if (!count) |
| 402 | 432 | __put_page(page); |
| @@ -1475,7 +1475,15 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, · 1474 unmodified lines | ||
| 1475 | 1475 | /* |
| 1476 | 1476 | * No need to invalidate here it will synchronize on |
| 1477 | 1477 | * against the special swap migration pte. |
| 1478 | + * | |
| 1479 | + * The assignment to subpage above was computed from a | |
| 1480 | + * swap PTE which results in an invalid pointer. | |
| 1481 | + * Since only PAGE_SIZE pages can currently be | |
| 1482 | + * migrated, just set it to page. This will need to be | |
| 1483 | + * changed when hugepage migrations to device private | |
| 1484 | + * memory are supported. | |
| 1478 | 1485 | */ |
| 1486 | + subpage = page; | |
| 1479 | 1487 | goto discard; |
| 1480 | 1488 | } |
| 1481 | 1489 | |
| @@ -1466,7 +1466,7 @@ static struct page *shmem_alloc_hugepage(gfp_t gfp, · 1465 unmodified lines | ||
| 1466 | 1466 | |
| 1467 | 1467 | shmem_pseudo_vma_init(&pvma, info, hindex); |
| 1468 | 1468 | page = alloc_pages_vma(gfp | __GFP_COMP | __GFP_NORETRY | __GFP_NOWARN, |
| 1469 | − HPAGE_PMD_ORDER, &pvma, 0, numa_node_id(), true); | |
| 1469 | + HPAGE_PMD_ORDER, &pvma, 0, numa_node_id()); | |
| 1470 | 1470 | shmem_pseudo_vma_destroy(&pvma); |
| 1471 | 1471 | if (page) |
| 1472 | 1472 | prep_transhuge_page(page); |
| @@ -147,7 +147,7 @@ static inline void check_bogus_address(const unsigned long ptr, unsigned long n, · 146 unmodified lines | ||
| 147 | 147 | bool to_user) |
| 148 | 148 | { |
| 149 | 149 | /* Reject if object wraps past end of memory. */ |
| 150 | − if (ptr + n < ptr) | |
| 150 | + if (ptr + (n - 1) < ptr) | |
| 151 | 151 | usercopy_abort("wrapped address", NULL, to_user, 0, ptr + n); |
| 152 | 152 | |
| 153 | 153 | /* Reject if NULL or ZERO-allocation. */ |
| @@ -3278,10 +3278,20 @@ retry: · 3277 unmodified lines | ||
| 3278 | 3278 | if (va == NULL) |
| 3279 | 3279 | goto overflow; |
| 3280 | 3280 | |
| 3281 | + /* | |
| 3282 | + * If required width exeeds current VA block, move | |
| 3283 | + * base downwards and then recheck. | |
| 3284 | + */ | |
| 3285 | + if (base + end > va->va_end) { | |
| 3286 | + base = pvm_determine_end_from_reverse(&va, align) - end; | |
| 3287 | + term_area = area; | |
| 3288 | + continue; | |
| 3289 | + } | |
| 3290 | + | |
| 3281 | 3291 | /* |
| 3282 | 3292 | * If this VA does not fit, move base downwards and recheck. |
| 3283 | 3293 | */ |
| 3284 | − if (base + start < va->va_start || base + end > va->va_end) { | |
| 3294 | + if (base + start < va->va_start) { | |
| 3285 | 3295 | va = node_to_va(rb_prev(&va->rb_node)); |
| 3286 | 3296 | base = pvm_determine_end_from_reverse(&va, align) - end; |
| 3287 | 3297 | term_area = area; |
| @@ -88,9 +88,6 @@ struct scan_control { · 87 unmodified lines | ||
| 88 | 88 | /* Can pages be swapped as part of reclaim? */ |
| 89 | 89 | unsigned int may_swap:1; |
| 90 | 90 | |
| 91 | − /* e.g. boosted watermark reclaim leaves slabs alone */ | |
| 92 | − unsigned int may_shrinkslab:1; | |
| 93 | − | |
| 94 | 91 | /* |
| 95 | 92 | * Cgroups are not reclaimed below their configured memory.low, |
| 96 | 93 | * unless we threaten to OOM. If any cgroups are skipped due to |
| @@ -2714,10 +2711,8 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) · 2617 unmodified lines | ||
| 2714 | 2711 | shrink_node_memcg(pgdat, memcg, sc, &lru_pages); |
| 2715 | 2712 | node_lru_pages += lru_pages; |
| 2716 | 2713 | |
| 2717 | − if (sc->may_shrinkslab) { | |
| 2718 | − shrink_slab(sc->gfp_mask, pgdat->node_id, | |
| 2719 | − memcg, sc->priority); | |
| 2720 | − } | |
| 2714 | + shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, | |
| 2715 | + sc->priority); | |
| 2721 | 2716 | |
| 2722 | 2717 | /* Record the group's reclaim efficiency */ |
| 2723 | 2718 | vmpressure(sc->gfp_mask, memcg, false, |
| @@ -3194,7 +3189,6 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, · 470 unmodified lines | ||
| 3194 | 3189 | .may_writepage = !laptop_mode, |
| 3195 | 3190 | .may_unmap = 1, |
| 3196 | 3191 | .may_swap = 1, |
| 3197 | − .may_shrinkslab = 1, | |
| 3198 | 3192 | }; |
| 3199 | 3193 | |
| 3200 | 3194 | /* |
| @@ -3238,7 +3232,6 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, · 37 unmodified lines | ||
| 3238 | 3232 | .may_unmap = 1, |
| 3239 | 3233 | .reclaim_idx = MAX_NR_ZONES - 1, |
| 3240 | 3234 | .may_swap = !noswap, |
| 3241 | − .may_shrinkslab = 1, | |
| 3242 | 3235 | }; |
| 3243 | 3236 | unsigned long lru_pages; |
| 3244 | 3237 | |
| @@ -3286,7 +3279,6 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg, · 41 unmodified lines | ||
| 3286 | 3279 | .may_writepage = !laptop_mode, |
| 3287 | 3280 | .may_unmap = 1, |
| 3288 | 3281 | .may_swap = may_swap, |
| 3289 | − .may_shrinkslab = 1, | |
| 3290 | 3282 | }; |
| 3291 | 3283 | |
| 3292 | 3284 | set_task_reclaim_state(current, &sc.reclaim_state); |
| @@ -3598,7 +3590,6 @@ restart: · 305 unmodified lines | ||
| 3598 | 3590 | */ |
| 3599 | 3591 | sc.may_writepage = !laptop_mode && !nr_boost_reclaim; |
| 3600 | 3592 | sc.may_swap = !nr_boost_reclaim; |
| 3601 | − sc.may_shrinkslab = !nr_boost_reclaim; | |
| 3602 | 3593 | |
| 3603 | 3594 | /* |
| 3604 | 3595 | * Do some background aging of the anon list, to give |
| @@ -380,14 +380,12 @@ void workingset_update_node(struct xa_node *node) · 379 unmodified lines | ||
| 380 | 380 | if (node->count && node->count == node->nr_values) { |
| 381 | 381 | if (list_empty(&node->private_list)) { |
| 382 | 382 | list_lru_add(&shadow_nodes, &node->private_list); |
| 383 | − __inc_lruvec_page_state(virt_to_page(node), | |
| 384 | − WORKINGSET_NODES); | |
| 383 | + __inc_lruvec_slab_state(node, WORKINGSET_NODES); | |
| 385 | 384 | } |
| 386 | 385 | } else { |
| 387 | 386 | if (!list_empty(&node->private_list)) { |
| 388 | 387 | list_lru_del(&shadow_nodes, &node->private_list); |
| 389 | − __dec_lruvec_page_state(virt_to_page(node), | |
| 390 | − WORKINGSET_NODES); | |
| 388 | + __dec_lruvec_slab_state(node, WORKINGSET_NODES); | |
| 391 | 389 | } |
| 392 | 390 | } |
| 393 | 391 | } |
| @@ -480,7 +478,7 @@ static enum lru_status shadow_lru_isolate(struct list_head *item, · 86 unmodified lines | ||
| 480 | 478 | } |
| 481 | 479 | |
| 482 | 480 | list_lru_isolate(lru, item); |
| 483 | − __dec_lruvec_page_state(virt_to_page(node), WORKINGSET_NODES); | |
| 481 | + __dec_lruvec_slab_state(node, WORKINGSET_NODES); | |
| 484 | 482 | |
| 485 | 483 | spin_unlock(lru_lock); |
| 486 | 484 | |
| @@ -503,7 +501,7 @@ static enum lru_status shadow_lru_isolate(struct list_head *item, · 16 unmodified lines | ||
| 503 | 501 | * shadow entries we were tracking ... |
| 504 | 502 | */ |
| 505 | 503 | xas_store(&xas, NULL); |
| 506 | − __inc_lruvec_page_state(virt_to_page(node), WORKINGSET_NODERECLAIM); | |
| 504 | + __inc_lruvec_slab_state(node, WORKINGSET_NODERECLAIM); | |
| 507 | 505 | |
| 508 | 506 | out_invalid: |
| 509 | 507 | xa_unlock_irq(&mapping->i_pages); |
| @@ -817,9 +817,19 @@ out: · 816 unmodified lines | ||
| 817 | 817 | static void z3fold_destroy_pool(struct z3fold_pool *pool) |
| 818 | 818 | { |
| 819 | 819 | kmem_cache_destroy(pool->c_handle); |
| 820 | − z3fold_unregister_migration(pool); | |
| 821 | − destroy_workqueue(pool->release_wq); | |
| 820 | + | |
| 821 | + /* | |
| 822 | + * We need to destroy pool->compact_wq before pool->release_wq, | |
| 823 | + * as any pending work on pool->compact_wq will call | |
| 824 | + * queue_work(pool->release_wq, &pool->work). | |
| 825 | + * | |
| 826 | + * There are still outstanding pages until both workqueues are drained, | |
| 827 | + * so we cannot unregister migration until then. | |
| 828 | + */ | |
| 829 | + | |
| 822 | 830 | destroy_workqueue(pool->compact_wq); |
| 831 | + destroy_workqueue(pool->release_wq); | |
| 832 | + z3fold_unregister_migration(pool); | |
| 823 | 833 | kfree(pool); |
| 824 | 834 | } |
| 825 | 835 | |
| @@ -2303,7 +2303,7 @@ __batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, · 2302 unmodified lines | ||
| 2303 | 2303 | |
| 2304 | 2304 | while (bucket_tmp < hash->size) { |
| 2305 | 2305 | if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash, |
| 2306 | − *bucket, &idx_tmp)) | |
| 2306 | + bucket_tmp, &idx_tmp)) | |
| 2307 | 2307 | break; |
| 2308 | 2308 | |
| 2309 | 2309 | bucket_tmp++; |
| @@ -2420,8 +2420,10 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig) · 110 unmodified lines | ||
| 2420 | 2420 | batadv_mcast_want_unsnoop_update(bat_priv, orig, BATADV_NO_FLAGS); |
| 2421 | 2421 | batadv_mcast_want_ipv4_update(bat_priv, orig, BATADV_NO_FLAGS); |
| 2422 | 2422 | batadv_mcast_want_ipv6_update(bat_priv, orig, BATADV_NO_FLAGS); |
| 2423 | − batadv_mcast_want_rtr4_update(bat_priv, orig, BATADV_NO_FLAGS); | |
| 2424 | − batadv_mcast_want_rtr6_update(bat_priv, orig, BATADV_NO_FLAGS); | |
| 2423 | + batadv_mcast_want_rtr4_update(bat_priv, orig, | |
| 2424 | + BATADV_MCAST_WANT_NO_RTR4); | |
| 2425 | + batadv_mcast_want_rtr6_update(bat_priv, orig, | |
| 2426 | + BATADV_MCAST_WANT_NO_RTR6); | |
| 2425 | 2427 | |
| 2426 | 2428 | spin_unlock_bh(&orig->mcast_handler_lock); |
| 2427 | 2429 | } |
| @@ -3202,6 +3202,7 @@ struct hci_dev *hci_alloc_dev(void) · 3201 unmodified lines | ||
| 3202 | 3202 | hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; |
| 3203 | 3203 | hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; |
| 3204 | 3204 | hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; |
| 3205 | + hdev->min_enc_key_size = HCI_MIN_ENC_KEY_SIZE; | |
| 3205 | 3206 | |
| 3206 | 3207 | mutex_init(&hdev->lock); |
| 3207 | 3208 | mutex_init(&hdev->req_lock); |
| @@ -433,6 +433,35 @@ static int auto_accept_delay_set(void *data, u64 val) · 432 unmodified lines | ||
| 433 | 433 | return 0; |
| 434 | 434 | } |
| 435 | 435 | |
| 436 | +static int min_encrypt_key_size_set(void *data, u64 val) | |
| 437 | +{ | |
| 438 | + struct hci_dev *hdev = data; | |
| 439 | + | |
| 440 | + if (val < 1 || val > 16) | |
| 441 | + return -EINVAL; | |
| 442 | + | |
| 443 | + hci_dev_lock(hdev); | |
| 444 | + hdev->min_enc_key_size = val; | |
| 445 | + hci_dev_unlock(hdev); | |
| 446 | + | |
| 447 | + return 0; | |
| 448 | +} | |
| 449 | + | |
| 450 | +static int min_encrypt_key_size_get(void *data, u64 *val) | |
| 451 | +{ | |
| 452 | + struct hci_dev *hdev = data; | |
| 453 | + | |
| 454 | + hci_dev_lock(hdev); | |
| 455 | + *val = hdev->min_enc_key_size; | |
| 456 | + hci_dev_unlock(hdev); | |
| 457 | + | |
| 458 | + return 0; | |
| 459 | +} | |
| 460 | + | |
| 461 | +DEFINE_SIMPLE_ATTRIBUTE(min_encrypt_key_size_fops, | |
| 462 | + min_encrypt_key_size_get, | |
| 463 | + min_encrypt_key_size_set, "%llu\n"); | |
| 464 | + | |
| 436 | 465 | static int auto_accept_delay_get(void *data, u64 *val) |
| 437 | 466 | { |
| 438 | 467 | struct hci_dev *hdev = data; |
| @@ -545,6 +574,8 @@ void hci_debugfs_create_bredr(struct hci_dev *hdev) · 106 unmodified lines | ||
| 545 | 574 | if (lmp_ssp_capable(hdev)) { |
| 546 | 575 | debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs, |
| 547 | 576 | hdev, &ssp_debug_mode_fops); |
| 577 | + debugfs_create_file("min_encrypt_key_size", 0644, hdev->debugfs, | |
| 578 | + hdev, &min_encrypt_key_size_fops); | |
| 548 | 579 | debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, |
| 549 | 580 | hdev, &auto_accept_delay_fops); |
| 550 | 581 | } |
| @@ -101,6 +101,7 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, · 100 unmodified lines | ||
| 101 | 101 | { |
| 102 | 102 | struct sk_buff *skb; |
| 103 | 103 | struct sock *sk = sock->sk; |
| 104 | + int ret; | |
| 104 | 105 | |
| 105 | 106 | BT_DBG("session %p data %p size %d", session, data, size); |
| 106 | 107 | |
| @@ -114,13 +115,17 @@ static int hidp_send_message(struct hidp_session *session, struct socket *sock, · 7 unmodified lines | ||
| 114 | 115 | } |
| 115 | 116 | |
| 116 | 117 | skb_put_u8(skb, hdr); |
| 117 | − if (data && size > 0) | |
| 118 | + if (data && size > 0) { | |
| 118 | 119 | skb_put_data(skb, data, size); |
| 120 | + ret = size; | |
| 121 | + } else { | |
| 122 | + ret = 0; | |
| 123 | + } | |
| 119 | 124 | |
| 120 | 125 | skb_queue_tail(transmit, skb); |
| 121 | 126 | wake_up_interruptible(sk_sleep(sk)); |
| 122 | 127 | |
| 123 | − return 0; | |
| 128 | + return ret; | |
| 124 | 129 | } |
| 125 | 130 | |
| 126 | 131 | static int hidp_send_ctrl_message(struct hidp_session *session, |
| @@ -1361,7 +1361,7 @@ static bool l2cap_check_enc_key_size(struct hci_conn *hcon) · 1360 unmodified lines | ||
| 1361 | 1361 | * actually encrypted before enforcing a key size. |
| 1362 | 1362 | */ |
| 1363 | 1363 | return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || |
| 1364 | − hcon->enc_key_size >= HCI_MIN_ENC_KEY_SIZE); | |
| 1364 | + hcon->enc_key_size >= hcon->hdev->min_enc_key_size); | |
| 1365 | 1365 | } |
| 1366 | 1366 | |
| 1367 | 1367 | static void l2cap_do_start(struct l2cap_chan *chan) |
| @@ -1992,6 +1992,19 @@ void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) · 1991 unmodified lines | ||
| 1992 | 1992 | } |
| 1993 | 1993 | EXPORT_SYMBOL(skb_set_owner_w); |
| 1994 | 1994 | |
| 1995 | +static bool can_skb_orphan_partial(const struct sk_buff *skb) | |
| 1996 | +{ | |
| 1997 | +#ifdef CONFIG_TLS_DEVICE | |
| 1998 | + /* Drivers depend on in-order delivery for crypto offload, | |
| 1999 | + * partial orphan breaks out-of-order-OK logic. | |
| 2000 | + */ | |
| 2001 | + if (skb->decrypted) | |
| 2002 | + return false; | |
| 2003 | +#endif | |
| 2004 | + return (skb->destructor == sock_wfree || | |
| 2005 | + (IS_ENABLED(CONFIG_INET) && skb->destructor == tcp_wfree)); | |
| 2006 | +} | |
| 2007 | + | |
| 1995 | 2008 | /* This helper is used by netem, as it can hold packets in its |
| 1996 | 2009 | * delay queue. We want to allow the owner socket to send more |
| 1997 | 2010 | * packets, as if they were already TX completed by a typical driver. |
| @@ -2003,11 +2016,7 @@ void skb_orphan_partial(struct sk_buff *skb) · 5 unmodified lines | ||
| 2003 | 2016 | if (skb_is_tcp_pure_ack(skb)) |
| 2004 | 2017 | return; |
| 2005 | 2018 | |
| 2006 | − if (skb->destructor == sock_wfree | |
| 2007 | −#ifdef CONFIG_INET | |
| 2008 | − || skb->destructor == tcp_wfree | |
| 2009 | −#endif | |
| 2010 | − ) { | |
| 2019 | + if (can_skb_orphan_partial(skb)) { | |
| 2011 | 2020 | struct sock *sk = skb->sk; |
| 2012 | 2021 | |
| 2013 | 2022 | if (refcount_inc_not_zero(&sk->sk_refcnt)) { |
| @@ -19,6 +19,7 @@ static const struct sock_diag_handler *sock_diag_handlers[AF_MAX]; · 18 unmodified lines | ||
| 19 | 19 | static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); |
| 20 | 20 | static DEFINE_MUTEX(sock_diag_table_mutex); |
| 21 | 21 | static struct workqueue_struct *broadcast_wq; |
| 22 | +static atomic64_t cookie_gen; | |
| 22 | 23 | |
| 23 | 24 | u64 sock_gen_cookie(struct sock *sk) |
| 24 | 25 | { |
| @@ -27,7 +28,7 @@ u64 sock_gen_cookie(struct sock *sk) · 2 unmodified lines | ||
| 27 | 28 | |
| 28 | 29 | if (res) |
| 29 | 30 | return res; |
| 30 | − res = atomic64_inc_return(&sock_net(sk)->cookie_gen); | |
| 31 | + res = atomic64_inc_return(&cookie_gen); | |
| 31 | 32 | atomic64_cmpxchg(&sk->sk_cookie, 0, res); |
| 32 | 33 | } |
| 33 | 34 | } |
| @@ -153,6 +153,9 @@ static void dsa_switch_mdb_add_bitmap(struct dsa_switch *ds, · 152 unmodified lines | ||
| 153 | 153 | { |
| 154 | 154 | int port; |
| 155 | 155 | |
| 156 | + if (!ds->ops->port_mdb_add) | |
| 157 | + return; | |
| 158 | + | |
| 156 | 159 | for_each_set_bit(port, bitmap, ds->num_ports) |
| 157 | 160 | ds->ops->port_mdb_add(ds, port, mdb); |
| 158 | 161 | } |
| @@ -170,7 +170,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *skb, · 169 unmodified lines | ||
| 170 | 170 | reasm_data = inet_frag_reasm_prepare(&fq->q, skb, prev_tail); |
| 171 | 171 | if (!reasm_data) |
| 172 | 172 | goto out_oom; |
| 173 | − inet_frag_reasm_finish(&fq->q, skb, reasm_data); | |
| 173 | + inet_frag_reasm_finish(&fq->q, skb, reasm_data, false); | |
| 174 | 174 | |
| 175 | 175 | skb->dev = ldev; |
| 176 | 176 | skb->tstamp = fq->q.stamp; |
| @@ -475,11 +475,12 @@ void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb, · 474 unmodified lines | ||
| 475 | 475 | EXPORT_SYMBOL(inet_frag_reasm_prepare); |
| 476 | 476 | |
| 477 | 477 | void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, |
| 478 | − void *reasm_data) | |
| 478 | + void *reasm_data, bool try_coalesce) | |
| 479 | 479 | { |
| 480 | 480 | struct sk_buff **nextp = (struct sk_buff **)reasm_data; |
| 481 | 481 | struct rb_node *rbn; |
| 482 | 482 | struct sk_buff *fp; |
| 483 | + int sum_truesize; | |
| 483 | 484 | |
| 484 | 485 | skb_push(head, head->data - skb_network_header(head)); |
| 485 | 486 | |
| @@ -487,25 +488,41 @@ void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, · 1 unmodified line | ||
| 487 | 488 | fp = FRAG_CB(head)->next_frag; |
| 488 | 489 | rbn = rb_next(&head->rbnode); |
| 489 | 490 | rb_erase(&head->rbnode, &q->rb_fragments); |
| 491 | + | |
| 492 | + sum_truesize = head->truesize; | |
| 490 | 493 | while (rbn || fp) { |
| 491 | 494 | /* fp points to the next sk_buff in the current run; |
| 492 | 495 | * rbn points to the next run. |
| 493 | 496 | */ |
| 494 | 497 | /* Go through the current run. */ |
| 495 | 498 | while (fp) { |
| 496 | − *nextp = fp; | |
| 497 | − nextp = &fp->next; | |
| 498 | − fp->prev = NULL; | |
| 499 | − memset(&fp->rbnode, 0, sizeof(fp->rbnode)); | |
| 500 | − fp->sk = NULL; | |
| 501 | − head->data_len += fp->len; | |
| 502 | − head->len += fp->len; | |
| 499 | + struct sk_buff *next_frag = FRAG_CB(fp)->next_frag; | |
| 500 | + bool stolen; | |
| 501 | + int delta; | |
| 502 | + | |
| 503 | + sum_truesize += fp->truesize; | |
| 503 | 504 | if (head->ip_summed != fp->ip_summed) |
| 504 | 505 | head->ip_summed = CHECKSUM_NONE; |
| 505 | 506 | else if (head->ip_summed == CHECKSUM_COMPLETE) |
| 506 | 507 | head->csum = csum_add(head->csum, fp->csum); |
| 507 | − head->truesize += fp->truesize; | |
| 508 | − fp = FRAG_CB(fp)->next_frag; | |
| 508 | + | |
| 509 | + if (try_coalesce && skb_try_coalesce(head, fp, &stolen, | |
| 510 | + &delta)) { | |
| 511 | + kfree_skb_partial(fp, stolen); | |
| 512 | + } else { | |
| 513 | + fp->prev = NULL; | |
| 514 | + memset(&fp->rbnode, 0, sizeof(fp->rbnode)); | |
| 515 | + fp->sk = NULL; | |
| 516 | + | |
| 517 | + head->data_len += fp->len; | |
| 518 | + head->len += fp->len; | |
| 519 | + head->truesize += fp->truesize; | |
| 520 | + | |
| 521 | + *nextp = fp; | |
| 522 | + nextp = &fp->next; | |
| 523 | + } | |
| 524 | + | |
| 525 | + fp = next_frag; | |
| 509 | 526 | } |
| 510 | 527 | /* Move to the next run. */ |
| 511 | 528 | if (rbn) { |
| @@ -516,7 +533,7 @@ void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, · 4 unmodified lines | ||
| 516 | 533 | rbn = rbnext; |
| 517 | 534 | } |
| 518 | 535 | } |
| 519 | − sub_frag_mem_limit(q->fqdir, head->truesize); | |
| 536 | + sub_frag_mem_limit(q->fqdir, sum_truesize); | |
| 520 | 537 | |
| 521 | 538 | *nextp = NULL; |
| 522 | 539 | skb_mark_not_on_list(head); |
| @@ -393,6 +393,11 @@ err: · 392 unmodified lines | ||
| 393 | 393 | return err; |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | +static bool ip_frag_coalesce_ok(const struct ipq *qp) | |
| 397 | +{ | |
| 398 | + return qp->q.key.v4.user == IP_DEFRAG_LOCAL_DELIVER; | |
| 399 | +} | |
| 400 | + | |
| 396 | 401 | /* Build a new IP datagram from all its fragments. */ |
| 397 | 402 | static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, |
| 398 | 403 | struct sk_buff *prev_tail, struct net_device *dev) |
| @@ -421,7 +426,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb, · 22 unmodified lines | ||
| 421 | 426 | if (len > 65535) |
| 422 | 427 | goto out_oversize; |
| 423 | 428 | |
| 424 | − inet_frag_reasm_finish(&qp->q, skb, reasm_data); | |
| 429 | + inet_frag_reasm_finish(&qp->q, skb, reasm_data, | |
| 430 | + ip_frag_coalesce_ok(qp)); | |
| 425 | 431 | |
| 426 | 432 | skb->dev = dev; |
| 427 | 433 | IPCB(skb)->frag_max_size = max(qp->max_df_size, qp->q.max_size); |
| @@ -984,6 +984,9 @@ new_segment: · 983 unmodified lines | ||
| 984 | 984 | if (!skb) |
| 985 | 985 | goto wait_for_memory; |
| 986 | 986 | |
| 987 | +#ifdef CONFIG_TLS_DEVICE | |
| 988 | + skb->decrypted = !!(flags & MSG_SENDPAGE_DECRYPTED); | |
| 989 | +#endif | |
| 987 | 990 | skb_entail(sk, skb); |
| 988 | 991 | copy = size_goal; |
| 989 | 992 | } |
| @@ -398,10 +398,14 @@ more_data: · 397 unmodified lines | ||
| 398 | 398 | static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) |
| 399 | 399 | { |
| 400 | 400 | struct sk_msg tmp, *msg_tx = NULL; |
| 401 | − int flags = msg->msg_flags | MSG_NO_SHARED_FRAGS; | |
| 402 | 401 | int copied = 0, err = 0; |
| 403 | 402 | struct sk_psock *psock; |
| 404 | 403 | long timeo; |
| 404 | + int flags; | |
| 405 | + | |
| 406 | + /* Don't let internal do_tcp_sendpages() flags through */ | |
| 407 | + flags = (msg->msg_flags & ~MSG_SENDPAGE_DECRYPTED); | |
| 408 | + flags |= MSG_NO_SHARED_FRAGS; | |
| 405 | 409 | |
| 406 | 410 | psock = sk_psock_get(sk); |
| 407 | 411 | if (unlikely(!psock)) |
| @@ -1320,6 +1320,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, · 1319 unmodified lines | ||
| 1320 | 1320 | buff = sk_stream_alloc_skb(sk, nsize, gfp, true); |
| 1321 | 1321 | if (!buff) |
| 1322 | 1322 | return -ENOMEM; /* We'll just try again later. */ |
| 1323 | + skb_copy_decrypted(buff, skb); | |
| 1323 | 1324 | |
| 1324 | 1325 | sk->sk_wmem_queued += buff->truesize; |
| 1325 | 1326 | sk_mem_charge(sk, buff->truesize); |
| @@ -1874,6 +1875,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, · 548 unmodified lines | ||
| 1874 | 1875 | buff = sk_stream_alloc_skb(sk, 0, gfp, true); |
| 1875 | 1876 | if (unlikely(!buff)) |
| 1876 | 1877 | return -ENOMEM; |
| 1878 | + skb_copy_decrypted(buff, skb); | |
| 1877 | 1879 | |
| 1878 | 1880 | sk->sk_wmem_queued += buff->truesize; |
| 1879 | 1881 | sk_mem_charge(sk, buff->truesize); |
| @@ -2143,6 +2145,7 @@ static int tcp_mtu_probe(struct sock *sk) · 263 unmodified lines | ||
| 2143 | 2145 | sk_mem_charge(sk, nskb->truesize); |
| 2144 | 2146 | |
| 2145 | 2147 | skb = tcp_send_head(sk); |
| 2148 | + skb_copy_decrypted(nskb, skb); | |
| 2146 | 2149 | |
| 2147 | 2150 | TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq; |
| 2148 | 2151 | TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size; |
| @@ -348,7 +348,7 @@ static int nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *skb, · 347 unmodified lines | ||
| 348 | 348 | |
| 349 | 349 | skb_reset_transport_header(skb); |
| 350 | 350 | |
| 351 | − inet_frag_reasm_finish(&fq->q, skb, reasm_data); | |
| 351 | + inet_frag_reasm_finish(&fq->q, skb, reasm_data, false); | |
| 352 | 352 | |
| 353 | 353 | skb->ignore_df = 1; |
| 354 | 354 | skb->dev = dev; |
| @@ -282,7 +282,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *skb, · 281 unmodified lines | ||
| 282 | 282 | |
| 283 | 283 | skb_reset_transport_header(skb); |
| 284 | 284 | |
| 285 | − inet_frag_reasm_finish(&fq->q, skb, reasm_data); | |
| 285 | + inet_frag_reasm_finish(&fq->q, skb, reasm_data, true); | |
| 286 | 286 | |
| 287 | 287 | skb->dev = dev; |
| 288 | 288 | ipv6_hdr(skb)->payload_len = htons(payload_len); |
| @@ -453,13 +453,12 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple); · 452 unmodified lines | ||
| 453 | 453 | * table location, we assume id gets exposed to userspace. |
| 454 | 454 | * |
| 455 | 455 | * Following nf_conn items do not change throughout lifetime |
| 456 | − * of the nf_conn after it has been committed to main hash table: | |
| 456 | + * of the nf_conn: | |
| 457 | 457 | * |
| 458 | 458 | * 1. nf_conn address |
| 459 | − * 2. nf_conn->ext address | |
| 460 | − * 3. nf_conn->master address (normally NULL) | |
| 461 | − * 4. tuple | |
| 462 | − * 5. the associated net namespace | |
| 459 | + * 2. nf_conn->master address (normally NULL) | |
| 460 | + * 3. the associated net namespace | |
| 461 | + * 4. the original direction tuple | |
| 463 | 462 | */ |
| 464 | 463 | u32 nf_ct_get_id(const struct nf_conn *ct) |
| 465 | 464 | { |
| @@ -469,9 +468,10 @@ u32 nf_ct_get_id(const struct nf_conn *ct) · 3 unmodified lines | ||
| 469 | 468 | net_get_random_once(&ct_id_seed, sizeof(ct_id_seed)); |
| 470 | 469 | |
| 471 | 470 | a = (unsigned long)ct; |
| 472 | − b = (unsigned long)ct->master ^ net_hash_mix(nf_ct_net(ct)); | |
| 473 | − c = (unsigned long)ct->ext; | |
| 474 | − d = (unsigned long)siphash(&ct->tuplehash, sizeof(ct->tuplehash), | |
| 471 | + b = (unsigned long)ct->master; | |
| 472 | + c = (unsigned long)nf_ct_net(ct); | |
| 473 | + d = (unsigned long)siphash(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | |
| 474 | + sizeof(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple), | |
| 475 | 475 | &ct_id_seed); |
| 476 | 476 | #ifdef CONFIG_64BIT |
| 477 | 477 | return siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &ct_id_seed); |
| @@ -111,15 +111,16 @@ static void flow_offload_fixup_tcp(struct ip_ct_tcp *tcp) · 110 unmodified lines | ||
| 111 | 111 | #define NF_FLOWTABLE_TCP_PICKUP_TIMEOUT (120 * HZ) |
| 112 | 112 | #define NF_FLOWTABLE_UDP_PICKUP_TIMEOUT (30 * HZ) |
| 113 | 113 | |
| 114 | −static void flow_offload_fixup_ct_state(struct nf_conn *ct) | |
| 114 | +static inline __s32 nf_flow_timeout_delta(unsigned int timeout) | |
| 115 | +{ | |
| 116 | + return (__s32)(timeout - (u32)jiffies); | |
| 117 | +} | |
| 118 | + | |
| 119 | +static void flow_offload_fixup_ct_timeout(struct nf_conn *ct) | |
| 115 | 120 | { |
| 116 | 121 | const struct nf_conntrack_l4proto *l4proto; |
| 122 | + int l4num = nf_ct_protonum(ct); | |
| 117 | 123 | unsigned int timeout; |
| 118 | − int l4num; | |
| 119 | − | |
| 120 | − l4num = nf_ct_protonum(ct); | |
| 121 | − if (l4num == IPPROTO_TCP) | |
| 122 | − flow_offload_fixup_tcp(&ct->proto.tcp); | |
| 123 | 124 | |
| 124 | 125 | l4proto = nf_ct_l4proto_find(l4num); |
| 125 | 126 | if (!l4proto) |
| @@ -132,7 +133,20 @@ static void flow_offload_fixup_ct_state(struct nf_conn *ct) · 6 unmodified lines | ||
| 132 | 133 | else |
| 133 | 134 | return; |
| 134 | 135 | |
| 135 | − ct->timeout = nfct_time_stamp + timeout; | |
| 136 | + if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout) | |
| 137 | + ct->timeout = nfct_time_stamp + timeout; | |
| 138 | +} | |
| 139 | + | |
| 140 | +static void flow_offload_fixup_ct_state(struct nf_conn *ct) | |
| 141 | +{ | |
| 142 | + if (nf_ct_protonum(ct) == IPPROTO_TCP) | |
| 143 | + flow_offload_fixup_tcp(&ct->proto.tcp); | |
| 144 | +} | |
| 145 | + | |
| 146 | +static void flow_offload_fixup_ct(struct nf_conn *ct) | |
| 147 | +{ | |
| 148 | + flow_offload_fixup_ct_state(ct); | |
| 149 | + flow_offload_fixup_ct_timeout(ct); | |
| 136 | 150 | } |
| 137 | 151 | |
| 138 | 152 | void flow_offload_free(struct flow_offload *flow) |
| @@ -208,6 +222,11 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) · 69 unmodified lines | ||
| 208 | 222 | } |
| 209 | 223 | EXPORT_SYMBOL_GPL(flow_offload_add); |
| 210 | 224 | |
| 225 | +static inline bool nf_flow_has_expired(const struct flow_offload *flow) | |
| 226 | +{ | |
| 227 | + return nf_flow_timeout_delta(flow->timeout) <= 0; | |
| 228 | +} | |
| 229 | + | |
| 211 | 230 | static void flow_offload_del(struct nf_flowtable *flow_table, |
| 212 | 231 | struct flow_offload *flow) |
| 213 | 232 | { |
| @@ -223,6 +242,11 @@ static void flow_offload_del(struct nf_flowtable *flow_table, · 9 unmodified lines | ||
| 223 | 242 | e = container_of(flow, struct flow_offload_entry, flow); |
| 224 | 243 | clear_bit(IPS_OFFLOAD_BIT, &e->ct->status); |
| 225 | 244 | |
| 245 | + if (nf_flow_has_expired(flow)) | |
| 246 | + flow_offload_fixup_ct(e->ct); | |
| 247 | + else if (flow->flags & FLOW_OFFLOAD_TEARDOWN) | |
| 248 | + flow_offload_fixup_ct_timeout(e->ct); | |
| 249 | + | |
| 226 | 250 | flow_offload_free(flow); |
| 227 | 251 | } |
| 228 | 252 | |
| @@ -298,11 +322,6 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table, · 69 unmodified lines | ||
| 298 | 322 | return err; |
| 299 | 323 | } |
| 300 | 324 | |
| 301 | −static inline bool nf_flow_has_expired(const struct flow_offload *flow) | |
| 302 | −{ | |
| 303 | − return (__s32)(flow->timeout - (u32)jiffies) <= 0; | |
| 304 | −} | |
| 305 | − | |
| 306 | 325 | static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data) |
| 307 | 326 | { |
| 308 | 327 | struct nf_flowtable *flow_table = data; |
| @@ -214,6 +214,25 @@ static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) · 213 unmodified lines | ||
| 214 | 214 | return true; |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | +static int nf_flow_offload_dst_check(struct dst_entry *dst) | |
| 218 | +{ | |
| 219 | + if (unlikely(dst_xfrm(dst))) | |
| 220 | + return dst_check(dst, 0) ? 0 : -1; | |
| 221 | + | |
| 222 | + return 0; | |
| 223 | +} | |
| 224 | + | |
| 225 | +static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb, | |
| 226 | + const struct nf_hook_state *state, | |
| 227 | + struct dst_entry *dst) | |
| 228 | +{ | |
| 229 | + skb_orphan(skb); | |
| 230 | + skb_dst_set_noref(skb, dst); | |
| 231 | + skb->tstamp = 0; | |
| 232 | + dst_output(state->net, state->sk, skb); | |
| 233 | + return NF_STOLEN; | |
| 234 | +} | |
| 235 | + | |
| 217 | 236 | unsigned int |
| 218 | 237 | nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, |
| 219 | 238 | const struct nf_hook_state *state) |
| @@ -254,6 +273,11 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, · 34 unmodified lines | ||
| 254 | 273 | if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff)) |
| 255 | 274 | return NF_ACCEPT; |
| 256 | 275 | |
| 276 | + if (nf_flow_offload_dst_check(&rt->dst)) { | |
| 277 | + flow_offload_teardown(flow); | |
| 278 | + return NF_ACCEPT; | |
| 279 | + } | |
| 280 | + | |
| 257 | 281 | if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) |
| 258 | 282 | return NF_DROP; |
| 259 | 283 | |
| @@ -261,6 +285,13 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, · 1 unmodified line | ||
| 261 | 285 | iph = ip_hdr(skb); |
| 262 | 286 | ip_decrease_ttl(iph); |
| 263 | 287 | |
| 288 | + if (unlikely(dst_xfrm(&rt->dst))) { | |
| 289 | + memset(skb->cb, 0, sizeof(struct inet_skb_parm)); | |
| 290 | + IPCB(skb)->iif = skb->dev->ifindex; | |
| 291 | + IPCB(skb)->flags = IPSKB_FORWARDED; | |
| 292 | + return nf_flow_xmit_xfrm(skb, state, &rt->dst); | |
| 293 | + } | |
| 294 | + | |
| 264 | 295 | skb->dev = outdev; |
| 265 | 296 | nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); |
| 266 | 297 | skb_dst_set_noref(skb, &rt->dst); |
| @@ -467,6 +498,11 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, · 200 unmodified lines | ||
| 467 | 498 | sizeof(*ip6h))) |
| 468 | 499 | return NF_ACCEPT; |
| 469 | 500 | |
| 501 | + if (nf_flow_offload_dst_check(&rt->dst)) { | |
| 502 | + flow_offload_teardown(flow); | |
| 503 | + return NF_ACCEPT; | |
| 504 | + } | |
| 505 | + | |
| 470 | 506 | if (skb_try_make_writable(skb, sizeof(*ip6h))) |
| 471 | 507 | return NF_DROP; |
| 472 | 508 | |
| @@ -477,6 +513,13 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, · 4 unmodified lines | ||
| 477 | 513 | ip6h = ipv6_hdr(skb); |
| 478 | 514 | ip6h->hop_limit--; |
| 479 | 515 | |
| 516 | + if (unlikely(dst_xfrm(&rt->dst))) { | |
| 517 | + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); | |
| 518 | + IP6CB(skb)->iif = skb->dev->ifindex; | |
| 519 | + IP6CB(skb)->flags = IP6SKB_FORWARDED; | |
| 520 | + return nf_flow_xmit_xfrm(skb, state, &rt->dst); | |
| 521 | + } | |
| 522 | + | |
| 480 | 523 | skb->dev = outdev; |
| 481 | 524 | nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); |
| 482 | 525 | skb_dst_set_noref(skb, &rt->dst); |
| @@ -138,9 +138,14 @@ static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set) · 137 unmodified lines | ||
| 138 | 138 | return; |
| 139 | 139 | |
| 140 | 140 | list_for_each_entry_reverse(trans, &net->nft.commit_list, list) { |
| 141 | − if (trans->msg_type == NFT_MSG_NEWSET && | |
| 142 | − nft_trans_set(trans) == set) { | |
| 143 | − set->bound = true; | |
| 141 | + switch (trans->msg_type) { | |
| 142 | + case NFT_MSG_NEWSET: | |
| 143 | + if (nft_trans_set(trans) == set) | |
| 144 | + nft_trans_set_bound(trans) = true; | |
| 145 | + break; | |
| 146 | + case NFT_MSG_NEWSETELEM: | |
| 147 | + if (nft_trans_elem_set(trans) == set) | |
| 148 | + nft_trans_elem_set_bound(trans) = true; | |
| 144 | 149 | break; |
| 145 | 150 | } |
| 146 | 151 | } |
| @@ -1662,6 +1667,10 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, · 1515 unmodified lines | ||
| 1662 | 1667 | |
| 1663 | 1668 | chain->flags |= NFT_BASE_CHAIN | flags; |
| 1664 | 1669 | basechain->policy = NF_ACCEPT; |
| 1670 | + if (chain->flags & NFT_CHAIN_HW_OFFLOAD && | |
| 1671 | + nft_chain_offload_priority(basechain) < 0) | |
| 1672 | + return -EOPNOTSUPP; | |
| 1673 | + | |
| 1665 | 1674 | flow_block_init(&basechain->flow_block); |
| 1666 | 1675 | } else { |
| 1667 | 1676 | chain = kzalloc(sizeof(*chain), GFP_KERNEL); |
| @@ -6906,7 +6915,7 @@ static int __nf_tables_abort(struct net *net) · 5238 unmodified lines | ||
| 6906 | 6915 | break; |
| 6907 | 6916 | case NFT_MSG_NEWSET: |
| 6908 | 6917 | trans->ctx.table->use--; |
| 6909 | − if (nft_trans_set(trans)->bound) { | |
| 6918 | + if (nft_trans_set_bound(trans)) { | |
| 6910 | 6919 | nft_trans_destroy(trans); |
| 6911 | 6920 | break; |
| 6912 | 6921 | } |
| @@ -6918,7 +6927,7 @@ static int __nf_tables_abort(struct net *net) · 5 unmodified lines | ||
| 6918 | 6927 | nft_trans_destroy(trans); |
| 6919 | 6928 | break; |
| 6920 | 6929 | case NFT_MSG_NEWSETELEM: |
| 6921 | − if (nft_trans_elem_set(trans)->bound) { | |
| 6930 | + if (nft_trans_elem_set_bound(trans)) { | |
| 6922 | 6931 | nft_trans_destroy(trans); |
| 6923 | 6932 | break; |
| 6924 | 6933 | } |
| @@ -103,10 +103,11 @@ void nft_offload_update_dependency(struct nft_offload_ctx *ctx, · 102 unmodified lines | ||
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | static void nft_flow_offload_common_init(struct flow_cls_common_offload *common, |
| 106 | − __be16 proto, | |
| 107 | − struct netlink_ext_ack *extack) | |
| 106 | + __be16 proto, int priority, | |
| 107 | + struct netlink_ext_ack *extack) | |
| 108 | 108 | { |
| 109 | 109 | common->protocol = proto; |
| 110 | + common->prio = priority; | |
| 110 | 111 | common->extack = extack; |
| 111 | 112 | } |
| 112 | 113 | |
| @@ -124,6 +125,15 @@ static int nft_setup_cb_call(struct nft_base_chain *basechain, · 11 unmodified lines | ||
| 124 | 125 | return 0; |
| 125 | 126 | } |
| 126 | 127 | |
| 128 | +int nft_chain_offload_priority(struct nft_base_chain *basechain) | |
| 129 | +{ | |
| 130 | + if (basechain->ops.priority <= 0 || | |
| 131 | + basechain->ops.priority > USHRT_MAX) | |
| 132 | + return -1; | |
| 133 | + | |
| 134 | + return 0; | |
| 135 | +} | |
| 136 | + | |
| 127 | 137 | static int nft_flow_offload_rule(struct nft_trans *trans, |
| 128 | 138 | enum flow_cls_command command) |
| 129 | 139 | { |
| @@ -142,7 +152,8 @@ static int nft_flow_offload_rule(struct nft_trans *trans, · 12 unmodified lines | ||
| 142 | 152 | if (flow) |
| 143 | 153 | proto = flow->proto; |
| 144 | 154 | |
| 145 | − nft_flow_offload_common_init(&cls_flow.common, proto, &extack); | |
| 155 | + nft_flow_offload_common_init(&cls_flow.common, proto, | |
| 156 | + basechain->ops.priority, &extack); | |
| 146 | 157 | cls_flow.command = command; |
| 147 | 158 | cls_flow.cookie = (unsigned long) rule; |
| 148 | 159 | if (flow) |
| @@ -72,11 +72,11 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, · 71 unmodified lines | ||
| 72 | 72 | { |
| 73 | 73 | struct nft_flow_offload *priv = nft_expr_priv(expr); |
| 74 | 74 | struct nf_flowtable *flowtable = &priv->flowtable->data; |
| 75 | + struct tcphdr _tcph, *tcph = NULL; | |
| 75 | 76 | enum ip_conntrack_info ctinfo; |
| 76 | 77 | struct nf_flow_route route; |
| 77 | 78 | struct flow_offload *flow; |
| 78 | 79 | enum ip_conntrack_dir dir; |
| 79 | − bool is_tcp = false; | |
| 80 | 80 | struct nf_conn *ct; |
| 81 | 81 | int ret; |
| 82 | 82 | |
| @@ -89,7 +89,10 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, · 6 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { |
| 91 | 91 | case IPPROTO_TCP: |
| 92 | − is_tcp = true; | |
| 92 | + tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff, | |
| 93 | + sizeof(_tcph), &_tcph); | |
| 94 | + if (unlikely(!tcph || tcph->fin || tcph->rst)) | |
| 95 | + goto out; | |
| 93 | 96 | break; |
| 94 | 97 | case IPPROTO_UDP: |
| 95 | 98 | break; |
| @@ -115,7 +118,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, · 19 unmodified lines | ||
| 115 | 118 | if (!flow) |
| 116 | 119 | goto err_flow_alloc; |
| 117 | 120 | |
| 118 | − if (is_tcp) { | |
| 121 | + if (tcph) { | |
| 119 | 122 | ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; |
| 120 | 123 | ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; |
| 121 | 124 | } |
| @@ -2618,6 +2618,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) · 2617 unmodified lines | ||
| 2618 | 2618 | |
| 2619 | 2619 | mutex_lock(&po->pg_vec_lock); |
| 2620 | 2620 | |
| 2621 | + /* packet_sendmsg() check on tx_ring.pg_vec was lockless, | |
| 2622 | + * we need to confirm it under protection of pg_vec_lock. | |
| 2623 | + */ | |
| 2624 | + if (unlikely(!po->tx_ring.pg_vec)) { | |
| 2625 | + err = -EBUSY; | |
| 2626 | + goto out; | |
| 2627 | + } | |
| 2621 | 2628 | if (likely(saddr == NULL)) { |
| 2622 | 2629 | dev = packet_cached_dev_get(po); |
| 2623 | 2630 | proto = po->num; |
| @@ -193,7 +193,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len) · 192 unmodified lines | ||
| 193 | 193 | |
| 194 | 194 | service_in_use: |
| 195 | 195 | write_unlock(&local->services_lock); |
| 196 | − rxrpc_put_local(local); | |
| 196 | + rxrpc_unuse_local(local); | |
| 197 | 197 | ret = -EADDRINUSE; |
| 198 | 198 | error_unlock: |
| 199 | 199 | release_sock(&rx->sk); |
| @@ -402,7 +402,7 @@ EXPORT_SYMBOL(rxrpc_kernel_check_life); · 202 unmodified lines | ||
| 402 | 402 | */ |
| 403 | 403 | void rxrpc_kernel_probe_life(struct socket *sock, struct rxrpc_call *call) |
| 404 | 404 | { |
| 405 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, | |
| 405 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, | |
| 406 | 406 | rxrpc_propose_ack_ping_for_check_life); |
| 407 | 407 | rxrpc_send_ack_packet(call, true, NULL); |
| 408 | 408 | } |
| @@ -901,7 +901,7 @@ static int rxrpc_release_sock(struct sock *sk) · 492 unmodified lines | ||
| 901 | 901 | rxrpc_queue_work(&rxnet->service_conn_reaper); |
| 902 | 902 | rxrpc_queue_work(&rxnet->client_conn_reaper); |
| 903 | 903 | |
| 904 | − rxrpc_put_local(rx->local); | |
| 904 | + rxrpc_unuse_local(rx->local); | |
| 905 | 905 | rx->local = NULL; |
| 906 | 906 | key_put(rx->key); |
| 907 | 907 | rx->key = NULL; |
| @@ -257,7 +257,8 @@ struct rxrpc_security { · 256 unmodified lines | ||
| 257 | 257 | */ |
| 258 | 258 | struct rxrpc_local { |
| 259 | 259 | struct rcu_head rcu; |
| 260 | − atomic_t usage; | |
| 260 | + atomic_t active_users; /* Number of users of the local endpoint */ | |
| 261 | + atomic_t usage; /* Number of references to the structure */ | |
| 261 | 262 | struct rxrpc_net *rxnet; /* The network ns in which this resides */ |
| 262 | 263 | struct list_head link; |
| 263 | 264 | struct socket *socket; /* my UDP socket */ |
| @@ -653,7 +654,6 @@ struct rxrpc_call { · 389 unmodified lines | ||
| 653 | 654 | |
| 654 | 655 | /* receive-phase ACK management */ |
| 655 | 656 | u8 ackr_reason; /* reason to ACK */ |
| 656 | − u16 ackr_skew; /* skew on packet being ACK'd */ | |
| 657 | 657 | rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ |
| 658 | 658 | rxrpc_serial_t ackr_first_seq; /* first sequence number received */ |
| 659 | 659 | rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ |
| @@ -747,7 +747,7 @@ int rxrpc_reject_call(struct rxrpc_sock *); · 87 unmodified lines | ||
| 747 | 747 | /* |
| 748 | 748 | * call_event.c |
| 749 | 749 | */ |
| 750 | −void rxrpc_propose_ACK(struct rxrpc_call *, u8, u16, u32, bool, bool, | |
| 750 | +void rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool, bool, | |
| 751 | 751 | enum rxrpc_propose_ack_trace); |
| 752 | 752 | void rxrpc_process_call(struct work_struct *); |
| 753 | 753 | |
| @@ -1006,6 +1006,8 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *, const struct sockaddr_rxrpc · 252 unmodified lines | ||
| 1006 | 1006 | struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *); |
| 1007 | 1007 | struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *); |
| 1008 | 1008 | void rxrpc_put_local(struct rxrpc_local *); |
| 1009 | +struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *); | |
| 1010 | +void rxrpc_unuse_local(struct rxrpc_local *); | |
| 1009 | 1011 | void rxrpc_queue_local(struct rxrpc_local *); |
| 1010 | 1012 | void rxrpc_destroy_all_locals(struct rxrpc_net *); |
| 1011 | 1013 | |
| @@ -43,8 +43,7 @@ static void rxrpc_propose_ping(struct rxrpc_call *call, · 42 unmodified lines | ||
| 43 | 43 | * propose an ACK be sent |
| 44 | 44 | */ |
| 45 | 45 | static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
| 46 | − u16 skew, u32 serial, bool immediate, | |
| 47 | − bool background, | |
| 46 | + u32 serial, bool immediate, bool background, | |
| 48 | 47 | enum rxrpc_propose_ack_trace why) |
| 49 | 48 | { |
| 50 | 49 | enum rxrpc_propose_ack_outcome outcome = rxrpc_propose_ack_use; |
| @@ -69,14 +68,12 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, · 18 unmodified lines | ||
| 69 | 68 | if (RXRPC_ACK_UPDATEABLE & (1 << ack_reason)) { |
| 70 | 69 | outcome = rxrpc_propose_ack_update; |
| 71 | 70 | call->ackr_serial = serial; |
| 72 | − call->ackr_skew = skew; | |
| 73 | 71 | } |
| 74 | 72 | if (!immediate) |
| 75 | 73 | goto trace; |
| 76 | 74 | } else if (prior > rxrpc_ack_priority[call->ackr_reason]) { |
| 77 | 75 | call->ackr_reason = ack_reason; |
| 78 | 76 | call->ackr_serial = serial; |
| 79 | − call->ackr_skew = skew; | |
| 80 | 77 | } else { |
| 81 | 78 | outcome = rxrpc_propose_ack_subsume; |
| 82 | 79 | } |
| @@ -137,11 +134,11 @@ trace: · 54 unmodified lines | ||
| 137 | 134 | * propose an ACK be sent, locking the call structure |
| 138 | 135 | */ |
| 139 | 136 | void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
| 140 | − u16 skew, u32 serial, bool immediate, bool background, | |
| 137 | + u32 serial, bool immediate, bool background, | |
| 141 | 138 | enum rxrpc_propose_ack_trace why) |
| 142 | 139 | { |
| 143 | 140 | spin_lock_bh(&call->lock); |
| 144 | − __rxrpc_propose_ACK(call, ack_reason, skew, serial, | |
| 141 | + __rxrpc_propose_ACK(call, ack_reason, serial, | |
| 145 | 142 | immediate, background, why); |
| 146 | 143 | spin_unlock_bh(&call->lock); |
| 147 | 144 | } |
| @@ -239,7 +236,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j) · 91 unmodified lines | ||
| 239 | 236 | ack_ts = ktime_sub(now, call->acks_latest_ts); |
| 240 | 237 | if (ktime_to_ns(ack_ts) < call->peer->rtt) |
| 241 | 238 | goto out; |
| 242 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, | |
| 239 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, | |
| 243 | 240 | rxrpc_propose_ack_ping_for_lost_ack); |
| 244 | 241 | rxrpc_send_ack_packet(call, true, NULL); |
| 245 | 242 | goto out; |
| @@ -372,7 +369,7 @@ recheck_state: · 126 unmodified lines | ||
| 372 | 369 | if (time_after_eq(now, t)) { |
| 373 | 370 | trace_rxrpc_timer(call, rxrpc_timer_exp_keepalive, now); |
| 374 | 371 | cmpxchg(&call->keepalive_at, t, now + MAX_JIFFY_OFFSET); |
| 375 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, true, | |
| 372 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, true, | |
| 376 | 373 | rxrpc_propose_ack_ping_for_keepalive); |
| 377 | 374 | set_bit(RXRPC_CALL_EV_PING, &call->events); |
| 378 | 375 | } |
| @@ -407,7 +404,7 @@ recheck_state: · 28 unmodified lines | ||
| 407 | 404 | send_ack = NULL; |
| 408 | 405 | if (test_and_clear_bit(RXRPC_CALL_EV_ACK_LOST, &call->events)) { |
| 409 | 406 | call->acks_lost_top = call->tx_top; |
| 410 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, | |
| 407 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, | |
| 411 | 408 | rxrpc_propose_ack_ping_for_lost_ack); |
| 412 | 409 | send_ack = &call->acks_lost_ping; |
| 413 | 410 | } |
| @@ -196,15 +196,14 @@ send_extra_data: · 195 unmodified lines | ||
| 196 | 196 | * Ping the other end to fill our RTT cache and to retrieve the rwind |
| 197 | 197 | * and MTU parameters. |
| 198 | 198 | */ |
| 199 | −static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb, | |
| 200 | − int skew) | |
| 199 | +static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb) | |
| 201 | 200 | { |
| 202 | 201 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 203 | 202 | ktime_t now = skb->tstamp; |
| 204 | 203 | |
| 205 | 204 | if (call->peer->rtt_usage < 3 || |
| 206 | 205 | ktime_before(ktime_add_ms(call->peer->rtt_last_req, 1000), now)) |
| 207 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial, | |
| 206 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, sp->hdr.serial, | |
| 208 | 207 | true, true, |
| 209 | 208 | rxrpc_propose_ack_ping_for_params); |
| 210 | 209 | } |
| @@ -419,8 +418,7 @@ static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq, · 208 unmodified lines | ||
| 419 | 418 | /* |
| 420 | 419 | * Process a DATA packet, adding the packet to the Rx ring. |
| 421 | 420 | */ |
| 422 | −static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb, | |
| 423 | − u16 skew) | |
| 421 | +static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) | |
| 424 | 422 | { |
| 425 | 423 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 426 | 424 | enum rxrpc_call_state state; |
| @@ -600,11 +598,11 @@ skip: · 173 unmodified lines | ||
| 600 | 598 | |
| 601 | 599 | ack: |
| 602 | 600 | if (ack) |
| 603 | − rxrpc_propose_ACK(call, ack, skew, ack_serial, | |
| 601 | + rxrpc_propose_ACK(call, ack, ack_serial, | |
| 604 | 602 | immediate_ack, true, |
| 605 | 603 | rxrpc_propose_ack_input_data); |
| 606 | 604 | else |
| 607 | − rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, skew, serial, | |
| 605 | + rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, | |
| 608 | 606 | false, true, |
| 609 | 607 | rxrpc_propose_ack_input_data); |
| 610 | 608 | |
| @@ -822,8 +820,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks, · 211 unmodified lines | ||
| 822 | 820 | * soft-ACK means that the packet may be discarded and retransmission |
| 823 | 821 | * requested. A phase is complete when all packets are hard-ACK'd. |
| 824 | 822 | */ |
| 825 | −static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |
| 826 | − u16 skew) | |
| 823 | +static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) | |
| 827 | 824 | { |
| 828 | 825 | struct rxrpc_ack_summary summary = { 0 }; |
| 829 | 826 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| @@ -867,11 +864,11 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, · 37 unmodified lines | ||
| 867 | 864 | if (buf.ack.reason == RXRPC_ACK_PING) { |
| 868 | 865 | _proto("Rx ACK %%%u PING Request", sp->hdr.serial); |
| 869 | 866 | rxrpc_propose_ACK(call, RXRPC_ACK_PING_RESPONSE, |
| 870 | − skew, sp->hdr.serial, true, true, | |
| 867 | + sp->hdr.serial, true, true, | |
| 871 | 868 | rxrpc_propose_ack_respond_to_ping); |
| 872 | 869 | } else if (sp->hdr.flags & RXRPC_REQUEST_ACK) { |
| 873 | 870 | rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, |
| 874 | − skew, sp->hdr.serial, true, true, | |
| 871 | + sp->hdr.serial, true, true, | |
| 875 | 872 | rxrpc_propose_ack_respond_to_ack); |
| 876 | 873 | } |
| 877 | 874 | |
| @@ -948,7 +945,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, · 70 unmodified lines | ||
| 948 | 945 | RXRPC_TX_ANNO_LAST && |
| 949 | 946 | summary.nr_acks == call->tx_top - hard_ack && |
| 950 | 947 | rxrpc_is_client_call(call)) |
| 951 | − rxrpc_propose_ACK(call, RXRPC_ACK_PING, skew, sp->hdr.serial, | |
| 948 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, sp->hdr.serial, | |
| 952 | 949 | false, true, |
| 953 | 950 | rxrpc_propose_ack_ping_for_lost_reply); |
| 954 | 951 | |
| @@ -1004,7 +1001,7 @@ static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb) · 49 unmodified lines | ||
| 1004 | 1001 | * Process an incoming call packet. |
| 1005 | 1002 | */ |
| 1006 | 1003 | static void rxrpc_input_call_packet(struct rxrpc_call *call, |
| 1007 | − struct sk_buff *skb, u16 skew) | |
| 1004 | + struct sk_buff *skb) | |
| 1008 | 1005 | { |
| 1009 | 1006 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 1010 | 1007 | unsigned long timo; |
| @@ -1023,11 +1020,11 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call, · 12 unmodified lines | ||
| 1023 | 1020 | |
| 1024 | 1021 | switch (sp->hdr.type) { |
| 1025 | 1022 | case RXRPC_PACKET_TYPE_DATA: |
| 1026 | − rxrpc_input_data(call, skb, skew); | |
| 1023 | + rxrpc_input_data(call, skb); | |
| 1027 | 1024 | break; |
| 1028 | 1025 | |
| 1029 | 1026 | case RXRPC_PACKET_TYPE_ACK: |
| 1030 | − rxrpc_input_ack(call, skb, skew); | |
| 1027 | + rxrpc_input_ack(call, skb); | |
| 1031 | 1028 | break; |
| 1032 | 1029 | |
| 1033 | 1030 | case RXRPC_PACKET_TYPE_BUSY: |
| @@ -1108,8 +1105,12 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local, · 74 unmodified lines | ||
| 1108 | 1105 | { |
| 1109 | 1106 | _enter("%p,%p", local, skb); |
| 1110 | 1107 | |
| 1111 | − skb_queue_tail(&local->event_queue, skb); | |
| 1112 | − rxrpc_queue_local(local); | |
| 1108 | + if (rxrpc_get_local_maybe(local)) { | |
| 1109 | + skb_queue_tail(&local->event_queue, skb); | |
| 1110 | + rxrpc_queue_local(local); | |
| 1111 | + } else { | |
| 1112 | + rxrpc_free_skb(skb, rxrpc_skb_rx_freed); | |
| 1113 | + } | |
| 1113 | 1114 | } |
| 1114 | 1115 | |
| 1115 | 1116 | /* |
| @@ -1119,8 +1120,12 @@ static void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb) · 3 unmodified lines | ||
| 1119 | 1120 | { |
| 1120 | 1121 | CHECK_SLAB_OKAY(&local->usage); |
| 1121 | 1122 | |
| 1122 | − skb_queue_tail(&local->reject_queue, skb); | |
| 1123 | − rxrpc_queue_local(local); | |
| 1123 | + if (rxrpc_get_local_maybe(local)) { | |
| 1124 | + skb_queue_tail(&local->reject_queue, skb); | |
| 1125 | + rxrpc_queue_local(local); | |
| 1126 | + } else { | |
| 1127 | + rxrpc_free_skb(skb, rxrpc_skb_rx_freed); | |
| 1128 | + } | |
| 1124 | 1129 | } |
| 1125 | 1130 | |
| 1126 | 1131 | /* |
| @@ -1173,7 +1178,6 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) · 46 unmodified lines | ||
| 1173 | 1178 | struct rxrpc_peer *peer = NULL; |
| 1174 | 1179 | struct rxrpc_sock *rx = NULL; |
| 1175 | 1180 | unsigned int channel; |
| 1176 | − int skew = 0; | |
| 1177 | 1181 | |
| 1178 | 1182 | _enter("%p", udp_sk); |
| 1179 | 1183 | |
| @@ -1301,15 +1305,8 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) · 121 unmodified lines | ||
| 1301 | 1305 | goto out; |
| 1302 | 1306 | } |
| 1303 | 1307 | |
| 1304 | − /* Note the serial number skew here */ | |
| 1305 | − skew = (int)sp->hdr.serial - (int)conn->hi_serial; | |
| 1306 | − if (skew >= 0) { | |
| 1307 | − if (skew > 0) | |
| 1308 | − conn->hi_serial = sp->hdr.serial; | |
| 1309 | − } else { | |
| 1310 | − skew = -skew; | |
| 1311 | − skew = min(skew, 65535); | |
| 1312 | − } | |
| 1308 | + if ((int)sp->hdr.serial - (int)conn->hi_serial > 0) | |
| 1309 | + conn->hi_serial = sp->hdr.serial; | |
| 1313 | 1310 | |
| 1314 | 1311 | /* Call-bound packets are routed by connection channel. */ |
| 1315 | 1312 | channel = sp->hdr.cid & RXRPC_CHANNELMASK; |
| @@ -1372,11 +1369,11 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) · 56 unmodified lines | ||
| 1372 | 1369 | call = rxrpc_new_incoming_call(local, rx, skb); |
| 1373 | 1370 | if (!call) |
| 1374 | 1371 | goto reject_packet; |
| 1375 | − rxrpc_send_ping(call, skb, skew); | |
| 1372 | + rxrpc_send_ping(call, skb); | |
| 1376 | 1373 | mutex_unlock(&call->user_mutex); |
| 1377 | 1374 | } |
| 1378 | 1375 | |
| 1379 | − rxrpc_input_call_packet(call, skb, skew); | |
| 1376 | + rxrpc_input_call_packet(call, skb); | |
| 1380 | 1377 | goto discard; |
| 1381 | 1378 | |
| 1382 | 1379 | discard: |
| @@ -79,6 +79,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet, · 78 unmodified lines | ||
| 79 | 79 | local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL); |
| 80 | 80 | if (local) { |
| 81 | 81 | atomic_set(&local->usage, 1); |
| 82 | + atomic_set(&local->active_users, 1); | |
| 82 | 83 | local->rxnet = rxnet; |
| 83 | 84 | INIT_LIST_HEAD(&local->link); |
| 84 | 85 | INIT_WORK(&local->processor, rxrpc_local_processor); |
| @@ -92,7 +93,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct rxrpc_net *rxnet, · 7 unmodified lines | ||
| 92 | 93 | local->debug_id = atomic_inc_return(&rxrpc_debug_id); |
| 93 | 94 | memcpy(&local->srx, srx, sizeof(*srx)); |
| 94 | 95 | local->srx.srx_service = 0; |
| 95 | − trace_rxrpc_local(local, rxrpc_local_new, 1, NULL); | |
| 96 | + trace_rxrpc_local(local->debug_id, rxrpc_local_new, 1, NULL); | |
| 96 | 97 | } |
| 97 | 98 | |
| 98 | 99 | _leave(" = %p", local); |
| @@ -266,11 +267,8 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net, · 167 unmodified lines | ||
| 266 | 267 | * bind the transport socket may still fail if we're attempting |
| 267 | 268 | * to use a local address that the dying object is still using. |
| 268 | 269 | */ |
| 269 | − if (!rxrpc_get_local_maybe(local)) { | |
| 270 | − cursor = cursor->next; | |
| 271 | − list_del_init(&local->link); | |
| 270 | + if (!rxrpc_use_local(local)) | |
| 272 | 271 | break; |
| 273 | − } | |
| 274 | 272 | |
| 275 | 273 | age = "old"; |
| 276 | 274 | goto found; |
| @@ -284,7 +282,10 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net, · 7 unmodified lines | ||
| 284 | 282 | if (ret < 0) |
| 285 | 283 | goto sock_error; |
| 286 | 284 | |
| 287 | − list_add_tail(&local->link, cursor); | |
| 285 | + if (cursor != &rxnet->local_endpoints) | |
| 286 | + list_replace_init(cursor, &local->link); | |
| 287 | + else | |
| 288 | + list_add_tail(&local->link, cursor); | |
| 288 | 289 | age = "new"; |
| 289 | 290 | |
| 290 | 291 | found: |
| @@ -320,7 +321,7 @@ struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local) · 29 unmodified lines | ||
| 320 | 321 | int n; |
| 321 | 322 | |
| 322 | 323 | n = atomic_inc_return(&local->usage); |
| 323 | − trace_rxrpc_local(local, rxrpc_local_got, n, here); | |
| 324 | + trace_rxrpc_local(local->debug_id, rxrpc_local_got, n, here); | |
| 324 | 325 | return local; |
| 325 | 326 | } |
| 326 | 327 | |
| @@ -334,7 +335,8 @@ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local) · 7 unmodified lines | ||
| 334 | 335 | if (local) { |
| 335 | 336 | int n = atomic_fetch_add_unless(&local->usage, 1, 0); |
| 336 | 337 | if (n > 0) |
| 337 | − trace_rxrpc_local(local, rxrpc_local_got, n + 1, here); | |
| 338 | + trace_rxrpc_local(local->debug_id, rxrpc_local_got, | |
| 339 | + n + 1, here); | |
| 338 | 340 | else |
| 339 | 341 | local = NULL; |
| 340 | 342 | } |
| @@ -342,24 +344,18 @@ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local) · 1 unmodified line | ||
| 342 | 344 | } |
| 343 | 345 | |
| 344 | 346 | /* |
| 345 | − * Queue a local endpoint. | |
| 347 | + * Queue a local endpoint and pass the caller's reference to the work item. | |
| 346 | 348 | */ |
| 347 | 349 | void rxrpc_queue_local(struct rxrpc_local *local) |
| 348 | 350 | { |
| 349 | 351 | const void *here = __builtin_return_address(0); |
| 352 | + unsigned int debug_id = local->debug_id; | |
| 353 | + int n = atomic_read(&local->usage); | |
| 350 | 354 | |
| 351 | 355 | if (rxrpc_queue_work(&local->processor)) |
| 352 | − trace_rxrpc_local(local, rxrpc_local_queued, | |
| 353 | − atomic_read(&local->usage), here); | |
| 354 | −} | |
| 355 | − | |
| 356 | −/* | |
| 357 | − * A local endpoint reached its end of life. | |
| 358 | − */ | |
| 359 | −static void __rxrpc_put_local(struct rxrpc_local *local) | |
| 360 | −{ | |
| 361 | − _enter("%d", local->debug_id); | |
| 362 | − rxrpc_queue_work(&local->processor); | |
| 356 | + trace_rxrpc_local(debug_id, rxrpc_local_queued, n, here); | |
| 357 | + else | |
| 358 | + rxrpc_put_local(local); | |
| 363 | 359 | } |
| 364 | 360 | |
| 365 | 361 | /* |
| @@ -372,10 +368,47 @@ void rxrpc_put_local(struct rxrpc_local *local) · 6 unmodified lines | ||
| 372 | 368 | |
| 373 | 369 | if (local) { |
| 374 | 370 | n = atomic_dec_return(&local->usage); |
| 375 | − trace_rxrpc_local(local, rxrpc_local_put, n, here); | |
| 371 | + trace_rxrpc_local(local->debug_id, rxrpc_local_put, n, here); | |
| 376 | 372 | |
| 377 | 373 | if (n == 0) |
| 378 | − __rxrpc_put_local(local); | |
| 374 | + call_rcu(&local->rcu, rxrpc_local_rcu); | |
| 375 | + } | |
| 376 | +} | |
| 377 | + | |
| 378 | +/* | |
| 379 | + * Start using a local endpoint. | |
| 380 | + */ | |
| 381 | +struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local) | |
| 382 | +{ | |
| 383 | + unsigned int au; | |
| 384 | + | |
| 385 | + local = rxrpc_get_local_maybe(local); | |
| 386 | + if (!local) | |
| 387 | + return NULL; | |
| 388 | + | |
| 389 | + au = atomic_fetch_add_unless(&local->active_users, 1, 0); | |
| 390 | + if (au == 0) { | |
| 391 | + rxrpc_put_local(local); | |
| 392 | + return NULL; | |
| 393 | + } | |
| 394 | + | |
| 395 | + return local; | |
| 396 | +} | |
| 397 | + | |
| 398 | +/* | |
| 399 | + * Cease using a local endpoint. Once the number of active users reaches 0, we | |
| 400 | + * start the closure of the transport in the work processor. | |
| 401 | + */ | |
| 402 | +void rxrpc_unuse_local(struct rxrpc_local *local) | |
| 403 | +{ | |
| 404 | + unsigned int au; | |
| 405 | + | |
| 406 | + if (local) { | |
| 407 | + au = atomic_dec_return(&local->active_users); | |
| 408 | + if (au == 0) | |
| 409 | + rxrpc_queue_local(local); | |
| 410 | + else | |
| 411 | + rxrpc_put_local(local); | |
| 379 | 412 | } |
| 380 | 413 | } |
| 381 | 414 | |
| @@ -393,16 +426,6 @@ static void rxrpc_local_destroyer(struct rxrpc_local *local) · 11 unmodified lines | ||
| 393 | 426 | |
| 394 | 427 | _enter("%d", local->debug_id); |
| 395 | 428 | |
| 396 | − /* We can get a race between an incoming call packet queueing the | |
| 397 | − * processor again and the work processor starting the destruction | |
| 398 | − * process which will shut down the UDP socket. | |
| 399 | − */ | |
| 400 | − if (local->dead) { | |
| 401 | − _leave(" [already dead]"); | |
| 402 | − return; | |
| 403 | − } | |
| 404 | − local->dead = true; | |
| 405 | − | |
| 406 | 429 | mutex_lock(&rxnet->local_mutex); |
| 407 | 430 | list_del_init(&local->link); |
| 408 | 431 | mutex_unlock(&rxnet->local_mutex); |
| @@ -422,13 +445,11 @@ static void rxrpc_local_destroyer(struct rxrpc_local *local) · 13 unmodified lines | ||
| 422 | 445 | */ |
| 423 | 446 | rxrpc_purge_queue(&local->reject_queue); |
| 424 | 447 | rxrpc_purge_queue(&local->event_queue); |
| 425 | − | |
| 426 | − _debug("rcu local %d", local->debug_id); | |
| 427 | − call_rcu(&local->rcu, rxrpc_local_rcu); | |
| 428 | 448 | } |
| 429 | 449 | |
| 430 | 450 | /* |
| 431 | − * Process events on an endpoint | |
| 451 | + * Process events on an endpoint. The work item carries a ref which | |
| 452 | + * we must release. | |
| 432 | 453 | */ |
| 433 | 454 | static void rxrpc_local_processor(struct work_struct *work) |
| 434 | 455 | { |
| @@ -436,13 +457,15 @@ static void rxrpc_local_processor(struct work_struct *work) · 1 unmodified line | ||
| 436 | 457 | container_of(work, struct rxrpc_local, processor); |
| 437 | 458 | bool again; |
| 438 | 459 | |
| 439 | − trace_rxrpc_local(local, rxrpc_local_processing, | |
| 460 | + trace_rxrpc_local(local->debug_id, rxrpc_local_processing, | |
| 440 | 461 | atomic_read(&local->usage), NULL); |
| 441 | 462 | |
| 442 | 463 | do { |
| 443 | 464 | again = false; |
| 444 | − if (atomic_read(&local->usage) == 0) | |
| 445 | − return rxrpc_local_destroyer(local); | |
| 465 | + if (atomic_read(&local->active_users) == 0) { | |
| 466 | + rxrpc_local_destroyer(local); | |
| 467 | + break; | |
| 468 | + } | |
| 446 | 469 | |
| 447 | 470 | if (!skb_queue_empty(&local->reject_queue)) { |
| 448 | 471 | rxrpc_reject_packets(local); |
| @@ -454,6 +477,8 @@ static void rxrpc_local_processor(struct work_struct *work) · 5 unmodified lines | ||
| 454 | 477 | again = true; |
| 455 | 478 | } |
| 456 | 479 | } while (again); |
| 480 | + | |
| 481 | + rxrpc_put_local(local); | |
| 457 | 482 | } |
| 458 | 483 | |
| 459 | 484 | /* |
| @@ -87,7 +87,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, · 86 unmodified lines | ||
| 87 | 87 | *_top = top; |
| 88 | 88 | |
| 89 | 89 | pkt->ack.bufferSpace = htons(8); |
| 90 | − pkt->ack.maxSkew = htons(call->ackr_skew); | |
| 90 | + pkt->ack.maxSkew = htons(0); | |
| 91 | 91 | pkt->ack.firstPacket = htonl(hard_ack + 1); |
| 92 | 92 | pkt->ack.previousPacket = htonl(call->ackr_prev_seq); |
| 93 | 93 | pkt->ack.serial = htonl(serial); |
| @@ -228,7 +228,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, · 134 unmodified lines | ||
| 228 | 228 | if (ping) |
| 229 | 229 | clear_bit(RXRPC_CALL_PINGING, &call->flags); |
| 230 | 230 | rxrpc_propose_ACK(call, pkt->ack.reason, |
| 231 | − ntohs(pkt->ack.maxSkew), | |
| 232 | 231 | ntohl(pkt->ack.serial), |
| 233 | 232 | false, true, |
| 234 | 233 | rxrpc_propose_ack_retry_tx); |
| @@ -141,7 +141,7 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial) · 140 unmodified lines | ||
| 141 | 141 | ASSERTCMP(call->rx_hard_ack, ==, call->rx_top); |
| 142 | 142 | |
| 143 | 143 | if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { |
| 144 | − rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, false, true, | |
| 144 | + rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, serial, false, true, | |
| 145 | 145 | rxrpc_propose_ack_terminal_ack); |
| 146 | 146 | //rxrpc_send_ack_packet(call, false, NULL); |
| 147 | 147 | } |
| @@ -159,7 +159,7 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial) · 11 unmodified lines | ||
| 159 | 159 | call->state = RXRPC_CALL_SERVER_ACK_REQUEST; |
| 160 | 160 | call->expect_req_by = jiffies + MAX_JIFFY_OFFSET; |
| 161 | 161 | write_unlock_bh(&call->state_lock); |
| 162 | − rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, 0, serial, false, true, | |
| 162 | + rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, false, true, | |
| 163 | 163 | rxrpc_propose_ack_processing_op); |
| 164 | 164 | break; |
| 165 | 165 | default: |
| @@ -212,7 +212,7 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call) · 46 unmodified lines | ||
| 212 | 212 | if (after_eq(hard_ack, call->ackr_consumed + 2) || |
| 213 | 213 | after_eq(top, call->ackr_seen + 2) || |
| 214 | 214 | (hard_ack == top && after(hard_ack, call->ackr_consumed))) |
| 215 | − rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, 0, serial, | |
| 215 | + rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, | |
| 216 | 216 | true, true, |
| 217 | 217 | rxrpc_propose_ack_rotate_rx); |
| 218 | 218 | if (call->ackr_reason && call->ackr_reason != RXRPC_ACK_DELAY) |
| @@ -307,6 +307,17 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index) · 306 unmodified lines | ||
| 307 | 307 | return tcf_idr_search(tn, a, index); |
| 308 | 308 | } |
| 309 | 309 | |
| 310 | +static size_t tcf_skbedit_get_fill_size(const struct tc_action *act) | |
| 311 | +{ | |
| 312 | + return nla_total_size(sizeof(struct tc_skbedit)) | |
| 313 | + + nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_PRIORITY */ | |
| 314 | + + nla_total_size(sizeof(u16)) /* TCA_SKBEDIT_QUEUE_MAPPING */ | |
| 315 | + + nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_MARK */ | |
| 316 | + + nla_total_size(sizeof(u16)) /* TCA_SKBEDIT_PTYPE */ | |
| 317 | + + nla_total_size(sizeof(u32)) /* TCA_SKBEDIT_MASK */ | |
| 318 | + + nla_total_size_64bit(sizeof(u64)); /* TCA_SKBEDIT_FLAGS */ | |
| 319 | +} | |
| 320 | + | |
| 310 | 321 | static struct tc_action_ops act_skbedit_ops = { |
| 311 | 322 | .kind = "skbedit", |
| 312 | 323 | .id = TCA_ID_SKBEDIT, |
| @@ -316,6 +327,7 @@ static struct tc_action_ops act_skbedit_ops = { · 3 unmodified lines | ||
| 316 | 327 | .init = tcf_skbedit_init, |
| 317 | 328 | .cleanup = tcf_skbedit_cleanup, |
| 318 | 329 | .walk = tcf_skbedit_walker, |
| 330 | + .get_fill_size = tcf_skbedit_get_fill_size, | |
| 319 | 331 | .lookup = tcf_skbedit_search, |
| 320 | 332 | .size = sizeof(struct tcf_skbedit), |
| 321 | 333 | }; |
| @@ -1191,7 +1191,8 @@ unlock: · 1190 unmodified lines | ||
| 1191 | 1191 | spin_unlock_bh(qdisc_lock(sch)); |
| 1192 | 1192 | |
| 1193 | 1193 | free_sched: |
| 1194 | − kfree(new_admin); | |
| 1194 | + if (new_admin) | |
| 1195 | + call_rcu(&new_admin->rcu, taprio_free_sched_cb); | |
| 1195 | 1196 | |
| 1196 | 1197 | return err; |
| 1197 | 1198 | } |
| @@ -546,7 +546,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_cmd_seq *commands, · 545 unmodified lines | ||
| 546 | 546 | */ |
| 547 | 547 | if (net->sctp.pf_enable && |
| 548 | 548 | (transport->state == SCTP_ACTIVE) && |
| 549 | − (asoc->pf_retrans < transport->pathmaxrxt) && | |
| 549 | + (transport->error_count < transport->pathmaxrxt) && | |
| 550 | 550 | (transport->error_count > asoc->pf_retrans)) { |
| 551 | 551 | |
| 552 | 552 | sctp_assoc_control_transport(asoc, transport, |
| @@ -316,6 +316,7 @@ int sctp_send_reset_streams(struct sctp_association *asoc, · 315 unmodified lines | ||
| 316 | 316 | nstr_list[i] = htons(str_list[i]); |
| 317 | 317 | |
| 318 | 318 | if (out && !sctp_stream_outq_is_empty(stream, str_nums, nstr_list)) { |
| 319 | + kfree(nstr_list); | |
| 319 | 320 | retval = -EAGAIN; |
| 320 | 321 | goto out; |
| 321 | 322 | } |
| @@ -75,6 +75,7 @@ void tipc_set_node_addr(struct net *net, u32 addr) · 74 unmodified lines | ||
| 75 | 75 | tipc_set_node_id(net, node_id); |
| 76 | 76 | } |
| 77 | 77 | tn->trial_addr = addr; |
| 78 | + tn->addr_trial_end = jiffies; | |
| 78 | 79 | pr_info("32-bit node address hash set to %x\n", addr); |
| 79 | 80 | } |
| 80 | 81 | |
| @@ -106,8 +106,6 @@ struct tipc_stats { · 105 unmodified lines | ||
| 106 | 106 | * @transmitq: queue for sent, non-acked messages |
| 107 | 107 | * @backlogq: queue for messages waiting to be sent |
| 108 | 108 | * @snt_nxt: next sequence number to use for outbound messages |
| 109 | − * @prev_from: sequence number of most previous retransmission request | |
| 110 | − * @stale_limit: time when repeated identical retransmits must force link reset | |
| 111 | 109 | * @ackers: # of peers that needs to ack each packet before it can be released |
| 112 | 110 | * @acked: # last packet acked by a certain peer. Used for broadcast. |
| 113 | 111 | * @rcv_nxt: next sequence number to expect for inbound messages |
| @@ -164,9 +162,7 @@ struct tipc_link { · 50 unmodified lines | ||
| 164 | 162 | u16 limit; |
| 165 | 163 | } backlog[5]; |
| 166 | 164 | u16 snd_nxt; |
| 167 | − u16 prev_from; | |
| 168 | 165 | u16 window; |
| 169 | − unsigned long stale_limit; | |
| 170 | 166 | |
| 171 | 167 | /* Reception */ |
| 172 | 168 | u16 rcv_nxt; |
| @@ -1063,47 +1059,53 @@ static void tipc_link_advance_backlog(struct tipc_link *l, · 890 unmodified lines | ||
| 1063 | 1059 | * link_retransmit_failure() - Detect repeated retransmit failures |
| 1064 | 1060 | * @l: tipc link sender |
| 1065 | 1061 | * @r: tipc link receiver (= l in case of unicast) |
| 1066 | − * @from: seqno of the 1st packet in retransmit request | |
| 1067 | 1062 | * @rc: returned code |
| 1068 | 1063 | * |
| 1069 | 1064 | * Return: true if the repeated retransmit failures happens, otherwise |
| 1070 | 1065 | * false |
| 1071 | 1066 | */ |
| 1072 | 1067 | static bool link_retransmit_failure(struct tipc_link *l, struct tipc_link *r, |
| 1073 | − u16 from, int *rc) | |
| 1068 | + int *rc) | |
| 1074 | 1069 | { |
| 1075 | 1070 | struct sk_buff *skb = skb_peek(&l->transmq); |
| 1076 | 1071 | struct tipc_msg *hdr; |
| 1077 | 1072 | |
| 1078 | 1073 | if (!skb) |
| 1079 | 1074 | return false; |
| 1080 | − hdr = buf_msg(skb); | |
| 1081 | 1075 | |
| 1082 | − /* Detect repeated retransmit failures on same packet */ | |
| 1083 | − if (r->prev_from != from) { | |
| 1084 | − r->prev_from = from; | |
| 1085 | − r->stale_limit = jiffies + msecs_to_jiffies(r->tolerance); | |
| 1086 | − } else if (time_after(jiffies, r->stale_limit)) { | |
| 1087 | − pr_warn("Retransmission failure on link <%s>\n", l->name); | |
| 1088 | − link_print(l, "State of link "); | |
| 1089 | − pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n", | |
| 1090 | − msg_user(hdr), msg_type(hdr), msg_size(hdr), | |
| 1091 | − msg_errcode(hdr)); | |
| 1092 | − pr_info("sqno %u, prev: %x, src: %x\n", | |
| 1093 | − msg_seqno(hdr), msg_prevnode(hdr), msg_orignode(hdr)); | |
| 1094 | − | |
| 1095 | − trace_tipc_list_dump(&l->transmq, true, "retrans failure!"); | |
| 1096 | − trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!"); | |
| 1097 | − trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!"); | |
| 1076 | + if (!TIPC_SKB_CB(skb)->retr_cnt) | |
| 1077 | + return false; | |
| 1098 | 1078 | |
| 1099 | − if (link_is_bc_sndlink(l)) | |
| 1100 | − *rc = TIPC_LINK_DOWN_EVT; | |
| 1079 | + if (!time_after(jiffies, TIPC_SKB_CB(skb)->retr_stamp + | |
| 1080 | + msecs_to_jiffies(r->tolerance))) | |
| 1081 | + return false; | |
| 1082 | + | |
| 1083 | + hdr = buf_msg(skb); | |
| 1084 | + if (link_is_bc_sndlink(l) && !less(r->acked, msg_seqno(hdr))) | |
| 1085 | + return false; | |
| 1101 | 1086 | |
| 1087 | + pr_warn("Retransmission failure on link <%s>\n", l->name); | |
| 1088 | + link_print(l, "State of link "); | |
| 1089 | + pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n", | |
| 1090 | + msg_user(hdr), msg_type(hdr), msg_size(hdr), msg_errcode(hdr)); | |
| 1091 | + pr_info("sqno %u, prev: %x, dest: %x\n", | |
| 1092 | + msg_seqno(hdr), msg_prevnode(hdr), msg_destnode(hdr)); | |
| 1093 | + pr_info("retr_stamp %d, retr_cnt %d\n", | |
| 1094 | + jiffies_to_msecs(TIPC_SKB_CB(skb)->retr_stamp), | |
| 1095 | + TIPC_SKB_CB(skb)->retr_cnt); | |
| 1096 | + | |
| 1097 | + trace_tipc_list_dump(&l->transmq, true, "retrans failure!"); | |
| 1098 | + trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!"); | |
| 1099 | + trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!"); | |
| 1100 | + | |
| 1101 | + if (link_is_bc_sndlink(l)) { | |
| 1102 | + r->state = LINK_RESET; | |
| 1103 | + *rc = TIPC_LINK_DOWN_EVT; | |
| 1104 | + } else { | |
| 1102 | 1105 | *rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
| 1103 | − return true; | |
| 1104 | 1106 | } |
| 1105 | 1107 | |
| 1106 | − return false; | |
| 1108 | + return true; | |
| 1107 | 1109 | } |
| 1108 | 1110 | |
| 1109 | 1111 | /* tipc_link_bc_retrans() - retransmit zero or more packets |
| @@ -1129,7 +1131,7 @@ static int tipc_link_bc_retrans(struct tipc_link *l, struct tipc_link *r, · 19 unmodified lines | ||
| 1129 | 1131 | |
| 1130 | 1132 | trace_tipc_link_retrans(r, from, to, &l->transmq); |
| 1131 | 1133 | |
| 1132 | − if (link_retransmit_failure(l, r, from, &rc)) | |
| 1134 | + if (link_retransmit_failure(l, r, &rc)) | |
| 1133 | 1135 | return rc; |
| 1134 | 1136 | |
| 1135 | 1137 | skb_queue_walk(&l->transmq, skb) { |
| @@ -1138,11 +1140,10 @@ static int tipc_link_bc_retrans(struct tipc_link *l, struct tipc_link *r, · 2 unmodified lines | ||
| 1138 | 1140 | continue; |
| 1139 | 1141 | if (more(msg_seqno(hdr), to)) |
| 1140 | 1142 | break; |
| 1141 | − if (link_is_bc_sndlink(l)) { | |
| 1142 | − if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) | |
| 1143 | − continue; | |
| 1144 | − TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM; | |
| 1145 | − } | |
| 1143 | + | |
| 1144 | + if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) | |
| 1145 | + continue; | |
| 1146 | + TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM; | |
| 1146 | 1147 | _skb = __pskb_copy(skb, LL_MAX_HEADER + MIN_H_SIZE, GFP_ATOMIC); |
| 1147 | 1148 | if (!_skb) |
| 1148 | 1149 | return 0; |
| @@ -1152,6 +1153,10 @@ static int tipc_link_bc_retrans(struct tipc_link *l, struct tipc_link *r, · 3 unmodified lines | ||
| 1152 | 1153 | _skb->priority = TC_PRIO_CONTROL; |
| 1153 | 1154 | __skb_queue_tail(xmitq, _skb); |
| 1154 | 1155 | l->stats.retransmitted++; |
| 1156 | + | |
| 1157 | + /* Increase actual retrans counter & mark first time */ | |
| 1158 | + if (!TIPC_SKB_CB(skb)->retr_cnt++) | |
| 1159 | + TIPC_SKB_CB(skb)->retr_stamp = jiffies; | |
| 1155 | 1160 | } |
| 1156 | 1161 | return 0; |
| 1157 | 1162 | } |
| @@ -1393,12 +1398,10 @@ static int tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap, · 235 unmodified lines | ||
| 1393 | 1398 | struct tipc_msg *hdr; |
| 1394 | 1399 | u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; |
| 1395 | 1400 | u16 ack = l->rcv_nxt - 1; |
| 1401 | + bool passed = false; | |
| 1396 | 1402 | u16 seqno, n = 0; |
| 1397 | 1403 | int rc = 0; |
| 1398 | 1404 | |
| 1399 | − if (gap && link_retransmit_failure(l, l, acked + 1, &rc)) | |
| 1400 | − return rc; | |
| 1401 | − | |
| 1402 | 1405 | skb_queue_walk_safe(&l->transmq, skb, tmp) { |
| 1403 | 1406 | seqno = buf_seqno(skb); |
| 1404 | 1407 | |
| @@ -1408,12 +1411,17 @@ next_gap_ack: · 3 unmodified lines | ||
| 1408 | 1411 | __skb_unlink(skb, &l->transmq); |
| 1409 | 1412 | kfree_skb(skb); |
| 1410 | 1413 | } else if (less_eq(seqno, acked + gap)) { |
| 1411 | − /* retransmit skb */ | |
| 1414 | + /* First, check if repeated retrans failures occurs? */ | |
| 1415 | + if (!passed && link_retransmit_failure(l, l, &rc)) | |
| 1416 | + return rc; | |
| 1417 | + passed = true; | |
| 1418 | + | |
| 1419 | + /* retransmit skb if unrestricted*/ | |
| 1412 | 1420 | if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) |
| 1413 | 1421 | continue; |
| 1414 | 1422 | TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME; |
| 1415 | − | |
| 1416 | − _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); | |
| 1423 | + _skb = __pskb_copy(skb, LL_MAX_HEADER + MIN_H_SIZE, | |
| 1424 | + GFP_ATOMIC); | |
| 1417 | 1425 | if (!_skb) |
| 1418 | 1426 | continue; |
| 1419 | 1427 | hdr = buf_msg(_skb); |
| @@ -1422,6 +1430,10 @@ next_gap_ack: · 2 unmodified lines | ||
| 1422 | 1430 | _skb->priority = TC_PRIO_CONTROL; |
| 1423 | 1431 | __skb_queue_tail(xmitq, _skb); |
| 1424 | 1432 | l->stats.retransmitted++; |
| 1433 | + | |
| 1434 | + /* Increase actual retrans counter & mark first time */ | |
| 1435 | + if (!TIPC_SKB_CB(skb)->retr_cnt++) | |
| 1436 | + TIPC_SKB_CB(skb)->retr_stamp = jiffies; | |
| 1425 | 1437 | } else { |
| 1426 | 1438 | /* retry with Gap ACK blocks if any */ |
| 1427 | 1439 | if (!ga || n >= ga->gack_cnt) |
| @@ -2681,7 +2693,7 @@ int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf) · 1253 unmodified lines | ||
| 2681 | 2693 | i += scnprintf(buf + i, sz - i, " %x", l->peer_caps); |
| 2682 | 2694 | i += scnprintf(buf + i, sz - i, " %u", l->silent_intv_cnt); |
| 2683 | 2695 | i += scnprintf(buf + i, sz - i, " %u", l->rst_cnt); |
| 2684 | − i += scnprintf(buf + i, sz - i, " %u", l->prev_from); | |
| 2696 | + i += scnprintf(buf + i, sz - i, " %u", 0); | |
| 2685 | 2697 | i += scnprintf(buf + i, sz - i, " %u", 0); |
| 2686 | 2698 | i += scnprintf(buf + i, sz - i, " %u", l->acked); |
| 2687 | 2699 | |
| @@ -102,13 +102,15 @@ struct plist; · 101 unmodified lines | ||
| 102 | 102 | #define TIPC_MEDIA_INFO_OFFSET 5 |
| 103 | 103 | |
| 104 | 104 | struct tipc_skb_cb { |
| 105 | − u32 bytes_read; | |
| 106 | − u32 orig_member; | |
| 107 | 105 | struct sk_buff *tail; |
| 108 | 106 | unsigned long nxt_retr; |
| 109 | − bool validated; | |
| 107 | + unsigned long retr_stamp; | |
| 108 | + u32 bytes_read; | |
| 109 | + u32 orig_member; | |
| 110 | 110 | u16 chain_imp; |
| 111 | 111 | u16 ackers; |
| 112 | + u16 retr_cnt; | |
| 113 | + bool validated; | |
| 112 | 114 | }; |
| 113 | 115 | |
| 114 | 116 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) |
| @@ -373,9 +373,9 @@ static int tls_push_data(struct sock *sk, · 372 unmodified lines | ||
| 373 | 373 | struct tls_context *tls_ctx = tls_get_ctx(sk); |
| 374 | 374 | struct tls_prot_info *prot = &tls_ctx->prot_info; |
| 375 | 375 | struct tls_offload_context_tx *ctx = tls_offload_ctx_tx(tls_ctx); |
| 376 | − int tls_push_record_flags = flags | MSG_SENDPAGE_NOTLAST; | |
| 377 | 376 | int more = flags & (MSG_SENDPAGE_NOTLAST | MSG_MORE); |
| 378 | 377 | struct tls_record_info *record = ctx->open_record; |
| 378 | + int tls_push_record_flags; | |
| 379 | 379 | struct page_frag *pfrag; |
| 380 | 380 | size_t orig_size = size; |
| 381 | 381 | u32 max_open_record_len; |
| @@ -390,6 +390,9 @@ static int tls_push_data(struct sock *sk, · 8 unmodified lines | ||
| 390 | 390 | if (sk->sk_err) |
| 391 | 391 | return -sk->sk_err; |
| 392 | 392 | |
| 393 | + flags |= MSG_SENDPAGE_DECRYPTED; | |
| 394 | + tls_push_record_flags = flags | MSG_SENDPAGE_NOTLAST; | |
| 395 | + | |
| 393 | 396 | timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); |
| 394 | 397 | if (tls_is_partially_sent_record(tls_ctx)) { |
| 395 | 398 | rc = tls_push_partial_record(sk, tls_ctx, flags); |
| @@ -576,7 +579,9 @@ void tls_device_write_space(struct sock *sk, struct tls_context *ctx) · 180 unmodified lines | ||
| 576 | 579 | gfp_t sk_allocation = sk->sk_allocation; |
| 577 | 580 | |
| 578 | 581 | sk->sk_allocation = GFP_ATOMIC; |
| 579 | − tls_push_partial_record(sk, ctx, MSG_DONTWAIT | MSG_NOSIGNAL); | |
| 582 | + tls_push_partial_record(sk, ctx, | |
| 583 | + MSG_DONTWAIT | MSG_NOSIGNAL | | |
| 584 | + MSG_SENDPAGE_DECRYPTED); | |
| 580 | 585 | sk->sk_allocation = sk_allocation; |
| 581 | 586 | } |
| 582 | 587 | } |
| @@ -308,6 +308,8 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) · 307 unmodified lines | ||
| 308 | 308 | if (free_ctx) |
| 309 | 309 | icsk->icsk_ulp_data = NULL; |
| 310 | 310 | sk->sk_prot = ctx->sk_proto; |
| 311 | + if (sk->sk_write_space == tls_write_space) | |
| 312 | + sk->sk_write_space = ctx->sk_write_space; | |
| 311 | 313 | write_unlock_bh(&sk->sk_callback_lock); |
| 312 | 314 | release_sock(sk); |
| 313 | 315 | if (ctx->tx_conf == TLS_SW) |
| @@ -245,7 +245,7 @@ int main(int argc, char *argv[]) · 244 unmodified lines | ||
| 245 | 245 | |
| 246 | 246 | if (argc != 2) { |
| 247 | 247 | printf( |
| 248 | − "Sintax: %s fbdev\n" | |
| 248 | + "Syntax: %s fbdev\n" | |
| 249 | 249 | "Usually: /dev/fb0, /dev/fb1...\n", argv[0]); |
| 250 | 250 | return -1; |
| 251 | 251 | } |
| @@ -52,6 +52,13 @@ ifndef obj · 51 unmodified lines | ||
| 52 | 52 | $(warning kbuild: Makefile.build is included improperly) |
| 53 | 53 | endif |
| 54 | 54 | |
| 55 | +ifeq ($(MAKECMDGOALS)$(need-modorder),) | |
| 56 | +ifneq ($(obj-m),) | |
| 57 | +$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.) | |
| 58 | +$(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.) | |
| 59 | +endif | |
| 60 | +endif | |
| 61 | + | |
| 55 | 62 | # =========================================================================== |
| 56 | 63 | |
| 57 | 64 | ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) |
| @@ -487,7 +494,9 @@ targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ · 429 unmodified lines | ||
| 487 | 494 | |
| 488 | 495 | PHONY += $(subdir-ym) |
| 489 | 496 | $(subdir-ym): |
| 490 | − $(Q)$(MAKE) $(build)=$@ need-builtin=$(if $(findstring $@,$(subdir-obj-y)),1) | |
| 497 | + $(Q)$(MAKE) $(build)=$@ \ | |
| 498 | + need-builtin=$(if $(filter $@/built-in.a, $(subdir-obj-y)),1) \ | |
| 499 | + need-modorder=$(if $(need-modorder),$(if $(filter $@/modules.order, $(modorder)),1)) | |
| 491 | 500 | |
| 492 | 501 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. |
| 493 | 502 | # --------------------------------------------------------------------------- |
| @@ -85,10 +85,8 @@ endif · 84 unmodified lines | ||
| 85 | 85 | |
| 86 | 86 | include scripts/Makefile.lib |
| 87 | 87 | |
| 88 | −modorder := $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)modules.order | |
| 89 | − | |
| 90 | 88 | # find all modules listed in modules.order |
| 91 | −modules := $(sort $(shell cat $(modorder))) | |
| 89 | +modules := $(sort $(shell cat $(MODORDER))) | |
| 92 | 90 | |
| 93 | 91 | # Stop after building .o files if NOFINAL is set. Makes compile tests quicker |
| 94 | 92 | __modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) |
| @@ -98,7 +96,7 @@ MODPOST += $(subst -i,-n,$(filter -i,$(MAKEFLAGS))) -s -T - $(wildcard vmlinux) · 3 unmodified lines | ||
| 98 | 96 | |
| 99 | 97 | # We can go over command line length here, so be careful. |
| 100 | 98 | quiet_cmd_modpost = MODPOST $(words $(modules)) modules |
| 101 | − cmd_modpost = sed 's/ko$$/o/' $(modorder) | $(MODPOST) | |
| 99 | + cmd_modpost = sed 's/ko$$/o/' $(MODORDER) | $(MODPOST) | |
| 102 | 100 | |
| 103 | 101 | PHONY += modules-modpost |
| 104 | 102 | modules-modpost: |
| @@ -1,3 +1,4 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 1 | 2 | // Check if refcount_t type and API should be used |
| 2 | 3 | // instead of atomic_t type when dealing with refcounters |
| 3 | 4 | // |
| @@ -1228,24 +1228,11 @@ hashalg_fail: · 1227 unmodified lines | ||
| 1228 | 1228 | |
| 1229 | 1229 | static int __init init_digests(void) |
| 1230 | 1230 | { |
| 1231 | − u8 digest[TPM_MAX_DIGEST_SIZE]; | |
| 1232 | − int ret; | |
| 1233 | − int i; | |
| 1234 | − | |
| 1235 | − ret = tpm_get_random(chip, digest, TPM_MAX_DIGEST_SIZE); | |
| 1236 | − if (ret < 0) | |
| 1237 | − return ret; | |
| 1238 | − if (ret < TPM_MAX_DIGEST_SIZE) | |
| 1239 | − return -EFAULT; | |
| 1240 | − | |
| 1241 | 1231 | digests = kcalloc(chip->nr_allocated_banks, sizeof(*digests), |
| 1242 | 1232 | GFP_KERNEL); |
| 1243 | 1233 | if (!digests) |
| 1244 | 1234 | return -ENOMEM; |
| 1245 | 1235 | |
| 1246 | − for (i = 0; i < chip->nr_allocated_banks; i++) | |
| 1247 | − memcpy(digests[i].digest, digest, TPM_MAX_DIGEST_SIZE); | |
| 1248 | − | |
| 1249 | 1236 | return 0; |
| 1250 | 1237 | } |
| 1251 | 1238 | |
| @@ -37,7 +37,7 @@ int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit, · 36 unmodified lines | ||
| 37 | 37 | packets_per_page = PAGE_SIZE / packet_size; |
| 38 | 38 | if (WARN_ON(!packets_per_page)) { |
| 39 | 39 | err = -EINVAL; |
| 40 | − goto error; | |
| 40 | + goto err_packets; | |
| 41 | 41 | } |
| 42 | 42 | pages = DIV_ROUND_UP(count, packets_per_page); |
| 43 | 43 | |
| @@ -598,11 +598,9 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) · 597 unmodified lines | ||
| 598 | 598 | } |
| 599 | 599 | runtime->private_data = azx_dev; |
| 600 | 600 | |
| 601 | − if (chip->gts_present) | |
| 602 | − azx_pcm_hw.info = azx_pcm_hw.info | | |
| 603 | − SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME; | |
| 604 | − | |
| 605 | 601 | runtime->hw = azx_pcm_hw; |
| 602 | + if (chip->gts_present) | |
| 603 | + runtime->hw.info |= SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME; | |
| 606 | 604 | runtime->hw.channels_min = hinfo->channels_min; |
| 607 | 605 | runtime->hw.channels_max = hinfo->channels_max; |
| 608 | 606 | runtime->hw.formats = hinfo->formats; |
| @@ -615,6 +613,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) · 6 unmodified lines | ||
| 615 | 613 | 20, |
| 616 | 614 | 178000000); |
| 617 | 615 | |
| 616 | + /* by some reason, the playback stream stalls on PulseAudio with | |
| 617 | + * tsched=1 when a capture stream triggers. Until we figure out the | |
| 618 | + * real cause, disable tsched mode by telling the PCM info flag. | |
| 619 | + */ | |
| 620 | + if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) | |
| 621 | + runtime->hw.info |= SNDRV_PCM_INFO_BATCH; | |
| 622 | + | |
| 618 | 623 | if (chip->align_buffer_size) |
| 619 | 624 | /* constrain buffer sizes to be multiple of 128 |
| 620 | 625 | bytes. This is more efficient in terms of memory |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | /* 14 unused */ |
| 32 | 32 | #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ |
| 33 | 33 | #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ |
| 34 | −/* 17 unused */ | |
| 34 | +#define AZX_DCAPS_AMD_WORKAROUND (1 << 17) /* AMD-specific workaround */ | |
| 35 | 35 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ |
| 36 | 36 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
| 37 | 37 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
| @@ -6051,6 +6051,24 @@ void snd_hda_gen_free(struct hda_codec *codec) · 6050 unmodified lines | ||
| 6051 | 6051 | } |
| 6052 | 6052 | EXPORT_SYMBOL_GPL(snd_hda_gen_free); |
| 6053 | 6053 | |
| 6054 | +/** | |
| 6055 | + * snd_hda_gen_reboot_notify - Make codec enter D3 before rebooting | |
| 6056 | + * @codec: the HDA codec | |
| 6057 | + * | |
| 6058 | + * This can be put as patch_ops reboot_notify function. | |
| 6059 | + */ | |
| 6060 | +void snd_hda_gen_reboot_notify(struct hda_codec *codec) | |
| 6061 | +{ | |
| 6062 | + /* Make the codec enter D3 to avoid spurious noises from the internal | |
| 6063 | + * speaker during (and after) reboot | |
| 6064 | + */ | |
| 6065 | + snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3); | |
| 6066 | + snd_hda_codec_write(codec, codec->core.afg, 0, | |
| 6067 | + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
| 6068 | + msleep(10); | |
| 6069 | +} | |
| 6070 | +EXPORT_SYMBOL_GPL(snd_hda_gen_reboot_notify); | |
| 6071 | + | |
| 6054 | 6072 | #ifdef CONFIG_PM |
| 6055 | 6073 | /** |
| 6056 | 6074 | * snd_hda_gen_check_power_status - check the loopback power save state |
| @@ -6078,6 +6096,7 @@ static const struct hda_codec_ops generic_patch_ops = { · 21 unmodified lines | ||
| 6078 | 6096 | .init = snd_hda_gen_init, |
| 6079 | 6097 | .free = snd_hda_gen_free, |
| 6080 | 6098 | .unsol_event = snd_hda_jack_unsol_event, |
| 6099 | + .reboot_notify = snd_hda_gen_reboot_notify, | |
| 6081 | 6100 | #ifdef CONFIG_PM |
| 6082 | 6101 | .check_power_status = snd_hda_gen_check_power_status, |
| 6083 | 6102 | #endif |
| @@ -6100,7 +6119,7 @@ static int snd_hda_parse_generic_codec(struct hda_codec *codec) · 16 unmodified lines | ||
| 6100 | 6119 | |
| 6101 | 6120 | err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0); |
| 6102 | 6121 | if (err < 0) |
| 6103 | − return err; | |
| 6122 | + goto error; | |
| 6104 | 6123 | |
| 6105 | 6124 | err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg); |
| 6106 | 6125 | if (err < 0) |
| @@ -332,6 +332,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, · 331 unmodified lines | ||
| 332 | 332 | struct auto_pin_cfg *cfg); |
| 333 | 333 | int snd_hda_gen_build_controls(struct hda_codec *codec); |
| 334 | 334 | int snd_hda_gen_build_pcms(struct hda_codec *codec); |
| 335 | +void snd_hda_gen_reboot_notify(struct hda_codec *codec); | |
| 335 | 336 | |
| 336 | 337 | /* standard jack event callbacks */ |
| 337 | 338 | void snd_hda_gen_hp_automute(struct hda_codec *codec, |
| @@ -64,6 +64,7 @@ enum { · 63 unmodified lines | ||
| 64 | 64 | POS_FIX_VIACOMBO, |
| 65 | 65 | POS_FIX_COMBO, |
| 66 | 66 | POS_FIX_SKL, |
| 67 | + POS_FIX_FIFO, | |
| 67 | 68 | }; |
| 68 | 69 | |
| 69 | 70 | /* Defines for ATI HD Audio support in SB450 south bridge */ |
| @@ -135,7 +136,7 @@ module_param_array(model, charp, NULL, 0444); · 65 unmodified lines | ||
| 135 | 136 | MODULE_PARM_DESC(model, "Use the given board model."); |
| 136 | 137 | module_param_array(position_fix, int, NULL, 0444); |
| 137 | 138 | MODULE_PARM_DESC(position_fix, "DMA pointer read method." |
| 138 | − "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+)."); | |
| 139 | + "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO)."); | |
| 139 | 140 | module_param_array(bdl_pos_adj, int, NULL, 0644); |
| 140 | 141 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); |
| 141 | 142 | module_param_array(probe_mask, int, NULL, 0444); |
| @@ -332,6 +333,11 @@ enum { · 190 unmodified lines | ||
| 332 | 333 | #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ |
| 333 | 334 | (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) |
| 334 | 335 | |
| 336 | +/* quirks for AMD SB */ | |
| 337 | +#define AZX_DCAPS_PRESET_AMD_SB \ | |
| 338 | + (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_AMD_WORKAROUND |\ | |
| 339 | + AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME) | |
| 340 | + | |
| 335 | 341 | /* quirks for Nvidia */ |
| 336 | 342 | #define AZX_DCAPS_PRESET_NVIDIA \ |
| 337 | 343 | (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ |
| @@ -841,6 +847,49 @@ static unsigned int azx_via_get_position(struct azx *chip, · 503 unmodified lines | ||
| 841 | 847 | return bound_pos + mod_dma_pos; |
| 842 | 848 | } |
| 843 | 849 | |
| 850 | +#define AMD_FIFO_SIZE 32 | |
| 851 | + | |
| 852 | +/* get the current DMA position with FIFO size correction */ | |
| 853 | +static unsigned int azx_get_pos_fifo(struct azx *chip, struct azx_dev *azx_dev) | |
| 854 | +{ | |
| 855 | + struct snd_pcm_substream *substream = azx_dev->core.substream; | |
| 856 | + struct snd_pcm_runtime *runtime = substream->runtime; | |
| 857 | + unsigned int pos, delay; | |
| 858 | + | |
| 859 | + pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev)); | |
| 860 | + if (!runtime) | |
| 861 | + return pos; | |
| 862 | + | |
| 863 | + runtime->delay = AMD_FIFO_SIZE; | |
| 864 | + delay = frames_to_bytes(runtime, AMD_FIFO_SIZE); | |
| 865 | + if (azx_dev->insufficient) { | |
| 866 | + if (pos < delay) { | |
| 867 | + delay = pos; | |
| 868 | + runtime->delay = bytes_to_frames(runtime, pos); | |
| 869 | + } else { | |
| 870 | + azx_dev->insufficient = 0; | |
| 871 | + } | |
| 872 | + } | |
| 873 | + | |
| 874 | + /* correct the DMA position for capture stream */ | |
| 875 | + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | |
| 876 | + if (pos < delay) | |
| 877 | + pos += azx_dev->core.bufsize; | |
| 878 | + pos -= delay; | |
| 879 | + } | |
| 880 | + | |
| 881 | + return pos; | |
| 882 | +} | |
| 883 | + | |
| 884 | +static int azx_get_delay_from_fifo(struct azx *chip, struct azx_dev *azx_dev, | |
| 885 | + unsigned int pos) | |
| 886 | +{ | |
| 887 | + struct snd_pcm_substream *substream = azx_dev->core.substream; | |
| 888 | + | |
| 889 | + /* just read back the calculated value in the above */ | |
| 890 | + return substream->runtime->delay; | |
| 891 | +} | |
| 892 | + | |
| 844 | 893 | static unsigned int azx_skl_get_dpib_pos(struct azx *chip, |
| 845 | 894 | struct azx_dev *azx_dev) |
| 846 | 895 | { |
| @@ -1417,6 +1466,7 @@ static int check_position_fix(struct azx *chip, int fix) · 570 unmodified lines | ||
| 1417 | 1466 | case POS_FIX_VIACOMBO: |
| 1418 | 1467 | case POS_FIX_COMBO: |
| 1419 | 1468 | case POS_FIX_SKL: |
| 1469 | + case POS_FIX_FIFO: | |
| 1420 | 1470 | return fix; |
| 1421 | 1471 | } |
| 1422 | 1472 | |
| @@ -1433,6 +1483,10 @@ static int check_position_fix(struct azx *chip, int fix) · 10 unmodified lines | ||
| 1433 | 1483 | dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n"); |
| 1434 | 1484 | return POS_FIX_VIACOMBO; |
| 1435 | 1485 | } |
| 1486 | + if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) { | |
| 1487 | + dev_dbg(chip->card->dev, "Using FIFO position fix\n"); | |
| 1488 | + return POS_FIX_FIFO; | |
| 1489 | + } | |
| 1436 | 1490 | if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) { |
| 1437 | 1491 | dev_dbg(chip->card->dev, "Using LPIB position fix\n"); |
| 1438 | 1492 | return POS_FIX_LPIB; |
| @@ -1453,6 +1507,7 @@ static void assign_position_fix(struct azx *chip, int fix) · 14 unmodified lines | ||
| 1453 | 1507 | [POS_FIX_VIACOMBO] = azx_via_get_position, |
| 1454 | 1508 | [POS_FIX_COMBO] = azx_get_pos_lpib, |
| 1455 | 1509 | [POS_FIX_SKL] = azx_get_pos_skl, |
| 1510 | + [POS_FIX_FIFO] = azx_get_pos_fifo, | |
| 1456 | 1511 | }; |
| 1457 | 1512 | |
| 1458 | 1513 | chip->get_position[0] = chip->get_position[1] = callbacks[fix]; |
| @@ -1467,6 +1522,9 @@ static void assign_position_fix(struct azx *chip, int fix) · 8 unmodified lines | ||
| 1467 | 1522 | azx_get_delay_from_lpib; |
| 1468 | 1523 | } |
| 1469 | 1524 | |
| 1525 | + if (fix == POS_FIX_FIFO) | |
| 1526 | + chip->get_delay[0] = chip->get_delay[1] = | |
| 1527 | + azx_get_delay_from_fifo; | |
| 1470 | 1528 | } |
| 1471 | 1529 | |
| 1472 | 1530 | /* |
| @@ -2447,6 +2505,12 @@ static const struct pci_device_id azx_ids[] = { · 974 unmodified lines | ||
| 2447 | 2505 | /* AMD Hudson */ |
| 2448 | 2506 | { PCI_DEVICE(0x1022, 0x780d), |
| 2449 | 2507 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, |
| 2508 | + /* AMD, X370 & co */ | |
| 2509 | + { PCI_DEVICE(0x1022, 0x1457), | |
| 2510 | + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB }, | |
| 2511 | + /* AMD, X570 & co */ | |
| 2512 | + { PCI_DEVICE(0x1022, 0x1487), | |
| 2513 | + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB }, | |
| 2450 | 2514 | /* AMD Stoney */ |
| 2451 | 2515 | { PCI_DEVICE(0x1022, 0x157a), |
| 2452 | 2516 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB | |
| @@ -163,23 +163,10 @@ static void cx_auto_reboot_notify(struct hda_codec *codec) · 162 unmodified lines | ||
| 163 | 163 | { |
| 164 | 164 | struct conexant_spec *spec = codec->spec; |
| 165 | 165 | |
| 166 | − switch (codec->core.vendor_id) { | |
| 167 | − case 0x14f12008: /* CX8200 */ | |
| 168 | − case 0x14f150f2: /* CX20722 */ | |
| 169 | − case 0x14f150f4: /* CX20724 */ | |
| 170 | − break; | |
| 171 | − default: | |
| 172 | − return; | |
| 173 | − } | |
| 174 | − | |
| 175 | 166 | /* Turn the problematic codec into D3 to avoid spurious noises |
| 176 | 167 | from the internal speaker during (and after) reboot */ |
| 177 | 168 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, false); |
| 178 | − | |
| 179 | − snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3); | |
| 180 | − snd_hda_codec_write(codec, codec->core.afg, 0, | |
| 181 | − AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
| 182 | − msleep(10); | |
| 169 | + snd_hda_gen_reboot_notify(codec); | |
| 183 | 170 | } |
| 184 | 171 | |
| 185 | 172 | static void cx_auto_free(struct hda_codec *codec) |
| @@ -869,15 +869,6 @@ static void alc_reboot_notify(struct hda_codec *codec) · 868 unmodified lines | ||
| 869 | 869 | alc_shutup(codec); |
| 870 | 870 | } |
| 871 | 871 | |
| 872 | −/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */ | |
| 873 | −static void alc_d3_at_reboot(struct hda_codec *codec) | |
| 874 | −{ | |
| 875 | − snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3); | |
| 876 | − snd_hda_codec_write(codec, codec->core.afg, 0, | |
| 877 | − AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
| 878 | − msleep(10); | |
| 879 | −} | |
| 880 | − | |
| 881 | 872 | #define alc_free snd_hda_gen_free |
| 882 | 873 | |
| 883 | 874 | #ifdef CONFIG_PM |
| @@ -5152,7 +5143,7 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec, · 4268 unmodified lines | ||
| 5152 | 5143 | struct alc_spec *spec = codec->spec; |
| 5153 | 5144 | |
| 5154 | 5145 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
| 5155 | − spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */ | |
| 5146 | + spec->reboot_notify = snd_hda_gen_reboot_notify; /* reduce noise */ | |
| 5156 | 5147 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
| 5157 | 5148 | codec->power_save_node = 0; /* avoid click noises */ |
| 5158 | 5149 | snd_hda_apply_pincfgs(codec, pincfgs); |
| @@ -6987,6 +6978,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 1828 unmodified lines | ||
| 6987 | 6978 | SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), |
| 6988 | 6979 | SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), |
| 6989 | 6980 | SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), |
| 6981 | + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), | |
| 6990 | 6982 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
| 6991 | 6983 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
| 6992 | 6984 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| @@ -31,8 +31,8 @@ struct i2s_stream_instance { · 30 unmodified lines | ||
| 31 | 31 | u16 num_pages; |
| 32 | 32 | u16 channels; |
| 33 | 33 | u32 xfer_resolution; |
| 34 | − struct page *pg; | |
| 35 | 34 | u64 bytescount; |
| 35 | + dma_addr_t dma_addr; | |
| 36 | 36 | void __iomem *acp3x_base; |
| 37 | 37 | }; |
| 38 | 38 | |
| @@ -211,9 +211,8 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id) · 172 unmodified lines | ||
| 211 | 211 | static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) |
| 212 | 212 | { |
| 213 | 213 | u16 page_idx; |
| 214 | − u64 addr; | |
| 215 | 214 | u32 low, high, val, acp_fifo_addr; |
| 216 | − struct page *pg = rtd->pg; | |
| 215 | + dma_addr_t addr = rtd->dma_addr; | |
| 217 | 216 | |
| 218 | 217 | /* 8 scratch registers used to map one 64 bit address */ |
| 219 | 218 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) |
| @@ -229,7 +228,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) · 9 unmodified lines | ||
| 229 | 228 | |
| 230 | 229 | for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { |
| 231 | 230 | /* Load the low address of page int ACP SRAM through SRBM */ |
| 232 | − addr = page_to_phys(pg); | |
| 233 | 231 | low = lower_32_bits(addr); |
| 234 | 232 | high = upper_32_bits(addr); |
| 235 | 233 | |
| @@ -239,7 +237,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) · 3 unmodified lines | ||
| 239 | 237 | + 4); |
| 240 | 238 | /* Move to next physically contiguos page */ |
| 241 | 239 | val += 8; |
| 242 | − pg++; | |
| 240 | + addr += PAGE_SIZE; | |
| 243 | 241 | } |
| 244 | 242 | |
| 245 | 243 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
| @@ -341,7 +339,6 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream, · 95 unmodified lines | ||
| 341 | 339 | { |
| 342 | 340 | int status; |
| 343 | 341 | u64 size; |
| 344 | − struct page *pg; | |
| 345 | 342 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 346 | 343 | struct i2s_stream_instance *rtd = runtime->private_data; |
| 347 | 344 | |
| @@ -354,9 +351,8 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 354 | 351 | return status; |
| 355 | 352 | |
| 356 | 353 | memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); |
| 357 | − pg = virt_to_page(substream->dma_buffer.area); | |
| 358 | − if (pg) { | |
| 359 | − rtd->pg = pg; | |
| 354 | + if (substream->dma_buffer.area) { | |
| 355 | + rtd->dma_addr = substream->dma_buffer.addr; | |
| 360 | 356 | rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); |
| 361 | 357 | config_acp3x_dma(rtd, substream->stream); |
| 362 | 358 | status = 0; |
| @@ -385,9 +381,11 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream) · 22 unmodified lines | ||
| 385 | 381 | |
| 386 | 382 | static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd) |
| 387 | 383 | { |
| 384 | + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, | |
| 385 | + DRV_NAME); | |
| 386 | + struct device *parent = component->dev->parent; | |
| 388 | 387 | snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, |
| 389 | − rtd->pcm->card->dev, | |
| 390 | − MIN_BUFFER, MAX_BUFFER); | |
| 388 | + parent, MIN_BUFFER, MAX_BUFFER); | |
| 391 | 389 | return 0; |
| 392 | 390 | } |
| 393 | 391 | |
| @@ -47,6 +47,7 @@ struct cs42xx8_priv { · 46 unmodified lines | ||
| 47 | 47 | unsigned long sysclk; |
| 48 | 48 | u32 tx_channels; |
| 49 | 49 | struct gpio_desc *gpiod_reset; |
| 50 | + u32 rate[2]; | |
| 50 | 51 | }; |
| 51 | 52 | |
| 52 | 53 | /* -127.5dB to 0dB with step of 0.5dB */ |
| @@ -176,21 +177,27 @@ static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = { · 123 unmodified lines | ||
| 176 | 177 | }; |
| 177 | 178 | |
| 178 | 179 | struct cs42xx8_ratios { |
| 179 | − unsigned int ratio; | |
| 180 | − unsigned char speed; | |
| 181 | − unsigned char mclk; | |
| 180 | + unsigned int mfreq; | |
| 181 | + unsigned int min_mclk; | |
| 182 | + unsigned int max_mclk; | |
| 183 | + unsigned int ratio[3]; | |
| 182 | 184 | }; |
| 183 | 185 | |
| 186 | +/* | |
| 187 | + * According to reference mannual, define the cs42xx8_ratio struct | |
| 188 | + * MFreq2 | MFreq1 | MFreq0 | Description | SSM | DSM | QSM | | |
| 189 | + * 0 | 0 | 0 |1.029MHz to 12.8MHz | 256 | 128 | 64 | | |
| 190 | + * 0 | 0 | 1 |1.536MHz to 19.2MHz | 384 | 192 | 96 | | |
| 191 | + * 0 | 1 | 0 |2.048MHz to 25.6MHz | 512 | 256 | 128 | | |
| 192 | + * 0 | 1 | 1 |3.072MHz to 38.4MHz | 768 | 384 | 192 | | |
| 193 | + * 1 | x | x |4.096MHz to 51.2MHz |1024 | 512 | 256 | | |
| 194 | + */ | |
| 184 | 195 | static const struct cs42xx8_ratios cs42xx8_ratios[] = { |
| 185 | − { 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) }, | |
| 186 | − { 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) }, | |
| 187 | − { 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) }, | |
| 188 | − { 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) }, | |
| 189 | − { 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) }, | |
| 190 | − { 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) }, | |
| 191 | − { 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) }, | |
| 192 | − { 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) }, | |
| 193 | − { 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) } | |
| 196 | + { 0, 1029000, 12800000, {256, 128, 64} }, | |
| 197 | + { 2, 1536000, 19200000, {384, 192, 96} }, | |
| 198 | + { 4, 2048000, 25600000, {512, 256, 128} }, | |
| 199 | + { 6, 3072000, 38400000, {768, 384, 192} }, | |
| 200 | + { 8, 4096000, 51200000, {1024, 512, 256} }, | |
| 194 | 201 | }; |
| 195 | 202 | |
| 196 | 203 | static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
| @@ -257,14 +264,68 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream, · 60 unmodified lines | ||
| 257 | 264 | struct snd_soc_component *component = dai->component; |
| 258 | 265 | struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); |
| 259 | 266 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
| 260 | − u32 ratio = cs42xx8->sysclk / params_rate(params); | |
| 261 | − u32 i, fm, val, mask; | |
| 267 | + u32 ratio[2]; | |
| 268 | + u32 rate[2]; | |
| 269 | + u32 fm[2]; | |
| 270 | + u32 i, val, mask; | |
| 271 | + bool condition1, condition2; | |
| 262 | 272 | |
| 263 | 273 | if (tx) |
| 264 | 274 | cs42xx8->tx_channels = params_channels(params); |
| 265 | 275 | |
| 276 | + rate[tx] = params_rate(params); | |
| 277 | + rate[!tx] = cs42xx8->rate[!tx]; | |
| 278 | + | |
| 279 | + ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0; | |
| 280 | + ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0; | |
| 281 | + | |
| 282 | + /* Get functional mode for tx and rx according to rate */ | |
| 283 | + for (i = 0; i < 2; i++) { | |
| 284 | + if (cs42xx8->slave_mode) { | |
| 285 | + fm[i] = CS42XX8_FM_AUTO; | |
| 286 | + } else { | |
| 287 | + if (rate[i] < 50000) { | |
| 288 | + fm[i] = CS42XX8_FM_SINGLE; | |
| 289 | + } else if (rate[i] > 50000 && rate[i] < 100000) { | |
| 290 | + fm[i] = CS42XX8_FM_DOUBLE; | |
| 291 | + } else if (rate[i] > 100000 && rate[i] < 200000) { | |
| 292 | + fm[i] = CS42XX8_FM_QUAD; | |
| 293 | + } else { | |
| 294 | + dev_err(component->dev, | |
| 295 | + "unsupported sample rate\n"); | |
| 296 | + return -EINVAL; | |
| 297 | + } | |
| 298 | + } | |
| 299 | + } | |
| 300 | + | |
| 266 | 301 | for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) { |
| 267 | − if (cs42xx8_ratios[i].ratio == ratio) | |
| 302 | + /* Is the ratio[tx] valid ? */ | |
| 303 | + condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ? | |
| 304 | + (cs42xx8_ratios[i].ratio[0] == ratio[tx] || | |
| 305 | + cs42xx8_ratios[i].ratio[1] == ratio[tx] || | |
| 306 | + cs42xx8_ratios[i].ratio[2] == ratio[tx]) : | |
| 307 | + (cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) && | |
| 308 | + cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk && | |
| 309 | + cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk; | |
| 310 | + | |
| 311 | + if (!ratio[tx]) | |
| 312 | + condition1 = true; | |
| 313 | + | |
| 314 | + /* Is the ratio[!tx] valid ? */ | |
| 315 | + condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ? | |
| 316 | + (cs42xx8_ratios[i].ratio[0] == ratio[!tx] || | |
| 317 | + cs42xx8_ratios[i].ratio[1] == ratio[!tx] || | |
| 318 | + cs42xx8_ratios[i].ratio[2] == ratio[!tx]) : | |
| 319 | + (cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx])); | |
| 320 | + | |
| 321 | + if (!ratio[!tx]) | |
| 322 | + condition2 = true; | |
| 323 | + | |
| 324 | + /* | |
| 325 | + * Both ratio[tx] and ratio[!tx] is valid, then we get | |
| 326 | + * a proper MFreq. | |
| 327 | + */ | |
| 328 | + if (condition1 && condition2) | |
| 268 | 329 | break; |
| 269 | 330 | } |
| 270 | 331 | |
| @@ -273,15 +334,31 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 273 | 334 | return -EINVAL; |
| 274 | 335 | } |
| 275 | 336 | |
| 276 | − mask = CS42XX8_FUNCMOD_MFREQ_MASK; | |
| 277 | − val = cs42xx8_ratios[i].mclk; | |
| 337 | + cs42xx8->rate[tx] = params_rate(params); | |
| 278 | 338 | |
| 279 | − fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed; | |
| 339 | + mask = CS42XX8_FUNCMOD_MFREQ_MASK; | |
| 340 | + val = cs42xx8_ratios[i].mfreq; | |
| 280 | 341 | |
| 281 | 342 | regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD, |
| 282 | 343 | CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask, |
| 283 | − CS42XX8_FUNCMOD_xC_FM(tx, fm) | val); | |
| 344 | + CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val); | |
| 345 | + | |
| 346 | + return 0; | |
| 347 | +} | |
| 348 | + | |
| 349 | +static int cs42xx8_hw_free(struct snd_pcm_substream *substream, | |
| 350 | + struct snd_soc_dai *dai) | |
| 351 | +{ | |
| 352 | + struct snd_soc_component *component = dai->component; | |
| 353 | + struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); | |
| 354 | + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | |
| 284 | 355 | |
| 356 | + /* Clear stored rate */ | |
| 357 | + cs42xx8->rate[tx] = 0; | |
| 358 | + | |
| 359 | + regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD, | |
| 360 | + CS42XX8_FUNCMOD_xC_FM_MASK(tx), | |
| 361 | + CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO)); | |
| 285 | 362 | return 0; |
| 286 | 363 | } |
| 287 | 364 | |
| @@ -302,6 +379,7 @@ static const struct snd_soc_dai_ops cs42xx8_dai_ops = { · 14 unmodified lines | ||
| 302 | 379 | .set_fmt = cs42xx8_set_dai_fmt, |
| 303 | 380 | .set_sysclk = cs42xx8_set_dai_sysclk, |
| 304 | 381 | .hw_params = cs42xx8_hw_params, |
| 382 | + .hw_free = cs42xx8_hw_free, | |
| 305 | 383 | .digital_mute = cs42xx8_digital_mute, |
| 306 | 384 | }; |
| 307 | 385 | |
| @@ -20,20 +20,10 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <sound/soc-dapm.h> |
| 21 | 21 | |
| 22 | 22 | struct max98357a_priv { |
| 23 | − struct delayed_work enable_sdmode_work; | |
| 24 | 23 | struct gpio_desc *sdmode; |
| 25 | 24 | unsigned int sdmode_delay; |
| 26 | 25 | }; |
| 27 | 26 | |
| 28 | −static void max98357a_enable_sdmode_work(struct work_struct *work) | |
| 29 | −{ | |
| 30 | − struct max98357a_priv *max98357a = | |
| 31 | − container_of(work, struct max98357a_priv, | |
| 32 | − enable_sdmode_work.work); | |
| 33 | − | |
| 34 | − gpiod_set_value(max98357a->sdmode, 1); | |
| 35 | −} | |
| 36 | − | |
| 37 | 27 | static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, |
| 38 | 28 | int cmd, struct snd_soc_dai *dai) |
| 39 | 29 | { |
| @@ -46,14 +36,12 @@ static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, · 6 unmodified lines | ||
| 46 | 36 | case SNDRV_PCM_TRIGGER_START: |
| 47 | 37 | case SNDRV_PCM_TRIGGER_RESUME: |
| 48 | 38 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 49 | − queue_delayed_work(system_power_efficient_wq, | |
| 50 | − &max98357a->enable_sdmode_work, | |
| 51 | − msecs_to_jiffies(max98357a->sdmode_delay)); | |
| 39 | + mdelay(max98357a->sdmode_delay); | |
| 40 | + gpiod_set_value(max98357a->sdmode, 1); | |
| 52 | 41 | break; |
| 53 | 42 | case SNDRV_PCM_TRIGGER_STOP: |
| 54 | 43 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 55 | 44 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 56 | − cancel_delayed_work_sync(&max98357a->enable_sdmode_work); | |
| 57 | 45 | gpiod_set_value(max98357a->sdmode, 0); |
| 58 | 46 | break; |
| 59 | 47 | } |
| @@ -112,30 +100,25 @@ static int max98357a_platform_probe(struct platform_device *pdev) · 52 unmodified lines | ||
| 112 | 100 | int ret; |
| 113 | 101 | |
| 114 | 102 | max98357a = devm_kzalloc(&pdev->dev, sizeof(*max98357a), GFP_KERNEL); |
| 115 | − | |
| 116 | 103 | if (!max98357a) |
| 117 | 104 | return -ENOMEM; |
| 118 | 105 | |
| 119 | 106 | max98357a->sdmode = devm_gpiod_get_optional(&pdev->dev, |
| 120 | 107 | "sdmode", GPIOD_OUT_LOW); |
| 121 | − | |
| 122 | 108 | if (IS_ERR(max98357a->sdmode)) |
| 123 | 109 | return PTR_ERR(max98357a->sdmode); |
| 124 | 110 | |
| 125 | 111 | ret = device_property_read_u32(&pdev->dev, "sdmode-delay", |
| 126 | 112 | &max98357a->sdmode_delay); |
| 127 | − | |
| 128 | 113 | if (ret) { |
| 129 | 114 | max98357a->sdmode_delay = 0; |
| 130 | 115 | dev_dbg(&pdev->dev, |
| 131 | − "no optional property 'sdmode-delay' found, default: no delay\n"); | |
| 116 | + "no optional property 'sdmode-delay' found, " | |
| 117 | + "default: no delay\n"); | |
| 132 | 118 | } |
| 133 | 119 | |
| 134 | 120 | dev_set_drvdata(&pdev->dev, max98357a); |
| 135 | 121 | |
| 136 | − INIT_DELAYED_WORK(&max98357a->enable_sdmode_work, | |
| 137 | − max98357a_enable_sdmode_work); | |
| 138 | − | |
| 139 | 122 | return devm_snd_soc_register_component(&pdev->dev, |
| 140 | 123 | &max98357a_component_driver, |
| 141 | 124 | &max98357a_dai_driver, 1); |
| @@ -267,6 +267,12 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream, · 266 unmodified lines | ||
| 267 | 267 | case 48000: |
| 268 | 268 | sampling_rate = MAX98373_PCM_SR_SET1_SR_48000; |
| 269 | 269 | break; |
| 270 | + case 88200: | |
| 271 | + sampling_rate = MAX98373_PCM_SR_SET1_SR_88200; | |
| 272 | + break; | |
| 273 | + case 96000: | |
| 274 | + sampling_rate = MAX98373_PCM_SR_SET1_SR_96000; | |
| 275 | + break; | |
| 270 | 276 | default: |
| 271 | 277 | dev_err(component->dev, "rate %d not supported\n", |
| 272 | 278 | params_rate(params)); |
| @@ -130,6 +130,8 @@ · 129 unmodified lines | ||
| 130 | 130 | #define MAX98373_PCM_SR_SET1_SR_32000 (0x6 << 0) |
| 131 | 131 | #define MAX98373_PCM_SR_SET1_SR_44100 (0x7 << 0) |
| 132 | 132 | #define MAX98373_PCM_SR_SET1_SR_48000 (0x8 << 0) |
| 133 | +#define MAX98373_PCM_SR_SET1_SR_88200 (0x9 << 0) | |
| 134 | +#define MAX98373_PCM_SR_SET1_SR_96000 (0xA << 0) | |
| 133 | 135 | |
| 134 | 136 | /* MAX98373_R2028_PCM_SR_SETUP_2 */ |
| 135 | 137 | #define MAX98373_PCM_SR_SET2_SR_MASK (0xF << 4) |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // PCM3060 I2C driver |
| 4 | 4 | // |
| 5 | −// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech> | |
| 5 | +// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 6 | 6 | |
| 7 | 7 | #include <linux/i2c.h> |
| 8 | 8 | #include <linux/module.h> |
| @@ -56,5 +56,5 @@ static struct i2c_driver pcm3060_i2c_driver = { · 47 unmodified lines | ||
| 56 | 56 | module_i2c_driver(pcm3060_i2c_driver); |
| 57 | 57 | |
| 58 | 58 | MODULE_DESCRIPTION("PCM3060 I2C driver"); |
| 59 | −MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>"); | |
| 59 | +MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); | |
| 60 | 60 | MODULE_LICENSE("GPL v2"); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // PCM3060 SPI driver |
| 4 | 4 | // |
| 5 | −// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech> | |
| 5 | +// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 6 | 6 | |
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <linux/spi/spi.h> |
| @@ -55,5 +55,5 @@ static struct spi_driver pcm3060_spi_driver = { · 46 unmodified lines | ||
| 55 | 55 | module_spi_driver(pcm3060_spi_driver); |
| 56 | 56 | |
| 57 | 57 | MODULE_DESCRIPTION("PCM3060 SPI driver"); |
| 58 | −MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>"); | |
| 58 | +MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); | |
| 59 | 59 | MODULE_LICENSE("GPL v2"); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // |
| 3 | 3 | // PCM3060 codec driver |
| 4 | 4 | // |
| 5 | −// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech> | |
| 5 | +// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 6 | 6 | |
| 7 | 7 | #include <linux/module.h> |
| 8 | 8 | #include <sound/pcm_params.h> |
| @@ -342,5 +342,5 @@ int pcm3060_probe(struct device *dev) · 333 unmodified lines | ||
| 342 | 342 | EXPORT_SYMBOL(pcm3060_probe); |
| 343 | 343 | |
| 344 | 344 | MODULE_DESCRIPTION("PCM3060 codec driver"); |
| 345 | −MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>"); | |
| 345 | +MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); | |
| 346 | 346 | MODULE_LICENSE("GPL v2"); |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * PCM3060 codec driver |
| 4 | 4 | * |
| 5 | − * Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech> | |
| 5 | + * Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #ifndef _SND_SOC_PCM3060_H |
| @@ -39,7 +39,7 @@ static const struct reg_sequence init_list[] = { · 38 unmodified lines | ||
| 39 | 39 | { RT1011_POWER_9, 0xa840 }, |
| 40 | 40 | |
| 41 | 41 | { RT1011_ADC_SET_5, 0x0a20 }, |
| 42 | − { RT1011_DAC_SET_2, 0xa232 }, | |
| 42 | + { RT1011_DAC_SET_2, 0xa032 }, | |
| 43 | 43 | { RT1011_ADC_SET_1, 0x2925 }, |
| 44 | 44 | |
| 45 | 45 | { RT1011_SPK_PRO_DC_DET_1, 0xb00c }, |
| @@ -1917,7 +1917,7 @@ static int rt1011_set_bias_level(struct snd_soc_component *component, · 1871 unmodified lines | ||
| 1917 | 1917 | snd_soc_component_write(component, |
| 1918 | 1918 | RT1011_SYSTEM_RESET_2, 0x0000); |
| 1919 | 1919 | snd_soc_component_write(component, |
| 1920 | − RT1011_SYSTEM_RESET_3, 0x0000); | |
| 1920 | + RT1011_SYSTEM_RESET_3, 0x0001); | |
| 1921 | 1921 | snd_soc_component_write(component, |
| 1922 | 1922 | RT1011_SYSTEM_RESET_1, 0x003f); |
| 1923 | 1923 | snd_soc_component_write(component, |
File mode changed from 100755 to 100644.
File mode changed from 100755 to 100644.
| @@ -63,6 +63,7 @@ static int graph_get_dai_id(struct device_node *ep) · 62 unmodified lines | ||
| 63 | 63 | struct device_node *endpoint; |
| 64 | 64 | struct of_endpoint info; |
| 65 | 65 | int i, id; |
| 66 | + const u32 *reg; | |
| 66 | 67 | int ret; |
| 67 | 68 | |
| 68 | 69 | /* use driver specified DAI ID if exist */ |
| @@ -83,8 +84,9 @@ static int graph_get_dai_id(struct device_node *ep) · 14 unmodified lines | ||
| 83 | 84 | return info.id; |
| 84 | 85 | |
| 85 | 86 | node = of_get_parent(ep); |
| 87 | + reg = of_get_property(node, "reg", NULL); | |
| 86 | 88 | of_node_put(node); |
| 87 | − if (of_get_property(node, "reg", NULL)) | |
| 89 | + if (reg) | |
| 88 | 90 | return info.port; |
| 89 | 91 | } |
| 90 | 92 | node = of_graph_get_port_parent(ep); |
| @@ -208,10 +210,6 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 117 unmodified lines | ||
| 208 | 210 | |
| 209 | 211 | dev_dbg(dev, "link_of DPCM (%pOF)\n", ep); |
| 210 | 212 | |
| 211 | − of_node_put(ports); | |
| 212 | − of_node_put(port); | |
| 213 | − of_node_put(node); | |
| 214 | − | |
| 215 | 213 | if (li->cpu) { |
| 216 | 214 | int is_single_links = 0; |
| 217 | 215 | |
| @@ -229,17 +227,17 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 11 unmodified lines | ||
| 229 | 227 | |
| 230 | 228 | ret = asoc_simple_parse_cpu(ep, dai_link, &is_single_links); |
| 231 | 229 | if (ret) |
| 232 | − return ret; | |
| 230 | + goto out_put_node; | |
| 233 | 231 | |
| 234 | 232 | ret = asoc_simple_parse_clk_cpu(dev, ep, dai_link, dai); |
| 235 | 233 | if (ret < 0) |
| 236 | − return ret; | |
| 234 | + goto out_put_node; | |
| 237 | 235 | |
| 238 | 236 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
| 239 | 237 | "fe.%s", |
| 240 | 238 | cpus->dai_name); |
| 241 | 239 | if (ret < 0) |
| 242 | − return ret; | |
| 240 | + goto out_put_node; | |
| 243 | 241 | |
| 244 | 242 | /* card->num_links includes Codec */ |
| 245 | 243 | asoc_simple_canonicalize_cpu(dai_link, is_single_links); |
| @@ -263,17 +261,17 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 17 unmodified lines | ||
| 263 | 261 | |
| 264 | 262 | ret = asoc_simple_parse_codec(ep, dai_link); |
| 265 | 263 | if (ret < 0) |
| 266 | − return ret; | |
| 264 | + goto out_put_node; | |
| 267 | 265 | |
| 268 | 266 | ret = asoc_simple_parse_clk_codec(dev, ep, dai_link, dai); |
| 269 | 267 | if (ret < 0) |
| 270 | − return ret; | |
| 268 | + goto out_put_node; | |
| 271 | 269 | |
| 272 | 270 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
| 273 | 271 | "be.%s", |
| 274 | 272 | codecs->dai_name); |
| 275 | 273 | if (ret < 0) |
| 276 | − return ret; | |
| 274 | + goto out_put_node; | |
| 277 | 275 | |
| 278 | 276 | /* check "prefix" from top node */ |
| 279 | 277 | snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, |
| @@ -293,19 +291,23 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 13 unmodified lines | ||
| 293 | 291 | |
| 294 | 292 | ret = asoc_simple_parse_tdm(ep, dai); |
| 295 | 293 | if (ret) |
| 296 | − return ret; | |
| 294 | + goto out_put_node; | |
| 297 | 295 | |
| 298 | 296 | ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep, |
| 299 | 297 | NULL, &dai_link->dai_fmt); |
| 300 | 298 | if (ret < 0) |
| 301 | − return ret; | |
| 299 | + goto out_put_node; | |
| 302 | 300 | |
| 303 | 301 | dai_link->dpcm_playback = 1; |
| 304 | 302 | dai_link->dpcm_capture = 1; |
| 305 | 303 | dai_link->ops = &graph_ops; |
| 306 | 304 | dai_link->init = asoc_simple_dai_init; |
| 307 | 305 | |
| 308 | − return 0; | |
| 306 | +out_put_node: | |
| 307 | + of_node_put(ports); | |
| 308 | + of_node_put(port); | |
| 309 | + of_node_put(node); | |
| 310 | + return ret; | |
| 309 | 311 | } |
| 310 | 312 | |
| 311 | 313 | static int graph_dai_link_of(struct asoc_simple_priv *priv, |
| @@ -349,6 +349,13 @@ void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link) · 348 unmodified lines | ||
| 349 | 349 | /* Assumes platform == cpu */ |
| 350 | 350 | if (!dai_link->platforms->of_node) |
| 351 | 351 | dai_link->platforms->of_node = dai_link->cpus->of_node; |
| 352 | + | |
| 353 | + /* | |
| 354 | + * DPCM BE can be no platform. | |
| 355 | + * Alloced memory will be waste, but not leak. | |
| 356 | + */ | |
| 357 | + if (!dai_link->platforms->of_node) | |
| 358 | + dai_link->num_platforms = 0; | |
| 352 | 359 | } |
| 353 | 360 | EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform); |
| 354 | 361 | |
| @@ -124,8 +124,6 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 123 unmodified lines | ||
| 124 | 124 | |
| 125 | 125 | li->link++; |
| 126 | 126 | |
| 127 | − of_node_put(node); | |
| 128 | − | |
| 129 | 127 | /* For single DAI link & old style of DT node */ |
| 130 | 128 | if (is_top) |
| 131 | 129 | prefix = PREFIX; |
| @@ -147,17 +145,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 15 unmodified lines | ||
| 147 | 145 | |
| 148 | 146 | ret = asoc_simple_parse_cpu(np, dai_link, &is_single_links); |
| 149 | 147 | if (ret) |
| 150 | − return ret; | |
| 148 | + goto out_put_node; | |
| 151 | 149 | |
| 152 | 150 | ret = asoc_simple_parse_clk_cpu(dev, np, dai_link, dai); |
| 153 | 151 | if (ret < 0) |
| 154 | − return ret; | |
| 152 | + goto out_put_node; | |
| 155 | 153 | |
| 156 | 154 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
| 157 | 155 | "fe.%s", |
| 158 | 156 | cpus->dai_name); |
| 159 | 157 | if (ret < 0) |
| 160 | − return ret; | |
| 158 | + goto out_put_node; | |
| 161 | 159 | |
| 162 | 160 | asoc_simple_canonicalize_cpu(dai_link, is_single_links); |
| 163 | 161 | } else { |
| @@ -180,17 +178,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 16 unmodified lines | ||
| 180 | 178 | |
| 181 | 179 | ret = asoc_simple_parse_codec(np, dai_link); |
| 182 | 180 | if (ret < 0) |
| 183 | − return ret; | |
| 181 | + goto out_put_node; | |
| 184 | 182 | |
| 185 | 183 | ret = asoc_simple_parse_clk_codec(dev, np, dai_link, dai); |
| 186 | 184 | if (ret < 0) |
| 187 | − return ret; | |
| 185 | + goto out_put_node; | |
| 188 | 186 | |
| 189 | 187 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
| 190 | 188 | "be.%s", |
| 191 | 189 | codecs->dai_name); |
| 192 | 190 | if (ret < 0) |
| 193 | − return ret; | |
| 191 | + goto out_put_node; | |
| 194 | 192 | |
| 195 | 193 | /* check "prefix" from top node */ |
| 196 | 194 | snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, |
| @@ -208,19 +206,21 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, · 11 unmodified lines | ||
| 208 | 206 | |
| 209 | 207 | ret = asoc_simple_parse_tdm(np, dai); |
| 210 | 208 | if (ret) |
| 211 | − return ret; | |
| 209 | + goto out_put_node; | |
| 212 | 210 | |
| 213 | 211 | ret = asoc_simple_parse_daifmt(dev, node, codec, |
| 214 | 212 | prefix, &dai_link->dai_fmt); |
| 215 | 213 | if (ret < 0) |
| 216 | − return ret; | |
| 214 | + goto out_put_node; | |
| 217 | 215 | |
| 218 | 216 | dai_link->dpcm_playback = 1; |
| 219 | 217 | dai_link->dpcm_capture = 1; |
| 220 | 218 | dai_link->ops = &simple_ops; |
| 221 | 219 | dai_link->init = asoc_simple_dai_init; |
| 222 | 220 | |
| 223 | − return 0; | |
| 221 | +out_put_node: | |
| 222 | + of_node_put(node); | |
| 223 | + return ret; | |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | 226 | static int simple_dai_link_of(struct asoc_simple_priv *priv, |
| @@ -364,8 +364,6 @@ static int simple_for_each_link(struct asoc_simple_priv *priv, · 137 unmodified lines | ||
| 364 | 364 | goto error; |
| 365 | 365 | } |
| 366 | 366 | |
| 367 | − of_node_put(codec); | |
| 368 | − | |
| 369 | 367 | /* get convert-xxx property */ |
| 370 | 368 | memset(&adata, 0, sizeof(adata)); |
| 371 | 369 | for_each_child_of_node(node, np) |
| @@ -387,11 +385,13 @@ static int simple_for_each_link(struct asoc_simple_priv *priv, · 15 unmodified lines | ||
| 387 | 385 | ret = func_noml(priv, np, codec, li, is_top); |
| 388 | 386 | |
| 389 | 387 | if (ret < 0) { |
| 388 | + of_node_put(codec); | |
| 390 | 389 | of_node_put(np); |
| 391 | 390 | goto error; |
| 392 | 391 | } |
| 393 | 392 | } |
| 394 | 393 | |
| 394 | + of_node_put(codec); | |
| 395 | 395 | node = of_get_next_child(top, node); |
| 396 | 396 | } while (!is_top && node); |
| 397 | 397 | |
| @@ -437,6 +437,14 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = { · 436 unmodified lines | ||
| 437 | 437 | |
| 438 | 438 | /* Please keep this list alphabetically sorted */ |
| 439 | 439 | static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { |
| 440 | + { /* Irbis NB41 */ | |
| 441 | + .matches = { | |
| 442 | + DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), | |
| 443 | + DMI_MATCH(DMI_PRODUCT_NAME, "NB41"), | |
| 444 | + }, | |
| 445 | + .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP | |
| 446 | + | BYT_CHT_ES8316_JD_INVERTED), | |
| 447 | + }, | |
| 440 | 448 | { /* Teclast X98 Plus II */ |
| 441 | 449 | .matches = { |
| 442 | 450 | DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-bxt-match.c - tables and support for BXT ACPI enumeration. | |
| 3 | + * soc-acpi-intel-bxt-match.c - tables and support for BXT ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-byt-match.c - tables and support for BYT ACPI enumeration. | |
| 3 | + * soc-acpi-intel-byt-match.c - tables and support for BYT ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2017, Intel Corporation. |
| 6 | 6 | */ |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-cht-match.c - tables and support for CHT ACPI enumeration. | |
| 3 | + * soc-acpi-intel-cht-match.c - tables and support for CHT ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2017, Intel Corporation. |
| 6 | 6 | */ |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-cnl-match.c - tables and support for CNL ACPI enumeration. | |
| 3 | + * soc-acpi-intel-cnl-match.c - tables and support for CNL ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-glk-match.c - tables and support for GLK ACPI enumeration. | |
| 3 | + * soc-acpi-intel-glk-match.c - tables and support for GLK ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | // Copyright (c) 2018, Intel Corporation. |
| 3 | 3 | |
| 4 | 4 | /* |
| 5 | − * soc-apci-intel-hda-match.c - tables and support for HDA+ACPI enumeration. | |
| 5 | + * soc-acpi-intel-hda-match.c - tables and support for HDA+ACPI enumeration. | |
| 6 | 6 | * |
| 7 | 7 | */ |
| 8 | 8 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-hsw-bdw-match.c - tables and support for ACPI enumeration. | |
| 3 | + * soc-acpi-intel-hsw-bdw-match.c - tables and support for ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2017, Intel Corporation. |
| 6 | 6 | */ |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-icl-match.c - tables and support for ICL ACPI enumeration. | |
| 3 | + * soc-acpi-intel-icl-match.c - tables and support for ICL ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-kbl-match.c - tables and support for KBL ACPI enumeration. | |
| 3 | + * soc-acpi-intel-kbl-match.c - tables and support for KBL ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | /* |
| 3 | − * soc-apci-intel-skl-match.c - tables and support for SKL ACPI enumeration. | |
| 3 | + * soc-acpi-intel-skl-match.c - tables and support for SKL ACPI enumeration. | |
| 4 | 4 | * |
| 5 | 5 | * Copyright (c) 2018, Intel Corporation. |
| 6 | 6 | * |
| @@ -150,17 +150,17 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) · 149 unmodified lines | ||
| 150 | 150 | |
| 151 | 151 | link = data->dai_link; |
| 152 | 152 | |
| 153 | − dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL); | |
| 154 | − if (!dlc) | |
| 155 | − return ERR_PTR(-ENOMEM); | |
| 153 | + for_each_child_of_node(node, np) { | |
| 154 | + dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL); | |
| 155 | + if (!dlc) | |
| 156 | + return ERR_PTR(-ENOMEM); | |
| 156 | 157 | |
| 157 | − link->cpus = &dlc[0]; | |
| 158 | − link->platforms = &dlc[1]; | |
| 158 | + link->cpus = &dlc[0]; | |
| 159 | + link->platforms = &dlc[1]; | |
| 159 | 160 | |
| 160 | − link->num_cpus = 1; | |
| 161 | − link->num_platforms = 1; | |
| 161 | + link->num_cpus = 1; | |
| 162 | + link->num_platforms = 1; | |
| 162 | 163 | |
| 163 | − for_each_child_of_node(node, np) { | |
| 164 | 164 | cpu = of_get_child_by_name(np, "cpu"); |
| 165 | 165 | codec = of_get_child_by_name(np, "codec"); |
| 166 | 166 | |
| @@ -326,7 +326,6 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, · 325 unmodified lines | ||
| 326 | 326 | val |= I2S_CHN_4; |
| 327 | 327 | break; |
| 328 | 328 | case 2: |
| 329 | − case 1: | |
| 330 | 329 | val |= I2S_CHN_2; |
| 331 | 330 | break; |
| 332 | 331 | default: |
| @@ -459,7 +458,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { · 126 unmodified lines | ||
| 459 | 458 | }, |
| 460 | 459 | .capture = { |
| 461 | 460 | .stream_name = "Capture", |
| 462 | − .channels_min = 1, | |
| 461 | + .channels_min = 2, | |
| 463 | 462 | .channels_max = 2, |
| 464 | 463 | .rates = SNDRV_PCM_RATE_8000_192000, |
| 465 | 464 | .formats = (SNDRV_PCM_FMTBIT_S8 | |
| @@ -659,7 +658,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) · 193 unmodified lines | ||
| 659 | 658 | } |
| 660 | 659 | |
| 661 | 660 | if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { |
| 662 | − if (val >= 1 && val <= 8) | |
| 661 | + if (val >= 2 && val <= 8) | |
| 663 | 662 | soc_dai->capture.channels_max = val; |
| 664 | 663 | } |
| 665 | 664 | |
| @@ -61,6 +61,37 @@ static const struct snd_kcontrol_new rk_mc_controls[] = { · 60 unmodified lines | ||
| 61 | 61 | SOC_DAPM_PIN_SWITCH("Speaker"), |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | +static int rk_jack_event(struct notifier_block *nb, unsigned long event, | |
| 65 | + void *data) | |
| 66 | +{ | |
| 67 | + struct snd_soc_jack *jack = (struct snd_soc_jack *)data; | |
| 68 | + struct snd_soc_dapm_context *dapm = &jack->card->dapm; | |
| 69 | + | |
| 70 | + if (event & SND_JACK_MICROPHONE) | |
| 71 | + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); | |
| 72 | + else | |
| 73 | + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); | |
| 74 | + | |
| 75 | + snd_soc_dapm_sync(dapm); | |
| 76 | + | |
| 77 | + return 0; | |
| 78 | +} | |
| 79 | + | |
| 80 | +static struct notifier_block rk_jack_nb = { | |
| 81 | + .notifier_call = rk_jack_event, | |
| 82 | +}; | |
| 83 | + | |
| 84 | +static int rk_init(struct snd_soc_pcm_runtime *runtime) | |
| 85 | +{ | |
| 86 | + /* | |
| 87 | + * The jack has already been created in the rk_98090_headset_init() | |
| 88 | + * function. | |
| 89 | + */ | |
| 90 | + snd_soc_jack_notifier_register(&headset_jack, &rk_jack_nb); | |
| 91 | + | |
| 92 | + return 0; | |
| 93 | +} | |
| 94 | + | |
| 64 | 95 | static int rk_aif1_hw_params(struct snd_pcm_substream *substream, |
| 65 | 96 | struct snd_pcm_hw_params *params) |
| 66 | 97 | { |
| @@ -119,6 +150,7 @@ SND_SOC_DAILINK_DEFS(hifi, · 52 unmodified lines | ||
| 119 | 150 | static struct snd_soc_dai_link rk_dailink = { |
| 120 | 151 | .name = "max98090", |
| 121 | 152 | .stream_name = "Audio", |
| 153 | + .init = rk_init, | |
| 122 | 154 | .ops = &rk_aif1_ops, |
| 123 | 155 | /* set max98090 as slave */ |
| 124 | 156 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
| @@ -284,9 +284,8 @@ static int odroid_audio_probe(struct platform_device *pdev) · 283 unmodified lines | ||
| 284 | 284 | } |
| 285 | 285 | |
| 286 | 286 | of_node_put(cpu); |
| 287 | − of_node_put(codec); | |
| 288 | 287 | if (ret < 0) |
| 289 | − return ret; | |
| 288 | + goto err_put_node; | |
| 290 | 289 | |
| 291 | 290 | ret = snd_soc_of_get_dai_link_codecs(dev, codec, codec_link); |
| 292 | 291 | if (ret < 0) |
| @@ -309,7 +308,6 @@ static int odroid_audio_probe(struct platform_device *pdev) · 16 unmodified lines | ||
| 309 | 308 | ret = PTR_ERR(priv->clk_i2s_bus); |
| 310 | 309 | goto err_put_sclk; |
| 311 | 310 | } |
| 312 | − of_node_put(cpu_dai); | |
| 313 | 311 | |
| 314 | 312 | ret = devm_snd_soc_register_card(dev, card); |
| 315 | 313 | if (ret < 0) { |
| @@ -317,6 +315,8 @@ static int odroid_audio_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 317 | 315 | goto err_put_clk_i2s; |
| 318 | 316 | } |
| 319 | 317 | |
| 318 | + of_node_put(cpu_dai); | |
| 319 | + of_node_put(codec); | |
| 320 | 320 | return 0; |
| 321 | 321 | |
| 322 | 322 | err_put_clk_i2s: |
| @@ -326,6 +326,8 @@ err_put_sclk: · 3 unmodified lines | ||
| 326 | 326 | err_put_cpu_dai: |
| 327 | 327 | of_node_put(cpu_dai); |
| 328 | 328 | snd_soc_of_put_dai_link_codecs(codec_link); |
| 329 | +err_put_node: | |
| 330 | + of_node_put(codec); | |
| 329 | 331 | return ret; |
| 330 | 332 | } |
| 331 | 333 | |
| @@ -1515,8 +1515,11 @@ static int soc_probe_link_dais(struct snd_soc_card *card, · 1514 unmodified lines | ||
| 1515 | 1515 | } |
| 1516 | 1516 | } |
| 1517 | 1517 | |
| 1518 | − if (dai_link->dai_fmt) | |
| 1519 | − snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); | |
| 1518 | + if (dai_link->dai_fmt) { | |
| 1519 | + ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); | |
| 1520 | + if (ret) | |
| 1521 | + return ret; | |
| 1522 | + } | |
| 1520 | 1523 | |
| 1521 | 1524 | ret = soc_post_component_init(rtd, dai_link->name); |
| 1522 | 1525 | if (ret) |
| @@ -1157,8 +1157,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget, · 1156 unmodified lines | ||
| 1157 | 1157 | list_add_tail(&widget->work_list, list); |
| 1158 | 1158 | |
| 1159 | 1159 | if (custom_stop_condition && custom_stop_condition(widget, dir)) { |
| 1160 | − widget->endpoints[dir] = 1; | |
| 1161 | − return widget->endpoints[dir]; | |
| 1160 | + list = NULL; | |
| 1161 | + custom_stop_condition = NULL; | |
| 1162 | 1162 | } |
| 1163 | 1163 | |
| 1164 | 1164 | if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) { |
| @@ -1195,8 +1195,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget, · 30 unmodified lines | ||
| 1195 | 1195 | * |
| 1196 | 1196 | * Optionally, can be supplied with a function acting as a stopping condition. |
| 1197 | 1197 | * This function takes the dapm widget currently being examined and the walk |
| 1198 | − * direction as an arguments, it should return true if the walk should be | |
| 1199 | − * stopped and false otherwise. | |
| 1198 | + * direction as an arguments, it should return true if widgets from that point | |
| 1199 | + * in the graph onwards should not be added to the widget list. | |
| 1200 | 1200 | */ |
| 1201 | 1201 | static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, |
| 1202 | 1202 | struct list_head *list, |
| @@ -3706,6 +3706,8 @@ request_failed: · 2503 unmodified lines | ||
| 3706 | 3706 | dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", |
| 3707 | 3707 | w->name, ret); |
| 3708 | 3708 | |
| 3709 | + kfree_const(w->sname); | |
| 3710 | + kfree(w); | |
| 3709 | 3711 | return ERR_PTR(ret); |
| 3710 | 3712 | } |
| 3711 | 3713 | |
| @@ -101,8 +101,8 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context) · 100 unmodified lines | ||
| 101 | 101 | /* |
| 102 | 102 | * This interrupt is not shared so no need to return IRQ_NONE. |
| 103 | 103 | */ |
| 104 | − dev_err_ratelimited(sdev->dev, | |
| 105 | − "error: nothing to do in IRQ thread\n"); | |
| 104 | + dev_dbg_ratelimited(sdev->dev, | |
| 105 | + "nothing to do in IPC IRQ thread\n"); | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | /* re-enable IPC interrupt */ |
| @@ -224,8 +224,8 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) · 223 unmodified lines | ||
| 224 | 224 | /* |
| 225 | 225 | * This interrupt is not shared so no need to return IRQ_NONE. |
| 226 | 226 | */ |
| 227 | − dev_err_ratelimited(sdev->dev, | |
| 228 | − "error: nothing to do in IRQ thread\n"); | |
| 227 | + dev_dbg_ratelimited(sdev->dev, | |
| 228 | + "nothing to do in IPC IRQ thread\n"); | |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | /* re-enable IPC interrupt */ |
| @@ -1002,8 +1002,8 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { · 1001 unmodified lines | ||
| 1002 | 1002 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), |
| 1003 | 1003 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), |
| 1004 | 1004 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), |
| 1005 | − .get_sr = sun8i_i2s_get_sr_wss, | |
| 1006 | − .get_wss = sun8i_i2s_get_sr_wss, | |
| 1005 | + .get_sr = sun4i_i2s_get_sr, | |
| 1006 | + .get_wss = sun4i_i2s_get_wss, | |
| 1007 | 1007 | }; |
| 1008 | 1008 | |
| 1009 | 1009 | static int sun4i_i2s_init_regmap_fields(struct device *dev, |
| @@ -195,7 +195,7 @@ static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable) · 194 unmodified lines | ||
| 195 | 195 | { |
| 196 | 196 | u32 bit; |
| 197 | 197 | |
| 198 | − for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AFSR) { | |
| 198 | + for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AMUTE) { | |
| 199 | 199 | if (enable) |
| 200 | 200 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit)); |
| 201 | 201 | else |
| @@ -223,6 +223,7 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp) · 21 unmodified lines | ||
| 223 | 223 | if (mcasp_is_synchronous(mcasp)) { |
| 224 | 224 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); |
| 225 | 225 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); |
| 226 | + mcasp_set_clk_pdir(mcasp, true); | |
| 226 | 227 | } |
| 227 | 228 | |
| 228 | 229 | /* Activate serializer(s) */ |
| @@ -1256,6 +1257,28 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, · 1027 unmodified lines | ||
| 1256 | 1257 | return ret; |
| 1257 | 1258 | } |
| 1258 | 1259 | |
| 1260 | +static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params, | |
| 1261 | + struct snd_pcm_hw_rule *rule) | |
| 1262 | +{ | |
| 1263 | + struct davinci_mcasp_ruledata *rd = rule->private; | |
| 1264 | + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | |
| 1265 | + struct snd_mask nfmt; | |
| 1266 | + int i, slot_width; | |
| 1267 | + | |
| 1268 | + snd_mask_none(&nfmt); | |
| 1269 | + slot_width = rd->mcasp->slot_width; | |
| 1270 | + | |
| 1271 | + for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) { | |
| 1272 | + if (snd_mask_test(fmt, i)) { | |
| 1273 | + if (snd_pcm_format_width(i) <= slot_width) { | |
| 1274 | + snd_mask_set(&nfmt, i); | |
| 1275 | + } | |
| 1276 | + } | |
| 1277 | + } | |
| 1278 | + | |
| 1279 | + return snd_mask_refine(fmt, &nfmt); | |
| 1280 | +} | |
| 1281 | + | |
| 1259 | 1282 | static const unsigned int davinci_mcasp_dai_rates[] = { |
| 1260 | 1283 | 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, |
| 1261 | 1284 | 88200, 96000, 176400, 192000, |
| @@ -1377,7 +1400,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 115 unmodified lines | ||
| 1377 | 1400 | struct davinci_mcasp_ruledata *ruledata = |
| 1378 | 1401 | &mcasp->ruledata[substream->stream]; |
| 1379 | 1402 | u32 max_channels = 0; |
| 1380 | − int i, dir; | |
| 1403 | + int i, dir, ret; | |
| 1381 | 1404 | int tdm_slots = mcasp->tdm_slots; |
| 1382 | 1405 | |
| 1383 | 1406 | /* Do not allow more then one stream per direction */ |
| @@ -1406,6 +1429,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 22 unmodified lines | ||
| 1406 | 1429 | max_channels++; |
| 1407 | 1430 | } |
| 1408 | 1431 | ruledata->serializers = max_channels; |
| 1432 | + ruledata->mcasp = mcasp; | |
| 1409 | 1433 | max_channels *= tdm_slots; |
| 1410 | 1434 | /* |
| 1411 | 1435 | * If the already active stream has less channels than the calculated |
| @@ -1431,20 +1455,22 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, · 19 unmodified lines | ||
| 1431 | 1455 | 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
| 1432 | 1456 | &mcasp->chconstr[substream->stream]); |
| 1433 | 1457 | |
| 1434 | − if (mcasp->slot_width) | |
| 1435 | − snd_pcm_hw_constraint_minmax(substream->runtime, | |
| 1436 | − SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | |
| 1437 | − 8, mcasp->slot_width); | |
| 1458 | + if (mcasp->slot_width) { | |
| 1459 | + /* Only allow formats require <= slot_width bits on the bus */ | |
| 1460 | + ret = snd_pcm_hw_rule_add(substream->runtime, 0, | |
| 1461 | + SNDRV_PCM_HW_PARAM_FORMAT, | |
| 1462 | + davinci_mcasp_hw_rule_slot_width, | |
| 1463 | + ruledata, | |
| 1464 | + SNDRV_PCM_HW_PARAM_FORMAT, -1); | |
| 1465 | + if (ret) | |
| 1466 | + return ret; | |
| 1467 | + } | |
| 1438 | 1468 | |
| 1439 | 1469 | /* |
| 1440 | 1470 | * If we rely on implicit BCLK divider setting we should |
| 1441 | 1471 | * set constraints based on what we can provide. |
| 1442 | 1472 | */ |
| 1443 | 1473 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { |
| 1444 | − int ret; | |
| 1445 | − | |
| 1446 | − ruledata->mcasp = mcasp; | |
| 1447 | − | |
| 1448 | 1474 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
| 1449 | 1475 | SNDRV_PCM_HW_PARAM_RATE, |
| 1450 | 1476 | davinci_mcasp_hw_rule_rate, |
| @@ -275,7 +275,8 @@ retry: · 274 unmodified lines | ||
| 275 | 275 | goto retry; |
| 276 | 276 | } |
| 277 | 277 | spin_unlock(&sound_loader_lock); |
| 278 | − return -EBUSY; | |
| 278 | + r = -EBUSY; | |
| 279 | + goto fail; | |
| 279 | 280 | } |
| 280 | 281 | } |
| 281 | 282 | |
| @@ -600,14 +600,13 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq) · 599 unmodified lines | ||
| 600 | 600 | ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP, |
| 601 | 601 | hiface_pcm_out_urb_handler); |
| 602 | 602 | if (ret < 0) |
| 603 | − return ret; | |
| 603 | + goto error; | |
| 604 | 604 | } |
| 605 | 605 | |
| 606 | 606 | ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm); |
| 607 | 607 | if (ret < 0) { |
| 608 | − kfree(rt); | |
| 609 | 608 | dev_err(&chip->dev->dev, "Cannot create pcm instance\n"); |
| 610 | − return ret; | |
| 609 | + goto error; | |
| 611 | 610 | } |
| 612 | 611 | |
| 613 | 612 | pcm->private_data = rt; |
| @@ -620,4 +619,10 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq) · 6 unmodified lines | ||
| 620 | 619 | |
| 621 | 620 | chip->pcm = rt; |
| 622 | 621 | return 0; |
| 622 | + | |
| 623 | +error: | |
| 624 | + for (i = 0; i < PCM_N_URBS; i++) | |
| 625 | + kfree(rt->out_urbs[i].buffer); | |
| 626 | + kfree(rt); | |
| 627 | + return ret; | |
| 623 | 628 | } |
| @@ -68,6 +68,7 @@ struct mixer_build { · 67 unmodified lines | ||
| 68 | 68 | unsigned char *buffer; |
| 69 | 69 | unsigned int buflen; |
| 70 | 70 | DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS); |
| 71 | + DECLARE_BITMAP(termbitmap, MAX_ID_ELEMS); | |
| 71 | 72 | struct usb_audio_term oterm; |
| 72 | 73 | const struct usbmix_name_map *map; |
| 73 | 74 | const struct usbmix_selector_map *selector_map; |
| @@ -744,6 +745,8 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, · 670 unmodified lines | ||
| 744 | 745 | return -EINVAL; |
| 745 | 746 | if (!desc->bNrInPins) |
| 746 | 747 | return -EINVAL; |
| 748 | + if (desc->bLength < sizeof(*desc) + desc->bNrInPins) | |
| 749 | + return -EINVAL; | |
| 747 | 750 | |
| 748 | 751 | switch (state->mixer->protocol) { |
| 749 | 752 | case UAC_VERSION_1: |
| @@ -773,16 +776,25 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, · 23 unmodified lines | ||
| 773 | 776 | * parse the source unit recursively until it reaches to a terminal |
| 774 | 777 | * or a branched unit. |
| 775 | 778 | */ |
| 776 | −static int check_input_term(struct mixer_build *state, int id, | |
| 779 | +static int __check_input_term(struct mixer_build *state, int id, | |
| 777 | 780 | struct usb_audio_term *term) |
| 778 | 781 | { |
| 779 | 782 | int protocol = state->mixer->protocol; |
| 780 | 783 | int err; |
| 781 | 784 | void *p1; |
| 785 | + unsigned char *hdr; | |
| 782 | 786 | |
| 783 | 787 | memset(term, 0, sizeof(*term)); |
| 784 | − while ((p1 = find_audio_control_unit(state, id)) != NULL) { | |
| 785 | − unsigned char *hdr = p1; | |
| 788 | + for (;;) { | |
| 789 | + /* a loop in the terminal chain? */ | |
| 790 | + if (test_and_set_bit(id, state->termbitmap)) | |
| 791 | + return -EINVAL; | |
| 792 | + | |
| 793 | + p1 = find_audio_control_unit(state, id); | |
| 794 | + if (!p1) | |
| 795 | + break; | |
| 796 | + | |
| 797 | + hdr = p1; | |
| 786 | 798 | term->id = id; |
| 787 | 799 | |
| 788 | 800 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
| @@ -800,7 +812,7 @@ static int check_input_term(struct mixer_build *state, int id, · 11 unmodified lines | ||
| 800 | 812 | |
| 801 | 813 | /* call recursively to verify that the |
| 802 | 814 | * referenced clock entity is valid */ |
| 803 | − err = check_input_term(state, d->bCSourceID, term); | |
| 815 | + err = __check_input_term(state, d->bCSourceID, term); | |
| 804 | 816 | if (err < 0) |
| 805 | 817 | return err; |
| 806 | 818 | |
| @@ -834,7 +846,7 @@ static int check_input_term(struct mixer_build *state, int id, · 27 unmodified lines | ||
| 834 | 846 | case UAC2_CLOCK_SELECTOR: { |
| 835 | 847 | struct uac_selector_unit_descriptor *d = p1; |
| 836 | 848 | /* call recursively to retrieve the channel info */ |
| 837 | − err = check_input_term(state, d->baSourceID[0], term); | |
| 849 | + err = __check_input_term(state, d->baSourceID[0], term); | |
| 838 | 850 | if (err < 0) |
| 839 | 851 | return err; |
| 840 | 852 | term->type = UAC3_SELECTOR_UNIT << 16; /* virtual type */ |
| @@ -897,7 +909,7 @@ static int check_input_term(struct mixer_build *state, int id, · 56 unmodified lines | ||
| 897 | 909 | |
| 898 | 910 | /* call recursively to verify that the |
| 899 | 911 | * referenced clock entity is valid */ |
| 900 | − err = check_input_term(state, d->bCSourceID, term); | |
| 912 | + err = __check_input_term(state, d->bCSourceID, term); | |
| 901 | 913 | if (err < 0) |
| 902 | 914 | return err; |
| 903 | 915 | |
| @@ -948,7 +960,7 @@ static int check_input_term(struct mixer_build *state, int id, · 44 unmodified lines | ||
| 948 | 960 | case UAC3_CLOCK_SELECTOR: { |
| 949 | 961 | struct uac_selector_unit_descriptor *d = p1; |
| 950 | 962 | /* call recursively to retrieve the channel info */ |
| 951 | − err = check_input_term(state, d->baSourceID[0], term); | |
| 963 | + err = __check_input_term(state, d->baSourceID[0], term); | |
| 952 | 964 | if (err < 0) |
| 953 | 965 | return err; |
| 954 | 966 | term->type = UAC3_SELECTOR_UNIT << 16; /* virtual type */ |
| @@ -964,7 +976,7 @@ static int check_input_term(struct mixer_build *state, int id, · 9 unmodified lines | ||
| 964 | 976 | return -EINVAL; |
| 965 | 977 | |
| 966 | 978 | /* call recursively to retrieve the channel info */ |
| 967 | − err = check_input_term(state, d->baSourceID[0], term); | |
| 979 | + err = __check_input_term(state, d->baSourceID[0], term); | |
| 968 | 980 | if (err < 0) |
| 969 | 981 | return err; |
| 970 | 982 | |
| @@ -982,6 +994,15 @@ static int check_input_term(struct mixer_build *state, int id, · 11 unmodified lines | ||
| 982 | 994 | return -ENODEV; |
| 983 | 995 | } |
| 984 | 996 | |
| 997 | + | |
| 998 | +static int check_input_term(struct mixer_build *state, int id, | |
| 999 | + struct usb_audio_term *term) | |
| 1000 | +{ | |
| 1001 | + memset(term, 0, sizeof(*term)); | |
| 1002 | + memset(state->termbitmap, 0, sizeof(state->termbitmap)); | |
| 1003 | + return __check_input_term(state, id, term); | |
| 1004 | +} | |
| 1005 | + | |
| 985 | 1006 | /* |
| 986 | 1007 | * Feature Unit |
| 987 | 1008 | */ |
| @@ -1043,6 +1043,7 @@ found_clock: · 1042 unmodified lines | ||
| 1043 | 1043 | |
| 1044 | 1044 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
| 1045 | 1045 | if (!pd) { |
| 1046 | + kfree(fp->chmap); | |
| 1046 | 1047 | kfree(fp->rate_table); |
| 1047 | 1048 | kfree(fp); |
| 1048 | 1049 | return NULL; |
| @@ -204,7 +204,11 @@ int do_pin_fd(int fd, const char *name) · 203 unmodified lines | ||
| 204 | 204 | if (err) |
| 205 | 205 | return err; |
| 206 | 206 | |
| 207 | − return bpf_obj_pin(fd, name); | |
| 207 | + err = bpf_obj_pin(fd, name); | |
| 208 | + if (err) | |
| 209 | + p_err("can't pin the object (%s): %s", name, strerror(errno)); | |
| 210 | + | |
| 211 | + return err; | |
| 208 | 212 | } |
| 209 | 213 | |
| 210 | 214 | int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) |
| @@ -237,7 +241,7 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) · 26 unmodified lines | ||
| 237 | 241 | |
| 238 | 242 | fd = get_fd_by_id(id); |
| 239 | 243 | if (fd < 0) { |
| 240 | − p_err("can't get prog by id (%u): %s", id, strerror(errno)); | |
| 244 | + p_err("can't open object by id (%u): %s", id, strerror(errno)); | |
| 241 | 245 | return -1; |
| 242 | 246 | } |
| 243 | 247 | |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | # the script prints the string "Disabled" to stdout. |
| 14 | 14 | # |
| 15 | 15 | # Each Distro is expected to implement this script in a distro specific |
| 16 | −# fashion. For instance on Distros that ship with Network Manager enabled, | |
| 16 | +# fashion. For instance, on Distros that ship with Network Manager enabled, | |
| 17 | 17 | # this script can be based on the Network Manager APIs for retrieving DHCP |
| 18 | 18 | # information. |
| 19 | 19 | |
| @@ -700,7 +700,7 @@ static void kvp_get_ipconfig_info(char *if_name, · 699 unmodified lines | ||
| 700 | 700 | |
| 701 | 701 | |
| 702 | 702 | /* |
| 703 | − * Gather the DNS state. | |
| 703 | + * Gather the DNS state. | |
| 704 | 704 | * Since there is no standard way to get this information |
| 705 | 705 | * across various distributions of interest; we just invoke |
| 706 | 706 | * an external script that needs to be ported across distros |
| @@ -1051,7 +1051,7 @@ static int parse_ip_val_buffer(char *in_buf, int *offset, · 344 unmodified lines | ||
| 1051 | 1051 | char *start; |
| 1052 | 1052 | |
| 1053 | 1053 | /* |
| 1054 | − * in_buf has sequence of characters that are seperated by | |
| 1054 | + * in_buf has sequence of characters that are separated by | |
| 1055 | 1055 | * the character ';'. The last sequence does not have the |
| 1056 | 1056 | * terminating ";" character. |
| 1057 | 1057 | */ |
| @@ -1386,6 +1386,8 @@ int main(int argc, char *argv[]) · 328 unmodified lines | ||
| 1386 | 1386 | daemonize = 0; |
| 1387 | 1387 | break; |
| 1388 | 1388 | case 'h': |
| 1389 | + print_usage(argv); | |
| 1390 | + exit(0); | |
| 1389 | 1391 | default: |
| 1390 | 1392 | print_usage(argv); |
| 1391 | 1393 | exit(EXIT_FAILURE); |
| @@ -1490,7 +1492,7 @@ int main(int argc, char *argv[]) · 98 unmodified lines | ||
| 1490 | 1492 | case KVP_OP_GET_IP_INFO: |
| 1491 | 1493 | kvp_ip_val = &hv_msg->body.kvp_ip_val; |
| 1492 | 1494 | |
| 1493 | − error = kvp_mac_to_ip(kvp_ip_val); | |
| 1495 | + error = kvp_mac_to_ip(kvp_ip_val); | |
| 1494 | 1496 | |
| 1495 | 1497 | if (error) |
| 1496 | 1498 | hv_msg->error = error; |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | # be used to configure the interface. |
| 13 | 13 | # |
| 14 | 14 | # Each Distro is expected to implement this script in a distro specific |
| 15 | −# fashion. For instance on Distros that ship with Network Manager enabled, | |
| 15 | +# fashion. For instance, on Distros that ship with Network Manager enabled, | |
| 16 | 16 | # this script can be based on the Network Manager APIs for configuring the |
| 17 | 17 | # interface. |
| 18 | 18 | # |
| @@ -42,7 +42,7 @@ static int vss_do_freeze(char *dir, unsigned int cmd) · 41 unmodified lines | ||
| 42 | 42 | * If a partition is mounted more than once, only the first |
| 43 | 43 | * FREEZE/THAW can succeed and the later ones will get |
| 44 | 44 | * EBUSY/EINVAL respectively: there could be 2 cases: |
| 45 | − * 1) a user may mount the same partition to differnt directories | |
| 45 | + * 1) a user may mount the same partition to different directories | |
| 46 | 46 | * by mistake or on purpose; |
| 47 | 47 | * 2) The subvolume of btrfs appears to have the same partition |
| 48 | 48 | * mounted more than once. |
| @@ -218,6 +218,8 @@ int main(int argc, char *argv[]) · 169 unmodified lines | ||
| 218 | 218 | daemonize = 0; |
| 219 | 219 | break; |
| 220 | 220 | case 'h': |
| 221 | + print_usage(argv); | |
| 222 | + exit(0); | |
| 221 | 223 | default: |
| 222 | 224 | print_usage(argv); |
| 223 | 225 | exit(EXIT_FAILURE); |
| @@ -4,10 +4,10 @@ · 3 unmodified lines | ||
| 4 | 4 | import os |
| 5 | 5 | from optparse import OptionParser |
| 6 | 6 | |
| 7 | +help_msg = "print verbose messages. Try -vv, -vvv for more verbose messages" | |
| 7 | 8 | parser = OptionParser() |
| 8 | −parser.add_option("-v", "--verbose", dest="verbose", | |
| 9 | − help="print verbose messages. Try -vv, -vvv for \ | |
| 10 | − more verbose messages", action="count") | |
| 9 | +parser.add_option( | |
| 10 | + "-v", "--verbose", dest="verbose", help=help_msg, action="count") | |
| 11 | 11 | |
| 12 | 12 | (options, args) = parser.parse_args() |
| 13 | 13 | |
| @@ -21,27 +21,28 @@ if not os.path.isdir(vmbus_sys_path): · 7 unmodified lines | ||
| 21 | 21 | exit(-1) |
| 22 | 22 | |
| 23 | 23 | vmbus_dev_dict = { |
| 24 | − '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]', | |
| 25 | − '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]', | |
| 26 | − '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]', | |
| 27 | − '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]', | |
| 28 | − '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]', | |
| 29 | − '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]', | |
| 30 | − '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]', | |
| 31 | − '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse', | |
| 32 | − '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard', | |
| 33 | − '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter', | |
| 34 | − '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter', | |
| 35 | − '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller', | |
| 36 | − '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller', | |
| 37 | − '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter', | |
| 38 | − '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter', | |
| 39 | − '{44c4f61d-4444-4400-9d52-802e27ede19f}' : 'PCI Express pass-through', | |
| 40 | − '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]', | |
| 41 | − '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]', | |
| 42 | − '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]', | |
| 24 | + '{0e0b6031-5213-4934-818b-38d90ced39db}': '[Operating system shutdown]', | |
| 25 | + '{9527e630-d0ae-497b-adce-e80ab0175caf}': '[Time Synchronization]', | |
| 26 | + '{57164f39-9115-4e78-ab55-382f3bd5422d}': '[Heartbeat]', | |
| 27 | + '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}': '[Data Exchange]', | |
| 28 | + '{35fa2e29-ea23-4236-96ae-3a6ebacba440}': '[Backup (volume checkpoint)]', | |
| 29 | + '{34d14be3-dee4-41c8-9ae7-6b174977c192}': '[Guest services]', | |
| 30 | + '{525074dc-8985-46e2-8057-a307dc18a502}': '[Dynamic Memory]', | |
| 31 | + '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}': 'Synthetic mouse', | |
| 32 | + '{f912ad6d-2b17-48ea-bd65-f927a61c7684}': 'Synthetic keyboard', | |
| 33 | + '{da0a7802-e377-4aac-8e77-0558eb1073f8}': 'Synthetic framebuffer adapter', | |
| 34 | + '{f8615163-df3e-46c5-913f-f2d2f965ed0e}': 'Synthetic network adapter', | |
| 35 | + '{32412632-86cb-44a2-9b5c-50d1417354f5}': 'Synthetic IDE Controller', | |
| 36 | + '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}': 'Synthetic SCSI Controller', | |
| 37 | + '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}': 'Synthetic fiber channel adapter', | |
| 38 | + '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}': 'Synthetic RDMA adapter', | |
| 39 | + '{44c4f61d-4444-4400-9d52-802e27ede19f}': 'PCI Express pass-through', | |
| 40 | + '{276aacf4-ac15-426c-98dd-7521ad3f01fe}': '[Reserved system device]', | |
| 41 | + '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}': '[Reserved system device]', | |
| 42 | + '{3375baf4-9e15-4b30-b765-67acb10d607b}': '[Reserved system device]', | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | + | |
| 45 | 46 | def get_vmbus_dev_attr(dev_name, attr): |
| 46 | 47 | try: |
| 47 | 48 | f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r') |
| @@ -52,6 +53,7 @@ def get_vmbus_dev_attr(dev_name, attr): · 4 unmodified lines | ||
| 52 | 53 | |
| 53 | 54 | return lines |
| 54 | 55 | |
| 56 | + | |
| 55 | 57 | class VMBus_Dev: |
| 56 | 58 | pass |
| 57 | 59 | |
| @@ -66,12 +68,13 @@ for f in os.listdir(vmbus_sys_path): · 8 unmodified lines | ||
| 66 | 68 | |
| 67 | 69 | chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping') |
| 68 | 70 | chn_vp_mapping = [c.strip() for c in chn_vp_mapping] |
| 69 | − chn_vp_mapping = sorted(chn_vp_mapping, | |
| 70 | − key = lambda c : int(c.split(':')[0])) | |
| 71 | + chn_vp_mapping = sorted( | |
| 72 | + chn_vp_mapping, key=lambda c: int(c.split(':')[0])) | |
| 71 | 73 | |
| 72 | − chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' % | |
| 73 | − (c.split(':')[0], c.split(':')[1]) | |
| 74 | − for c in chn_vp_mapping] | |
| 74 | + chn_vp_mapping = [ | |
| 75 | + '\tRel_ID=%s, target_cpu=%s' % | |
| 76 | + (c.split(':')[0], c.split(':')[1]) for c in chn_vp_mapping | |
| 77 | + ] | |
| 75 | 78 | d = VMBus_Dev() |
| 76 | 79 | d.sysfs_path = '%s/%s' % (vmbus_sys_path, f) |
| 77 | 80 | d.vmbus_id = vmbus_id |
| @@ -85,7 +88,7 @@ for f in os.listdir(vmbus_sys_path): · 7 unmodified lines | ||
| 85 | 88 | vmbus_dev_list.append(d) |
| 86 | 89 | |
| 87 | 90 | |
| 88 | −vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id)) | |
| 91 | +vmbus_dev_list = sorted(vmbus_dev_list, key=lambda d: int(d.vmbus_id)) | |
| 89 | 92 | |
| 90 | 93 | format0 = '%2s: %s' |
| 91 | 94 | format1 = '%2s: Class_ID = %s - %s\n%s' |
| @@ -95,9 +98,15 @@ for d in vmbus_dev_list: · 3 unmodified lines | ||
| 95 | 98 | if verbose == 0: |
| 96 | 99 | print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)) |
| 97 | 100 | elif verbose == 1: |
| 98 | − print (('VMBUS ID ' + format1) % \ | |
| 99 | − (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)) | |
| 101 | + print( | |
| 102 | + ('VMBUS ID ' + format1) % | |
| 103 | + (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) | |
| 104 | + ) | |
| 100 | 105 | else: |
| 101 | − print (('VMBUS ID ' + format2) % \ | |
| 102 | − (d.vmbus_id, d.class_id, d.dev_desc, \ | |
| 103 | − d.device_id, d.sysfs_path, d.chn_vp_mapping)) | |
| 106 | + print( | |
| 107 | + ('VMBUS ID ' + format2) % | |
| 108 | + ( | |
| 109 | + d.vmbus_id, d.class_id, d.dev_desc, | |
| 110 | + d.device_id, d.sysfs_path, d.chn_vp_mapping | |
| 111 | + ) | |
| 112 | + ) | |
| @@ -1467,8 +1467,8 @@ union bpf_attr { · 1466 unmodified lines | ||
| 1467 | 1467 | * If no cookie has been set yet, generate a new cookie. Once |
| 1468 | 1468 | * generated, the socket cookie remains stable for the life of the |
| 1469 | 1469 | * socket. This helper can be useful for monitoring per socket |
| 1470 | − * networking traffic statistics as it provides a unique socket | |
| 1471 | − * identifier per namespace. | |
| 1470 | + * networking traffic statistics as it provides a global socket | |
| 1471 | + * identifier that can be assumed unique. | |
| 1472 | 1472 | * Return |
| 1473 | 1473 | * A 8-byte long non-decreasing number on success, or 0 if the |
| 1474 | 1474 | * socket field is missing inside *skb*. |
| @@ -187,7 +187,6 @@ struct bpf_program { · 186 unmodified lines | ||
| 187 | 187 | bpf_program_clear_priv_t clear_priv; |
| 188 | 188 | |
| 189 | 189 | enum bpf_attach_type expected_attach_type; |
| 190 | − int btf_fd; | |
| 191 | 190 | void *func_info; |
| 192 | 191 | __u32 func_info_rec_size; |
| 193 | 192 | __u32 func_info_cnt; |
| @@ -318,7 +317,6 @@ void bpf_program__unload(struct bpf_program *prog) · 124 unmodified lines | ||
| 318 | 317 | prog->instances.nr = -1; |
| 319 | 318 | zfree(&prog->instances.fds); |
| 320 | 319 | |
| 321 | − zclose(prog->btf_fd); | |
| 322 | 320 | zfree(&prog->func_info); |
| 323 | 321 | zfree(&prog->line_info); |
| 324 | 322 | } |
| @@ -397,7 +395,6 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx, · 72 unmodified lines | ||
| 397 | 395 | prog->instances.fds = NULL; |
| 398 | 396 | prog->instances.nr = -1; |
| 399 | 397 | prog->type = BPF_PROG_TYPE_UNSPEC; |
| 400 | − prog->btf_fd = -1; | |
| 401 | 398 | |
| 402 | 399 | return 0; |
| 403 | 400 | errout: |
| @@ -2296,9 +2293,6 @@ bpf_program_reloc_btf_ext(struct bpf_program *prog, struct bpf_object *obj, · 1892 unmodified lines | ||
| 2296 | 2293 | prog->line_info_rec_size = btf_ext__line_info_rec_size(obj->btf_ext); |
| 2297 | 2294 | } |
| 2298 | 2295 | |
| 2299 | − if (!insn_offset) | |
| 2300 | − prog->btf_fd = btf__fd(obj->btf); | |
| 2301 | − | |
| 2302 | 2296 | return 0; |
| 2303 | 2297 | } |
| 2304 | 2298 | |
| @@ -3366,7 +3360,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 1061 unmodified lines | ||
| 3366 | 3360 | char *cp, errmsg[STRERR_BUFSIZE]; |
| 3367 | 3361 | int log_buf_size = BPF_LOG_BUF_SIZE; |
| 3368 | 3362 | char *log_buf; |
| 3369 | − int ret; | |
| 3363 | + int btf_fd, ret; | |
| 3370 | 3364 | |
| 3371 | 3365 | if (!insns || !insns_cnt) |
| 3372 | 3366 | return -EINVAL; |
| @@ -3381,7 +3375,12 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 8 unmodified lines | ||
| 3381 | 3375 | load_attr.license = license; |
| 3382 | 3376 | load_attr.kern_version = kern_version; |
| 3383 | 3377 | load_attr.prog_ifindex = prog->prog_ifindex; |
| 3384 | − load_attr.prog_btf_fd = prog->btf_fd >= 0 ? prog->btf_fd : 0; | |
| 3378 | + /* if .BTF.ext was loaded, kernel supports associated BTF for prog */ | |
| 3379 | + if (prog->obj->btf_ext) | |
| 3380 | + btf_fd = bpf_object__btf_fd(prog->obj); | |
| 3381 | + else | |
| 3382 | + btf_fd = -1; | |
| 3383 | + load_attr.prog_btf_fd = btf_fd >= 0 ? btf_fd : 0; | |
| 3385 | 3384 | load_attr.func_info = prog->func_info; |
| 3386 | 3385 | load_attr.func_info_rec_size = prog->func_info_rec_size; |
| 3387 | 3386 | load_attr.func_info_cnt = prog->func_info_cnt; |
| @@ -5903,13 +5902,15 @@ int libbpf_num_possible_cpus(void) · 2515 unmodified lines | ||
| 5903 | 5902 | static const char *fcpu = "/sys/devices/system/cpu/possible"; |
| 5904 | 5903 | int len = 0, n = 0, il = 0, ir = 0; |
| 5905 | 5904 | unsigned int start = 0, end = 0; |
| 5905 | + int tmp_cpus = 0; | |
| 5906 | 5906 | static int cpus; |
| 5907 | 5907 | char buf[128]; |
| 5908 | 5908 | int error = 0; |
| 5909 | 5909 | int fd = -1; |
| 5910 | 5910 | |
| 5911 | − if (cpus > 0) | |
| 5912 | − return cpus; | |
| 5911 | + tmp_cpus = READ_ONCE(cpus); | |
| 5912 | + if (tmp_cpus > 0) | |
| 5913 | + return tmp_cpus; | |
| 5913 | 5914 | |
| 5914 | 5915 | fd = open(fcpu, O_RDONLY); |
| 5915 | 5916 | if (fd < 0) { |
| @@ -5932,7 +5933,7 @@ int libbpf_num_possible_cpus(void) · 16 unmodified lines | ||
| 5932 | 5933 | } |
| 5933 | 5934 | buf[len] = '\0'; |
| 5934 | 5935 | |
| 5935 | − for (ir = 0, cpus = 0; ir <= len; ir++) { | |
| 5936 | + for (ir = 0, tmp_cpus = 0; ir <= len; ir++) { | |
| 5936 | 5937 | /* Each sub string separated by ',' has format \d+-\d+ or \d+ */ |
| 5937 | 5938 | if (buf[ir] == ',' || buf[ir] == '\0') { |
| 5938 | 5939 | buf[ir] = '\0'; |
| @@ -5944,13 +5945,15 @@ int libbpf_num_possible_cpus(void) · 5 unmodified lines | ||
| 5944 | 5945 | } else if (n == 1) { |
| 5945 | 5946 | end = start; |
| 5946 | 5947 | } |
| 5947 | − cpus += end - start + 1; | |
| 5948 | + tmp_cpus += end - start + 1; | |
| 5948 | 5949 | il = ir + 1; |
| 5949 | 5950 | } |
| 5950 | 5951 | } |
| 5951 | − if (cpus <= 0) { | |
| 5952 | − pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu); | |
| 5952 | + if (tmp_cpus <= 0) { | |
| 5953 | + pr_warning("Invalid #CPUs %d from %s\n", tmp_cpus, fcpu); | |
| 5953 | 5954 | return -EINVAL; |
| 5954 | 5955 | } |
| 5955 | − return cpus; | |
| 5956 | + | |
| 5957 | + WRITE_ONCE(cpus, tmp_cpus); | |
| 5958 | + return tmp_cpus; | |
| 5956 | 5959 | } |
| @@ -242,7 +242,7 @@ $(OUTPUT)doc.dep : $(wildcard *.txt) build-docdep.perl · 241 unmodified lines | ||
| 242 | 242 | $(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \ |
| 243 | 243 | mv $@+ $@ |
| 244 | 244 | |
| 245 | −-include $(OUPTUT)doc.dep | |
| 245 | +-include $(OUTPUT)doc.dep | |
| 246 | 246 | |
| 247 | 247 | _cmds_txt = cmds-ancillaryinterrogators.txt \ |
| 248 | 248 | cmds-ancillarymanipulators.txt \ |
| @@ -6,8 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "machine.h" |
| 7 | 7 | #include "api/fs/fs.h" |
| 8 | 8 | #include "debug.h" |
| 9 | +#include "symbol.h" | |
| 9 | 10 | |
| 10 | −int arch__fix_module_text_start(u64 *start, const char *name) | |
| 11 | +int arch__fix_module_text_start(u64 *start, u64 *size, const char *name) | |
| 11 | 12 | { |
| 12 | 13 | u64 m_start = *start; |
| 13 | 14 | char path[PATH_MAX]; |
| @@ -17,7 +18,35 @@ int arch__fix_module_text_start(u64 *start, const char *name) · 3 unmodified lines | ||
| 17 | 18 | if (sysfs__read_ull(path, (unsigned long long *)start) < 0) { |
| 18 | 19 | pr_debug2("Using module %s start:%#lx\n", path, m_start); |
| 19 | 20 | *start = m_start; |
| 21 | + } else { | |
| 22 | + /* Successful read of the modules segment text start address. | |
| 23 | + * Calculate difference between module start address | |
| 24 | + * in memory and module text segment start address. | |
| 25 | + * For example module load address is 0x3ff8011b000 | |
| 26 | + * (from /proc/modules) and module text segment start | |
| 27 | + * address is 0x3ff8011b870 (from file above). | |
| 28 | + * | |
| 29 | + * Adjust the module size and subtract the GOT table | |
| 30 | + * size located at the beginning of the module. | |
| 31 | + */ | |
| 32 | + *size -= (*start - m_start); | |
| 20 | 33 | } |
| 21 | 34 | |
| 22 | 35 | return 0; |
| 23 | 36 | } |
| 37 | + | |
| 38 | +/* On s390 kernel text segment start is located at very low memory addresses, | |
| 39 | + * for example 0x10000. Modules are located at very high memory addresses, | |
| 40 | + * for example 0x3ff xxxx xxxx. The gap between end of kernel text segment | |
| 41 | + * and beginning of first module's text segment is very big. | |
| 42 | + * Therefore do not fill this gap and do not assign it to the kernel dso map. | |
| 43 | + */ | |
| 44 | +void arch__symbols__fixup_end(struct symbol *p, struct symbol *c) | |
| 45 | +{ | |
| 46 | + if (strchr(p->name, '[') == NULL && strchr(c->name, '[')) | |
| 47 | + /* Last kernel symbol mapped to end of page */ | |
| 48 | + p->end = roundup(p->end, page_size); | |
| 49 | + else | |
| 50 | + p->end = c->start; | |
| 51 | + pr_debug4("%s sym:%s end:%#lx\n", __func__, p->name, p->end); | |
| 52 | +} | |
| @@ -379,8 +379,10 @@ static u8 *alloc_data(ssize_t bytes0, int map_flags, · 378 unmodified lines | ||
| 379 | 379 | |
| 380 | 380 | /* Allocate and initialize all memory on CPU#0: */ |
| 381 | 381 | if (init_cpu0) { |
| 382 | − orig_mask = bind_to_node(0); | |
| 383 | − bind_to_memnode(0); | |
| 382 | + int node = numa_node_of_cpu(0); | |
| 383 | + | |
| 384 | + orig_mask = bind_to_node(node); | |
| 385 | + bind_to_memnode(node); | |
| 384 | 386 | } |
| 385 | 387 | |
| 386 | 388 | bytes = bytes0 + HPSIZE; |
| @@ -173,7 +173,7 @@ static int set_tracing_cpumask(struct cpu_map *cpumap) · 172 unmodified lines | ||
| 173 | 173 | int last_cpu; |
| 174 | 174 | |
| 175 | 175 | last_cpu = cpu_map__cpu(cpumap, cpumap->nr - 1); |
| 176 | − mask_size = (last_cpu + 3) / 4 + 1; | |
| 176 | + mask_size = last_cpu / 4 + 2; /* one more byte for EOS */ | |
| 177 | 177 | mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */ |
| 178 | 178 | |
| 179 | 179 | cpumask = malloc(mask_size); |
| @@ -453,6 +453,7 @@ static struct fixed { · 452 unmodified lines | ||
| 453 | 453 | { "inst_retired.any_p", "event=0xc0" }, |
| 454 | 454 | { "cpu_clk_unhalted.ref", "event=0x0,umask=0x03" }, |
| 455 | 455 | { "cpu_clk_unhalted.thread", "event=0x3c" }, |
| 456 | + { "cpu_clk_unhalted.core", "event=0x3c" }, | |
| 456 | 457 | { "cpu_clk_unhalted.thread_any", "event=0x3c,any=1" }, |
| 457 | 458 | { NULL, NULL}, |
| 458 | 459 | }; |
| @@ -1,7 +1,8 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | −#include "../string2.h" | |
| 3 | −#include "../config.h" | |
| 4 | −#include "../../perf.h" | |
| 2 | +#include "../util/util.h" | |
| 3 | +#include "../util/string2.h" | |
| 4 | +#include "../util/config.h" | |
| 5 | +#include "../perf.h" | |
| 5 | 6 | #include "libslang.h" |
| 6 | 7 | #include "ui.h" |
| 7 | 8 | #include "util.h" |
| @@ -14,7 +15,7 @@ · 6 unmodified lines | ||
| 14 | 15 | #include "browser.h" |
| 15 | 16 | #include "helpline.h" |
| 16 | 17 | #include "keysyms.h" |
| 17 | −#include "../color.h" | |
| 18 | +#include "../util/color.h" | |
| 18 | 19 | #include <linux/ctype.h> |
| 19 | 20 | #include <linux/zalloc.h> |
| 20 | 21 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <linux/kernel.h> |
| 3 | −#include "../cache.h" | |
| 3 | +#include "../../util/cache.h" | |
| 4 | 4 | #include "../progress.h" |
| 5 | 5 | #include "../libslang.h" |
| 6 | 6 | #include "../ui.h" |
| @@ -1122,7 +1122,7 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) · 1121 unmodified lines | ||
| 1122 | 1122 | goto out; |
| 1123 | 1123 | |
| 1124 | 1124 | (*rawp)[0] = tmp; |
| 1125 | − *rawp = skip_spaces(*rawp); | |
| 1125 | + *rawp = strim(*rawp); | |
| 1126 | 1126 | |
| 1127 | 1127 | return 0; |
| 1128 | 1128 | |
| @@ -751,7 +751,10 @@ size_t cpu_map__snprint_mask(struct cpu_map *map, char *buf, size_t size) · 750 unmodified lines | ||
| 751 | 751 | unsigned char *bitmap; |
| 752 | 752 | int last_cpu = cpu_map__cpu(map, map->nr - 1); |
| 753 | 753 | |
| 754 | − bitmap = zalloc((last_cpu + 7) / 8); | |
| 754 | + if (buf == NULL) | |
| 755 | + return 0; | |
| 756 | + | |
| 757 | + bitmap = zalloc(last_cpu / 8 + 1); | |
| 755 | 758 | if (bitmap == NULL) { |
| 756 | 759 | buf[0] = '\0'; |
| 757 | 760 | return 0; |
| @@ -1378,6 +1378,7 @@ static int machine__set_modules_path(struct machine *machine) · 1377 unmodified lines | ||
| 1378 | 1378 | return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); |
| 1379 | 1379 | } |
| 1380 | 1380 | int __weak arch__fix_module_text_start(u64 *start __maybe_unused, |
| 1381 | + u64 *size __maybe_unused, | |
| 1381 | 1382 | const char *name __maybe_unused) |
| 1382 | 1383 | { |
| 1383 | 1384 | return 0; |
| @@ -1389,7 +1390,7 @@ static int machine__create_module(void *arg, const char *name, u64 start, · 5 unmodified lines | ||
| 1389 | 1390 | struct machine *machine = arg; |
| 1390 | 1391 | struct map *map; |
| 1391 | 1392 | |
| 1392 | − if (arch__fix_module_text_start(&start, name) < 0) | |
| 1393 | + if (arch__fix_module_text_start(&start, &size, name) < 0) | |
| 1393 | 1394 | return -1; |
| 1394 | 1395 | |
| 1395 | 1396 | map = machine__findnew_module_map(machine, start, name); |
| @@ -222,7 +222,7 @@ struct symbol *machine__find_kernel_symbol_by_name(struct machine *machine, · 221 unmodified lines | ||
| 222 | 222 | |
| 223 | 223 | struct map *machine__findnew_module_map(struct machine *machine, u64 start, |
| 224 | 224 | const char *filename); |
| 225 | −int arch__fix_module_text_start(u64 *start, const char *name); | |
| 225 | +int arch__fix_module_text_start(u64 *start, u64 *size, const char *name); | |
| 226 | 226 | |
| 227 | 227 | int machine__load_kallsyms(struct machine *machine, const char *filename); |
| 228 | 228 | |
| @@ -92,6 +92,11 @@ static int prefix_underscores_count(const char *str) · 91 unmodified lines | ||
| 92 | 92 | return tail - str; |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | +void __weak arch__symbols__fixup_end(struct symbol *p, struct symbol *c) | |
| 96 | +{ | |
| 97 | + p->end = c->start; | |
| 98 | +} | |
| 99 | + | |
| 95 | 100 | const char * __weak arch__normalize_symbol_name(const char *name) |
| 96 | 101 | { |
| 97 | 102 | return name; |
| @@ -218,7 +223,7 @@ void symbols__fixup_end(struct rb_root_cached *symbols) · 120 unmodified lines | ||
| 218 | 223 | curr = rb_entry(nd, struct symbol, rb_node); |
| 219 | 224 | |
| 220 | 225 | if (prev->end == prev->start && prev->end != curr->start) |
| 221 | − prev->end = curr->start; | |
| 226 | + arch__symbols__fixup_end(prev, curr); | |
| 222 | 227 | } |
| 223 | 228 | |
| 224 | 229 | /* Last entry */ |
| @@ -288,6 +288,7 @@ const char *arch__normalize_symbol_name(const char *name); · 287 unmodified lines | ||
| 288 | 288 | #define SYMBOL_A 0 |
| 289 | 289 | #define SYMBOL_B 1 |
| 290 | 290 | |
| 291 | +void arch__symbols__fixup_end(struct symbol *p, struct symbol *c); | |
| 291 | 292 | int arch__compare_symbol_names(const char *namea, const char *nameb); |
| 292 | 293 | int arch__compare_symbol_names_n(const char *namea, const char *nameb, |
| 293 | 294 | unsigned int n); |
| @@ -214,14 +214,24 @@ struct comm *thread__comm(const struct thread *thread) · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | struct comm *thread__exec_comm(const struct thread *thread) |
| 216 | 216 | { |
| 217 | − struct comm *comm, *last = NULL; | |
| 217 | + struct comm *comm, *last = NULL, *second_last = NULL; | |
| 218 | 218 | |
| 219 | 219 | list_for_each_entry(comm, &thread->comm_list, list) { |
| 220 | 220 | if (comm->exec) |
| 221 | 221 | return comm; |
| 222 | + second_last = last; | |
| 222 | 223 | last = comm; |
| 223 | 224 | } |
| 224 | 225 | |
| 226 | + /* | |
| 227 | + * 'last' with no start time might be the parent's comm of a synthesized | |
| 228 | + * thread (created by processing a synthesized fork event). For a main | |
| 229 | + * thread, that is very probably wrong. Prefer a later comm to avoid | |
| 230 | + * that case. | |
| 231 | + */ | |
| 232 | + if (second_last && !last->start && thread->pid_ == thread->tid) | |
| 233 | + return second_last; | |
| 234 | + | |
| 225 | 235 | return last; |
| 226 | 236 | } |
| 227 | 237 | |
| @@ -159,3 +159,31 @@ · 158 unmodified lines | ||
| 159 | 159 | .errstr = "loop detected", |
| 160 | 160 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, |
| 161 | 161 | }, |
| 162 | +{ | |
| 163 | + "not-taken loop with back jump to 1st insn", | |
| 164 | + .insns = { | |
| 165 | + BPF_MOV64_IMM(BPF_REG_0, 123), | |
| 166 | + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 4, -2), | |
| 167 | + BPF_EXIT_INSN(), | |
| 168 | + }, | |
| 169 | + .result = ACCEPT, | |
| 170 | + .prog_type = BPF_PROG_TYPE_XDP, | |
| 171 | + .retval = 123, | |
| 172 | +}, | |
| 173 | +{ | |
| 174 | + "taken loop with back jump to 1st insn", | |
| 175 | + .insns = { | |
| 176 | + BPF_MOV64_IMM(BPF_REG_1, 10), | |
| 177 | + BPF_MOV64_IMM(BPF_REG_2, 0), | |
| 178 | + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), | |
| 179 | + BPF_EXIT_INSN(), | |
| 180 | + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1), | |
| 181 | + BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1), | |
| 182 | + BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, -3), | |
| 183 | + BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), | |
| 184 | + BPF_EXIT_INSN(), | |
| 185 | + }, | |
| 186 | + .result = ACCEPT, | |
| 187 | + .prog_type = BPF_PROG_TYPE_XDP, | |
| 188 | + .retval = 55, | |
| 189 | +}, | |
| @@ -1,7 +1,7 @@ | ||
| 1 | +/s390x/sync_regs_test | |
| 1 | 2 | /x86_64/cr4_cpuid_sync_test |
| 2 | 3 | /x86_64/evmcs_test |
| 3 | 4 | /x86_64/hyperv_cpuid |
| 4 | −/x86_64/kvm_create_max_vcpus | |
| 5 | 5 | /x86_64/mmio_warning_test |
| 6 | 6 | /x86_64/platform_info_test |
| 7 | 7 | /x86_64/set_sregs_test |
| @@ -13,3 +13,4 @@ · 5 unmodified lines | ||
| 13 | 13 | /x86_64/vmx_tsc_adjust_test |
| 14 | 14 | /clear_dirty_log_test |
| 15 | 15 | /dirty_log_test |
| 16 | +/kvm_create_max_vcpus | |
| @@ -0,0 +1,3 @@ | ||
| 1 | +CONFIG_KVM=y | |
| 2 | +CONFIG_KVM_INTEL=y | |
| 3 | +CONFIG_KVM_AMD=y | |
| @@ -30,7 +30,7 @@ do_test() { · 29 unmodified lines | ||
| 30 | 30 | ip netns exec "${NETNS}" ./tcp_fastopen_backup_key "$1" |
| 31 | 31 | val=$(ip netns exec "${NETNS}" nstat -az | \ |
| 32 | 32 | grep TcpExtTCPFastOpenPassiveFail | awk '{print $2}') |
| 33 | − if [ $val -ne 0 ]; then | |
| 33 | + if [ "$val" != 0 ]; then | |
| 34 | 34 | echo "FAIL: TcpExtTCPFastOpenPassiveFail non-zero" |
| 35 | 35 | return 1 |
| 36 | 36 | fi |
| @@ -321,4 +321,52 @@ else · 320 unmodified lines | ||
| 321 | 321 | ip netns exec nsr1 nft list ruleset |
| 322 | 322 | fi |
| 323 | 323 | |
| 324 | +KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1) | |
| 325 | +KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1) | |
| 326 | +SPI1=$RANDOM | |
| 327 | +SPI2=$RANDOM | |
| 328 | + | |
| 329 | +if [ $SPI1 -eq $SPI2 ]; then | |
| 330 | + SPI2=$((SPI2+1)) | |
| 331 | +fi | |
| 332 | + | |
| 333 | +do_esp() { | |
| 334 | + local ns=$1 | |
| 335 | + local me=$2 | |
| 336 | + local remote=$3 | |
| 337 | + local lnet=$4 | |
| 338 | + local rnet=$5 | |
| 339 | + local spi_out=$6 | |
| 340 | + local spi_in=$7 | |
| 341 | + | |
| 342 | + ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $rnet dst $lnet | |
| 343 | + ip -net $ns xfrm state add src $me dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet | |
| 344 | + | |
| 345 | + # to encrypt packets as they go out (includes forwarded packets that need encapsulation) | |
| 346 | + ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow | |
| 347 | + # to fwd decrypted packets after esp processing: | |
| 348 | + ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 1 action allow | |
| 349 | + | |
| 350 | +} | |
| 351 | + | |
| 352 | +do_esp nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2 | |
| 353 | + | |
| 354 | +do_esp nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1 | |
| 355 | + | |
| 356 | +ip netns exec nsr1 nft delete table ip nat | |
| 357 | + | |
| 358 | +# restore default routes | |
| 359 | +ip -net ns2 route del 192.168.10.1 via 10.0.2.1 | |
| 360 | +ip -net ns2 route add default via 10.0.2.1 | |
| 361 | +ip -net ns2 route add default via dead:2::1 | |
| 362 | + | |
| 363 | +test_tcp_forwarding ns1 ns2 | |
| 364 | +if [ $? -eq 0 ] ;then | |
| 365 | + echo "PASS: ipsec tunnel mode for ns1/ns2" | |
| 366 | +else | |
| 367 | + echo "FAIL: ipsec tunnel mode for ns1/ns2" | |
| 368 | + ip netns exec nsr1 nft list ruleset 1>&2 | |
| 369 | + ip netns exec nsr1 cat /proc/net/xfrm_stat 1>&2 | |
| 370 | +fi | |
| 371 | + | |
| 324 | 372 | exit $ret |
| @@ -670,5 +670,52 @@ · 669 unmodified lines | ||
| 670 | 670 | "teardown": [ |
| 671 | 671 | "$TC actions flush action skbedit" |
| 672 | 672 | ] |
| 673 | + }, | |
| 674 | + { | |
| 675 | + "id": "630c", | |
| 676 | + "name": "Add batch of 32 skbedit actions with all parameters and cookie", | |
| 677 | + "category": [ | |
| 678 | + "actions", | |
| 679 | + "skbedit" | |
| 680 | + ], | |
| 681 | + "setup": [ | |
| 682 | + [ | |
| 683 | + "$TC actions flush action skbedit", | |
| 684 | + 0, | |
| 685 | + 1, | |
| 686 | + 255 | |
| 687 | + ] | |
| 688 | + ], | |
| 689 | + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit queue_mapping 2 priority 10 mark 7/0xaabbccdd ptype host inheritdsfield index \\$i cookie aabbccddeeff112233445566778800a1 \\\"; args=\"\\$args\\$cmd\"; done && $TC actions add \\$args\"", | |
| 690 | + "expExitCode": "0", | |
| 691 | + "verifyCmd": "$TC actions list action skbedit", | |
| 692 | + "matchPattern": "^[ \t]+index [0-9]+ ref", | |
| 693 | + "matchCount": "32", | |
| 694 | + "teardown": [ | |
| 695 | + "$TC actions flush action skbedit" | |
| 696 | + ] | |
| 697 | + }, | |
| 698 | + { | |
| 699 | + "id": "706d", | |
| 700 | + "name": "Delete batch of 32 skbedit actions with all parameters", | |
| 701 | + "category": [ | |
| 702 | + "actions", | |
| 703 | + "skbedit" | |
| 704 | + ], | |
| 705 | + "setup": [ | |
| 706 | + [ | |
| 707 | + "$TC actions flush action skbedit", | |
| 708 | + 0, | |
| 709 | + 1, | |
| 710 | + 255 | |
| 711 | + ], | |
| 712 | + "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit queue_mapping 2 priority 10 mark 7/0xaabbccdd ptype host inheritdsfield index \\$i \\\"; args=\\\"\\$args\\$cmd\\\"; done && $TC actions add \\$args\"" | |
| 713 | + ], | |
| 714 | + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action skbedit index \\$i \\\"; args=\"\\$args\\$cmd\"; done && $TC actions del \\$args\"", | |
| 715 | + "expExitCode": "0", | |
| 716 | + "verifyCmd": "$TC actions list action skbedit", | |
| 717 | + "matchPattern": "^[ \t]+index [0-9]+ ref", | |
| 718 | + "matchCount": "0", | |
| 719 | + "teardown": [] | |
| 673 | 720 | } |
| 674 | 721 | ] |
| @@ -144,11 +144,6 @@ out_fail_alloc: · 143 unmodified lines | ||
| 144 | 144 | return ret; |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | −bool kvm_arch_has_vcpu_debugfs(void) | |
| 148 | −{ | |
| 149 | − return false; | |
| 150 | −} | |
| 151 | − | |
| 152 | 147 | int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu) |
| 153 | 148 | { |
| 154 | 149 | return 0; |
| @@ -323,6 +318,17 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) · 168 unmodified lines | ||
| 323 | 318 | |
| 324 | 319 | void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) |
| 325 | 320 | { |
| 321 | + /* | |
| 322 | + * If we're about to block (most likely because we've just hit a | |
| 323 | + * WFI), we need to sync back the state of the GIC CPU interface | |
| 324 | + * so that we have the lastest PMR and group enables. This ensures | |
| 325 | + * that kvm_arch_vcpu_runnable has up-to-date data to decide | |
| 326 | + * whether we have pending interrupts. | |
| 327 | + */ | |
| 328 | + preempt_disable(); | |
| 329 | + kvm_vgic_vmcr_sync(vcpu); | |
| 330 | + preempt_enable(); | |
| 331 | + | |
| 326 | 332 | kvm_vgic_v4_enable_doorbell(vcpu); |
| 327 | 333 | } |
| 328 | 334 | |
| @@ -340,6 +346,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 340 | 346 | /* Set up the timer */ |
| 341 | 347 | kvm_timer_vcpu_init(vcpu); |
| 342 | 348 | |
| 349 | + kvm_pmu_vcpu_init(vcpu); | |
| 350 | + | |
| 343 | 351 | kvm_arm_reset_debug_ptr(vcpu); |
| 344 | 352 | |
| 345 | 353 | return kvm_vgic_vcpu_init(vcpu); |
| @@ -349,8 +349,10 @@ void __hyp_text __vgic_v3_save_aprs(struct kvm_vcpu *vcpu) · 348 unmodified lines | ||
| 349 | 349 | case 7: |
| 350 | 350 | cpu_if->vgic_ap0r[3] = __vgic_v3_read_ap0rn(3); |
| 351 | 351 | cpu_if->vgic_ap0r[2] = __vgic_v3_read_ap0rn(2); |
| 352 | + /* Fall through */ | |
| 352 | 353 | case 6: |
| 353 | 354 | cpu_if->vgic_ap0r[1] = __vgic_v3_read_ap0rn(1); |
| 355 | + /* Fall through */ | |
| 354 | 356 | default: |
| 355 | 357 | cpu_if->vgic_ap0r[0] = __vgic_v3_read_ap0rn(0); |
| 356 | 358 | } |
| @@ -359,8 +361,10 @@ void __hyp_text __vgic_v3_save_aprs(struct kvm_vcpu *vcpu) · 2 unmodified lines | ||
| 359 | 361 | case 7: |
| 360 | 362 | cpu_if->vgic_ap1r[3] = __vgic_v3_read_ap1rn(3); |
| 361 | 363 | cpu_if->vgic_ap1r[2] = __vgic_v3_read_ap1rn(2); |
| 364 | + /* Fall through */ | |
| 362 | 365 | case 6: |
| 363 | 366 | cpu_if->vgic_ap1r[1] = __vgic_v3_read_ap1rn(1); |
| 367 | + /* Fall through */ | |
| 364 | 368 | default: |
| 365 | 369 | cpu_if->vgic_ap1r[0] = __vgic_v3_read_ap1rn(0); |
| 366 | 370 | } |
| @@ -382,8 +386,10 @@ void __hyp_text __vgic_v3_restore_aprs(struct kvm_vcpu *vcpu) · 15 unmodified lines | ||
| 382 | 386 | case 7: |
| 383 | 387 | __vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[3], 3); |
| 384 | 388 | __vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[2], 2); |
| 389 | + /* Fall through */ | |
| 385 | 390 | case 6: |
| 386 | 391 | __vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[1], 1); |
| 392 | + /* Fall through */ | |
| 387 | 393 | default: |
| 388 | 394 | __vgic_v3_write_ap0rn(cpu_if->vgic_ap0r[0], 0); |
| 389 | 395 | } |
| @@ -392,8 +398,10 @@ void __hyp_text __vgic_v3_restore_aprs(struct kvm_vcpu *vcpu) · 2 unmodified lines | ||
| 392 | 398 | case 7: |
| 393 | 399 | __vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[3], 3); |
| 394 | 400 | __vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[2], 2); |
| 401 | + /* Fall through */ | |
| 395 | 402 | case 6: |
| 396 | 403 | __vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[1], 1); |
| 404 | + /* Fall through */ | |
| 397 | 405 | default: |
| 398 | 406 | __vgic_v3_write_ap1rn(cpu_if->vgic_ap1r[0], 0); |
| 399 | 407 | } |
| @@ -214,6 +214,20 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc) · 213 unmodified lines | ||
| 214 | 214 | kvm_pmu_release_perf_event(pmc); |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | +/** | |
| 218 | + * kvm_pmu_vcpu_init - assign pmu counter idx for cpu | |
| 219 | + * @vcpu: The vcpu pointer | |
| 220 | + * | |
| 221 | + */ | |
| 222 | +void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu) | |
| 223 | +{ | |
| 224 | + int i; | |
| 225 | + struct kvm_pmu *pmu = &vcpu->arch.pmu; | |
| 226 | + | |
| 227 | + for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) | |
| 228 | + pmu->pmc[i].idx = i; | |
| 229 | +} | |
| 230 | + | |
| 217 | 231 | /** |
| 218 | 232 | * kvm_pmu_vcpu_reset - reset pmu state for cpu |
| 219 | 233 | * @vcpu: The vcpu pointer |
| @@ -224,10 +238,8 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) · 4 unmodified lines | ||
| 224 | 238 | int i; |
| 225 | 239 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
| 226 | 240 | |
| 227 | − for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { | |
| 241 | + for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) | |
| 228 | 242 | kvm_pmu_stop_counter(vcpu, &pmu->pmc[i]); |
| 229 | − pmu->pmc[i].idx = i; | |
| 230 | − } | |
| 231 | 243 | |
| 232 | 244 | bitmap_zero(vcpu->arch.pmu.chained, ARMV8_PMU_MAX_COUNTER_PAIRS); |
| 233 | 245 | } |
| @@ -113,6 +113,22 @@ void vgic_mmio_write_senable(struct kvm_vcpu *vcpu, · 112 unmodified lines | ||
| 113 | 113 | struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); |
| 114 | 114 | |
| 115 | 115 | raw_spin_lock_irqsave(&irq->irq_lock, flags); |
| 116 | + if (vgic_irq_is_mapped_level(irq)) { | |
| 117 | + bool was_high = irq->line_level; | |
| 118 | + | |
| 119 | + /* | |
| 120 | + * We need to update the state of the interrupt because | |
| 121 | + * the guest might have changed the state of the device | |
| 122 | + * while the interrupt was disabled at the VGIC level. | |
| 123 | + */ | |
| 124 | + irq->line_level = vgic_get_phys_line_level(irq); | |
| 125 | + /* | |
| 126 | + * Deactivate the physical interrupt so the GIC will let | |
| 127 | + * us know when it is asserted again. | |
| 128 | + */ | |
| 129 | + if (!irq->active && was_high && !irq->line_level) | |
| 130 | + vgic_irq_set_phys_active(irq, false); | |
| 131 | + } | |
| 116 | 132 | irq->enabled = true; |
| 117 | 133 | vgic_queue_irq_unlock(vcpu->kvm, irq, flags); |
| 118 | 134 | |
| @@ -484,10 +484,17 @@ void vgic_v2_load(struct kvm_vcpu *vcpu) · 483 unmodified lines | ||
| 484 | 484 | kvm_vgic_global_state.vctrl_base + GICH_APR); |
| 485 | 485 | } |
| 486 | 486 | |
| 487 | −void vgic_v2_put(struct kvm_vcpu *vcpu) | |
| 487 | +void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu) | |
| 488 | 488 | { |
| 489 | 489 | struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; |
| 490 | 490 | |
| 491 | 491 | cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR); |
| 492 | +} | |
| 493 | + | |
| 494 | +void vgic_v2_put(struct kvm_vcpu *vcpu) | |
| 495 | +{ | |
| 496 | + struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2; | |
| 497 | + | |
| 498 | + vgic_v2_vmcr_sync(vcpu); | |
| 492 | 499 | cpu_if->vgic_apr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_APR); |
| 493 | 500 | } |
| @@ -662,12 +662,17 @@ void vgic_v3_load(struct kvm_vcpu *vcpu) · 661 unmodified lines | ||
| 662 | 662 | __vgic_v3_activate_traps(vcpu); |
| 663 | 663 | } |
| 664 | 664 | |
| 665 | −void vgic_v3_put(struct kvm_vcpu *vcpu) | |
| 665 | +void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu) | |
| 666 | 666 | { |
| 667 | 667 | struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3; |
| 668 | 668 | |
| 669 | 669 | if (likely(cpu_if->vgic_sre)) |
| 670 | 670 | cpu_if->vgic_vmcr = kvm_call_hyp_ret(__vgic_v3_read_vmcr); |
| 671 | +} | |
| 672 | + | |
| 673 | +void vgic_v3_put(struct kvm_vcpu *vcpu) | |
| 674 | +{ | |
| 675 | + vgic_v3_vmcr_sync(vcpu); | |
| 671 | 676 | |
| 672 | 677 | kvm_call_hyp(__vgic_v3_save_aprs, vcpu); |
| 673 | 678 | |
| @@ -919,6 +919,17 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu) · 918 unmodified lines | ||
| 919 | 919 | vgic_v3_put(vcpu); |
| 920 | 920 | } |
| 921 | 921 | |
| 922 | +void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu) | |
| 923 | +{ | |
| 924 | + if (unlikely(!irqchip_in_kernel(vcpu->kvm))) | |
| 925 | + return; | |
| 926 | + | |
| 927 | + if (kvm_vgic_global_state.type == VGIC_V2) | |
| 928 | + vgic_v2_vmcr_sync(vcpu); | |
| 929 | + else | |
| 930 | + vgic_v3_vmcr_sync(vcpu); | |
| 931 | +} | |
| 932 | + | |
| 922 | 933 | int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) |
| 923 | 934 | { |
| 924 | 935 | struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; |
| @@ -193,6 +193,7 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address, · 192 unmodified lines | ||
| 193 | 193 | void vgic_v2_init_lrs(void); |
| 194 | 194 | void vgic_v2_load(struct kvm_vcpu *vcpu); |
| 195 | 195 | void vgic_v2_put(struct kvm_vcpu *vcpu); |
| 196 | +void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu); | |
| 196 | 197 | |
| 197 | 198 | void vgic_v2_save_state(struct kvm_vcpu *vcpu); |
| 198 | 199 | void vgic_v2_restore_state(struct kvm_vcpu *vcpu); |
| @@ -223,6 +224,7 @@ bool vgic_v3_check_base(struct kvm *kvm); · 24 unmodified lines | ||
| 223 | 224 | |
| 224 | 225 | void vgic_v3_load(struct kvm_vcpu *vcpu); |
| 225 | 226 | void vgic_v3_put(struct kvm_vcpu *vcpu); |
| 227 | +void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu); | |
| 226 | 228 | |
| 227 | 229 | bool vgic_has_its(struct kvm *kvm); |
| 228 | 230 | int kvm_vgic_register_its_device(void); |
| @@ -1855,8 +1855,7 @@ void kvm_set_pfn_dirty(kvm_pfn_t pfn) · 1854 unmodified lines | ||
| 1855 | 1855 | if (!kvm_is_reserved_pfn(pfn)) { |
| 1856 | 1856 | struct page *page = pfn_to_page(pfn); |
| 1857 | 1857 | |
| 1858 | − if (!PageReserved(page)) | |
| 1859 | − SetPageDirty(page); | |
| 1858 | + SetPageDirty(page); | |
| 1860 | 1859 | } |
| 1861 | 1860 | } |
| 1862 | 1861 | EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty); |
| @@ -2477,6 +2476,29 @@ static bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu) · 614 unmodified lines | ||
| 2477 | 2476 | #endif |
| 2478 | 2477 | } |
| 2479 | 2478 | |
| 2479 | +/* | |
| 2480 | + * Unlike kvm_arch_vcpu_runnable, this function is called outside | |
| 2481 | + * a vcpu_load/vcpu_put pair. However, for most architectures | |
| 2482 | + * kvm_arch_vcpu_runnable does not require vcpu_load. | |
| 2483 | + */ | |
| 2484 | +bool __weak kvm_arch_dy_runnable(struct kvm_vcpu *vcpu) | |
| 2485 | +{ | |
| 2486 | + return kvm_arch_vcpu_runnable(vcpu); | |
| 2487 | +} | |
| 2488 | + | |
| 2489 | +static bool vcpu_dy_runnable(struct kvm_vcpu *vcpu) | |
| 2490 | +{ | |
| 2491 | + if (kvm_arch_dy_runnable(vcpu)) | |
| 2492 | + return true; | |
| 2493 | + | |
| 2494 | +#ifdef CONFIG_KVM_ASYNC_PF | |
| 2495 | + if (!list_empty_careful(&vcpu->async_pf.done)) | |
| 2496 | + return true; | |
| 2497 | +#endif | |
| 2498 | + | |
| 2499 | + return false; | |
| 2500 | +} | |
| 2501 | + | |
| 2480 | 2502 | void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) |
| 2481 | 2503 | { |
| 2482 | 2504 | struct kvm *kvm = me->kvm; |
| @@ -2506,9 +2528,10 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode) · 23 unmodified lines | ||
| 2506 | 2528 | continue; |
| 2507 | 2529 | if (vcpu == me) |
| 2508 | 2530 | continue; |
| 2509 | − if (swait_active(&vcpu->wq) && !kvm_arch_vcpu_runnable(vcpu)) | |
| 2531 | + if (swait_active(&vcpu->wq) && !vcpu_dy_runnable(vcpu)) | |
| 2510 | 2532 | continue; |
| 2511 | − if (yield_to_kernel_mode && !kvm_arch_vcpu_in_kernel(vcpu)) | |
| 2533 | + if (READ_ONCE(vcpu->preempted) && yield_to_kernel_mode && | |
| 2534 | + !kvm_arch_vcpu_in_kernel(vcpu)) | |
| 2512 | 2535 | continue; |
| 2513 | 2536 | if (!kvm_vcpu_eligible_for_directed_yield(vcpu)) |
| 2514 | 2537 | continue; |
| @@ -2591,30 +2614,20 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu) · 76 unmodified lines | ||
| 2591 | 2614 | return anon_inode_getfd(name, &kvm_vcpu_fops, vcpu, O_RDWR | O_CLOEXEC); |
| 2592 | 2615 | } |
| 2593 | 2616 | |
| 2594 | −static int kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 2617 | +static void kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu) | |
| 2595 | 2618 | { |
| 2619 | +#ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS | |
| 2596 | 2620 | char dir_name[ITOA_MAX_LEN * 2]; |
| 2597 | − int ret; | |
| 2598 | − | |
| 2599 | − if (!kvm_arch_has_vcpu_debugfs()) | |
| 2600 | − return 0; | |
| 2601 | 2621 | |
| 2602 | 2622 | if (!debugfs_initialized()) |
| 2603 | − return 0; | |
| 2623 | + return; | |
| 2604 | 2624 | |
| 2605 | 2625 | snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id); |
| 2606 | 2626 | vcpu->debugfs_dentry = debugfs_create_dir(dir_name, |
| 2607 | − vcpu->kvm->debugfs_dentry); | |
| 2608 | − if (!vcpu->debugfs_dentry) | |
| 2609 | − return -ENOMEM; | |
| 2610 | − | |
| 2611 | − ret = kvm_arch_create_vcpu_debugfs(vcpu); | |
| 2612 | − if (ret < 0) { | |
| 2613 | − debugfs_remove_recursive(vcpu->debugfs_dentry); | |
| 2614 | − return ret; | |
| 2615 | − } | |
| 2627 | + vcpu->kvm->debugfs_dentry); | |
| 2616 | 2628 | |
| 2617 | − return 0; | |
| 2629 | + kvm_arch_create_vcpu_debugfs(vcpu); | |
| 2630 | +#endif | |
| 2618 | 2631 | } |
| 2619 | 2632 | |
| 2620 | 2633 | /* |
| @@ -2649,9 +2662,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) · 28 unmodified lines | ||
| 2649 | 2662 | if (r) |
| 2650 | 2663 | goto vcpu_destroy; |
| 2651 | 2664 | |
| 2652 | − r = kvm_create_vcpu_debugfs(vcpu); | |
| 2653 | − if (r) | |
| 2654 | − goto vcpu_destroy; | |
| 2665 | + kvm_create_vcpu_debugfs(vcpu); | |
| 2655 | 2666 | |
| 2656 | 2667 | mutex_lock(&kvm->lock); |
| 2657 | 2668 | if (kvm_get_vcpu_by_id(kvm, id)) { |
| @@ -4205,7 +4216,7 @@ static void kvm_sched_in(struct preempt_notifier *pn, int cpu) · 1547 unmodified lines | ||
| 4205 | 4216 | { |
| 4206 | 4217 | struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn); |
| 4207 | 4218 | |
| 4208 | − vcpu->preempted = false; | |
| 4219 | + WRITE_ONCE(vcpu->preempted, false); | |
| 4209 | 4220 | WRITE_ONCE(vcpu->ready, false); |
| 4210 | 4221 | |
| 4211 | 4222 | kvm_arch_sched_in(vcpu, cpu); |
| @@ -4219,7 +4230,7 @@ static void kvm_sched_out(struct preempt_notifier *pn, · 7 unmodified lines | ||
| 4219 | 4230 | struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn); |
| 4220 | 4231 | |
| 4221 | 4232 | if (current->state == TASK_RUNNING) { |
| 4222 | − vcpu->preempted = true; | |
| 4233 | + WRITE_ONCE(vcpu->preempted, true); | |
| 4223 | 4234 | WRITE_ONCE(vcpu->ready, true); |
| 4224 | 4235 | } |
| 4225 | 4236 | kvm_arch_vcpu_put(vcpu); |