Unified · Split
| @@ -92,6 +92,13 @@ Brief summary of control files. · 91 unmodified lines | |||
| 92 | memory.oom_control set/show oom controls. | 92 | memory.oom_control set/show oom controls. |
| 93 | memory.numa_stat show the number of memory usage per numa | 93 | memory.numa_stat show the number of memory usage per numa |
| 94 | node | 94 | node |
| 95 | memory.kmem.limit_in_bytes Deprecated knob to set and read the kernel | ||
| 96 | memory hard limit. Kernel hard limit is not | ||
| 97 | supported since 5.16. Writing any value to | ||
| 98 | do file will not have any effect same as if | ||
| 99 | nokmem kernel parameter was specified. | ||
| 100 | Kernel memory is still charged and reported | ||
| 101 | by memory.kmem.usage_in_bytes. | ||
| 95 | memory.kmem.usage_in_bytes show current kernel memory allocation | 102 | memory.kmem.usage_in_bytes show current kernel memory allocation |
| 96 | memory.kmem.failcnt show the number of kernel memory usage | 103 | memory.kmem.failcnt show the number of kernel memory usage |
| 97 | hits limits | 104 | hits limits |
| @@ -175,6 +175,8 @@ infrastructure: · 174 unmodified lines | |||
| 175 | +------------------------------+---------+---------+ | 175 | +------------------------------+---------+---------+ |
| 176 | | Name | bits | visible | | 176 | | Name | bits | visible | |
| 177 | +------------------------------+---------+---------+ | 177 | +------------------------------+---------+---------+ |
| 178 | | SME | [27-24] | y | | ||
| 179 | +------------------------------+---------+---------+ | ||
| 178 | | MTE | [11-8] | y | | 180 | | MTE | [11-8] | y | |
| 179 | +------------------------------+---------+---------+ | 181 | +------------------------------+---------+---------+ |
| 180 | | SSBS | [7-4] | y | | 182 | | SSBS | [7-4] | y | |
| @@ -288,8 +290,18 @@ infrastructure: · 107 unmodified lines | |||
| 288 | +------------------------------+---------+---------+ | 290 | +------------------------------+---------+---------+ |
| 289 | | Name | bits | visible | | 291 | | Name | bits | visible | |
| 290 | +------------------------------+---------+---------+ | 292 | +------------------------------+---------+---------+ |
| 293 | | CSSC | [55-52] | y | | ||
| 294 | +------------------------------+---------+---------+ | ||
| 295 | | RPRFM | [51-48] | y | | ||
| 296 | +------------------------------+---------+---------+ | ||
| 297 | | BC | [23-20] | y | | ||
| 298 | +------------------------------+---------+---------+ | ||
| 291 | | MOPS | [19-16] | y | | 299 | | MOPS | [19-16] | y | |
| 292 | +------------------------------+---------+---------+ | 300 | +------------------------------+---------+---------+ |
| 301 | | APA3 | [15-12] | y | | ||
| 302 | +------------------------------+---------+---------+ | ||
| 303 | | GPA3 | [11-8] | y | | ||
| 304 | +------------------------------+---------+---------+ | ||
| 293 | | RPRES | [7-4] | y | | 305 | | RPRES | [7-4] | y | |
| 294 | +------------------------------+---------+---------+ | 306 | +------------------------------+---------+---------+ |
| 295 | | WFXT | [3-0] | y | | 307 | | WFXT | [3-0] | y | |
| @@ -305,6 +305,9 @@ HWCAP2_SMEF16F16 · 304 unmodified lines | |||
| 305 | HWCAP2_MOPS | 305 | HWCAP2_MOPS |
| 306 | Functionality implied by ID_AA64ISAR2_EL1.MOPS == 0b0001. | 306 | Functionality implied by ID_AA64ISAR2_EL1.MOPS == 0b0001. |
| 307 | 307 | ||
| 308 | HWCAP2_HBC | ||
| 309 | Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001. | ||
| 310 | |||
| 308 | 4. Unused AT_HWCAP bits | 311 | 4. Unused AT_HWCAP bits |
| 309 | ----------------------- | 312 | ----------------------- |
| 310 | 313 | ||
| @@ -381,9 +381,9 @@ Documentation of LoongArch ISA: · 380 unmodified lines | |||
| 381 | 381 | ||
| 382 | Documentation of LoongArch ELF psABI: | 382 | Documentation of LoongArch ELF psABI: |
| 383 | 383 | ||
| 384 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (in Chinese) | 384 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (in Chinese) |
| 385 | 385 | ||
| 386 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (in English) | 386 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (in English) |
| 387 | 387 | ||
| 388 | Linux kernel repository of Loongson and LoongArch: | 388 | Linux kernel repository of Loongson and LoongArch: |
| 389 | 389 | ||
| @@ -38,6 +38,7 @@ patternProperties: · 37 unmodified lines | |||
| 38 | ID number 0 and the slave drive will have ID number 1. The PATA port | 38 | ID number 0 and the slave drive will have ID number 1. The PATA port |
| 39 | nodes will be named "ide-port". | 39 | nodes will be named "ide-port". |
| 40 | type: object | 40 | type: object |
| 41 | additionalProperties: false | ||
| 41 | 42 | ||
| 42 | properties: | 43 | properties: |
| 43 | reg: | 44 | reg: |
| @@ -37,6 +37,9 @@ properties: · 36 unmodified lines | |||
| 37 | maxItems: 1 | 37 | maxItems: 1 |
| 38 | 38 | ||
| 39 | '#clock-cells': | 39 | '#clock-cells': |
| 40 | description: | ||
| 41 | The index in the assigned-clocks is mapped to the output clock as below | ||
| 42 | 0 - REF, 1 - SE1, 2 - SE2, 3 - SE3, 4 - DIFF1, 5 - DIFF2. | ||
| 40 | const: 1 | 43 | const: 1 |
| 41 | 44 | ||
| 42 | clocks: | 45 | clocks: |
| @@ -68,7 +71,7 @@ examples: · 25 unmodified lines | |||
| 68 | reg = <0x68>; | 71 | reg = <0x68>; |
| 69 | #clock-cells = <1>; | 72 | #clock-cells = <1>; |
| 70 | 73 | ||
| 71 | clocks = <&x1_x2>; | 74 | clocks = <&x1>; |
| 72 | 75 | ||
| 73 | renesas,settings = [ | 76 | renesas,settings = [ |
| 74 | 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf | 77 | 80 00 11 19 4c 02 23 7f 83 19 08 a9 5f 25 24 bf |
| @@ -79,8 +82,8 @@ examples: · 4 unmodified lines | |||
| 79 | assigned-clocks = <&versa3 0>, <&versa3 1>, | 82 | assigned-clocks = <&versa3 0>, <&versa3 1>, |
| 80 | <&versa3 2>, <&versa3 3>, | 83 | <&versa3 2>, <&versa3 3>, |
| 81 | <&versa3 4>, <&versa3 5>; | 84 | <&versa3 4>, <&versa3 5>; |
| 82 | assigned-clock-rates = <12288000>, <25000000>, | 85 | assigned-clock-rates = <24000000>, <11289600>, |
| 83 | <12000000>, <11289600>, | 86 | <11289600>, <12000000>, |
| 84 | <11289600>, <24000000>; | 87 | <25000000>, <12288000>; |
| 85 | }; | 88 | }; |
| 86 | }; | 89 | }; |
| @@ -9,6 +9,9 @@ title: Freescale MXS Inter IC (I2C) Controller · 8 unmodified lines | |||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Shawn Guo <shawnguo@kernel.org> | 10 | - Shawn Guo <shawnguo@kernel.org> |
| 11 | 11 | ||
| 12 | allOf: | ||
| 13 | - $ref: /schemas/i2c/i2c-controller.yaml# | ||
| 14 | |||
| 12 | properties: | 15 | properties: |
| 13 | compatible: | 16 | compatible: |
| 14 | enum: | 17 | enum: |
| @@ -37,7 +40,7 @@ required: · 22 unmodified lines | |||
| 37 | - dmas | 40 | - dmas |
| 38 | - dma-names | 41 | - dma-names |
| 39 | 42 | ||
| 40 | additionalProperties: false | 43 | unevaluatedProperties: false |
| 41 | 44 | ||
| 42 | examples: | 45 | examples: |
| 43 | - | | 46 | - | |
| @@ -11,11 +11,16 @@ maintainers: · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | properties: | 12 | properties: |
| 13 | compatible: | 13 | compatible: |
| 14 | items: | 14 | oneOf: |
| 15 | - enum: | 15 | - items: |
| 16 | - loongson,ls2k0500-pmc | 16 | - const: loongson,ls2k0500-pmc |
| 17 | - loongson,ls2k1000-pmc | 17 | - const: syscon |
| 18 | - const: syscon | 18 | - items: |
| 19 | - enum: | ||
| 20 | - loongson,ls2k1000-pmc | ||
| 21 | - loongson,ls2k2000-pmc | ||
| 22 | - const: loongson,ls2k0500-pmc | ||
| 23 | - const: syscon | ||
| 19 | 24 | ||
| 20 | reg: | 25 | reg: |
| 21 | maxItems: 1 | 26 | maxItems: 1 |
| @@ -32,6 +37,18 @@ properties: · 10 unmodified lines | |||
| 32 | addition, the PM need according to it to indicate that current | 37 | addition, the PM need according to it to indicate that current |
| 33 | SoC whether support Suspend To RAM. | 38 | SoC whether support Suspend To RAM. |
| 34 | 39 | ||
| 40 | syscon-poweroff: | ||
| 41 | $ref: /schemas/power/reset/syscon-poweroff.yaml# | ||
| 42 | type: object | ||
| 43 | description: | ||
| 44 | Node for power off method | ||
| 45 | |||
| 46 | syscon-reboot: | ||
| 47 | $ref: /schemas/power/reset/syscon-reboot.yaml# | ||
| 48 | type: object | ||
| 49 | description: | ||
| 50 | Node for reboot method | ||
| 51 | |||
| 35 | required: | 52 | required: |
| 36 | - compatible | 53 | - compatible |
| 37 | - reg | 54 | - reg |
| @@ -44,9 +61,23 @@ examples: · 6 unmodified lines | |||
| 44 | #include <dt-bindings/interrupt-controller/irq.h> | 61 | #include <dt-bindings/interrupt-controller/irq.h> |
| 45 | 62 | ||
| 46 | power-management@1fe27000 { | 63 | power-management@1fe27000 { |
| 47 | compatible = "loongson,ls2k1000-pmc", "syscon"; | 64 | compatible = "loongson,ls2k1000-pmc", "loongson,ls2k0500-pmc", "syscon"; |
| 48 | reg = <0x1fe27000 0x58>; | 65 | reg = <0x1fe27000 0x58>; |
| 49 | interrupt-parent = <&liointc1>; | 66 | interrupt-parent = <&liointc1>; |
| 50 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | 67 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; |
| 51 | loongson,suspend-address = <0x0 0x1c000500>; | 68 | loongson,suspend-address = <0x0 0x1c000500>; |
| 69 | |||
| 70 | syscon-reboot { | ||
| 71 | compatible = "syscon-reboot"; | ||
| 72 | offset = <0x30>; | ||
| 73 | mask = <0x1>; | ||
| 74 | }; | ||
| 75 | |||
| 76 | syscon-poweroff { | ||
| 77 | compatible = "syscon-poweroff"; | ||
| 78 | regmap = <&pmc>; | ||
| 79 | offset = <0x14>; | ||
| 80 | mask = <0x3c00>; | ||
| 81 | value = <0x3c00>; | ||
| 82 | }; | ||
| 52 | }; | 83 | }; |
| @@ -22,6 +22,13 @@ properties: · 21 unmodified lines | |||
| 22 | - const: fsl,imx35-cspi | 22 | - const: fsl,imx35-cspi |
| 23 | - const: fsl,imx51-ecspi | 23 | - const: fsl,imx51-ecspi |
| 24 | - const: fsl,imx53-ecspi | 24 | - const: fsl,imx53-ecspi |
| 25 | - items: | ||
| 26 | - enum: | ||
| 27 | - fsl,imx25-cspi | ||
| 28 | - fsl,imx50-cspi | ||
| 29 | - fsl,imx51-cspi | ||
| 30 | - fsl,imx53-cspi | ||
| 31 | - const: fsl,imx35-cspi | ||
| 25 | - items: | 32 | - items: |
| 26 | - const: fsl,imx8mp-ecspi | 33 | - const: fsl,imx8mp-ecspi |
| 27 | - const: fsl,imx6ul-ecspi | 34 | - const: fsl,imx6ul-ecspi |
| @@ -37,7 +37,6 @@ For more information please refer to the documentation site or wiki · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | https://btrfs.readthedocs.io | 38 | https://btrfs.readthedocs.io |
| 39 | 39 | ||
| 40 | https://btrfs.wiki.kernel.org | ||
| 41 | 40 | ||
| 42 | that maintains information about administration tasks, frequently asked | 41 | that maintains information about administration tasks, frequently asked |
| 43 | questions, use cases, mount options, comprehensible changelogs, features, | 42 | questions, use cases, mount options, comprehensible changelogs, features, |
| @@ -949,3 +949,99 @@ mmap_lock held. All in-tree users have been audited and do not seem to · 948 unmodified lines | |||
| 949 | depend on the mmap_lock being held, but out of tree users should verify | 949 | depend on the mmap_lock being held, but out of tree users should verify |
| 950 | for themselves. If they do need it, they can return VM_FAULT_RETRY to | 950 | for themselves. If they do need it, they can return VM_FAULT_RETRY to |
| 951 | be called with the mmap_lock held. | 951 | be called with the mmap_lock held. |
| 952 | |||
| 953 | --- | ||
| 954 | |||
| 955 | **mandatory** | ||
| 956 | |||
| 957 | The order of opening block devices and matching or creating superblocks has | ||
| 958 | changed. | ||
| 959 | |||
| 960 | The old logic opened block devices first and then tried to find a | ||
| 961 | suitable superblock to reuse based on the block device pointer. | ||
| 962 | |||
| 963 | The new logic tries to find a suitable superblock first based on the device | ||
| 964 | number, and opening the block device afterwards. | ||
| 965 | |||
| 966 | Since opening block devices cannot happen under s_umount because of lock | ||
| 967 | ordering requirements s_umount is now dropped while opening block devices and | ||
| 968 | reacquired before calling fill_super(). | ||
| 969 | |||
| 970 | In the old logic concurrent mounters would find the superblock on the list of | ||
| 971 | superblocks for the filesystem type. Since the first opener of the block device | ||
| 972 | would hold s_umount they would wait until the superblock became either born or | ||
| 973 | was discarded due to initialization failure. | ||
| 974 | |||
| 975 | Since the new logic drops s_umount concurrent mounters could grab s_umount and | ||
| 976 | would spin. Instead they are now made to wait using an explicit wait-wake | ||
| 977 | mechanism without having to hold s_umount. | ||
| 978 | |||
| 979 | --- | ||
| 980 | |||
| 981 | **mandatory** | ||
| 982 | |||
| 983 | The holder of a block device is now the superblock. | ||
| 984 | |||
| 985 | The holder of a block device used to be the file_system_type which wasn't | ||
| 986 | particularly useful. It wasn't possible to go from block device to owning | ||
| 987 | superblock without matching on the device pointer stored in the superblock. | ||
| 988 | This mechanism would only work for a single device so the block layer couldn't | ||
| 989 | find the owning superblock of any additional devices. | ||
| 990 | |||
| 991 | In the old mechanism reusing or creating a superblock for a racing mount(2) and | ||
| 992 | umount(2) relied on the file_system_type as the holder. This was severly | ||
| 993 | underdocumented however: | ||
| 994 | |||
| 995 | (1) Any concurrent mounter that managed to grab an active reference on an | ||
| 996 | existing superblock was made to wait until the superblock either became | ||
| 997 | ready or until the superblock was removed from the list of superblocks of | ||
| 998 | the filesystem type. If the superblock is ready the caller would simple | ||
| 999 | reuse it. | ||
| 1000 | |||
| 1001 | (2) If the mounter came after deactivate_locked_super() but before | ||
| 1002 | the superblock had been removed from the list of superblocks of the | ||
| 1003 | filesystem type the mounter would wait until the superblock was shutdown, | ||
| 1004 | reuse the block device and allocate a new superblock. | ||
| 1005 | |||
| 1006 | (3) If the mounter came after deactivate_locked_super() and after | ||
| 1007 | the superblock had been removed from the list of superblocks of the | ||
| 1008 | filesystem type the mounter would reuse the block device and allocate a new | ||
| 1009 | superblock (the bd_holder point may still be set to the filesystem type). | ||
| 1010 | |||
| 1011 | Because the holder of the block device was the file_system_type any concurrent | ||
| 1012 | mounter could open the block devices of any superblock of the same | ||
| 1013 | file_system_type without risking seeing EBUSY because the block device was | ||
| 1014 | still in use by another superblock. | ||
| 1015 | |||
| 1016 | Making the superblock the owner of the block device changes this as the holder | ||
| 1017 | is now a unique superblock and thus block devices associated with it cannot be | ||
| 1018 | reused by concurrent mounters. So a concurrent mounter in (2) could suddenly | ||
| 1019 | see EBUSY when trying to open a block device whose holder was a different | ||
| 1020 | superblock. | ||
| 1021 | |||
| 1022 | The new logic thus waits until the superblock and the devices are shutdown in | ||
| 1023 | ->kill_sb(). Removal of the superblock from the list of superblocks of the | ||
| 1024 | filesystem type is now moved to a later point when the devices are closed: | ||
| 1025 | |||
| 1026 | (1) Any concurrent mounter managing to grab an active reference on an existing | ||
| 1027 | superblock is made to wait until the superblock is either ready or until | ||
| 1028 | the superblock and all devices are shutdown in ->kill_sb(). If the | ||
| 1029 | superblock is ready the caller will simply reuse it. | ||
| 1030 | |||
| 1031 | (2) If the mounter comes after deactivate_locked_super() but before | ||
| 1032 | the superblock has been removed from the list of superblocks of the | ||
| 1033 | filesystem type the mounter is made to wait until the superblock and the | ||
| 1034 | devices are shut down in ->kill_sb() and the superblock is removed from the | ||
| 1035 | list of superblocks of the filesystem type. The mounter will allocate a new | ||
| 1036 | superblock and grab ownership of the block device (the bd_holder pointer of | ||
| 1037 | the block device will be set to the newly allocated superblock). | ||
| 1038 | |||
| 1039 | (3) This case is now collapsed into (2) as the superblock is left on the list | ||
| 1040 | of superblocks of the filesystem type until all devices are shutdown in | ||
| 1041 | ->kill_sb(). In other words, if the superblock isn't on the list of | ||
| 1042 | superblock of the filesystem type anymore then it has given up ownership of | ||
| 1043 | all associated block devices (the bd_holder pointer is NULL). | ||
| 1044 | |||
| 1045 | As this is a VFS level change it has no practical consequences for filesystems | ||
| 1046 | other than that all of them must use one of the provided kill_litter_super(), | ||
| 1047 | kill_anon_super(), or kill_block_super() helpers. | ||
| @@ -573,6 +573,32 @@ above, leading to: · 572 unmodified lines | |||
| 573 | bool "Support for foo hardware" | 573 | bool "Support for foo hardware" |
| 574 | depends on ARCH_FOO_VENDOR || COMPILE_TEST | 574 | depends on ARCH_FOO_VENDOR || COMPILE_TEST |
| 575 | 575 | ||
| 576 | Optional dependencies | ||
| 577 | ~~~~~~~~~~~~~~~~~~~~~ | ||
| 578 | |||
| 579 | Some drivers are able to optionally use a feature from another module | ||
| 580 | or build cleanly with that module disabled, but cause a link failure | ||
| 581 | when trying to use that loadable module from a built-in driver. | ||
| 582 | |||
| 583 | The most common way to express this optional dependency in Kconfig logic | ||
| 584 | uses the slightly counterintuitive:: | ||
| 585 | |||
| 586 | config FOO | ||
| 587 | tristate "Support for foo hardware" | ||
| 588 | depends on BAR || !BAR | ||
| 589 | |||
| 590 | This means that there is either a dependency on BAR that disallows | ||
| 591 | the combination of FOO=y with BAR=m, or BAR is completely disabled. | ||
| 592 | For a more formalized approach if there are multiple drivers that have | ||
| 593 | the same dependency, a helper symbol can be used, like:: | ||
| 594 | |||
| 595 | config FOO | ||
| 596 | tristate "Support for foo hardware" | ||
| 597 | depends on BAR_OPTIONAL | ||
| 598 | |||
| 599 | config BAR_OPTIONAL | ||
| 600 | def_tristate BAR || !BAR | ||
| 601 | |||
| 576 | Kconfig recursive dependency limitations | 602 | Kconfig recursive dependency limitations |
| 577 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 603 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 578 | 604 | ||
| @@ -7,9 +7,9 @@ AX.25 · 6 unmodified lines | |||
| 7 | To use the amateur radio protocols within Linux you will need to get a | 7 | To use the amateur radio protocols within Linux you will need to get a |
| 8 | suitable copy of the AX.25 Utilities. More detailed information about | 8 | suitable copy of the AX.25 Utilities. More detailed information about |
| 9 | AX.25, NET/ROM and ROSE, associated programs and utilities can be | 9 | AX.25, NET/ROM and ROSE, associated programs and utilities can be |
| 10 | found on http://www.linux-ax25.org. | 10 | found on https://linux-ax25.in-berlin.de. |
| 11 | 11 | ||
| 12 | There is an active mailing list for discussing Linux amateur radio matters | 12 | There is a mailing list for discussing Linux amateur radio matters |
| 13 | called linux-hams@vger.kernel.org. To subscribe to it, send a message to | 13 | called linux-hams@vger.kernel.org. To subscribe to it, send a message to |
| 14 | majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body | 14 | majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body |
| 15 | of the message, the subject field is ignored. You don't need to be | 15 | of the message, the subject field is ignored. You don't need to be |
| @@ -251,6 +251,7 @@ an involved disclosed party. The current ambassadors list: · 250 unmodified lines | |||
| 251 | IBM Z Christian Borntraeger <borntraeger@de.ibm.com> | 251 | IBM Z Christian Borntraeger <borntraeger@de.ibm.com> |
| 252 | Intel Tony Luck <tony.luck@intel.com> | 252 | Intel Tony Luck <tony.luck@intel.com> |
| 253 | Qualcomm Trilok Soni <tsoni@codeaurora.org> | 253 | Qualcomm Trilok Soni <tsoni@codeaurora.org> |
| 254 | RISC-V Palmer Dabbelt <palmer@dabbelt.com> | ||
| 254 | Samsung Javier González <javier.gonz@samsung.com> | 255 | Samsung Javier González <javier.gonz@samsung.com> |
| 255 | 256 | ||
| 256 | Microsoft James Morris <jamorris@linux.microsoft.com> | 257 | Microsoft James Morris <jamorris@linux.microsoft.com> |
| @@ -74,8 +74,8 @@ topology based on those information. When the device is older and · 73 unmodified lines | |||
| 74 | doesn't respond to the new UMP inquiries, the driver falls back and | 74 | doesn't respond to the new UMP inquiries, the driver falls back and |
| 75 | builds the topology based on Group Terminal Block (GTB) information | 75 | builds the topology based on Group Terminal Block (GTB) information |
| 76 | from the USB descriptor. Some device might be screwed up by the | 76 | from the USB descriptor. Some device might be screwed up by the |
| 77 | unexpected UMP command; in such a case, pass `midi2_probe=0` option to | 77 | unexpected UMP command; in such a case, pass `midi2_ump_probe=0` |
| 78 | snd-usb-audio driver for skipping the UMP v1.1 inquiries. | 78 | option to snd-usb-audio driver for skipping the UMP v1.1 inquiries. |
| 79 | 79 | ||
| 80 | When the MIDI 2.0 device is probed, the kernel creates a rawmidi | 80 | When the MIDI 2.0 device is probed, the kernel creates a rawmidi |
| 81 | device for each UMP Endpoint of the device. Its device name is | 81 | device for each UMP Endpoint of the device. Its device name is |
| @@ -344,9 +344,9 @@ LoongArch指令集架构的文档: · 343 unmodified lines | |||
| 344 | 344 | ||
| 345 | LoongArch的ELF psABI文档: | 345 | LoongArch的ELF psABI文档: |
| 346 | 346 | ||
| 347 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-CN.pdf (中文版) | 347 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-CN.pdf (中文版) |
| 348 | 348 | ||
| 349 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.00-EN.pdf (英文版) | 349 | https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-ELF-ABI-v2.01-EN.pdf (英文版) |
| 350 | 350 | ||
| 351 | Loongson与LoongArch的Linux内核源码仓库: | 351 | Loongson与LoongArch的Linux内核源码仓库: |
| 352 | 352 | ||
| @@ -1662,7 +1662,7 @@ F: arch/arm*/include/asm/perf_event.h · 1661 unmodified lines | |||
| 1662 | F: arch/arm*/kernel/hw_breakpoint.c | 1662 | F: arch/arm*/kernel/hw_breakpoint.c |
| 1663 | F: arch/arm*/kernel/perf_* | 1663 | F: arch/arm*/kernel/perf_* |
| 1664 | F: drivers/perf/ | 1664 | F: drivers/perf/ |
| 1665 | F: include/linux/perf/arm_pmu.h | 1665 | F: include/linux/perf/arm_pmu*.h |
| 1666 | 1666 | ||
| 1667 | ARM PORT | 1667 | ARM PORT |
| 1668 | M: Russell King <linux@armlinux.org.uk> | 1668 | M: Russell King <linux@armlinux.org.uk> |
| @@ -1855,7 +1855,7 @@ F: Documentation/devicetree/bindings/phy/amlogic* · 186 unmodified lines | |||
| 1855 | F: arch/arm/boot/dts/amlogic/ | 1855 | F: arch/arm/boot/dts/amlogic/ |
| 1856 | F: arch/arm/mach-meson/ | 1856 | F: arch/arm/mach-meson/ |
| 1857 | F: arch/arm64/boot/dts/amlogic/ | 1857 | F: arch/arm64/boot/dts/amlogic/ |
| 1858 | F: drivers/genpd/amlogic/ | 1858 | F: drivers/pmdomain/amlogic/ |
| 1859 | F: drivers/mmc/host/meson* | 1859 | F: drivers/mmc/host/meson* |
| 1860 | F: drivers/phy/amlogic/ | 1860 | F: drivers/phy/amlogic/ |
| 1861 | F: drivers/pinctrl/meson/ | 1861 | F: drivers/pinctrl/meson/ |
| @@ -1918,7 +1918,7 @@ F: drivers/bluetooth/hci_bcm4377.c · 56 unmodified lines | |||
| 1918 | F: drivers/clk/clk-apple-nco.c | 1918 | F: drivers/clk/clk-apple-nco.c |
| 1919 | F: drivers/cpufreq/apple-soc-cpufreq.c | 1919 | F: drivers/cpufreq/apple-soc-cpufreq.c |
| 1920 | F: drivers/dma/apple-admac.c | 1920 | F: drivers/dma/apple-admac.c |
| 1921 | F: drivers/genpd/apple/ | 1921 | F: drivers/pmdomain/apple/ |
| 1922 | F: drivers/i2c/busses/i2c-pasemi-core.c | 1922 | F: drivers/i2c/busses/i2c-pasemi-core.c |
| 1923 | F: drivers/i2c/busses/i2c-pasemi-platform.c | 1923 | F: drivers/i2c/busses/i2c-pasemi-platform.c |
| 1924 | F: drivers/iommu/apple-dart.c | 1924 | F: drivers/iommu/apple-dart.c |
| @@ -1963,12 +1963,12 @@ F: drivers/irqchip/irq-aspeed-i2c-ic.c · 38 unmodified lines | |||
| 1963 | 1963 | ||
| 1964 | ARM/ASPEED MACHINE SUPPORT | 1964 | ARM/ASPEED MACHINE SUPPORT |
| 1965 | M: Joel Stanley <joel@jms.id.au> | 1965 | M: Joel Stanley <joel@jms.id.au> |
| 1966 | R: Andrew Jeffery <andrew@aj.id.au> | 1966 | R: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 1967 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1967 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1968 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 1968 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 1969 | S: Supported | 1969 | S: Supported |
| 1970 | Q: https://patchwork.ozlabs.org/project/linux-aspeed/list/ | 1970 | Q: https://patchwork.ozlabs.org/project/linux-aspeed/list/ |
| 1971 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git | 1971 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git |
| 1972 | F: Documentation/devicetree/bindings/arm/aspeed/ | 1972 | F: Documentation/devicetree/bindings/arm/aspeed/ |
| 1973 | F: arch/arm/boot/dts/aspeed/ | 1973 | F: arch/arm/boot/dts/aspeed/ |
| 1974 | F: arch/arm/mach-aspeed/ | 1974 | F: arch/arm/mach-aspeed/ |
| @@ -2435,7 +2435,7 @@ F: arch/arm/mach-ux500/ · 460 unmodified lines | |||
| 2435 | F: drivers/clk/clk-nomadik.c | 2435 | F: drivers/clk/clk-nomadik.c |
| 2436 | F: drivers/clocksource/clksrc-dbx500-prcmu.c | 2436 | F: drivers/clocksource/clksrc-dbx500-prcmu.c |
| 2437 | F: drivers/dma/ste_dma40* | 2437 | F: drivers/dma/ste_dma40* |
| 2438 | F: drivers/genpd/st/ste-ux500-pm-domain.c | 2438 | F: drivers/pmdomain/st/ste-ux500-pm-domain.c |
| 2439 | F: drivers/hwspinlock/u8500_hsem.c | 2439 | F: drivers/hwspinlock/u8500_hsem.c |
| 2440 | F: drivers/i2c/busses/i2c-nomadik.c | 2440 | F: drivers/i2c/busses/i2c-nomadik.c |
| 2441 | F: drivers/iio/adc/ab8500-gpadc.c | 2441 | F: drivers/iio/adc/ab8500-gpadc.c |
| @@ -2598,7 +2598,7 @@ F: arch/arm/include/debug/renesas-scif.S · 156 unmodified lines | |||
| 2598 | F: arch/arm/mach-shmobile/ | 2598 | F: arch/arm/mach-shmobile/ |
| 2599 | F: arch/arm64/boot/dts/renesas/ | 2599 | F: arch/arm64/boot/dts/renesas/ |
| 2600 | F: arch/riscv/boot/dts/renesas/ | 2600 | F: arch/riscv/boot/dts/renesas/ |
| 2601 | F: drivers/genpd/renesas/ | 2601 | F: drivers/pmdomain/renesas/ |
| 2602 | F: drivers/soc/renesas/ | 2602 | F: drivers/soc/renesas/ |
| 2603 | F: include/linux/soc/renesas/ | 2603 | F: include/linux/soc/renesas/ |
| 2604 | K: \brenesas, | 2604 | K: \brenesas, |
| @@ -3058,7 +3058,7 @@ F: Documentation/devicetree/bindings/peci/peci-aspeed.yaml · 453 unmodified lines | |||
| 3058 | F: drivers/peci/controller/peci-aspeed.c | 3058 | F: drivers/peci/controller/peci-aspeed.c |
| 3059 | 3059 | ||
| 3060 | ASPEED PINCTRL DRIVERS | 3060 | ASPEED PINCTRL DRIVERS |
| 3061 | M: Andrew Jeffery <andrew@aj.id.au> | 3061 | M: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 3062 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 3062 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 3063 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) | 3063 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) |
| 3064 | L: linux-gpio@vger.kernel.org | 3064 | L: linux-gpio@vger.kernel.org |
| @@ -3075,7 +3075,7 @@ F: drivers/irqchip/irq-aspeed-scu-ic.c · 10 unmodified lines | |||
| 3075 | F: include/dt-bindings/interrupt-controller/aspeed-scu-ic.h | 3075 | F: include/dt-bindings/interrupt-controller/aspeed-scu-ic.h |
| 3076 | 3076 | ||
| 3077 | ASPEED SD/MMC DRIVER | 3077 | ASPEED SD/MMC DRIVER |
| 3078 | M: Andrew Jeffery <andrew@aj.id.au> | 3078 | M: Andrew Jeffery <andrew@codeconstruct.com.au> |
| 3079 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) | 3079 | L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) |
| 3080 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) | 3080 | L: openbmc@lists.ozlabs.org (moderated for non-subscribers) |
| 3081 | L: linux-mmc@vger.kernel.org | 3081 | L: linux-mmc@vger.kernel.org |
| @@ -3344,7 +3344,7 @@ AX.25 NETWORK LAYER · 262 unmodified lines | |||
| 3344 | M: Ralf Baechle <ralf@linux-mips.org> | 3344 | M: Ralf Baechle <ralf@linux-mips.org> |
| 3345 | L: linux-hams@vger.kernel.org | 3345 | L: linux-hams@vger.kernel.org |
| 3346 | S: Maintained | 3346 | S: Maintained |
| 3347 | W: http://www.linux-ax25.org/ | 3347 | W: https://linux-ax25.in-berlin.de |
| 3348 | F: include/net/ax25.h | 3348 | F: include/net/ax25.h |
| 3349 | F: include/uapi/linux/ax25.h | 3349 | F: include/uapi/linux/ax25.h |
| 3350 | F: net/ax25/ | 3350 | F: net/ax25/ |
| @@ -4026,7 +4026,7 @@ F: arch/mips/kernel/*bmips* · 675 unmodified lines | |||
| 4026 | F: drivers/irqchip/irq-bcm63* | 4026 | F: drivers/irqchip/irq-bcm63* |
| 4027 | F: drivers/irqchip/irq-bcm7* | 4027 | F: drivers/irqchip/irq-bcm7* |
| 4028 | F: drivers/irqchip/irq-brcmstb* | 4028 | F: drivers/irqchip/irq-brcmstb* |
| 4029 | F: drivers/genpd/bcm/bcm63xx-power.c | 4029 | F: drivers/pmdomain/bcm/bcm63xx-power.c |
| 4030 | F: include/linux/bcm963xx_nvram.h | 4030 | F: include/linux/bcm963xx_nvram.h |
| 4031 | F: include/linux/bcm963xx_tag.h | 4031 | F: include/linux/bcm963xx_tag.h |
| 4032 | 4032 | ||
| @@ -4082,7 +4082,7 @@ F: drivers/net/wireless/broadcom/brcm80211/ · 49 unmodified lines | |||
| 4082 | 4082 | ||
| 4083 | BROADCOM BRCMSTB GPIO DRIVER | 4083 | BROADCOM BRCMSTB GPIO DRIVER |
| 4084 | M: Doug Berger <opendmb@gmail.com> | 4084 | M: Doug Berger <opendmb@gmail.com> |
| 4085 | M: Florian Fainelli <florian.fainelli@broadcom> | 4085 | M: Florian Fainelli <florian.fainelli@broadcom.com> |
| 4086 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> | 4086 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4087 | S: Supported | 4087 | S: Supported |
| 4088 | F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml | 4088 | F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml |
| @@ -4248,7 +4248,7 @@ R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> · 159 unmodified lines | |||
| 4248 | L: linux-pm@vger.kernel.org | 4248 | L: linux-pm@vger.kernel.org |
| 4249 | S: Maintained | 4249 | S: Maintained |
| 4250 | T: git https://github.com/broadcom/stblinux.git | 4250 | T: git https://github.com/broadcom/stblinux.git |
| 4251 | F: drivers/genpd/bcm/bcm-pmb.c | 4251 | F: drivers/pmdomain/bcm/bcm-pmb.c |
| 4252 | F: include/dt-bindings/soc/bcm-pmb.h | 4252 | F: include/dt-bindings/soc/bcm-pmb.h |
| 4253 | 4253 | ||
| 4254 | BROADCOM SPECIFIC AMBA DRIVER (BCMA) | 4254 | BROADCOM SPECIFIC AMBA DRIVER (BCMA) |
| @@ -4378,7 +4378,6 @@ M: David Sterba <dsterba@suse.com> · 123 unmodified lines | |||
| 4378 | L: linux-btrfs@vger.kernel.org | 4378 | L: linux-btrfs@vger.kernel.org |
| 4379 | S: Maintained | 4379 | S: Maintained |
| 4380 | W: https://btrfs.readthedocs.io | 4380 | W: https://btrfs.readthedocs.io |
| 4381 | W: https://btrfs.wiki.kernel.org/ | ||
| 4382 | Q: https://patchwork.kernel.org/project/linux-btrfs/list/ | 4381 | Q: https://patchwork.kernel.org/project/linux-btrfs/list/ |
| 4383 | C: irc://irc.libera.chat/btrfs | 4382 | C: irc://irc.libera.chat/btrfs |
| 4384 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git | 4383 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git |
| @@ -6646,9 +6645,9 @@ F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml · 2261 unmodified lines | |||
| 6646 | F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c | 6645 | F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c |
| 6647 | 6646 | ||
| 6648 | DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS | 6647 | DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS |
| 6649 | M: Ben Skeggs <bskeggs@redhat.com> | ||
| 6650 | M: Karol Herbst <kherbst@redhat.com> | 6648 | M: Karol Herbst <kherbst@redhat.com> |
| 6651 | M: Lyude Paul <lyude@redhat.com> | 6649 | M: Lyude Paul <lyude@redhat.com> |
| 6650 | M: Danilo Krummrich <dakr@redhat.com> | ||
| 6652 | L: dri-devel@lists.freedesktop.org | 6651 | L: dri-devel@lists.freedesktop.org |
| 6653 | L: nouveau@lists.freedesktop.org | 6652 | L: nouveau@lists.freedesktop.org |
| 6654 | S: Supported | 6653 | S: Supported |
| @@ -8729,7 +8728,7 @@ M: Ulf Hansson <ulf.hansson@linaro.org> · 2074 unmodified lines | |||
| 8729 | L: linux-pm@vger.kernel.org | 8728 | L: linux-pm@vger.kernel.org |
| 8730 | S: Supported | 8729 | S: Supported |
| 8731 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git | 8730 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git |
| 8732 | F: drivers/genpd/ | 8731 | F: drivers/pmdomain/ |
| 8733 | 8732 | ||
| 8734 | GENERIC RESISTIVE TOUCHSCREEN ADC DRIVER | 8733 | GENERIC RESISTIVE TOUCHSCREEN ADC DRIVER |
| 8735 | M: Eugen Hristev <eugen.hristev@microchip.com> | 8734 | M: Eugen Hristev <eugen.hristev@microchip.com> |
| @@ -8875,7 +8874,7 @@ F: drivers/gpio/gpio-mockup.c · 139 unmodified lines | |||
| 8875 | F: tools/testing/selftests/gpio/ | 8874 | F: tools/testing/selftests/gpio/ |
| 8876 | 8875 | ||
| 8877 | GPIO REGMAP | 8876 | GPIO REGMAP |
| 8878 | R: Michael Walle <michael@walle.cc> | 8877 | M: Michael Walle <michael@walle.cc> |
| 8879 | S: Maintained | 8878 | S: Maintained |
| 8880 | F: drivers/gpio/gpio-regmap.c | 8879 | F: drivers/gpio/gpio-regmap.c |
| 8881 | F: include/linux/gpio/regmap.h | 8880 | F: include/linux/gpio/regmap.h |
| @@ -13617,6 +13616,7 @@ F: drivers/net/ethernet/mellanox/mlxfw/ · 4735 unmodified lines | |||
| 13617 | 13616 | ||
| 13618 | MELLANOX HARDWARE PLATFORM SUPPORT | 13617 | MELLANOX HARDWARE PLATFORM SUPPORT |
| 13619 | M: Hans de Goede <hdegoede@redhat.com> | 13618 | M: Hans de Goede <hdegoede@redhat.com> |
| 13619 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 13620 | M: Mark Gross <markgross@kernel.org> | 13620 | M: Mark Gross <markgross@kernel.org> |
| 13621 | M: Vadim Pasternak <vadimp@nvidia.com> | 13621 | M: Vadim Pasternak <vadimp@nvidia.com> |
| 13622 | L: platform-driver-x86@vger.kernel.org | 13622 | L: platform-driver-x86@vger.kernel.org |
| @@ -14211,6 +14211,7 @@ F: drivers/platform/surface/surface_gpe.c · 588 unmodified lines | |||
| 14211 | 14211 | ||
| 14212 | MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT | 14212 | MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT |
| 14213 | M: Hans de Goede <hdegoede@redhat.com> | 14213 | M: Hans de Goede <hdegoede@redhat.com> |
| 14214 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 14214 | M: Mark Gross <markgross@kernel.org> | 14215 | M: Mark Gross <markgross@kernel.org> |
| 14215 | M: Maximilian Luz <luzmaximilian@gmail.com> | 14216 | M: Maximilian Luz <luzmaximilian@gmail.com> |
| 14216 | L: platform-driver-x86@vger.kernel.org | 14217 | L: platform-driver-x86@vger.kernel.org |
| @@ -14757,7 +14758,7 @@ NETROM NETWORK LAYER · 540 unmodified lines | |||
| 14757 | M: Ralf Baechle <ralf@linux-mips.org> | 14758 | M: Ralf Baechle <ralf@linux-mips.org> |
| 14758 | L: linux-hams@vger.kernel.org | 14759 | L: linux-hams@vger.kernel.org |
| 14759 | S: Maintained | 14760 | S: Maintained |
| 14760 | W: http://www.linux-ax25.org/ | 14761 | W: https://linux-ax25.in-berlin.de |
| 14761 | F: include/net/netrom.h | 14762 | F: include/net/netrom.h |
| 14762 | F: include/uapi/linux/netrom.h | 14763 | F: include/uapi/linux/netrom.h |
| 14763 | F: net/netrom/ | 14764 | F: net/netrom/ |
| @@ -17680,7 +17681,7 @@ L: linux-pm@vger.kernel.org · 2916 unmodified lines | |||
| 17680 | L: linux-arm-msm@vger.kernel.org | 17681 | L: linux-arm-msm@vger.kernel.org |
| 17681 | S: Maintained | 17682 | S: Maintained |
| 17682 | F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml | 17683 | F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml |
| 17683 | F: drivers/genpd/qcom/cpr.c | 17684 | F: drivers/pmdomain/qcom/cpr.c |
| 17684 | 17685 | ||
| 17685 | QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096 | 17686 | QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096 |
| 17686 | M: Ilia Lin <ilia.lin@kernel.org> | 17687 | M: Ilia Lin <ilia.lin@kernel.org> |
| @@ -18608,7 +18609,7 @@ ROSE NETWORK LAYER · 921 unmodified lines | |||
| 18608 | M: Ralf Baechle <ralf@linux-mips.org> | 18609 | M: Ralf Baechle <ralf@linux-mips.org> |
| 18609 | L: linux-hams@vger.kernel.org | 18610 | L: linux-hams@vger.kernel.org |
| 18610 | S: Maintained | 18611 | S: Maintained |
| 18611 | W: http://www.linux-ax25.org/ | 18612 | W: https://linux-ax25.in-berlin.de |
| 18612 | F: include/net/rose.h | 18613 | F: include/net/rose.h |
| 18613 | F: include/uapi/linux/rose.h | 18614 | F: include/uapi/linux/rose.h |
| 18614 | F: net/rose/ | 18615 | F: net/rose/ |
| @@ -20514,7 +20515,7 @@ STARFIVE JH71XX PMU CONTROLLER DRIVER · 1899 unmodified lines | |||
| 20514 | M: Walker Chen <walker.chen@starfivetech.com> | 20515 | M: Walker Chen <walker.chen@starfivetech.com> |
| 20515 | S: Supported | 20516 | S: Supported |
| 20516 | F: Documentation/devicetree/bindings/power/starfive* | 20517 | F: Documentation/devicetree/bindings/power/starfive* |
| 20517 | F: drivers/genpd/starfive/jh71xx-pmu.c | 20518 | F: drivers/pmdomain/starfive/jh71xx-pmu.c |
| 20518 | F: include/dt-bindings/power/starfive,jh7110-pmu.h | 20519 | F: include/dt-bindings/power/starfive,jh7110-pmu.h |
| 20519 | 20520 | ||
| 20520 | STARFIVE SOC DRIVERS | 20521 | STARFIVE SOC DRIVERS |
| @@ -21339,7 +21340,7 @@ F: drivers/irqchip/irq-ti-sci-inta.c · 818 unmodified lines | |||
| 21339 | F: drivers/irqchip/irq-ti-sci-intr.c | 21340 | F: drivers/irqchip/irq-ti-sci-intr.c |
| 21340 | F: drivers/reset/reset-ti-sci.c | 21341 | F: drivers/reset/reset-ti-sci.c |
| 21341 | F: drivers/soc/ti/ti_sci_inta_msi.c | 21342 | F: drivers/soc/ti/ti_sci_inta_msi.c |
| 21342 | F: drivers/genpd/ti/ti_sci_pm_domains.c | 21343 | F: drivers/pmdomain/ti/ti_sci_pm_domains.c |
| 21343 | F: include/dt-bindings/soc/ti,sci_pm_domain.h | 21344 | F: include/dt-bindings/soc/ti,sci_pm_domain.h |
| 21344 | F: include/linux/soc/ti/ti_sci_inta_msi.h | 21345 | F: include/linux/soc/ti/ti_sci_inta_msi.h |
| 21345 | F: include/linux/soc/ti/ti_sci_protocol.h | 21346 | F: include/linux/soc/ti/ti_sci_protocol.h |
| @@ -21581,7 +21582,7 @@ L: linux-kernel@vger.kernel.org · 235 unmodified lines | |||
| 21581 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 21582 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 21582 | S: Maintained | 21583 | S: Maintained |
| 21583 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git | 21584 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git |
| 21584 | F: drivers/genpd/ti/omap_prm.c | 21585 | F: drivers/pmdomain/ti/omap_prm.c |
| 21585 | F: drivers/soc/ti/* | 21586 | F: drivers/soc/ti/* |
| 21586 | 21587 | ||
| 21587 | TI LM49xxx FAMILY ASoC CODEC DRIVERS | 21588 | TI LM49xxx FAMILY ASoC CODEC DRIVERS |
| @@ -23424,9 +23425,11 @@ F: drivers/platform/x86/x86-android-tablets/ · 1836 unmodified lines | |||
| 23424 | 23425 | ||
| 23425 | X86 PLATFORM DRIVERS | 23426 | X86 PLATFORM DRIVERS |
| 23426 | M: Hans de Goede <hdegoede@redhat.com> | 23427 | M: Hans de Goede <hdegoede@redhat.com> |
| 23428 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | ||
| 23427 | M: Mark Gross <markgross@kernel.org> | 23429 | M: Mark Gross <markgross@kernel.org> |
| 23428 | L: platform-driver-x86@vger.kernel.org | 23430 | L: platform-driver-x86@vger.kernel.org |
| 23429 | S: Maintained | 23431 | S: Maintained |
| 23432 | Q: https://patchwork.kernel.org/project/platform-driver-x86/list/ | ||
| 23430 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git | 23433 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git |
| 23431 | F: drivers/platform/olpc/ | 23434 | F: drivers/platform/olpc/ |
| 23432 | F: drivers/platform/x86/ | 23435 | F: drivers/platform/x86/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 6 | 3 | PATCHLEVEL = 6 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc1 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Hurr durr I'ma ninja sloth | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -614,12 +614,12 @@ · 613 unmodified lines | |||
| 614 | /* Configure pwm clock source for timers 8 & 9 */ | 614 | /* Configure pwm clock source for timers 8 & 9 */ |
| 615 | &timer8 { | 615 | &timer8 { |
| 616 | assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; | 616 | assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; |
| 617 | assigned-clock-parents = <&sys_clkin_ck>; | 617 | assigned-clock-parents = <&sys_32k_ck>; |
| 618 | }; | 618 | }; |
| 619 | 619 | ||
| 620 | &timer9 { | 620 | &timer9 { |
| 621 | assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; | 621 | assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; |
| 622 | assigned-clock-parents = <&sys_clkin_ck>; | 622 | assigned-clock-parents = <&sys_32k_ck>; |
| 623 | }; | 623 | }; |
| 624 | 624 | ||
| 625 | /* | 625 | /* |
| @@ -640,6 +640,7 @@ · 14 unmodified lines | |||
| 640 | &uart3 { | 640 | &uart3 { |
| 641 | interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH | 641 | interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH |
| 642 | &omap4_pmx_core 0x17c>; | 642 | &omap4_pmx_core 0x17c>; |
| 643 | overrun-throttle-ms = <500>; | ||
| 643 | }; | 644 | }; |
| 644 | 645 | ||
| 645 | &uart4 { | 646 | &uart4 { |
| @@ -12,8 +12,7 @@ cpu_thermal: cpu-thermal { · 11 unmodified lines | |||
| 12 | polling-delay = <1000>; /* milliseconds */ | 12 | polling-delay = <1000>; /* milliseconds */ |
| 13 | coefficients = <0 20000>; | 13 | coefficients = <0 20000>; |
| 14 | 14 | ||
| 15 | /* sensor ID */ | 15 | thermal-sensors = <&bandgap>; |
| 16 | thermal-sensors = <&bandgap 0>; | ||
| 17 | 16 | ||
| 18 | cpu_trips: trips { | 17 | cpu_trips: trips { |
| 19 | cpu_alert0: cpu_alert { | 18 | cpu_alert0: cpu_alert { |
| @@ -12,7 +12,10 @@ cpu_thermal: cpu_thermal { · 11 unmodified lines | |||
| 12 | polling-delay-passive = <250>; /* milliseconds */ | 12 | polling-delay-passive = <250>; /* milliseconds */ |
| 13 | polling-delay = <1000>; /* milliseconds */ | 13 | polling-delay = <1000>; /* milliseconds */ |
| 14 | 14 | ||
| 15 | /* sensor ID */ | 15 | /* |
| 16 | * See 44xx files for single sensor addressing, omap5 and dra7 need | ||
| 17 | * also sensor ID for addressing. | ||
| 18 | */ | ||
| 16 | thermal-sensors = <&bandgap 0>; | 19 | thermal-sensors = <&bandgap 0>; |
| 17 | 20 | ||
| 18 | cpu_trips: trips { | 21 | cpu_trips: trips { |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | |||
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | &cpu_thermal { | 71 | &cpu_thermal { |
| 72 | thermal-sensors = <&bandgap>; | ||
| 72 | coefficients = <0 20000>; | 73 | coefficients = <0 20000>; |
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| @@ -79,6 +79,7 @@ · 78 unmodified lines | |||
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | &cpu_thermal { | 81 | &cpu_thermal { |
| 82 | thermal-sensors = <&bandgap>; | ||
| 82 | coefficients = <348 (-9301)>; | 83 | coefficients = <348 (-9301)>; |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| @@ -195,7 +195,7 @@ struct locomo_driver { · 194 unmodified lines | |||
| 195 | 195 | ||
| 196 | #define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) | 196 | #define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) |
| 197 | 197 | ||
| 198 | void locomo_lcd_power(struct locomo_dev *, int, unsigned int); | 198 | extern void locomolcd_power(int on); |
| 199 | 199 | ||
| 200 | int locomo_driver_register(struct locomo_driver *); | 200 | int locomo_driver_register(struct locomo_driver *); |
| 201 | void locomo_driver_unregister(struct locomo_driver *); | 201 | void locomo_driver_unregister(struct locomo_driver *); |
| @@ -99,7 +99,7 @@ static int omap4_pm_suspend(void) · 98 unmodified lines | |||
| 99 | * possible causes. | 99 | * possible causes. |
| 100 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | 100 | * http://www.spinics.net/lists/arm-kernel/msg218641.html |
| 101 | */ | 101 | */ |
| 102 | pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); | 102 | pr_debug("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); |
| 103 | } else { | 103 | } else { |
| 104 | pr_info("Successfully put all powerdomains to target state\n"); | 104 | pr_info("Successfully put all powerdomains to target state\n"); |
| 105 | } | 105 | } |
| @@ -257,7 +257,7 @@ int __init omap4_pm_init(void) · 151 unmodified lines | |||
| 257 | * http://www.spinics.net/lists/arm-kernel/msg218641.html | 257 | * http://www.spinics.net/lists/arm-kernel/msg218641.html |
| 258 | */ | 258 | */ |
| 259 | if (cpu_is_omap44xx()) | 259 | if (cpu_is_omap44xx()) |
| 260 | pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); | 260 | pr_debug("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); |
| 261 | 261 | ||
| 262 | ret = pwrdm_for_each(pwrdms_setup, NULL); | 262 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
| 263 | if (ret) { | 263 | if (ret) { |
| @@ -16,8 +16,6 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #include "hardware.h" /* Gives GPIO_MAX */ | 17 | #include "hardware.h" /* Gives GPIO_MAX */ |
| 18 | 18 | ||
| 19 | extern void locomolcd_power(int on); | ||
| 20 | |||
| 21 | #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) | 19 | #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) |
| 22 | #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) | 20 | #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) |
| 23 | #define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12 | 21 | #define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12 |
| @@ -58,11 +58,13 @@ · 57 unmodified lines | |||
| 58 | ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE) | 58 | ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE) |
| 59 | 59 | ||
| 60 | /** | 60 | /** |
| 61 | * uniphier_cache_data - UniPhier outer cache specific data | 61 | * struct uniphier_cache_data - UniPhier outer cache specific data |
| 62 | * | 62 | * |
| 63 | * @ctrl_base: virtual base address of control registers | 63 | * @ctrl_base: virtual base address of control registers |
| 64 | * @rev_base: virtual base address of revision registers | 64 | * @rev_base: virtual base address of revision registers |
| 65 | * @op_base: virtual base address of operation registers | 65 | * @op_base: virtual base address of operation registers |
| 66 | * @way_ctrl_base: virtual address of the way control registers for this | ||
| 67 | * SoC revision | ||
| 66 | * @way_mask: each bit specifies if the way is present | 68 | * @way_mask: each bit specifies if the way is present |
| 67 | * @nsets: number of associativity sets | 69 | * @nsets: number of associativity sets |
| 68 | * @line_size: line size in bytes | 70 | * @line_size: line size in bytes |
| @@ -207,7 +207,7 @@ static void xen_power_off(void) · 206 unmodified lines | |||
| 207 | 207 | ||
| 208 | static irqreturn_t xen_arm_callback(int irq, void *arg) | 208 | static irqreturn_t xen_arm_callback(int irq, void *arg) |
| 209 | { | 209 | { |
| 210 | xen_hvm_evtchn_do_upcall(); | 210 | xen_evtchn_do_upcall(); |
| 211 | return IRQ_HANDLED; | 211 | return IRQ_HANDLED; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| @@ -66,6 +66,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-mx8menlo.dtb · 65 unmodified lines | |||
| 66 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb | 66 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb |
| 67 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb | 67 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb |
| 68 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb | 68 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb |
| 69 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb | ||
| 69 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb | 70 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb |
| 70 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb | 71 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb |
| 71 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb | 72 | dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | port { | 27 | port { |
| 28 | hdmi_connector_in: endpoint { | 28 | hdmi_connector_in: endpoint { |
| 29 | remote-endpoint = <&adv7533_out>; | 29 | remote-endpoint = <&adv7535_out>; |
| 30 | }; | 30 | }; |
| 31 | }; | 31 | }; |
| 32 | }; | 32 | }; |
| @@ -72,6 +72,13 @@ · 39 unmodified lines | |||
| 72 | enable-active-high; | 72 | enable-active-high; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | reg_vddext_3v3: regulator-vddext-3v3 { | ||
| 76 | compatible = "regulator-fixed"; | ||
| 77 | regulator-name = "VDDEXT_3V3"; | ||
| 78 | regulator-min-microvolt = <3300000>; | ||
| 79 | regulator-max-microvolt = <3300000>; | ||
| 80 | }; | ||
| 81 | |||
| 75 | backlight: backlight { | 82 | backlight: backlight { |
| 76 | compatible = "pwm-backlight"; | 83 | compatible = "pwm-backlight"; |
| 77 | pwms = <&pwm1 0 5000000 0>; | 84 | pwms = <&pwm1 0 5000000 0>; |
| @@ -317,15 +324,16 @@ · 239 unmodified lines | |||
| 317 | 324 | ||
| 318 | hdmi@3d { | 325 | hdmi@3d { |
| 319 | compatible = "adi,adv7535"; | 326 | compatible = "adi,adv7535"; |
| 320 | reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>; | 327 | reg = <0x3d>; |
| 321 | reg-names = "main", "cec", "edid", "packet"; | 328 | interrupt-parent = <&gpio1>; |
| 329 | interrupts = <9 IRQ_TYPE_EDGE_FALLING>; | ||
| 322 | adi,dsi-lanes = <4>; | 330 | adi,dsi-lanes = <4>; |
| 323 | 331 | avdd-supply = <&buck5_reg>; | |
| 324 | adi,input-depth = <8>; | 332 | dvdd-supply = <&buck5_reg>; |
| 325 | adi,input-colorspace = "rgb"; | 333 | pvdd-supply = <&buck5_reg>; |
| 326 | adi,input-clock = "1x"; | 334 | a2vdd-supply = <&buck5_reg>; |
| 327 | adi,input-style = <1>; | 335 | v3p3-supply = <®_vddext_3v3>; |
| 328 | adi,input-justification = "evenly"; | 336 | v1p2-supply = <&buck5_reg>; |
| 329 | 337 | ||
| 330 | ports { | 338 | ports { |
| 331 | #address-cells = <1>; | 339 | #address-cells = <1>; |
| @@ -334,7 +342,7 @@ · 2 unmodified lines | |||
| 334 | port@0 { | 342 | port@0 { |
| 335 | reg = <0>; | 343 | reg = <0>; |
| 336 | 344 | ||
| 337 | adv7533_in: endpoint { | 345 | adv7535_in: endpoint { |
| 338 | remote-endpoint = <&dsi_out>; | 346 | remote-endpoint = <&dsi_out>; |
| 339 | }; | 347 | }; |
| 340 | }; | 348 | }; |
| @@ -342,7 +350,7 @@ · 1 unmodified line | |||
| 342 | port@1 { | 350 | port@1 { |
| 343 | reg = <1>; | 351 | reg = <1>; |
| 344 | 352 | ||
| 345 | adv7533_out: endpoint { | 353 | adv7535_out: endpoint { |
| 346 | remote-endpoint = <&hdmi_connector_in>; | 354 | remote-endpoint = <&hdmi_connector_in>; |
| 347 | }; | 355 | }; |
| 348 | }; | 356 | }; |
| @@ -448,7 +456,7 @@ · 99 unmodified lines | |||
| 448 | reg = <1>; | 456 | reg = <1>; |
| 449 | 457 | ||
| 450 | dsi_out: endpoint { | 458 | dsi_out: endpoint { |
| 451 | remote-endpoint = <&adv7533_in>; | 459 | remote-endpoint = <&adv7535_in>; |
| 452 | data-lanes = <1 2 3 4>; | 460 | data-lanes = <1 2 3 4>; |
| 453 | }; | 461 | }; |
| 454 | }; | 462 | }; |
| @@ -381,9 +381,10 @@ · 380 unmodified lines | |||
| 381 | &sai3 { | 381 | &sai3 { |
| 382 | pinctrl-names = "default"; | 382 | pinctrl-names = "default"; |
| 383 | pinctrl-0 = <&pinctrl_sai3>; | 383 | pinctrl-0 = <&pinctrl_sai3>; |
| 384 | assigned-clocks = <&clk IMX8MP_CLK_SAI3>; | 384 | assigned-clocks = <&clk IMX8MP_CLK_SAI3>, |
| 385 | <&clk IMX8MP_AUDIO_PLL2> ; | ||
| 385 | assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; | 386 | assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; |
| 386 | assigned-clock-rates = <12288000>; | 387 | assigned-clock-rates = <12288000>, <361267200>; |
| 387 | fsl,sai-mclk-direction-output; | 388 | fsl,sai-mclk-direction-output; |
| 388 | status = "okay"; | 389 | status = "okay"; |
| 389 | }; | 390 | }; |
| @@ -790,6 +790,12 @@ · 789 unmodified lines | |||
| 790 | reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>; | 790 | reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>; |
| 791 | clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>, | 791 | clocks = <&clk IMX8MP_CLK_AUDIO_ROOT>, |
| 792 | <&clk IMX8MP_CLK_AUDIO_AXI>; | 792 | <&clk IMX8MP_CLK_AUDIO_AXI>; |
| 793 | assigned-clocks = <&clk IMX8MP_CLK_AUDIO_AHB>, | ||
| 794 | <&clk IMX8MP_CLK_AUDIO_AXI_SRC>; | ||
| 795 | assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>, | ||
| 796 | <&clk IMX8MP_SYS_PLL1_800M>; | ||
| 797 | assigned-clock-rates = <400000000>, | ||
| 798 | <600000000>; | ||
| 793 | }; | 799 | }; |
| 794 | 800 | ||
| 795 | pgc_gpu2d: power-domain@6 { | 801 | pgc_gpu2d: power-domain@6 { |
| @@ -81,7 +81,7 @@ · 80 unmodified lines | |||
| 81 | &gpio1 { | 81 | &gpio1 { |
| 82 | pmic-irq-hog { | 82 | pmic-irq-hog { |
| 83 | gpio-hog; | 83 | gpio-hog; |
| 84 | gpios = <2 GPIO_ACTIVE_LOW>; | 84 | gpios = <3 GPIO_ACTIVE_LOW>; |
| 85 | input; | 85 | input; |
| 86 | line-name = "PMIC_IRQ#"; | 86 | line-name = "PMIC_IRQ#"; |
| 87 | }; | 87 | }; |
| @@ -2957,7 +2957,7 @@ · 2956 unmodified lines | |||
| 2957 | clock-names = "merge","merge_async"; | 2957 | clock-names = "merge","merge_async"; |
| 2958 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2958 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2959 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>; | 2959 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>; |
| 2960 | mediatek,merge-mute = <1>; | 2960 | mediatek,merge-mute; |
| 2961 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>; | 2961 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>; |
| 2962 | }; | 2962 | }; |
| 2963 | 2963 | ||
| @@ -2970,7 +2970,7 @@ · 6 unmodified lines | |||
| 2970 | clock-names = "merge","merge_async"; | 2970 | clock-names = "merge","merge_async"; |
| 2971 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2971 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2972 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>; | 2972 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>; |
| 2973 | mediatek,merge-mute = <1>; | 2973 | mediatek,merge-mute; |
| 2974 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>; | 2974 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>; |
| 2975 | }; | 2975 | }; |
| 2976 | 2976 | ||
| @@ -2983,7 +2983,7 @@ · 6 unmodified lines | |||
| 2983 | clock-names = "merge","merge_async"; | 2983 | clock-names = "merge","merge_async"; |
| 2984 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2984 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2985 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>; | 2985 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>; |
| 2986 | mediatek,merge-mute = <1>; | 2986 | mediatek,merge-mute; |
| 2987 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>; | 2987 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>; |
| 2988 | }; | 2988 | }; |
| 2989 | 2989 | ||
| @@ -2996,7 +2996,7 @@ · 6 unmodified lines | |||
| 2996 | clock-names = "merge","merge_async"; | 2996 | clock-names = "merge","merge_async"; |
| 2997 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 2997 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 2998 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>; | 2998 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>; |
| 2999 | mediatek,merge-mute = <1>; | 2999 | mediatek,merge-mute; |
| 3000 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>; | 3000 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>; |
| 3001 | }; | 3001 | }; |
| 3002 | 3002 | ||
| @@ -3009,7 +3009,7 @@ · 6 unmodified lines | |||
| 3009 | clock-names = "merge","merge_async"; | 3009 | clock-names = "merge","merge_async"; |
| 3010 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; | 3010 | power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; |
| 3011 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>; | 3011 | mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>; |
| 3012 | mediatek,merge-fifo-en = <1>; | 3012 | mediatek,merge-fifo-en; |
| 3013 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; | 3013 | resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>; |
| 3014 | }; | 3014 | }; |
| 3015 | 3015 | ||
| @@ -636,6 +636,7 @@ CONFIG_POWER_RESET_MSM=y · 635 unmodified lines | |||
| 636 | CONFIG_POWER_RESET_QCOM_PON=m | 636 | CONFIG_POWER_RESET_QCOM_PON=m |
| 637 | CONFIG_POWER_RESET_XGENE=y | 637 | CONFIG_POWER_RESET_XGENE=y |
| 638 | CONFIG_POWER_RESET_SYSCON=y | 638 | CONFIG_POWER_RESET_SYSCON=y |
| 639 | CONFIG_POWER_RESET_SYSCON_POWEROFF=y | ||
| 639 | CONFIG_SYSCON_REBOOT_MODE=y | 640 | CONFIG_SYSCON_REBOOT_MODE=y |
| 640 | CONFIG_NVMEM_REBOOT_MODE=m | 641 | CONFIG_NVMEM_REBOOT_MODE=m |
| 641 | CONFIG_BATTERY_SBS=m | 642 | CONFIG_BATTERY_SBS=m |
| @@ -1175,7 +1176,6 @@ CONFIG_COMMON_CLK_S2MPS11=y · 533 unmodified lines | |||
| 1175 | CONFIG_COMMON_CLK_PWM=y | 1176 | CONFIG_COMMON_CLK_PWM=y |
| 1176 | CONFIG_COMMON_CLK_RS9_PCIE=y | 1177 | CONFIG_COMMON_CLK_RS9_PCIE=y |
| 1177 | CONFIG_COMMON_CLK_VC5=y | 1178 | CONFIG_COMMON_CLK_VC5=y |
| 1178 | CONFIG_COMMON_CLK_NPCM8XX=y | ||
| 1179 | CONFIG_COMMON_CLK_BD718XX=m | 1179 | CONFIG_COMMON_CLK_BD718XX=m |
| 1180 | CONFIG_CLK_RASPBERRYPI=m | 1180 | CONFIG_CLK_RASPBERRYPI=m |
| 1181 | CONFIG_CLK_IMX8MM=y | 1181 | CONFIG_CLK_IMX8MM=y |
| @@ -663,7 +663,7 @@ static inline bool supports_clearbhb(int scope) · 662 unmodified lines | |||
| 663 | isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); | 663 | isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); |
| 664 | 664 | ||
| 665 | return cpuid_feature_extract_unsigned_field(isar2, | 665 | return cpuid_feature_extract_unsigned_field(isar2, |
| 666 | ID_AA64ISAR2_EL1_BC_SHIFT); | 666 | ID_AA64ISAR2_EL1_CLRBHB_SHIFT); |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | const struct cpumask *system_32bit_el0_cpumask(void); | 669 | const struct cpumask *system_32bit_el0_cpumask(void); |
| @@ -28,7 +28,7 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags); · 27 unmodified lines | |||
| 28 | #define arch_make_huge_pte arch_make_huge_pte | 28 | #define arch_make_huge_pte arch_make_huge_pte |
| 29 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 29 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 30 | extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 30 | extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 31 | pte_t *ptep, pte_t pte); | 31 | pte_t *ptep, pte_t pte, unsigned long sz); |
| 32 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS | 32 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS |
| 33 | extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, | 33 | extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, |
| 34 | unsigned long addr, pte_t *ptep, | 34 | unsigned long addr, pte_t *ptep, |
| @@ -118,7 +118,7 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu); · 117 unmodified lines | |||
| 118 | 118 | ||
| 119 | u64 __guest_enter(struct kvm_vcpu *vcpu); | 119 | u64 __guest_enter(struct kvm_vcpu *vcpu); |
| 120 | 120 | ||
| 121 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt); | 121 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id); |
| 122 | 122 | ||
| 123 | #ifdef __KVM_NVHE_HYPERVISOR__ | 123 | #ifdef __KVM_NVHE_HYPERVISOR__ |
| 124 | void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, | 124 | void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, |
| @@ -222,7 +222,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { · 221 unmodified lines | |||
| 222 | static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { | 222 | static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { |
| 223 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0), | 223 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0), |
| 224 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), | 224 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), |
| 225 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), | 225 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0), |
| 226 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), | ||
| 226 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0), | 227 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0), |
| 227 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), | 228 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), |
| 228 | FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), | 229 | FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), |
| @@ -12,6 +12,6 @@ · 11 unmodified lines | |||
| 12 | #define FFA_MAX_FUNC_NUM 0x7F | 12 | #define FFA_MAX_FUNC_NUM 0x7F |
| 13 | 13 | ||
| 14 | int hyp_ffa_init(void *pages); | 14 | int hyp_ffa_init(void *pages); |
| 15 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt); | 15 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id); |
| 16 | 16 | ||
| 17 | #endif /* __KVM_HYP_FFA_H */ | 17 | #endif /* __KVM_HYP_FFA_H */ |
| @@ -634,9 +634,8 @@ out_handled: · 633 unmodified lines | |||
| 634 | return true; | 634 | return true; |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt) | 637 | bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) |
| 638 | { | 638 | { |
| 639 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 640 | struct arm_smccc_res res; | 639 | struct arm_smccc_res res; |
| 641 | 640 | ||
| 642 | /* | 641 | /* |
| @@ -57,6 +57,7 @@ __do_hyp_init: · 56 unmodified lines | |||
| 57 | cmp x0, #HVC_STUB_HCALL_NR | 57 | cmp x0, #HVC_STUB_HCALL_NR |
| 58 | b.lo __kvm_handle_stub_hvc | 58 | b.lo __kvm_handle_stub_hvc |
| 59 | 59 | ||
| 60 | bic x0, x0, #ARM_SMCCC_CALL_HINTS | ||
| 60 | mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) | 61 | mov x3, #KVM_HOST_SMCCC_FUNC(__kvm_hyp_init) |
| 61 | cmp x0, x3 | 62 | cmp x0, x3 |
| 62 | b.eq 1f | 63 | b.eq 1f |
| @@ -368,6 +368,7 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) · 367 unmodified lines | |||
| 368 | if (static_branch_unlikely(&kvm_protected_mode_initialized)) | 368 | if (static_branch_unlikely(&kvm_protected_mode_initialized)) |
| 369 | hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize; | 369 | hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize; |
| 370 | 370 | ||
| 371 | id &= ~ARM_SMCCC_CALL_HINTS; | ||
| 371 | id -= KVM_HOST_SMCCC_ID(0); | 372 | id -= KVM_HOST_SMCCC_ID(0); |
| 372 | 373 | ||
| 373 | if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall))) | 374 | if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall))) |
| @@ -392,11 +393,14 @@ static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) · 18 unmodified lines | |||
| 392 | 393 | ||
| 393 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) | 394 | static void handle_host_smc(struct kvm_cpu_context *host_ctxt) |
| 394 | { | 395 | { |
| 396 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 395 | bool handled; | 397 | bool handled; |
| 396 | 398 | ||
| 397 | handled = kvm_host_psci_handler(host_ctxt); | 399 | func_id &= ~ARM_SMCCC_CALL_HINTS; |
| 400 | |||
| 401 | handled = kvm_host_psci_handler(host_ctxt, func_id); | ||
| 398 | if (!handled) | 402 | if (!handled) |
| 399 | handled = kvm_host_ffa_handler(host_ctxt); | 403 | handled = kvm_host_ffa_handler(host_ctxt, func_id); |
| 400 | if (!handled) | 404 | if (!handled) |
| 401 | default_host_smc_handler(host_ctxt); | 405 | default_host_smc_handler(host_ctxt); |
| 402 | 406 | ||
| @@ -273,9 +273,8 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ · 272 unmodified lines | |||
| 273 | } | 273 | } |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt) | 276 | bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id) |
| 277 | { | 277 | { |
| 278 | DECLARE_REG(u64, func_id, host_ctxt, 0); | ||
| 279 | unsigned long ret; | 278 | unsigned long ret; |
| 280 | 279 | ||
| 281 | switch (kvm_host_psci_config.version) { | 280 | switch (kvm_host_psci_config.version) { |
| @@ -652,6 +652,9 @@ int hyp_alloc_private_va_range(size_t size, unsigned long *haddr) · 651 unmodified lines | |||
| 652 | 652 | ||
| 653 | mutex_unlock(&kvm_hyp_pgd_mutex); | 653 | mutex_unlock(&kvm_hyp_pgd_mutex); |
| 654 | 654 | ||
| 655 | if (!ret) | ||
| 656 | *haddr = base; | ||
| 657 | |||
| 655 | return ret; | 658 | return ret; |
| 656 | } | 659 | } |
| 657 | 660 | ||
| @@ -241,15 +241,8 @@ static void clear_flush(struct mm_struct *mm, · 240 unmodified lines | |||
| 241 | flush_tlb_range(&vma, saddr, addr); | 241 | flush_tlb_range(&vma, saddr, addr); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry) | ||
| 245 | { | ||
| 246 | VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry)); | ||
| 247 | |||
| 248 | return page_folio(pfn_to_page(swp_offset_pfn(entry))); | ||
| 249 | } | ||
| 250 | |||
| 251 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 244 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 252 | pte_t *ptep, pte_t pte) | 245 | pte_t *ptep, pte_t pte, unsigned long sz) |
| 253 | { | 246 | { |
| 254 | size_t pgsize; | 247 | size_t pgsize; |
| 255 | int i; | 248 | int i; |
| @@ -257,13 +250,10 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 1 unmodified line | |||
| 257 | unsigned long pfn, dpfn; | 250 | unsigned long pfn, dpfn; |
| 258 | pgprot_t hugeprot; | 251 | pgprot_t hugeprot; |
| 259 | 252 | ||
| 260 | if (!pte_present(pte)) { | 253 | ncontig = num_contig_ptes(sz, &pgsize); |
| 261 | struct folio *folio; | ||
| 262 | |||
| 263 | folio = hugetlb_swap_entry_to_folio(pte_to_swp_entry(pte)); | ||
| 264 | ncontig = num_contig_ptes(folio_size(folio), &pgsize); | ||
| 265 | 254 | ||
| 266 | for (i = 0; i < ncontig; i++, ptep++) | 255 | if (!pte_present(pte)) { |
| 256 | for (i = 0; i < ncontig; i++, ptep++, addr += pgsize) | ||
| 267 | set_pte_at(mm, addr, ptep, pte); | 257 | set_pte_at(mm, addr, ptep, pte); |
| 268 | return; | 258 | return; |
| 269 | } | 259 | } |
| @@ -273,7 +263,6 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 3 unmodified lines | |||
| 273 | return; | 263 | return; |
| 274 | } | 264 | } |
| 275 | 265 | ||
| 276 | ncontig = find_num_contig(mm, addr, ptep, &pgsize); | ||
| 277 | pfn = pte_pfn(pte); | 266 | pfn = pte_pfn(pte); |
| 278 | dpfn = pgsize >> PAGE_SHIFT; | 267 | dpfn = pgsize >> PAGE_SHIFT; |
| 279 | hugeprot = pte_pgprot(pte); | 268 | hugeprot = pte_pgprot(pte); |
| @@ -571,5 +560,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr · 291 unmodified lines | |||
| 571 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, | 560 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, |
| 572 | pte_t old_pte, pte_t pte) | 561 | pte_t old_pte, pte_t pte) |
| 573 | { | 562 | { |
| 574 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 563 | unsigned long psize = huge_page_size(hstate_vma(vma)); |
| 564 | |||
| 565 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); | ||
| 575 | } | 566 | } |
| @@ -1347,7 +1347,11 @@ UnsignedEnum 51:48 RPRFM · 1346 unmodified lines | |||
| 1347 | 0b0000 NI | 1347 | 0b0000 NI |
| 1348 | 0b0001 IMP | 1348 | 0b0001 IMP |
| 1349 | EndEnum | 1349 | EndEnum |
| 1350 | Res0 47:28 | 1350 | Res0 47:32 |
| 1351 | UnsignedEnum 31:28 CLRBHB | ||
| 1352 | 0b0000 NI | ||
| 1353 | 0b0001 IMP | ||
| 1354 | EndEnum | ||
| 1351 | UnsignedEnum 27:24 PAC_frac | 1355 | UnsignedEnum 27:24 PAC_frac |
| 1352 | 0b0000 NI | 1356 | 0b0000 NI |
| 1353 | 0b0001 IMP | 1357 | 0b0001 IMP |
| @@ -907,3 +907,7 @@ EXPORT_SYMBOL(acpi_unregister_ioapic); · 906 unmodified lines | |||
| 907 | * TBD when IA64 starts to support suspend... | 907 | * TBD when IA64 starts to support suspend... |
| 908 | */ | 908 | */ |
| 909 | int acpi_suspend_lowlevel(void) { return 0; } | 909 | int acpi_suspend_lowlevel(void) { return 0; } |
| 910 | |||
| 911 | void acpi_proc_quirk_mwait_check(void) | ||
| 912 | { | ||
| 913 | } | ||
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 19 | */ | 19 | */ |
| 20 | #ifndef __ASSEMBLY__ | 20 | #ifndef __ASSEMBLY__ |
| 21 | #ifndef PHYS_OFFSET | 21 | #ifndef PHYS_OFFSET |
| 22 | #define PHYS_OFFSET _AC(0, UL) | 22 | #define PHYS_OFFSET _UL(0) |
| 23 | #endif | 23 | #endif |
| 24 | extern unsigned long vm_map_base; | 24 | extern unsigned long vm_map_base; |
| 25 | #endif /* __ASSEMBLY__ */ | 25 | #endif /* __ASSEMBLY__ */ |
| @@ -43,7 +43,7 @@ extern unsigned long vm_map_base; · 17 unmodified lines | |||
| 43 | * Memory above this physical address will be considered highmem. | 43 | * Memory above this physical address will be considered highmem. |
| 44 | */ | 44 | */ |
| 45 | #ifndef HIGHMEM_START | 45 | #ifndef HIGHMEM_START |
| 46 | #define HIGHMEM_START (_AC(1, UL) << _AC(DMW_PABITS, UL)) | 46 | #define HIGHMEM_START (_UL(1) << _UL(DMW_PABITS)) |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) | 49 | #define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) |
| @@ -65,16 +65,16 @@ extern unsigned long vm_map_base; · 15 unmodified lines | |||
| 65 | #define _ATYPE_ | 65 | #define _ATYPE_ |
| 66 | #define _ATYPE32_ | 66 | #define _ATYPE32_ |
| 67 | #define _ATYPE64_ | 67 | #define _ATYPE64_ |
| 68 | #define _CONST64_(x) x | ||
| 69 | #else | 68 | #else |
| 70 | #define _ATYPE_ __PTRDIFF_TYPE__ | 69 | #define _ATYPE_ __PTRDIFF_TYPE__ |
| 71 | #define _ATYPE32_ int | 70 | #define _ATYPE32_ int |
| 72 | #define _ATYPE64_ __s64 | 71 | #define _ATYPE64_ __s64 |
| 72 | #endif | ||
| 73 | |||
| 73 | #ifdef CONFIG_64BIT | 74 | #ifdef CONFIG_64BIT |
| 74 | #define _CONST64_(x) x ## UL | 75 | #define _CONST64_(x) _UL(x) |
| 75 | #else | 76 | #else |
| 76 | #define _CONST64_(x) x ## ULL | 77 | #define _CONST64_(x) _ULL(x) |
| 77 | #endif | ||
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | /* | 80 | /* |
| @@ -111,6 +111,15 @@ · 110 unmodified lines | |||
| 111 | #define R_LARCH_TLS_GD_HI20 98 | 111 | #define R_LARCH_TLS_GD_HI20 98 |
| 112 | #define R_LARCH_32_PCREL 99 | 112 | #define R_LARCH_32_PCREL 99 |
| 113 | #define R_LARCH_RELAX 100 | 113 | #define R_LARCH_RELAX 100 |
| 114 | #define R_LARCH_DELETE 101 | ||
| 115 | #define R_LARCH_ALIGN 102 | ||
| 116 | #define R_LARCH_PCREL20_S2 103 | ||
| 117 | #define R_LARCH_CFA 104 | ||
| 118 | #define R_LARCH_ADD6 105 | ||
| 119 | #define R_LARCH_SUB6 106 | ||
| 120 | #define R_LARCH_ADD_ULEB128 107 | ||
| 121 | #define R_LARCH_SUB_ULEB128 108 | ||
| 122 | #define R_LARCH_64_PCREL 109 | ||
| 114 | 123 | ||
| 115 | #ifndef ELF_ARCH | 124 | #ifndef ELF_ARCH |
| 116 | 125 | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | |||
| 3 | #ifndef __ASM_EXCEPTION_H | ||
| 4 | #define __ASM_EXCEPTION_H | ||
| 5 | |||
| 6 | #include <asm/ptrace.h> | ||
| 7 | #include <linux/kprobes.h> | ||
| 8 | |||
| 9 | void show_registers(struct pt_regs *regs); | ||
| 10 | |||
| 11 | asmlinkage void cache_parity_error(void); | ||
| 12 | asmlinkage void noinstr do_ade(struct pt_regs *regs); | ||
| 13 | asmlinkage void noinstr do_ale(struct pt_regs *regs); | ||
| 14 | asmlinkage void noinstr do_bce(struct pt_regs *regs); | ||
| 15 | asmlinkage void noinstr do_bp(struct pt_regs *regs); | ||
| 16 | asmlinkage void noinstr do_ri(struct pt_regs *regs); | ||
| 17 | asmlinkage void noinstr do_fpu(struct pt_regs *regs); | ||
| 18 | asmlinkage void noinstr do_fpe(struct pt_regs *regs, unsigned long fcsr); | ||
| 19 | asmlinkage void noinstr do_lsx(struct pt_regs *regs); | ||
| 20 | asmlinkage void noinstr do_lasx(struct pt_regs *regs); | ||
| 21 | asmlinkage void noinstr do_lbt(struct pt_regs *regs); | ||
| 22 | asmlinkage void noinstr do_watch(struct pt_regs *regs); | ||
| 23 | asmlinkage void noinstr do_syscall(struct pt_regs *regs); | ||
| 24 | asmlinkage void noinstr do_reserved(struct pt_regs *regs); | ||
| 25 | asmlinkage void noinstr do_vint(struct pt_regs *regs, unsigned long sp); | ||
| 26 | asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | ||
| 27 | unsigned long write, unsigned long address); | ||
| 28 | |||
| 29 | asmlinkage void handle_ade(void); | ||
| 30 | asmlinkage void handle_ale(void); | ||
| 31 | asmlinkage void handle_bce(void); | ||
| 32 | asmlinkage void handle_sys(void); | ||
| 33 | asmlinkage void handle_bp(void); | ||
| 34 | asmlinkage void handle_ri(void); | ||
| 35 | asmlinkage void handle_fpu(void); | ||
| 36 | asmlinkage void handle_fpe(void); | ||
| 37 | asmlinkage void handle_lsx(void); | ||
| 38 | asmlinkage void handle_lasx(void); | ||
| 39 | asmlinkage void handle_lbt(void); | ||
| 40 | asmlinkage void handle_watch(void); | ||
| 41 | asmlinkage void handle_reserved(void); | ||
| 42 | asmlinkage void handle_vint(void); | ||
| 43 | asmlinkage void noinstr handle_loongarch_irq(struct pt_regs *regs); | ||
| 44 | |||
| 45 | #endif /* __ASM_EXCEPTION_H */ | ||
| @@ -10,8 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include <asm/io.h> | 10 | #include <asm/io.h> |
| 11 | #include <asm/pgtable.h> | 11 | #include <asm/pgtable.h> |
| 12 | 12 | ||
| 13 | #define __HAVE_ARCH_SHADOW_MAP | ||
| 14 | |||
| 15 | #define KASAN_SHADOW_SCALE_SHIFT 3 | 13 | #define KASAN_SHADOW_SCALE_SHIFT 3 |
| 16 | #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) | 14 | #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL) |
| 17 | 15 | ||
| @@ -62,61 +60,22 @@ · 44 unmodified lines | |||
| 62 | extern bool kasan_early_stage; | 60 | extern bool kasan_early_stage; |
| 63 | extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; | 61 | extern unsigned char kasan_early_shadow_page[PAGE_SIZE]; |
| 64 | 62 | ||
| 63 | #define kasan_mem_to_shadow kasan_mem_to_shadow | ||
| 64 | void *kasan_mem_to_shadow(const void *addr); | ||
| 65 | |||
| 66 | #define kasan_shadow_to_mem kasan_shadow_to_mem | ||
| 67 | const void *kasan_shadow_to_mem(const void *shadow_addr); | ||
| 68 | |||
| 65 | #define kasan_arch_is_ready kasan_arch_is_ready | 69 | #define kasan_arch_is_ready kasan_arch_is_ready |
| 66 | static __always_inline bool kasan_arch_is_ready(void) | 70 | static __always_inline bool kasan_arch_is_ready(void) |
| 67 | { | 71 | { |
| 68 | return !kasan_early_stage; | 72 | return !kasan_early_stage; |
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | static inline void *kasan_mem_to_shadow(const void *addr) | 75 | #define addr_has_metadata addr_has_metadata |
| 72 | { | 76 | static __always_inline bool addr_has_metadata(const void *addr) |
| 73 | if (!kasan_arch_is_ready()) { | ||
| 74 | return (void *)(kasan_early_shadow_page); | ||
| 75 | } else { | ||
| 76 | unsigned long maddr = (unsigned long)addr; | ||
| 77 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; | ||
| 78 | unsigned long offset = 0; | ||
| 79 | |||
| 80 | maddr &= XRANGE_SHADOW_MASK; | ||
| 81 | switch (xrange) { | ||
| 82 | case XKPRANGE_CC_SEG: | ||
| 83 | offset = XKPRANGE_CC_SHADOW_OFFSET; | ||
| 84 | break; | ||
| 85 | case XKPRANGE_UC_SEG: | ||
| 86 | offset = XKPRANGE_UC_SHADOW_OFFSET; | ||
| 87 | break; | ||
| 88 | case XKVRANGE_VC_SEG: | ||
| 89 | offset = XKVRANGE_VC_SHADOW_OFFSET; | ||
| 90 | break; | ||
| 91 | default: | ||
| 92 | WARN_ON(1); | ||
| 93 | return NULL; | ||
| 94 | } | ||
| 95 | |||
| 96 | return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | static inline const void *kasan_shadow_to_mem(const void *shadow_addr) | ||
| 101 | { | 77 | { |
| 102 | unsigned long addr = (unsigned long)shadow_addr; | 78 | return (kasan_mem_to_shadow((void *)addr) != NULL); |
| 103 | |||
| 104 | if (unlikely(addr > KASAN_SHADOW_END) || | ||
| 105 | unlikely(addr < KASAN_SHADOW_START)) { | ||
| 106 | WARN_ON(1); | ||
| 107 | return NULL; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (addr >= XKVRANGE_VC_SHADOW_OFFSET) | ||
| 111 | return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START); | ||
| 112 | else if (addr >= XKPRANGE_UC_SHADOW_OFFSET) | ||
| 113 | return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START); | ||
| 114 | else if (addr >= XKPRANGE_CC_SHADOW_OFFSET) | ||
| 115 | return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START); | ||
| 116 | else { | ||
| 117 | WARN_ON(1); | ||
| 118 | return NULL; | ||
| 119 | } | ||
| 120 | } | 79 | } |
| 121 | 80 | ||
| 122 | void kasan_init(void); | 81 | void kasan_init(void); |
| @@ -70,6 +70,7 @@ struct secondary_data { · 69 unmodified lines | |||
| 70 | extern struct secondary_data cpuboot_data; | 70 | extern struct secondary_data cpuboot_data; |
| 71 | 71 | ||
| 72 | extern asmlinkage void smpboot_entry(void); | 72 | extern asmlinkage void smpboot_entry(void); |
| 73 | extern asmlinkage void start_secondary(void); | ||
| 73 | 74 | ||
| 74 | extern void calculate_cpu_foreign_map(void); | 75 | extern void calculate_cpu_foreign_map(void); |
| 75 | 76 | ||
| @@ -19,6 +19,10 @@ obj-$(CONFIG_CPU_HAS_LBT) += lbt.o · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o | 20 | obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o |
| 21 | 21 | ||
| 22 | CFLAGS_module.o += $(call cc-option,-Wno-override-init,) | ||
| 23 | CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,) | ||
| 24 | CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,) | ||
| 25 | |||
| 22 | ifdef CONFIG_FUNCTION_TRACER | 26 | ifdef CONFIG_FUNCTION_TRACER |
| 23 | ifndef CONFIG_DYNAMIC_FTRACE | 27 | ifndef CONFIG_DYNAMIC_FTRACE |
| 24 | obj-y += mcount.o ftrace.o | 28 | obj-y += mcount.o ftrace.o |
| @@ -281,7 +281,6 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) · 280 unmodified lines | |||
| 281 | pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node); | 281 | pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | void __init acpi_numa_arch_fixup(void) {} | ||
| 285 | #endif | 284 | #endif |
| 286 | 285 | ||
| 287 | void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) | 286 | void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) |
| @@ -50,7 +50,6 @@ void __init memblock_init(void) · 49 unmodified lines | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | memblock_set_current_limit(PFN_PHYS(max_low_pfn)); | 52 | memblock_set_current_limit(PFN_PHYS(max_low_pfn)); |
| 53 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); | ||
| 54 | 53 | ||
| 55 | /* Reserve the first 2MB */ | 54 | /* Reserve the first 2MB */ |
| 56 | memblock_reserve(PHYS_OFFSET, 0x200000); | 55 | memblock_reserve(PHYS_OFFSET, 0x200000); |
| @@ -58,4 +57,7 @@ void __init memblock_init(void) · 1 unmodified line | |||
| 58 | /* Reserve the kernel text/data/bss */ | 57 | /* Reserve the kernel text/data/bss */ |
| 59 | memblock_reserve(__pa_symbol(&_text), | 58 | memblock_reserve(__pa_symbol(&_text), |
| 60 | __pa_symbol(&_end) - __pa_symbol(&_text)); | 59 | __pa_symbol(&_end) - __pa_symbol(&_text)); |
| 60 | |||
| 61 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); | ||
| 62 | memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0); | ||
| 61 | } | 63 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/elf.h> | 6 | #include <linux/elf.h> |
| 7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/moduleloader.h> | ||
| 9 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
| 10 | 11 | ||
| 11 | Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) | 12 | Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) |
| @@ -367,6 +367,24 @@ static int apply_r_larch_got_pc(struct module *mod, · 366 unmodified lines | |||
| 367 | return apply_r_larch_pcala(mod, location, got, rela_stack, rela_stack_top, type); | 367 | return apply_r_larch_pcala(mod, location, got, rela_stack, rela_stack_top, type); |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v, | ||
| 371 | s64 *rela_stack, size_t *rela_stack_top, unsigned int type) | ||
| 372 | { | ||
| 373 | ptrdiff_t offset = (void *)v - (void *)location; | ||
| 374 | |||
| 375 | *(u32 *)location = offset; | ||
| 376 | return 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v, | ||
| 380 | s64 *rela_stack, size_t *rela_stack_top, unsigned int type) | ||
| 381 | { | ||
| 382 | ptrdiff_t offset = (void *)v - (void *)location; | ||
| 383 | |||
| 384 | *(u64 *)location = offset; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 370 | /* | 388 | /* |
| 371 | * reloc_handlers_rela() - Apply a particular relocation to a module | 389 | * reloc_handlers_rela() - Apply a particular relocation to a module |
| 372 | * @mod: the module to apply the reloc to | 390 | * @mod: the module to apply the reloc to |
| @@ -382,7 +400,7 @@ typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v, · 9 unmodified lines | |||
| 382 | 400 | ||
| 383 | /* The handlers for known reloc types */ | 401 | /* The handlers for known reloc types */ |
| 384 | static reloc_rela_handler reloc_rela_handlers[] = { | 402 | static reloc_rela_handler reloc_rela_handlers[] = { |
| 385 | [R_LARCH_NONE ... R_LARCH_RELAX] = apply_r_larch_error, | 403 | [R_LARCH_NONE ... R_LARCH_64_PCREL] = apply_r_larch_error, |
| 386 | 404 | ||
| 387 | [R_LARCH_NONE] = apply_r_larch_none, | 405 | [R_LARCH_NONE] = apply_r_larch_none, |
| 388 | [R_LARCH_32] = apply_r_larch_32, | 406 | [R_LARCH_32] = apply_r_larch_32, |
| @@ -396,6 +414,8 @@ static reloc_rela_handler reloc_rela_handlers[] = { · 7 unmodified lines | |||
| 396 | [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, | 414 | [R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field, |
| 397 | [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, | 415 | [R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub, |
| 398 | [R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, | 416 | [R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala, |
| 417 | [R_LARCH_32_PCREL] = apply_r_larch_32_pcrel, | ||
| 418 | [R_LARCH_64_PCREL] = apply_r_larch_64_pcrel, | ||
| 399 | }; | 419 | }; |
| 400 | 420 | ||
| 401 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, | 421 | int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, |
| @@ -436,7 +436,7 @@ void __init paging_init(void) · 435 unmodified lines | |||
| 436 | 436 | ||
| 437 | void __init mem_init(void) | 437 | void __init mem_init(void) |
| 438 | { | 438 | { |
| 439 | high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); | 439 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
| 440 | memblock_free_all(); | 440 | memblock_free_all(); |
| 441 | } | 441 | } |
| 442 | 442 | ||
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <asm/bootinfo.h> | 37 | #include <asm/bootinfo.h> |
| 38 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
| 39 | #include <asm/elf.h> | 39 | #include <asm/elf.h> |
| 40 | #include <asm/exec.h> | ||
| 40 | #include <asm/fpu.h> | 41 | #include <asm/fpu.h> |
| 41 | #include <asm/lbt.h> | 42 | #include <asm/lbt.h> |
| 42 | #include <asm/io.h> | 43 | #include <asm/io.h> |
| @@ -72,7 +72,6 @@ copy_word: · 71 unmodified lines | |||
| 72 | LONG_ADDI s5, s5, -1 | 72 | LONG_ADDI s5, s5, -1 |
| 73 | beqz s5, process_entry | 73 | beqz s5, process_entry |
| 74 | b copy_word | 74 | b copy_word |
| 75 | b process_entry | ||
| 76 | 75 | ||
| 77 | done: | 76 | done: |
| 78 | ibar 0 | 77 | ibar 0 |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/audit.h> | 13 | #include <linux/audit.h> |
| 14 | #include <linux/cache.h> | 14 | #include <linux/cache.h> |
| 15 | #include <linux/context_tracking.h> | 15 | #include <linux/context_tracking.h> |
| 16 | #include <linux/entry-common.h> | ||
| 16 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
| 17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 18 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
| @@ -891,8 +892,8 @@ static unsigned long setup_extcontext(struct extctx_layout *extctx, unsigned lon · 872 unmodified lines | |||
| 891 | return new_sp; | 892 | return new_sp; |
| 892 | } | 893 | } |
| 893 | 894 | ||
| 894 | void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, | 895 | static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, |
| 895 | struct extctx_layout *extctx) | 896 | struct extctx_layout *extctx) |
| 896 | { | 897 | { |
| 897 | unsigned long sp; | 898 | unsigned long sp; |
| 898 | 899 | ||
| @@ -922,7 +923,7 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, · 23 unmodified lines | |||
| 922 | * Atomically swap in the new signal mask, and wait for a signal. | 923 | * Atomically swap in the new signal mask, and wait for a signal. |
| 923 | */ | 924 | */ |
| 924 | 925 | ||
| 925 | asmlinkage long sys_rt_sigreturn(void) | 926 | SYSCALL_DEFINE0(rt_sigreturn) |
| 926 | { | 927 | { |
| 927 | int sig; | 928 | int sig; |
| 928 | sigset_t set; | 929 | sigset_t set; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/cpumask.h> | 13 | #include <linux/cpumask.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
| 16 | #include <linux/profile.h> | ||
| 16 | #include <linux/seq_file.h> | 17 | #include <linux/seq_file.h> |
| 17 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
| 18 | #include <linux/threads.h> | 19 | #include <linux/threads.h> |
| @@ -556,10 +557,12 @@ void smp_send_stop(void) · 537 unmodified lines | |||
| 556 | smp_call_function(stop_this_cpu, NULL, 0); | 557 | smp_call_function(stop_this_cpu, NULL, 0); |
| 557 | } | 558 | } |
| 558 | 559 | ||
| 560 | #ifdef CONFIG_PROFILING | ||
| 559 | int setup_profiling_timer(unsigned int multiplier) | 561 | int setup_profiling_timer(unsigned int multiplier) |
| 560 | { | 562 | { |
| 561 | return 0; | 563 | return 0; |
| 562 | } | 564 | } |
| 565 | #endif | ||
| 563 | 566 | ||
| 564 | static void flush_tlb_all_ipi(void *info) | 567 | static void flush_tlb_all_ipi(void *info) |
| 565 | { | 568 | { |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/unistd.h> | 13 | #include <linux/unistd.h> |
| 14 | 14 | ||
| 15 | #include <asm/asm.h> | 15 | #include <asm/asm.h> |
| 16 | #include <asm/exception.h> | ||
| 16 | #include <asm/signal.h> | 17 | #include <asm/signal.h> |
| 17 | #include <asm/switch_to.h> | 18 | #include <asm/switch_to.h> |
| 18 | #include <asm-generic/syscalls.h> | 19 | #include <asm-generic/syscalls.h> |
| @@ -29,7 +29,7 @@ static void constant_event_handler(struct clock_event_device *dev) · 28 unmodified lines | |||
| 29 | { | 29 | { |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | irqreturn_t constant_timer_interrupt(int irq, void *data) | 32 | static irqreturn_t constant_timer_interrupt(int irq, void *data) |
| 33 | { | 33 | { |
| 34 | int cpu = smp_processor_id(); | 34 | int cpu = smp_processor_id(); |
| 35 | struct clock_event_device *cd; | 35 | struct clock_event_device *cd; |
| @@ -1,4 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/acpi.h> | ||
| 2 | #include <linux/cpu.h> | 3 | #include <linux/cpu.h> |
| 3 | #include <linux/cpumask.h> | 4 | #include <linux/cpumask.h> |
| 4 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| @@ -7,6 +8,8 @@ · 2 unmodified lines | |||
| 7 | #include <linux/percpu.h> | 8 | #include <linux/percpu.h> |
| 8 | #include <asm/bootinfo.h> | 9 | #include <asm/bootinfo.h> |
| 9 | 10 | ||
| 11 | #include <acpi/processor.h> | ||
| 12 | |||
| 10 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 13 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |
| 11 | 14 | ||
| 12 | #ifdef CONFIG_HOTPLUG_CPU | 15 | #ifdef CONFIG_HOTPLUG_CPU |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
| 26 | #include <linux/kgdb.h> | 26 | #include <linux/kgdb.h> |
| 27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
| 28 | #include <linux/kprobes.h> | ||
| 29 | #include <linux/notifier.h> | 28 | #include <linux/notifier.h> |
| 30 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
| 31 | #include <linux/perf_event.h> | 30 | #include <linux/perf_event.h> |
| @@ -35,6 +34,7 @@ · 3 unmodified lines | |||
| 35 | #include <asm/branch.h> | 34 | #include <asm/branch.h> |
| 36 | #include <asm/break.h> | 35 | #include <asm/break.h> |
| 37 | #include <asm/cpu.h> | 36 | #include <asm/cpu.h> |
| 37 | #include <asm/exception.h> | ||
| 38 | #include <asm/fpu.h> | 38 | #include <asm/fpu.h> |
| 39 | #include <asm/lbt.h> | 39 | #include <asm/lbt.h> |
| 40 | #include <asm/inst.h> | 40 | #include <asm/inst.h> |
| @@ -53,21 +53,6 @@ · 12 unmodified lines | |||
| 53 | 53 | ||
| 54 | #include "access-helper.h" | 54 | #include "access-helper.h" |
| 55 | 55 | ||
| 56 | extern asmlinkage void handle_ade(void); | ||
| 57 | extern asmlinkage void handle_ale(void); | ||
| 58 | extern asmlinkage void handle_bce(void); | ||
| 59 | extern asmlinkage void handle_sys(void); | ||
| 60 | extern asmlinkage void handle_bp(void); | ||
| 61 | extern asmlinkage void handle_ri(void); | ||
| 62 | extern asmlinkage void handle_fpu(void); | ||
| 63 | extern asmlinkage void handle_fpe(void); | ||
| 64 | extern asmlinkage void handle_lbt(void); | ||
| 65 | extern asmlinkage void handle_lsx(void); | ||
| 66 | extern asmlinkage void handle_lasx(void); | ||
| 67 | extern asmlinkage void handle_reserved(void); | ||
| 68 | extern asmlinkage void handle_watch(void); | ||
| 69 | extern asmlinkage void handle_vint(void); | ||
| 70 | |||
| 71 | static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, | 56 | static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, |
| 72 | const char *loglvl, bool user) | 57 | const char *loglvl, bool user) |
| 73 | { | 58 | { |
| @@ -439,8 +424,8 @@ static inline void setup_vint_size(unsigned int size) · 365 unmodified lines | |||
| 439 | * happen together with Overflow or Underflow, and `ptrace' can set | 424 | * happen together with Overflow or Underflow, and `ptrace' can set |
| 440 | * any bits. | 425 | * any bits. |
| 441 | */ | 426 | */ |
| 442 | void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr, | 427 | static void force_fcsr_sig(unsigned long fcsr, |
| 443 | struct task_struct *tsk) | 428 | void __user *fault_addr, struct task_struct *tsk) |
| 444 | { | 429 | { |
| 445 | int si_code = FPE_FLTUNK; | 430 | int si_code = FPE_FLTUNK; |
| 446 | 431 | ||
| @@ -458,7 +443,7 @@ void force_fcsr_sig(unsigned long fcsr, void __user *fault_addr, · 11 unmodified lines | |||
| 458 | force_sig_fault(SIGFPE, si_code, fault_addr); | 443 | force_sig_fault(SIGFPE, si_code, fault_addr); |
| 459 | } | 444 | } |
| 460 | 445 | ||
| 461 | int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr) | 446 | static int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcsr) |
| 462 | { | 447 | { |
| 463 | int si_code; | 448 | int si_code; |
| 464 | 449 | ||
| @@ -824,7 +809,7 @@ out: · 359 unmodified lines | |||
| 824 | asmlinkage void noinstr do_ri(struct pt_regs *regs) | 809 | asmlinkage void noinstr do_ri(struct pt_regs *regs) |
| 825 | { | 810 | { |
| 826 | int status = SIGILL; | 811 | int status = SIGILL; |
| 827 | unsigned int opcode = 0; | 812 | unsigned int __maybe_unused opcode; |
| 828 | unsigned int __user *era = (unsigned int __user *)exception_era(regs); | 813 | unsigned int __user *era = (unsigned int __user *)exception_era(regs); |
| 829 | irqentry_state_t state = irqentry_enter(regs); | 814 | irqentry_state_t state = irqentry_enter(regs); |
| 830 | 815 | ||
| @@ -53,33 +53,6 @@ SECTIONS · 52 unmodified lines | |||
| 53 | . = ALIGN(PECOFF_SEGMENT_ALIGN); | 53 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 54 | _etext = .; | 54 | _etext = .; |
| 55 | 55 | ||
| 56 | /* | ||
| 57 | * struct alt_inst entries. From the header (alternative.h): | ||
| 58 | * "Alternative instructions for different CPU types or capabilities" | ||
| 59 | * Think locking instructions on spinlocks. | ||
| 60 | */ | ||
| 61 | . = ALIGN(4); | ||
| 62 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { | ||
| 63 | __alt_instructions = .; | ||
| 64 | *(.altinstructions) | ||
| 65 | __alt_instructions_end = .; | ||
| 66 | } | ||
| 67 | |||
| 68 | #ifdef CONFIG_RELOCATABLE | ||
| 69 | . = ALIGN(8); | ||
| 70 | .la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) { | ||
| 71 | __la_abs_begin = .; | ||
| 72 | *(.la_abs) | ||
| 73 | __la_abs_end = .; | ||
| 74 | } | ||
| 75 | #endif | ||
| 76 | |||
| 77 | .got : ALIGN(16) { *(.got) } | ||
| 78 | .plt : ALIGN(16) { *(.plt) } | ||
| 79 | .got.plt : ALIGN(16) { *(.got.plt) } | ||
| 80 | |||
| 81 | .data.rel : { *(.data.rel*) } | ||
| 82 | |||
| 83 | . = ALIGN(PECOFF_SEGMENT_ALIGN); | 56 | . = ALIGN(PECOFF_SEGMENT_ALIGN); |
| 84 | __init_begin = .; | 57 | __init_begin = .; |
| 85 | __inittext_begin = .; | 58 | __inittext_begin = .; |
| @@ -94,6 +67,18 @@ SECTIONS · 8 unmodified lines | |||
| 94 | 67 | ||
| 95 | __initdata_begin = .; | 68 | __initdata_begin = .; |
| 96 | 69 | ||
| 70 | /* | ||
| 71 | * struct alt_inst entries. From the header (alternative.h): | ||
| 72 | * "Alternative instructions for different CPU types or capabilities" | ||
| 73 | * Think locking instructions on spinlocks. | ||
| 74 | */ | ||
| 75 | . = ALIGN(4); | ||
| 76 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { | ||
| 77 | __alt_instructions = .; | ||
| 78 | *(.altinstructions) | ||
| 79 | __alt_instructions_end = .; | ||
| 80 | } | ||
| 81 | |||
| 97 | INIT_DATA_SECTION(16) | 82 | INIT_DATA_SECTION(16) |
| 98 | .exit.data : { | 83 | .exit.data : { |
| 99 | EXIT_DATA | 84 | EXIT_DATA |
| @@ -113,6 +98,11 @@ SECTIONS · 13 unmodified lines | |||
| 113 | 98 | ||
| 114 | _sdata = .; | 99 | _sdata = .; |
| 115 | RO_DATA(4096) | 100 | RO_DATA(4096) |
| 101 | |||
| 102 | .got : ALIGN(16) { *(.got) } | ||
| 103 | .plt : ALIGN(16) { *(.plt) } | ||
| 104 | .got.plt : ALIGN(16) { *(.got.plt) } | ||
| 105 | |||
| 116 | RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) | 106 | RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) |
| 117 | 107 | ||
| 118 | .rela.dyn : ALIGN(8) { | 108 | .rela.dyn : ALIGN(8) { |
| @@ -121,6 +111,17 @@ SECTIONS · 2 unmodified lines | |||
| 121 | __rela_dyn_end = .; | 111 | __rela_dyn_end = .; |
| 122 | } | 112 | } |
| 123 | 113 | ||
| 114 | .data.rel : { *(.data.rel*) } | ||
| 115 | |||
| 116 | #ifdef CONFIG_RELOCATABLE | ||
| 117 | . = ALIGN(8); | ||
| 118 | .la_abs : AT(ADDR(.la_abs) - LOAD_OFFSET) { | ||
| 119 | __la_abs_begin = .; | ||
| 120 | *(.la_abs) | ||
| 121 | __la_abs_end = .; | ||
| 122 | } | ||
| 123 | #endif | ||
| 124 | |||
| 124 | .sdata : { | 125 | .sdata : { |
| 125 | *(.sdata) | 126 | *(.sdata) |
| 126 | } | 127 | } |
| @@ -20,12 +20,12 @@ · 19 unmodified lines | |||
| 20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/kdebug.h> | 22 | #include <linux/kdebug.h> |
| 23 | #include <linux/kprobes.h> | ||
| 24 | #include <linux/perf_event.h> | 23 | #include <linux/perf_event.h> |
| 25 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
| 26 | #include <linux/kfence.h> | 25 | #include <linux/kfence.h> |
| 27 | 26 | ||
| 28 | #include <asm/branch.h> | 27 | #include <asm/branch.h> |
| 28 | #include <asm/exception.h> | ||
| 29 | #include <asm/mmu_context.h> | 29 | #include <asm/mmu_context.h> |
| 30 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
| 31 | 31 | ||
| @@ -50,18 +50,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, · 49 unmodified lines | |||
| 50 | return (pte_t *) pmd; | 50 | return (pte_t *) pmd; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | /* | ||
| 54 | * This function checks for proper alignment of input addr and len parameters. | ||
| 55 | */ | ||
| 56 | int is_aligned_hugepage_range(unsigned long addr, unsigned long len) | ||
| 57 | { | ||
| 58 | if (len & ~HPAGE_MASK) | ||
| 59 | return -EINVAL; | ||
| 60 | if (addr & ~HPAGE_MASK) | ||
| 61 | return -EINVAL; | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | int pmd_huge(pmd_t pmd) | 53 | int pmd_huge(pmd_t pmd) |
| 66 | { | 54 | { |
| 67 | return (pmd_val(pmd) & _PAGE_HUGE) != 0; | 55 | return (pmd_val(pmd) & _PAGE_HUGE) != 0; |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <asm/io.h> | 6 | #include <asm/io.h> |
| 7 | #include <asm-generic/early_ioremap.h> | ||
| 7 | 8 | ||
| 8 | void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size) | 9 | void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size) |
| 9 | { | 10 | { |
| @@ -35,6 +35,57 @@ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | bool kasan_early_stage = true; | 36 | bool kasan_early_stage = true; |
| 37 | 37 | ||
| 38 | void *kasan_mem_to_shadow(const void *addr) | ||
| 39 | { | ||
| 40 | if (!kasan_arch_is_ready()) { | ||
| 41 | return (void *)(kasan_early_shadow_page); | ||
| 42 | } else { | ||
| 43 | unsigned long maddr = (unsigned long)addr; | ||
| 44 | unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; | ||
| 45 | unsigned long offset = 0; | ||
| 46 | |||
| 47 | maddr &= XRANGE_SHADOW_MASK; | ||
| 48 | switch (xrange) { | ||
| 49 | case XKPRANGE_CC_SEG: | ||
| 50 | offset = XKPRANGE_CC_SHADOW_OFFSET; | ||
| 51 | break; | ||
| 52 | case XKPRANGE_UC_SEG: | ||
| 53 | offset = XKPRANGE_UC_SHADOW_OFFSET; | ||
| 54 | break; | ||
| 55 | case XKVRANGE_VC_SEG: | ||
| 56 | offset = XKVRANGE_VC_SHADOW_OFFSET; | ||
| 57 | break; | ||
| 58 | default: | ||
| 59 | WARN_ON(1); | ||
| 60 | return NULL; | ||
| 61 | } | ||
| 62 | |||
| 63 | return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | const void *kasan_shadow_to_mem(const void *shadow_addr) | ||
| 68 | { | ||
| 69 | unsigned long addr = (unsigned long)shadow_addr; | ||
| 70 | |||
| 71 | if (unlikely(addr > KASAN_SHADOW_END) || | ||
| 72 | unlikely(addr < KASAN_SHADOW_START)) { | ||
| 73 | WARN_ON(1); | ||
| 74 | return NULL; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (addr >= XKVRANGE_VC_SHADOW_OFFSET) | ||
| 78 | return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START); | ||
| 79 | else if (addr >= XKPRANGE_UC_SHADOW_OFFSET) | ||
| 80 | return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START); | ||
| 81 | else if (addr >= XKPRANGE_CC_SHADOW_OFFSET) | ||
| 82 | return (void *)(((addr - XKPRANGE_CC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_CC_START); | ||
| 83 | else { | ||
| 84 | WARN_ON(1); | ||
| 85 | return NULL; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 38 | /* | 89 | /* |
| 39 | * Alloc memory for shadow memory page table. | 90 | * Alloc memory for shadow memory page table. |
| 40 | */ | 91 | */ |
| @@ -261,7 +261,7 @@ unsigned long pcpu_handlers[NR_CPUS]; · 260 unmodified lines | |||
| 261 | #endif | 261 | #endif |
| 262 | extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; | 262 | extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; |
| 263 | 263 | ||
| 264 | void setup_tlb_handler(int cpu) | 264 | static void setup_tlb_handler(int cpu) |
| 265 | { | 265 | { |
| 266 | setup_ptwalker(); | 266 | setup_ptwalker(); |
| 267 | local_flush_tlb_all(); | 267 | local_flush_tlb_all(); |
| @@ -164,6 +164,7 @@ static struct platform_device db1x00_audio_dev = { · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | /******************************************************************************/ | 165 | /******************************************************************************/ |
| 166 | 166 | ||
| 167 | #ifdef CONFIG_MMC_AU1X | ||
| 167 | static irqreturn_t db1100_mmc_cd(int irq, void *ptr) | 168 | static irqreturn_t db1100_mmc_cd(int irq, void *ptr) |
| 168 | { | 169 | { |
| 169 | mmc_detect_change(ptr, msecs_to_jiffies(500)); | 170 | mmc_detect_change(ptr, msecs_to_jiffies(500)); |
| @@ -369,6 +370,7 @@ static struct platform_device db1100_mmc1_dev = { · 199 unmodified lines | |||
| 369 | .num_resources = ARRAY_SIZE(au1100_mmc1_res), | 370 | .num_resources = ARRAY_SIZE(au1100_mmc1_res), |
| 370 | .resource = au1100_mmc1_res, | 371 | .resource = au1100_mmc1_res, |
| 371 | }; | 372 | }; |
| 373 | #endif /* CONFIG_MMC_AU1X */ | ||
| 372 | 374 | ||
| 373 | /******************************************************************************/ | 375 | /******************************************************************************/ |
| 374 | 376 | ||
| @@ -440,8 +442,10 @@ static struct platform_device *db1x00_devs[] = { · 65 unmodified lines | |||
| 440 | 442 | ||
| 441 | static struct platform_device *db1100_devs[] = { | 443 | static struct platform_device *db1100_devs[] = { |
| 442 | &au1100_lcd_device, | 444 | &au1100_lcd_device, |
| 445 | #ifdef CONFIG_MMC_AU1X | ||
| 443 | &db1100_mmc0_dev, | 446 | &db1100_mmc0_dev, |
| 444 | &db1100_mmc1_dev, | 447 | &db1100_mmc1_dev, |
| 448 | #endif | ||
| 445 | }; | 449 | }; |
| 446 | 450 | ||
| 447 | int __init db1000_dev_setup(void) | 451 | int __init db1000_dev_setup(void) |
| @@ -326,6 +326,7 @@ static struct platform_device db1200_ide_dev = { · 325 unmodified lines | |||
| 326 | 326 | ||
| 327 | /**********************************************************************/ | 327 | /**********************************************************************/ |
| 328 | 328 | ||
| 329 | #ifdef CONFIG_MMC_AU1X | ||
| 329 | /* SD carddetects: they're supposed to be edge-triggered, but ack | 330 | /* SD carddetects: they're supposed to be edge-triggered, but ack |
| 330 | * doesn't seem to work (CPLD Rev 2). Instead, the screaming one | 331 | * doesn't seem to work (CPLD Rev 2). Instead, the screaming one |
| 331 | * is disabled and its counterpart enabled. The 200ms timeout is | 332 | * is disabled and its counterpart enabled. The 200ms timeout is |
| @@ -584,6 +585,7 @@ static struct platform_device pb1200_mmc1_dev = { · 252 unmodified lines | |||
| 584 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), | 585 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), |
| 585 | .resource = au1200_mmc1_res, | 586 | .resource = au1200_mmc1_res, |
| 586 | }; | 587 | }; |
| 588 | #endif /* CONFIG_MMC_AU1X */ | ||
| 587 | 589 | ||
| 588 | /**********************************************************************/ | 590 | /**********************************************************************/ |
| 589 | 591 | ||
| @@ -751,7 +753,9 @@ static struct platform_device db1200_audiodma_dev = { · 161 unmodified lines | |||
| 751 | static struct platform_device *db1200_devs[] __initdata = { | 753 | static struct platform_device *db1200_devs[] __initdata = { |
| 752 | NULL, /* PSC0, selected by S6.8 */ | 754 | NULL, /* PSC0, selected by S6.8 */ |
| 753 | &db1200_ide_dev, | 755 | &db1200_ide_dev, |
| 756 | #ifdef CONFIG_MMC_AU1X | ||
| 754 | &db1200_mmc0_dev, | 757 | &db1200_mmc0_dev, |
| 758 | #endif | ||
| 755 | &au1200_lcd_dev, | 759 | &au1200_lcd_dev, |
| 756 | &db1200_eth_dev, | 760 | &db1200_eth_dev, |
| 757 | &db1200_nand_dev, | 761 | &db1200_nand_dev, |
| @@ -762,7 +766,9 @@ static struct platform_device *db1200_devs[] __initdata = { · 4 unmodified lines | |||
| 762 | }; | 766 | }; |
| 763 | 767 | ||
| 764 | static struct platform_device *pb1200_devs[] __initdata = { | 768 | static struct platform_device *pb1200_devs[] __initdata = { |
| 769 | #ifdef CONFIG_MMC_AU1X | ||
| 765 | &pb1200_mmc1_dev, | 770 | &pb1200_mmc1_dev, |
| 771 | #endif | ||
| 766 | }; | 772 | }; |
| 767 | 773 | ||
| 768 | /* Some peripheral base addresses differ on the PB1200 */ | 774 | /* Some peripheral base addresses differ on the PB1200 */ |
| @@ -450,6 +450,7 @@ static struct platform_device db1300_ide_dev = { · 449 unmodified lines | |||
| 450 | 450 | ||
| 451 | /**********************************************************************/ | 451 | /**********************************************************************/ |
| 452 | 452 | ||
| 453 | #ifdef CONFIG_MMC_AU1X | ||
| 453 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) | 454 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) |
| 454 | { | 455 | { |
| 455 | disable_irq_nosync(irq); | 456 | disable_irq_nosync(irq); |
| @@ -632,6 +633,7 @@ static struct platform_device db1300_sd0_dev = { · 176 unmodified lines | |||
| 632 | .resource = au1300_sd0_res, | 633 | .resource = au1300_sd0_res, |
| 633 | .num_resources = ARRAY_SIZE(au1300_sd0_res), | 634 | .num_resources = ARRAY_SIZE(au1300_sd0_res), |
| 634 | }; | 635 | }; |
| 636 | #endif /* CONFIG_MMC_AU1X */ | ||
| 635 | 637 | ||
| 636 | /**********************************************************************/ | 638 | /**********************************************************************/ |
| 637 | 639 | ||
| @@ -767,8 +769,10 @@ static struct platform_device *db1300_dev[] __initdata = { · 129 unmodified lines | |||
| 767 | &db1300_5waysw_dev, | 769 | &db1300_5waysw_dev, |
| 768 | &db1300_nand_dev, | 770 | &db1300_nand_dev, |
| 769 | &db1300_ide_dev, | 771 | &db1300_ide_dev, |
| 772 | #ifdef CONFIG_MMC_AU1X | ||
| 770 | &db1300_sd0_dev, | 773 | &db1300_sd0_dev, |
| 771 | &db1300_sd1_dev, | 774 | &db1300_sd1_dev, |
| 775 | #endif | ||
| 772 | &db1300_lcd_dev, | 776 | &db1300_lcd_dev, |
| 773 | &db1300_ac97_dev, | 777 | &db1300_ac97_dev, |
| 774 | &db1300_i2s_dev, | 778 | &db1300_i2s_dev, |
| @@ -37,6 +37,7 @@ extern int split_tlb; · 36 unmodified lines | |||
| 37 | extern int dcache_stride; | 37 | extern int dcache_stride; |
| 38 | extern int icache_stride; | 38 | extern int icache_stride; |
| 39 | extern struct pdc_cache_info cache_info; | 39 | extern struct pdc_cache_info cache_info; |
| 40 | extern struct pdc_btlb_info btlb_info; | ||
| 40 | void parisc_setup_cache_timing(void); | 41 | void parisc_setup_cache_timing(void); |
| 41 | 42 | ||
| 42 | #define pdtlb(sr, addr) asm volatile("pdtlb 0(%%sr%0,%1)" \ | 43 | #define pdtlb(sr, addr) asm volatile("pdtlb 0(%%sr%0,%1)" \ |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 7 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 8 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 8 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 9 | pte_t *ptep, pte_t pte); | 9 | pte_t *ptep, pte_t pte, unsigned long sz); |
| 10 | 10 | ||
| 11 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 11 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| 12 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | 12 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, |
| @@ -1,8 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef ASM_PARISC_MCKINLEY_H | ||
| 3 | #define ASM_PARISC_MCKINLEY_H | ||
| 4 | |||
| 5 | /* declared in arch/parisc/kernel/setup.c */ | ||
| 6 | extern struct proc_dir_entry * proc_mckinley_root; | ||
| 7 | |||
| 8 | #endif /*ASM_PARISC_MCKINLEY_H*/ | ||
| @@ -44,10 +44,11 @@ int pdc_model_capabilities(unsigned long *capabilities); · 43 unmodified lines | |||
| 44 | int pdc_model_platform_info(char *orig_prod_num, char *current_prod_num, char *serial_no); | 44 | int pdc_model_platform_info(char *orig_prod_num, char *current_prod_num, char *serial_no); |
| 45 | int pdc_cache_info(struct pdc_cache_info *cache); | 45 | int pdc_cache_info(struct pdc_cache_info *cache); |
| 46 | int pdc_spaceid_bits(unsigned long *space_bits); | 46 | int pdc_spaceid_bits(unsigned long *space_bits); |
| 47 | #ifndef CONFIG_PA20 | ||
| 48 | int pdc_btlb_info(struct pdc_btlb_info *btlb); | 47 | int pdc_btlb_info(struct pdc_btlb_info *btlb); |
| 48 | int pdc_btlb_insert(unsigned long long vpage, unsigned long physpage, unsigned long len, | ||
| 49 | unsigned long entry_info, unsigned long slot); | ||
| 50 | int pdc_btlb_purge_all(void); | ||
| 49 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); | 51 | int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); |
| 50 | #endif /* !CONFIG_PA20 */ | ||
| 51 | int pdc_pim_toc11(struct pdc_toc_pim_11 *ret); | 52 | int pdc_pim_toc11(struct pdc_toc_pim_11 *ret); |
| 52 | int pdc_pim_toc20(struct pdc_toc_pim_20 *ret); | 53 | int pdc_pim_toc20(struct pdc_toc_pim_20 *ret); |
| 53 | int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa); | 54 | int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa); |
| @@ -310,6 +310,7 @@ extern void do_syscall_trace_exit(struct pt_regs *); · 309 unmodified lines | |||
| 310 | struct seq_file; | 310 | struct seq_file; |
| 311 | extern void early_trap_init(void); | 311 | extern void early_trap_init(void); |
| 312 | extern void collect_boot_cpu_data(void); | 312 | extern void collect_boot_cpu_data(void); |
| 313 | extern void btlb_init_per_cpu(void); | ||
| 313 | extern int show_cpuinfo (struct seq_file *m, void *v); | 314 | extern int show_cpuinfo (struct seq_file *m, void *v); |
| 314 | 315 | ||
| 315 | /* driver code in driver/parisc */ | 316 | /* driver code in driver/parisc */ |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | struct ioc { | 29 | struct ioc { |
| 30 | void __iomem *ioc_hpa; /* I/O MMU base address */ | 30 | void __iomem *ioc_hpa; /* I/O MMU base address */ |
| 31 | char *res_map; /* resource map, bit == pdir entry */ | 31 | char *res_map; /* resource map, bit == pdir entry */ |
| 32 | u64 *pdir_base; /* physical base address */ | 32 | __le64 *pdir_base; /* physical base address */ |
| 33 | unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */ | 33 | unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */ |
| 34 | unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */ | 34 | unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */ |
| 35 | #ifdef ZX1_SUPPORT | 35 | #ifdef ZX1_SUPPORT |
| @@ -86,6 +86,9 @@ struct sba_device { · 50 unmodified lines | |||
| 86 | struct ioc ioc[MAX_IOC]; | 86 | struct ioc ioc[MAX_IOC]; |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | /* list of SBA's in system, see drivers/parisc/sba_iommu.c */ | ||
| 90 | extern struct sba_device *sba_list; | ||
| 91 | |||
| 89 | #define ASTRO_RUNWAY_PORT 0x582 | 92 | #define ASTRO_RUNWAY_PORT 0x582 |
| 90 | #define IKE_MERCED_PORT 0x803 | 93 | #define IKE_MERCED_PORT 0x803 |
| 91 | #define REO_MERCED_PORT 0x804 | 94 | #define REO_MERCED_PORT 0x804 |
| @@ -110,7 +113,7 @@ static inline int IS_PLUTO(struct parisc_device *d) { · 18 unmodified lines | |||
| 110 | 113 | ||
| 111 | #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL | 114 | #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL |
| 112 | 115 | ||
| 113 | #define SBA_AGPGART_COOKIE 0x0000badbadc0ffeeULL | 116 | #define SBA_AGPGART_COOKIE (__force __le64) 0x0000badbadc0ffeeULL |
| 114 | 117 | ||
| 115 | #define SBA_FUNC_ID 0x0000 /* function id */ | 118 | #define SBA_FUNC_ID 0x0000 /* function id */ |
| 116 | #define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */ | 119 | #define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */ |
| @@ -2,6 +2,21 @@ · 1 unmodified line | |||
| 2 | #ifndef _ASMPARISC_SHMPARAM_H | 2 | #ifndef _ASMPARISC_SHMPARAM_H |
| 3 | #define _ASMPARISC_SHMPARAM_H | 3 | #define _ASMPARISC_SHMPARAM_H |
| 4 | 4 | ||
| 5 | /* | ||
| 6 | * PA-RISC uses virtually indexed & physically tagged (VIPT) caches | ||
| 7 | * which has strict requirements when two pages to the same physical | ||
| 8 | * address are accessed through different mappings. Read the section | ||
| 9 | * "Address Aliasing" in the arch docs for more detail: | ||
| 10 | * PA-RISC 1.1 (page 3-6): | ||
| 11 | * https://parisc.wiki.kernel.org/images-parisc/6/68/Pa11_acd.pdf | ||
| 12 | * PA-RISC 2.0 (page F-5): | ||
| 13 | * https://parisc.wiki.kernel.org/images-parisc/7/73/Parisc2.0.pdf | ||
| 14 | * | ||
| 15 | * For Linux we allow kernel and userspace to map pages on page size | ||
| 16 | * granularity (SHMLBA) but have to ensure that, if two pages are | ||
| 17 | * mapped to the same physical address, the virtual and physical | ||
| 18 | * addresses modulo SHM_COLOUR are identical. | ||
| 19 | */ | ||
| 5 | #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ | 20 | #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ |
| 6 | #define SHM_COLOUR 0x00400000 /* shared mappings colouring */ | 21 | #define SHM_COLOUR 0x00400000 /* shared mappings colouring */ |
| 7 | 22 | ||
| @@ -275,6 +275,8 @@ int main(void) · 274 unmodified lines | |||
| 275 | * and kernel data on physical huge pages */ | 275 | * and kernel data on physical huge pages */ |
| 276 | #ifdef CONFIG_HUGETLB_PAGE | 276 | #ifdef CONFIG_HUGETLB_PAGE |
| 277 | DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT); | 277 | DEFINE(HUGEPAGE_SIZE, 1UL << REAL_HPAGE_SHIFT); |
| 278 | #elif !defined(CONFIG_64BIT) | ||
| 279 | DEFINE(HUGEPAGE_SIZE, 4*1024*1024); | ||
| 278 | #else | 280 | #else |
| 279 | DEFINE(HUGEPAGE_SIZE, PAGE_SIZE); | 281 | DEFINE(HUGEPAGE_SIZE, PAGE_SIZE); |
| 280 | #endif | 282 | #endif |
| @@ -58,7 +58,7 @@ int pa_serialize_tlb_flushes __ro_after_init; · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | struct pdc_cache_info cache_info __ro_after_init; | 59 | struct pdc_cache_info cache_info __ro_after_init; |
| 60 | #ifndef CONFIG_PA20 | 60 | #ifndef CONFIG_PA20 |
| 61 | static struct pdc_btlb_info btlb_info __ro_after_init; | 61 | struct pdc_btlb_info btlb_info __ro_after_init; |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | DEFINE_STATIC_KEY_TRUE(parisc_has_cache); | 64 | DEFINE_STATIC_KEY_TRUE(parisc_has_cache); |
| @@ -264,12 +264,6 @@ parisc_cache_init(void) · 199 unmodified lines | |||
| 264 | icache_stride = CAFL_STRIDE(cache_info.ic_conf); | 264 | icache_stride = CAFL_STRIDE(cache_info.ic_conf); |
| 265 | #undef CAFL_STRIDE | 265 | #undef CAFL_STRIDE |
| 266 | 266 | ||
| 267 | #ifndef CONFIG_PA20 | ||
| 268 | if (pdc_btlb_info(&btlb_info) < 0) { | ||
| 269 | memset(&btlb_info, 0, sizeof btlb_info); | ||
| 270 | } | ||
| 271 | #endif | ||
| 272 | |||
| 273 | if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == | 267 | if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == |
| 274 | PDC_MODEL_NVA_UNSUPPORTED) { | 268 | PDC_MODEL_NVA_UNSUPPORTED) { |
| 275 | printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n"); | 269 | printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n"); |
| @@ -925,9 +925,9 @@ static __init void qemu_header(void) · 924 unmodified lines | |||
| 925 | pr_info("#define PARISC_MODEL \"%s\"\n\n", | 925 | pr_info("#define PARISC_MODEL \"%s\"\n\n", |
| 926 | boot_cpu_data.pdc.sys_model_name); | 926 | boot_cpu_data.pdc.sys_model_name); |
| 927 | 927 | ||
| 928 | #define p ((unsigned long *)&boot_cpu_data.pdc.model) | ||
| 928 | pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " | 929 | pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " |
| 929 | "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", | 930 | "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", |
| 930 | #define p ((unsigned long *)&boot_cpu_data.pdc.model) | ||
| 931 | p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); | 931 | p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); |
| 932 | #undef p | 932 | #undef p |
| 933 | 933 | ||
| @@ -687,7 +687,6 @@ int pdc_spaceid_bits(unsigned long *space_bits) · 686 unmodified lines | |||
| 687 | return retval; | 687 | return retval; |
| 688 | } | 688 | } |
| 689 | 689 | ||
| 690 | #ifndef CONFIG_PA20 | ||
| 691 | /** | 690 | /** |
| 692 | * pdc_btlb_info - Return block TLB information. | 691 | * pdc_btlb_info - Return block TLB information. |
| 693 | * @btlb: The return buffer. | 692 | * @btlb: The return buffer. |
| @@ -696,18 +695,51 @@ int pdc_spaceid_bits(unsigned long *space_bits) · 2 unmodified lines | |||
| 696 | */ | 695 | */ |
| 697 | int pdc_btlb_info(struct pdc_btlb_info *btlb) | 696 | int pdc_btlb_info(struct pdc_btlb_info *btlb) |
| 698 | { | 697 | { |
| 699 | int retval; | 698 | int retval; |
| 700 | unsigned long flags; | 699 | unsigned long flags; |
| 701 | 700 | ||
| 702 | spin_lock_irqsave(&pdc_lock, flags); | 701 | if (IS_ENABLED(CONFIG_PA20)) |
| 703 | retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0); | 702 | return PDC_BAD_PROC; |
| 704 | memcpy(btlb, pdc_result, sizeof(*btlb)); | ||
| 705 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 706 | 703 | ||
| 707 | if(retval < 0) { | 704 | spin_lock_irqsave(&pdc_lock, flags); |
| 708 | btlb->max_size = 0; | 705 | retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0); |
| 709 | } | 706 | memcpy(btlb, pdc_result, sizeof(*btlb)); |
| 710 | return retval; | 707 | spin_unlock_irqrestore(&pdc_lock, flags); |
| 708 | |||
| 709 | if(retval < 0) { | ||
| 710 | btlb->max_size = 0; | ||
| 711 | } | ||
| 712 | return retval; | ||
| 713 | } | ||
| 714 | |||
| 715 | int pdc_btlb_insert(unsigned long long vpage, unsigned long physpage, unsigned long len, | ||
| 716 | unsigned long entry_info, unsigned long slot) | ||
| 717 | { | ||
| 718 | int retval; | ||
| 719 | unsigned long flags; | ||
| 720 | |||
| 721 | if (IS_ENABLED(CONFIG_PA20)) | ||
| 722 | return PDC_BAD_PROC; | ||
| 723 | |||
| 724 | spin_lock_irqsave(&pdc_lock, flags); | ||
| 725 | retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INSERT, (unsigned long) (vpage >> 32), | ||
| 726 | (unsigned long) vpage, physpage, len, entry_info, slot); | ||
| 727 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 728 | return retval; | ||
| 729 | } | ||
| 730 | |||
| 731 | int pdc_btlb_purge_all(void) | ||
| 732 | { | ||
| 733 | int retval; | ||
| 734 | unsigned long flags; | ||
| 735 | |||
| 736 | if (IS_ENABLED(CONFIG_PA20)) | ||
| 737 | return PDC_BAD_PROC; | ||
| 738 | |||
| 739 | spin_lock_irqsave(&pdc_lock, flags); | ||
| 740 | retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_PURGE_ALL); | ||
| 741 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 742 | return retval; | ||
| 711 | } | 743 | } |
| 712 | 744 | ||
| 713 | /** | 745 | /** |
| @@ -728,6 +760,9 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address, · 14 unmodified lines | |||
| 728 | int retval; | 760 | int retval; |
| 729 | unsigned long flags; | 761 | unsigned long flags; |
| 730 | 762 | ||
| 763 | if (IS_ENABLED(CONFIG_PA20)) | ||
| 764 | return PDC_BAD_PROC; | ||
| 765 | |||
| 731 | spin_lock_irqsave(&pdc_lock, flags); | 766 | spin_lock_irqsave(&pdc_lock, flags); |
| 732 | memcpy(pdc_result2, mod_path, sizeof(*mod_path)); | 767 | memcpy(pdc_result2, mod_path, sizeof(*mod_path)); |
| 733 | retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result), | 768 | retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result), |
| @@ -737,7 +772,6 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address, · 3 unmodified lines | |||
| 737 | 772 | ||
| 738 | return retval; | 773 | return retval; |
| 739 | } | 774 | } |
| 740 | #endif /* !CONFIG_PA20 */ | ||
| 741 | 775 | ||
| 742 | /** | 776 | /** |
| 743 | * pdc_lan_station_id - Get the LAN address. | 777 | * pdc_lan_station_id - Get the LAN address. |
| @@ -180,10 +180,10 @@ $pgt_fill_loop: · 179 unmodified lines | |||
| 180 | std %dp,0x18(%r10) | 180 | std %dp,0x18(%r10) |
| 181 | #endif | 181 | #endif |
| 182 | 182 | ||
| 183 | #ifdef CONFIG_64BIT | ||
| 184 | /* Get PDCE_PROC for monarch CPU. */ | ||
| 185 | #define MEM_PDC_LO 0x388 | 183 | #define MEM_PDC_LO 0x388 |
| 186 | #define MEM_PDC_HI 0x35C | 184 | #define MEM_PDC_HI 0x35C |
| 185 | #ifdef CONFIG_64BIT | ||
| 186 | /* Get PDCE_PROC for monarch CPU. */ | ||
| 187 | ldw MEM_PDC_LO(%r0),%r3 | 187 | ldw MEM_PDC_LO(%r0),%r3 |
| 188 | ldw MEM_PDC_HI(%r0),%r10 | 188 | ldw MEM_PDC_HI(%r0),%r10 |
| 189 | depd %r10, 31, 32, %r3 /* move to upper word */ | 189 | depd %r10, 31, 32, %r3 /* move to upper word */ |
| @@ -269,7 +269,17 @@ stext_pdc_ret: · 79 unmodified lines | |||
| 269 | tovirt_r1 %r6 | 269 | tovirt_r1 %r6 |
| 270 | mtctl %r6,%cr30 /* restore task thread info */ | 270 | mtctl %r6,%cr30 /* restore task thread info */ |
| 271 | #endif | 271 | #endif |
| 272 | 272 | ||
| 273 | #ifndef CONFIG_64BIT | ||
| 274 | /* clear all BTLBs */ | ||
| 275 | ldi PDC_BLOCK_TLB,%arg0 | ||
| 276 | load32 PA(stext_pdc_btlb_ret), %rp | ||
| 277 | ldw MEM_PDC_LO(%r0),%r3 | ||
| 278 | bv (%r3) | ||
| 279 | ldi PDC_BTLB_PURGE_ALL,%arg1 | ||
| 280 | stext_pdc_btlb_ret: | ||
| 281 | #endif | ||
| 282 | |||
| 273 | /* PARANOID: clear user scratch/user space SR's */ | 283 | /* PARANOID: clear user scratch/user space SR's */ |
| 274 | mtsp %r0,%sr0 | 284 | mtsp %r0,%sr0 |
| 275 | mtsp %r0,%sr1 | 285 | mtsp %r0,%sr1 |
| @@ -365,7 +365,7 @@ union irq_stack_union { · 364 unmodified lines | |||
| 365 | volatile unsigned int lock[1]; | 365 | volatile unsigned int lock[1]; |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| 368 | DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { | 368 | static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { |
| 369 | .slock = { 1,1,1,1 }, | 369 | .slock = { 1,1,1,1 }, |
| 370 | }; | 370 | }; |
| 371 | #endif | 371 | #endif |
| @@ -368,6 +368,8 @@ int init_per_cpu(int cpunum) · 367 unmodified lines | |||
| 368 | /* FUTURE: Enable Performance Monitor : ccr bit 0x20 */ | 368 | /* FUTURE: Enable Performance Monitor : ccr bit 0x20 */ |
| 369 | init_percpu_prof(cpunum); | 369 | init_percpu_prof(cpunum); |
| 370 | 370 | ||
| 371 | btlb_init_per_cpu(); | ||
| 372 | |||
| 371 | return ret; | 373 | return ret; |
| 372 | } | 374 | } |
| 373 | 375 | ||
| @@ -154,6 +154,7 @@ SECTIONS · 153 unmodified lines | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /* End of data section */ | 156 | /* End of data section */ |
| 157 | . = ALIGN(PAGE_SIZE); | ||
| 157 | _edata = .; | 158 | _edata = .; |
| 158 | 159 | ||
| 159 | /* BSS */ | 160 | /* BSS */ |
| @@ -140,7 +140,7 @@ static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 139 unmodified lines | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 142 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 143 | pte_t *ptep, pte_t entry) | 143 | pte_t *ptep, pte_t entry, unsigned long sz) |
| 144 | { | 144 | { |
| 145 | __set_huge_pte_at(mm, addr, ptep, entry); | 145 | __set_huge_pte_at(mm, addr, ptep, entry); |
| 146 | } | 146 | } |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include <asm/sections.h> | 32 | #include <asm/sections.h> |
| 33 | #include <asm/msgbuf.h> | 33 | #include <asm/msgbuf.h> |
| 34 | #include <asm/sparsemem.h> | 34 | #include <asm/sparsemem.h> |
| 35 | #include <asm/asm-offsets.h> | ||
| 35 | 36 | ||
| 36 | extern int data_start; | 37 | extern int data_start; |
| 37 | extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ | 38 | extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ |
| @@ -720,6 +721,77 @@ void __init paging_init(void) · 682 unmodified lines | |||
| 720 | parisc_bootmem_free(); | 721 | parisc_bootmem_free(); |
| 721 | } | 722 | } |
| 722 | 723 | ||
| 724 | static void alloc_btlb(unsigned long start, unsigned long end, int *slot, | ||
| 725 | unsigned long entry_info) | ||
| 726 | { | ||
| 727 | const int slot_max = btlb_info.fixed_range_info.num_comb; | ||
| 728 | int min_num_pages = btlb_info.min_size; | ||
| 729 | unsigned long size; | ||
| 730 | |||
| 731 | /* map at minimum 4 pages */ | ||
| 732 | if (min_num_pages < 4) | ||
| 733 | min_num_pages = 4; | ||
| 734 | |||
| 735 | size = HUGEPAGE_SIZE; | ||
| 736 | while (start < end && *slot < slot_max && size >= PAGE_SIZE) { | ||
| 737 | /* starting address must have same alignment as size! */ | ||
| 738 | /* if correctly aligned and fits in double size, increase */ | ||
| 739 | if (((start & (2 * size - 1)) == 0) && | ||
| 740 | (end - start) >= (2 * size)) { | ||
| 741 | size <<= 1; | ||
| 742 | continue; | ||
| 743 | } | ||
| 744 | /* if current size alignment is too big, try smaller size */ | ||
| 745 | if ((start & (size - 1)) != 0) { | ||
| 746 | size >>= 1; | ||
| 747 | continue; | ||
| 748 | } | ||
| 749 | if ((end - start) >= size) { | ||
| 750 | if ((size >> PAGE_SHIFT) >= min_num_pages) | ||
| 751 | pdc_btlb_insert(start >> PAGE_SHIFT, __pa(start) >> PAGE_SHIFT, | ||
| 752 | size >> PAGE_SHIFT, entry_info, *slot); | ||
| 753 | (*slot)++; | ||
| 754 | start += size; | ||
| 755 | continue; | ||
| 756 | } | ||
| 757 | size /= 2; | ||
| 758 | continue; | ||
| 759 | } | ||
| 760 | } | ||
| 761 | |||
| 762 | void btlb_init_per_cpu(void) | ||
| 763 | { | ||
| 764 | unsigned long s, t, e; | ||
| 765 | int slot; | ||
| 766 | |||
| 767 | /* BTLBs are not available on 64-bit CPUs */ | ||
| 768 | if (IS_ENABLED(CONFIG_PA20)) | ||
| 769 | return; | ||
| 770 | else if (pdc_btlb_info(&btlb_info) < 0) { | ||
| 771 | memset(&btlb_info, 0, sizeof btlb_info); | ||
| 772 | } | ||
| 773 | |||
| 774 | /* insert BLTLBs for code and data segments */ | ||
| 775 | s = (uintptr_t) dereference_function_descriptor(&_stext); | ||
| 776 | e = (uintptr_t) dereference_function_descriptor(&_etext); | ||
| 777 | t = (uintptr_t) dereference_function_descriptor(&_sdata); | ||
| 778 | BUG_ON(t != e); | ||
| 779 | |||
| 780 | /* code segments */ | ||
| 781 | slot = 0; | ||
| 782 | alloc_btlb(s, e, &slot, 0x13800000); | ||
| 783 | |||
| 784 | /* sanity check */ | ||
| 785 | t = (uintptr_t) dereference_function_descriptor(&_edata); | ||
| 786 | e = (uintptr_t) dereference_function_descriptor(&__bss_start); | ||
| 787 | BUG_ON(t != e); | ||
| 788 | |||
| 789 | /* data segments */ | ||
| 790 | s = (uintptr_t) dereference_function_descriptor(&_sdata); | ||
| 791 | e = (uintptr_t) dereference_function_descriptor(&__bss_stop); | ||
| 792 | alloc_btlb(s, e, &slot, 0x11800000); | ||
| 793 | } | ||
| 794 | |||
| 723 | #ifdef CONFIG_PA20 | 795 | #ifdef CONFIG_PA20 |
| 724 | 796 | ||
| 725 | /* | 797 | /* |
| @@ -255,7 +255,7 @@ config PPC · 254 unmodified lines | |||
| 255 | select HAVE_KPROBES | 255 | select HAVE_KPROBES |
| 256 | select HAVE_KPROBES_ON_FTRACE | 256 | select HAVE_KPROBES_ON_FTRACE |
| 257 | select HAVE_KRETPROBES | 257 | select HAVE_KRETPROBES |
| 258 | select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT | 258 | select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT && (!ARCH_USING_PATCHABLE_FUNCTION_ENTRY || (!CC_IS_GCC || GCC_VERSION >= 110100)) |
| 259 | select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS | 259 | select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS |
| 260 | select HAVE_MOD_ARCH_SPECIFIC | 260 | select HAVE_MOD_ARCH_SPECIFIC |
| 261 | select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) | 261 | select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) |
| @@ -46,7 +46,8 @@ static inline int check_and_get_huge_psize(int shift) · 45 unmodified lines | |||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 48 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 49 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); | 49 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
| 50 | pte_t pte, unsigned long sz); | ||
| 50 | 51 | ||
| 51 | #define __HAVE_ARCH_HUGE_PTE_CLEAR | 52 | #define __HAVE_ARCH_HUGE_PTE_CLEAR |
| 52 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | 53 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, |
| @@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) · 229 unmodified lines | |||
| 230 | struct arch_hw_breakpoint *info; | 230 | struct arch_hw_breakpoint *info; |
| 231 | int i; | 231 | int i; |
| 232 | 232 | ||
| 233 | preempt_disable(); | ||
| 234 | |||
| 233 | for (i = 0; i < nr_wp_slots(); i++) { | 235 | for (i = 0; i < nr_wp_slots(); i++) { |
| 234 | struct perf_event *bp = __this_cpu_read(bp_per_reg[i]); | 236 | struct perf_event *bp = __this_cpu_read(bp_per_reg[i]); |
| 235 | 237 | ||
| 236 | if (unlikely(bp && counter_arch_bp(bp)->perf_single_step)) | 238 | if (unlikely(bp && counter_arch_bp(bp)->perf_single_step)) |
| 237 | goto reset; | 239 | goto reset; |
| 238 | } | 240 | } |
| 239 | return; | 241 | goto out; |
| 240 | 242 | ||
| 241 | reset: | 243 | reset: |
| 242 | regs_set_return_msr(regs, regs->msr & ~MSR_SE); | 244 | regs_set_return_msr(regs, regs->msr & ~MSR_SE); |
| @@ -245,6 +247,9 @@ reset: · 2 unmodified lines | |||
| 245 | __set_breakpoint(i, info); | 247 | __set_breakpoint(i, info); |
| 246 | info->perf_single_step = false; | 248 | info->perf_single_step = false; |
| 247 | } | 249 | } |
| 250 | |||
| 251 | out: | ||
| 252 | preempt_enable(); | ||
| 248 | } | 253 | } |
| 249 | 254 | ||
| 250 | static bool is_larx_stcx_instr(int type) | 255 | static bool is_larx_stcx_instr(int type) |
| @@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp, · 112 unmodified lines | |||
| 363 | } | 368 | } |
| 364 | } | 369 | } |
| 365 | 370 | ||
| 371 | /* | ||
| 372 | * Handle a DABR or DAWR exception. | ||
| 373 | * | ||
| 374 | * Called in atomic context. | ||
| 375 | */ | ||
| 366 | int hw_breakpoint_handler(struct die_args *args) | 376 | int hw_breakpoint_handler(struct die_args *args) |
| 367 | { | 377 | { |
| 368 | bool err = false; | 378 | bool err = false; |
| @@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler); · 121 unmodified lines | |||
| 490 | 500 | ||
| 491 | /* | 501 | /* |
| 492 | * Handle single-step exceptions following a DABR hit. | 502 | * Handle single-step exceptions following a DABR hit. |
| 503 | * | ||
| 504 | * Called in atomic context. | ||
| 493 | */ | 505 | */ |
| 494 | static int single_step_dabr_instruction(struct die_args *args) | 506 | static int single_step_dabr_instruction(struct die_args *args) |
| 495 | { | 507 | { |
| @@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction); · 45 unmodified lines | |||
| 541 | 553 | ||
| 542 | /* | 554 | /* |
| 543 | * Handle debug exception notifications. | 555 | * Handle debug exception notifications. |
| 556 | * | ||
| 557 | * Called in atomic context. | ||
| 544 | */ | 558 | */ |
| 545 | int hw_breakpoint_exceptions_notify( | 559 | int hw_breakpoint_exceptions_notify( |
| 546 | struct notifier_block *unused, unsigned long val, void *data) | 560 | struct notifier_block *unused, unsigned long val, void *data) |
| @@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr, · 130 unmodified lines | |||
| 131 | int *type, int *size, unsigned long *ea) | 131 | int *type, int *size, unsigned long *ea) |
| 132 | { | 132 | { |
| 133 | struct instruction_op op; | 133 | struct instruction_op op; |
| 134 | int err; | ||
| 134 | 135 | ||
| 135 | if (__get_user_instr(*instr, (void __user *)regs->nip)) | 136 | pagefault_disable(); |
| 137 | err = __get_user_instr(*instr, (void __user *)regs->nip); | ||
| 138 | pagefault_enable(); | ||
| 139 | |||
| 140 | if (err) | ||
| 136 | return; | 141 | return; |
| 137 | 142 | ||
| 138 | analyse_instr(&op, regs, *instr); | 143 | analyse_instr(&op, regs, *instr); |
| @@ -73,29 +73,12 @@ int __no_sanitize_address arch_stack_walk_reliable(stack_trace_consume_fn consum · 72 unmodified lines | |||
| 73 | bool firstframe; | 73 | bool firstframe; |
| 74 | 74 | ||
| 75 | stack_end = stack_page + THREAD_SIZE; | 75 | stack_end = stack_page + THREAD_SIZE; |
| 76 | if (!is_idle_task(task)) { | 76 | |
| 77 | /* | 77 | // See copy_thread() for details. |
| 78 | * For user tasks, this is the SP value loaded on | 78 | if (task->flags & PF_KTHREAD) |
| 79 | * kernel entry, see "PACAKSAVE(r13)" in _switch() and | ||
| 80 | * system_call_common(). | ||
| 81 | * | ||
| 82 | * Likewise for non-swapper kernel threads, | ||
| 83 | * this also happens to be the top of the stack | ||
| 84 | * as setup by copy_thread(). | ||
| 85 | * | ||
| 86 | * Note that stack backlinks are not properly setup by | ||
| 87 | * copy_thread() and thus, a forked task() will have | ||
| 88 | * an unreliable stack trace until it's been | ||
| 89 | * _switch()'ed to for the first time. | ||
| 90 | */ | ||
| 91 | stack_end -= STACK_USER_INT_FRAME_SIZE; | ||
| 92 | } else { | ||
| 93 | /* | ||
| 94 | * idle tasks have a custom stack layout, | ||
| 95 | * c.f. cpu_idle_thread_init(). | ||
| 96 | */ | ||
| 97 | stack_end -= STACK_FRAME_MIN_SIZE; | 79 | stack_end -= STACK_FRAME_MIN_SIZE; |
| 98 | } | 80 | else |
| 81 | stack_end -= STACK_USER_INT_FRAME_SIZE; | ||
| 99 | 82 | ||
| 100 | if (task == current) | 83 | if (task == current) |
| 101 | sp = current_stack_frame(); | 84 | sp = current_stack_frame(); |
| @@ -1512,23 +1512,11 @@ static void do_program_check(struct pt_regs *regs) · 1511 unmodified lines | |||
| 1512 | return; | 1512 | return; |
| 1513 | } | 1513 | } |
| 1514 | 1514 | ||
| 1515 | if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) { | 1515 | /* User mode considers other cases after enabling IRQs */ |
| 1516 | ppc_inst_t insn; | 1516 | if (!user_mode(regs)) { |
| 1517 | 1517 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | |
| 1518 | if (get_user_instr(insn, (void __user *)regs->nip)) { | 1518 | return; |
| 1519 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | ||
| 1520 | return; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | if (ppc_inst_primary_opcode(insn) == 31 && | ||
| 1524 | get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) { | ||
| 1525 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); | ||
| 1526 | return; | ||
| 1527 | } | ||
| 1528 | } | 1519 | } |
| 1529 | |||
| 1530 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | ||
| 1531 | return; | ||
| 1532 | } | 1520 | } |
| 1533 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1521 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 1534 | if (reason & REASON_TM) { | 1522 | if (reason & REASON_TM) { |
| @@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs) · 26 unmodified lines | |||
| 1561 | 1549 | ||
| 1562 | /* | 1550 | /* |
| 1563 | * If we took the program check in the kernel skip down to sending a | 1551 | * If we took the program check in the kernel skip down to sending a |
| 1564 | * SIGILL. The subsequent cases all relate to emulating instructions | 1552 | * SIGILL. The subsequent cases all relate to user space, such as |
| 1565 | * which we should only do for userspace. We also do not want to enable | 1553 | * emulating instructions which we should only do for user space. We |
| 1566 | * interrupts for kernel faults because that might lead to further | 1554 | * also do not want to enable interrupts for kernel faults because that |
| 1567 | * faults, and loose the context of the original exception. | 1555 | * might lead to further faults, and loose the context of the original |
| 1556 | * exception. | ||
| 1568 | */ | 1557 | */ |
| 1569 | if (!user_mode(regs)) | 1558 | if (!user_mode(regs)) |
| 1570 | goto sigill; | 1559 | goto sigill; |
| 1571 | 1560 | ||
| 1572 | interrupt_cond_local_irq_enable(regs); | 1561 | interrupt_cond_local_irq_enable(regs); |
| 1573 | 1562 | ||
| 1563 | /* | ||
| 1564 | * (reason & REASON_TRAP) is mostly handled before enabling IRQs, | ||
| 1565 | * except get_user_instr() can sleep so we cannot reliably inspect the | ||
| 1566 | * current instruction in that context. Now that we know we are | ||
| 1567 | * handling a user space trap and can sleep, we can check if the trap | ||
| 1568 | * was a hashchk failure. | ||
| 1569 | */ | ||
| 1570 | if (reason & REASON_TRAP) { | ||
| 1571 | if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) { | ||
| 1572 | ppc_inst_t insn; | ||
| 1573 | |||
| 1574 | if (get_user_instr(insn, (void __user *)regs->nip)) { | ||
| 1575 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | ||
| 1576 | return; | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | if (ppc_inst_primary_opcode(insn) == 31 && | ||
| 1580 | get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) { | ||
| 1581 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); | ||
| 1582 | return; | ||
| 1583 | } | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | ||
| 1587 | return; | ||
| 1588 | } | ||
| 1589 | |||
| 1574 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, | 1590 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, |
| 1575 | * but there seems to be a hardware bug on the 405GP (RevD) | 1591 | * but there seems to be a hardware bug on the 405GP (RevD) |
| 1576 | * that means ESR is sometimes set incorrectly - either to | 1592 | * that means ESR is sometimes set incorrectly - either to |
| @@ -143,11 +143,14 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, · 142 unmodified lines | |||
| 143 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, | 143 | void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, |
| 144 | pte_t *ptep, pte_t old_pte, pte_t pte) | 144 | pte_t *ptep, pte_t old_pte, pte_t pte) |
| 145 | { | 145 | { |
| 146 | unsigned long psize; | ||
| 146 | 147 | ||
| 147 | if (radix_enabled()) | 148 | if (radix_enabled()) |
| 148 | return radix__huge_ptep_modify_prot_commit(vma, addr, ptep, | 149 | return radix__huge_ptep_modify_prot_commit(vma, addr, ptep, |
| 149 | old_pte, pte); | 150 | old_pte, pte); |
| 150 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 151 | |
| 152 | psize = huge_page_size(hstate_vma(vma)); | ||
| 153 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); | ||
| 151 | } | 154 | } |
| 152 | 155 | ||
| 153 | void __init hugetlbpage_init_defaultsize(void) | 156 | void __init hugetlbpage_init_defaultsize(void) |
| @@ -47,6 +47,7 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 46 unmodified lines | |||
| 47 | pte_t old_pte, pte_t pte) | 47 | pte_t old_pte, pte_t pte) |
| 48 | { | 48 | { |
| 49 | struct mm_struct *mm = vma->vm_mm; | 49 | struct mm_struct *mm = vma->vm_mm; |
| 50 | unsigned long psize = huge_page_size(hstate_vma(vma)); | ||
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * POWER9 NMMU must flush the TLB after clearing the PTE before | 53 | * POWER9 NMMU must flush the TLB after clearing the PTE before |
| @@ -58,5 +59,5 @@ void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 5 unmodified lines | |||
| 58 | atomic_read(&mm->context.copros) > 0) | 59 | atomic_read(&mm->context.copros) > 0) |
| 59 | radix__flush_hugetlb_page(vma, addr); | 60 | radix__flush_hugetlb_page(vma, addr); |
| 60 | 61 | ||
| 61 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 62 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte, psize); |
| 62 | } | 63 | } |
| @@ -91,7 +91,8 @@ static int __ref __early_map_kernel_hugepage(unsigned long va, phys_addr_t pa, · 90 unmodified lines | |||
| 91 | if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot))) | 91 | if (new && WARN_ON(pte_present(*ptep) && pgprot_val(prot))) |
| 92 | return -EINVAL; | 92 | return -EINVAL; |
| 93 | 93 | ||
| 94 | set_huge_pte_at(&init_mm, va, ptep, pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot))); | 94 | set_huge_pte_at(&init_mm, va, ptep, |
| 95 | pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), psize); | ||
| 95 | 96 | ||
| 96 | return 0; | 97 | return 0; |
| 97 | } | 98 | } |
| @@ -288,7 +288,8 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 287 unmodified lines | |||
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | #if defined(CONFIG_PPC_8xx) | 290 | #if defined(CONFIG_PPC_8xx) |
| 291 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) | 291 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
| 292 | pte_t pte, unsigned long sz) | ||
| 292 | { | 293 | { |
| 293 | pmd_t *pmd = pmd_off(mm, addr); | 294 | pmd_t *pmd = pmd_off(mm, addr); |
| 294 | pte_basic_t val; | 295 | pte_basic_t val; |
| @@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event) · 1417 unmodified lines | |||
| 1418 | } | 1418 | } |
| 1419 | 1419 | ||
| 1420 | domain = event_get_domain(event); | 1420 | domain = event_get_domain(event); |
| 1421 | if (domain >= HV_PERF_DOMAIN_MAX) { | 1421 | if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { |
| 1422 | pr_devel("invalid domain %d\n", domain); | 1422 | pr_devel("invalid domain %d\n", domain); |
| 1423 | return -EINVAL; | 1423 | return -EINVAL; |
| 1424 | } | 1424 | } |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | menuconfig PPC_82xx | 2 | menuconfig PPC_82xx |
| 3 | bool "82xx-based boards (PQ II)" | 3 | bool "82xx-based boards (PQ II)" |
| 4 | depends on PPC_BOOK3S_32 | 4 | depends on PPC_BOOK3S_32 |
| 5 | select FSL_SOC | ||
| 5 | 6 | ||
| 6 | if PPC_82xx | 7 | if PPC_82xx |
| 7 | 8 | ||
| @@ -9,7 +10,6 @@ config EP8248E · 1 unmodified line | |||
| 9 | bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)" | 10 | bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)" |
| 10 | select CPM2 | 11 | select CPM2 |
| 11 | select PPC_INDIRECT_PCI if PCI | 12 | select PPC_INDIRECT_PCI if PCI |
| 12 | select FSL_SOC | ||
| 13 | select PHYLIB if NETDEVICES | 13 | select PHYLIB if NETDEVICES |
| 14 | select MDIO_BITBANG if PHYLIB | 14 | select MDIO_BITBANG if PHYLIB |
| 15 | help | 15 | help |
| @@ -22,7 +22,6 @@ config MGCOGE · 6 unmodified lines | |||
| 22 | bool "Keymile MGCOGE" | 22 | bool "Keymile MGCOGE" |
| 23 | select CPM2 | 23 | select CPM2 |
| 24 | select PPC_INDIRECT_PCI if PCI | 24 | select PPC_INDIRECT_PCI if PCI |
| 25 | select FSL_SOC | ||
| 26 | help | 25 | help |
| 27 | This enables support for the Keymile MGCOGE board. | 26 | This enables support for the Keymile MGCOGE board. |
| 28 | 27 | ||
| @@ -262,7 +262,7 @@ · 261 unmodified lines | |||
| 262 | reg = <0x100000 0x400000>; | 262 | reg = <0x100000 0x400000>; |
| 263 | }; | 263 | }; |
| 264 | reserved-data@600000 { | 264 | reserved-data@600000 { |
| 265 | reg = <0x600000 0x1000000>; | 265 | reg = <0x600000 0xa00000>; |
| 266 | }; | 266 | }; |
| 267 | }; | 267 | }; |
| 268 | }; | 268 | }; |
| @@ -440,30 +440,6 @@ · 171 unmodified lines | |||
| 440 | }; | 440 | }; |
| 441 | }; | 441 | }; |
| 442 | 442 | ||
| 443 | uart0_pins: uart0-0 { | ||
| 444 | tx-pins { | ||
| 445 | pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX, | ||
| 446 | GPOEN_ENABLE, | ||
| 447 | GPI_NONE)>; | ||
| 448 | bias-disable; | ||
| 449 | drive-strength = <12>; | ||
| 450 | input-disable; | ||
| 451 | input-schmitt-disable; | ||
| 452 | slew-rate = <0>; | ||
| 453 | }; | ||
| 454 | |||
| 455 | rx-pins { | ||
| 456 | pinmux = <GPIOMUX(6, GPOUT_LOW, | ||
| 457 | GPOEN_DISABLE, | ||
| 458 | GPI_SYS_UART0_RX)>; | ||
| 459 | bias-disable; /* external pull-up */ | ||
| 460 | drive-strength = <2>; | ||
| 461 | input-enable; | ||
| 462 | input-schmitt-enable; | ||
| 463 | slew-rate = <0>; | ||
| 464 | }; | ||
| 465 | }; | ||
| 466 | |||
| 467 | tdm_pins: tdm-0 { | 443 | tdm_pins: tdm-0 { |
| 468 | tx-pins { | 444 | tx-pins { |
| 469 | pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD, | 445 | pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD, |
| @@ -497,6 +473,30 @@ · 27 unmodified lines | |||
| 497 | input-enable; | 473 | input-enable; |
| 498 | }; | 474 | }; |
| 499 | }; | 475 | }; |
| 476 | |||
| 477 | uart0_pins: uart0-0 { | ||
| 478 | tx-pins { | ||
| 479 | pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX, | ||
| 480 | GPOEN_ENABLE, | ||
| 481 | GPI_NONE)>; | ||
| 482 | bias-disable; | ||
| 483 | drive-strength = <12>; | ||
| 484 | input-disable; | ||
| 485 | input-schmitt-disable; | ||
| 486 | slew-rate = <0>; | ||
| 487 | }; | ||
| 488 | |||
| 489 | rx-pins { | ||
| 490 | pinmux = <GPIOMUX(6, GPOUT_LOW, | ||
| 491 | GPOEN_DISABLE, | ||
| 492 | GPI_SYS_UART0_RX)>; | ||
| 493 | bias-disable; /* external pull-up */ | ||
| 494 | drive-strength = <2>; | ||
| 495 | input-enable; | ||
| 496 | input-schmitt-enable; | ||
| 497 | slew-rate = <0>; | ||
| 498 | }; | ||
| 499 | }; | ||
| 500 | }; | 500 | }; |
| 501 | 501 | ||
| 502 | &tdm { | 502 | &tdm { |
| @@ -513,6 +513,7 @@ · 10 unmodified lines | |||
| 513 | 513 | ||
| 514 | &usb0 { | 514 | &usb0 { |
| 515 | dr_mode = "peripheral"; | 515 | dr_mode = "peripheral"; |
| 516 | status = "okay"; | ||
| 516 | }; | 517 | }; |
| 517 | 518 | ||
| 518 | &U74_1 { | 519 | &U74_1 { |
| @@ -105,7 +105,7 @@ asm volatile(ALTERNATIVE( \ · 104 unmodified lines | |||
| 105 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | | 105 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | |
| 106 | * 0000001 01001 rs1 000 00000 0001011 | 106 | * 0000001 01001 rs1 000 00000 0001011 |
| 107 | * dcache.cva rs1 (clean, virtual address) | 107 | * dcache.cva rs1 (clean, virtual address) |
| 108 | * 0000001 00100 rs1 000 00000 0001011 | 108 | * 0000001 00101 rs1 000 00000 0001011 |
| 109 | * | 109 | * |
| 110 | * dcache.cipa rs1 (clean then invalidate, physical address) | 110 | * dcache.cipa rs1 (clean then invalidate, physical address) |
| 111 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | | 111 | * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | |
| @@ -118,7 +118,7 @@ asm volatile(ALTERNATIVE( \ · 6 unmodified lines | |||
| 118 | * 0000000 11001 00000 000 00000 0001011 | 118 | * 0000000 11001 00000 000 00000 0001011 |
| 119 | */ | 119 | */ |
| 120 | #define THEAD_inval_A0 ".long 0x0265000b" | 120 | #define THEAD_inval_A0 ".long 0x0265000b" |
| 121 | #define THEAD_clean_A0 ".long 0x0245000b" | 121 | #define THEAD_clean_A0 ".long 0x0255000b" |
| 122 | #define THEAD_flush_A0 ".long 0x0275000b" | 122 | #define THEAD_flush_A0 ".long 0x0275000b" |
| 123 | #define THEAD_SYNC_S ".long 0x0190000b" | 123 | #define THEAD_SYNC_S ".long 0x0190000b" |
| 124 | 124 | ||
| @@ -18,7 +18,8 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr, · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 19 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 20 | void set_huge_pte_at(struct mm_struct *mm, | 20 | void set_huge_pte_at(struct mm_struct *mm, |
| 21 | unsigned long addr, pte_t *ptep, pte_t pte); | 21 | unsigned long addr, pte_t *ptep, pte_t pte, |
| 22 | unsigned long sz); | ||
| 22 | 23 | ||
| 23 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 24 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| 24 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 25 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
| @@ -98,7 +98,13 @@ static int elf_find_pbase(struct kimage *image, unsigned long kernel_len, · 97 unmodified lines | |||
| 98 | kbuf.image = image; | 98 | kbuf.image = image; |
| 99 | kbuf.buf_min = lowest_paddr; | 99 | kbuf.buf_min = lowest_paddr; |
| 100 | kbuf.buf_max = ULONG_MAX; | 100 | kbuf.buf_max = ULONG_MAX; |
| 101 | kbuf.buf_align = PAGE_SIZE; | 101 | |
| 102 | /* | ||
| 103 | * Current riscv boot protocol requires 2MB alignment for | ||
| 104 | * RV64 and 4MB alignment for RV32 | ||
| 105 | * | ||
| 106 | */ | ||
| 107 | kbuf.buf_align = PMD_SIZE; | ||
| 102 | kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; | 108 | kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; |
| 103 | kbuf.memsz = ALIGN(kernel_len, PAGE_SIZE); | 109 | kbuf.memsz = ALIGN(kernel_len, PAGE_SIZE); |
| 104 | kbuf.top_down = false; | 110 | kbuf.top_down = false; |
| @@ -460,8 +460,11 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu, · 459 unmodified lines | |||
| 460 | reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) | 460 | reg_num >= ARRAY_SIZE(kvm_isa_ext_arr)) |
| 461 | return -ENOENT; | 461 | return -ENOENT; |
| 462 | 462 | ||
| 463 | *reg_val = 0; | ||
| 464 | host_isa_ext = kvm_isa_ext_arr[reg_num]; | 463 | host_isa_ext = kvm_isa_ext_arr[reg_num]; |
| 464 | if (!__riscv_isa_extension_available(NULL, host_isa_ext)) | ||
| 465 | return -ENOENT; | ||
| 466 | |||
| 467 | *reg_val = 0; | ||
| 465 | if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext)) | 468 | if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext)) |
| 466 | *reg_val = 1; /* Mark the given extension as available */ | 469 | *reg_val = 1; /* Mark the given extension as available */ |
| 467 | 470 | ||
| @@ -842,7 +845,7 @@ static int copy_isa_ext_reg_indices(const struct kvm_vcpu *vcpu, · 374 unmodified lines | |||
| 842 | u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i; | 845 | u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i; |
| 843 | 846 | ||
| 844 | isa_ext = kvm_isa_ext_arr[i]; | 847 | isa_ext = kvm_isa_ext_arr[i]; |
| 845 | if (!__riscv_isa_extension_available(vcpu->arch.isa, isa_ext)) | 848 | if (!__riscv_isa_extension_available(NULL, isa_ext)) |
| 846 | continue; | 849 | continue; |
| 847 | 850 | ||
| 848 | if (uindices) { | 851 | if (uindices) { |
| @@ -180,7 +180,8 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) · 179 unmodified lines | |||
| 180 | void set_huge_pte_at(struct mm_struct *mm, | 180 | void set_huge_pte_at(struct mm_struct *mm, |
| 181 | unsigned long addr, | 181 | unsigned long addr, |
| 182 | pte_t *ptep, | 182 | pte_t *ptep, |
| 183 | pte_t pte) | 183 | pte_t pte, |
| 184 | unsigned long sz) | ||
| 184 | { | 185 | { |
| 185 | int i, pte_num; | 186 | int i, pte_num; |
| 186 | 187 | ||
| @@ -40,23 +40,25 @@ CONFIG_SCHED_AUTOGROUP=y · 39 unmodified lines | |||
| 40 | CONFIG_EXPERT=y | 40 | CONFIG_EXPERT=y |
| 41 | # CONFIG_SYSFS_SYSCALL is not set | 41 | # CONFIG_SYSFS_SYSCALL is not set |
| 42 | CONFIG_PROFILING=y | 42 | CONFIG_PROFILING=y |
| 43 | CONFIG_KEXEC_FILE=y | ||
| 44 | CONFIG_KEXEC_SIG=y | ||
| 45 | CONFIG_CRASH_DUMP=y | ||
| 43 | CONFIG_LIVEPATCH=y | 46 | CONFIG_LIVEPATCH=y |
| 44 | CONFIG_MARCH_ZEC12=y | 47 | CONFIG_MARCH_ZEC12=y |
| 45 | CONFIG_TUNE_ZEC12=y | 48 | CONFIG_TUNE_ZEC12=y |
| 46 | CONFIG_NR_CPUS=512 | 49 | CONFIG_NR_CPUS=512 |
| 47 | CONFIG_NUMA=y | 50 | CONFIG_NUMA=y |
| 48 | CONFIG_HZ_100=y | 51 | CONFIG_HZ_100=y |
| 49 | CONFIG_KEXEC_FILE=y | 52 | CONFIG_CERT_STORE=y |
| 50 | CONFIG_KEXEC_SIG=y | ||
| 51 | CONFIG_EXPOLINE=y | 53 | CONFIG_EXPOLINE=y |
| 52 | CONFIG_EXPOLINE_AUTO=y | 54 | CONFIG_EXPOLINE_AUTO=y |
| 53 | CONFIG_CHSC_SCH=y | 55 | CONFIG_CHSC_SCH=y |
| 54 | CONFIG_VFIO_CCW=m | 56 | CONFIG_VFIO_CCW=m |
| 55 | CONFIG_VFIO_AP=m | 57 | CONFIG_VFIO_AP=m |
| 56 | CONFIG_CRASH_DUMP=y | ||
| 57 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y | 58 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y |
| 58 | CONFIG_CMM=m | 59 | CONFIG_CMM=m |
| 59 | CONFIG_APPLDATA_BASE=y | 60 | CONFIG_APPLDATA_BASE=y |
| 61 | CONFIG_S390_HYPFS_FS=y | ||
| 60 | CONFIG_KVM=m | 62 | CONFIG_KVM=m |
| 61 | CONFIG_S390_UNWIND_SELFTEST=m | 63 | CONFIG_S390_UNWIND_SELFTEST=m |
| 62 | CONFIG_S390_KPROBES_SANITY_TEST=m | 64 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| @@ -434,6 +436,7 @@ CONFIG_SCSI_DH_EMC=m · 371 unmodified lines | |||
| 434 | CONFIG_SCSI_DH_ALUA=m | 436 | CONFIG_SCSI_DH_ALUA=m |
| 435 | CONFIG_MD=y | 437 | CONFIG_MD=y |
| 436 | CONFIG_BLK_DEV_MD=y | 438 | CONFIG_BLK_DEV_MD=y |
| 439 | # CONFIG_MD_BITMAP_FILE is not set | ||
| 437 | CONFIG_MD_LINEAR=m | 440 | CONFIG_MD_LINEAR=m |
| 438 | CONFIG_MD_MULTIPATH=m | 441 | CONFIG_MD_MULTIPATH=m |
| 439 | CONFIG_MD_FAULTY=m | 442 | CONFIG_MD_FAULTY=m |
| @@ -577,6 +580,7 @@ CONFIG_SOFT_WATCHDOG=m · 137 unmodified lines | |||
| 577 | CONFIG_DIAG288_WATCHDOG=m | 580 | CONFIG_DIAG288_WATCHDOG=m |
| 578 | # CONFIG_DRM_DEBUG_MODESET_LOCK is not set | 581 | # CONFIG_DRM_DEBUG_MODESET_LOCK is not set |
| 579 | CONFIG_FB=y | 582 | CONFIG_FB=y |
| 583 | # CONFIG_FB_DEVICE is not set | ||
| 580 | CONFIG_FRAMEBUFFER_CONSOLE=y | 584 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 581 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 585 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| 582 | # CONFIG_HID_SUPPORT is not set | 586 | # CONFIG_HID_SUPPORT is not set |
| @@ -647,6 +651,7 @@ CONFIG_PROC_KCORE=y · 64 unmodified lines | |||
| 647 | CONFIG_TMPFS=y | 651 | CONFIG_TMPFS=y |
| 648 | CONFIG_TMPFS_POSIX_ACL=y | 652 | CONFIG_TMPFS_POSIX_ACL=y |
| 649 | CONFIG_TMPFS_INODE64=y | 653 | CONFIG_TMPFS_INODE64=y |
| 654 | CONFIG_TMPFS_QUOTA=y | ||
| 650 | CONFIG_HUGETLBFS=y | 655 | CONFIG_HUGETLBFS=y |
| 651 | CONFIG_ECRYPT_FS=m | 656 | CONFIG_ECRYPT_FS=m |
| 652 | CONFIG_CRAMFS=m | 657 | CONFIG_CRAMFS=m |
| @@ -703,6 +708,7 @@ CONFIG_IMA_WRITE_POLICY=y · 50 unmodified lines | |||
| 703 | CONFIG_IMA_APPRAISE=y | 708 | CONFIG_IMA_APPRAISE=y |
| 704 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" | 709 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" |
| 705 | CONFIG_INIT_STACK_NONE=y | 710 | CONFIG_INIT_STACK_NONE=y |
| 711 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 706 | CONFIG_CRYPTO_USER=m | 712 | CONFIG_CRYPTO_USER=m |
| 707 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | 713 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| 708 | CONFIG_CRYPTO_PCRYPT=m | 714 | CONFIG_CRYPTO_PCRYPT=m |
| @@ -825,9 +831,9 @@ CONFIG_LOCK_STAT=y · 116 unmodified lines | |||
| 825 | CONFIG_DEBUG_ATOMIC_SLEEP=y | 831 | CONFIG_DEBUG_ATOMIC_SLEEP=y |
| 826 | CONFIG_DEBUG_LOCKING_API_SELFTESTS=y | 832 | CONFIG_DEBUG_LOCKING_API_SELFTESTS=y |
| 827 | CONFIG_DEBUG_IRQFLAGS=y | 833 | CONFIG_DEBUG_IRQFLAGS=y |
| 834 | CONFIG_DEBUG_LIST=y | ||
| 828 | CONFIG_DEBUG_SG=y | 835 | CONFIG_DEBUG_SG=y |
| 829 | CONFIG_DEBUG_NOTIFIERS=y | 836 | CONFIG_DEBUG_NOTIFIERS=y |
| 830 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 831 | CONFIG_DEBUG_CREDENTIALS=y | 837 | CONFIG_DEBUG_CREDENTIALS=y |
| 832 | CONFIG_RCU_TORTURE_TEST=m | 838 | CONFIG_RCU_TORTURE_TEST=m |
| 833 | CONFIG_RCU_REF_SCALE_TEST=m | 839 | CONFIG_RCU_REF_SCALE_TEST=m |
| @@ -38,23 +38,25 @@ CONFIG_SCHED_AUTOGROUP=y · 37 unmodified lines | |||
| 38 | CONFIG_EXPERT=y | 38 | CONFIG_EXPERT=y |
| 39 | # CONFIG_SYSFS_SYSCALL is not set | 39 | # CONFIG_SYSFS_SYSCALL is not set |
| 40 | CONFIG_PROFILING=y | 40 | CONFIG_PROFILING=y |
| 41 | CONFIG_KEXEC_FILE=y | ||
| 42 | CONFIG_KEXEC_SIG=y | ||
| 43 | CONFIG_CRASH_DUMP=y | ||
| 41 | CONFIG_LIVEPATCH=y | 44 | CONFIG_LIVEPATCH=y |
| 42 | CONFIG_MARCH_ZEC12=y | 45 | CONFIG_MARCH_ZEC12=y |
| 43 | CONFIG_TUNE_ZEC12=y | 46 | CONFIG_TUNE_ZEC12=y |
| 44 | CONFIG_NR_CPUS=512 | 47 | CONFIG_NR_CPUS=512 |
| 45 | CONFIG_NUMA=y | 48 | CONFIG_NUMA=y |
| 46 | CONFIG_HZ_100=y | 49 | CONFIG_HZ_100=y |
| 47 | CONFIG_KEXEC_FILE=y | 50 | CONFIG_CERT_STORE=y |
| 48 | CONFIG_KEXEC_SIG=y | ||
| 49 | CONFIG_EXPOLINE=y | 51 | CONFIG_EXPOLINE=y |
| 50 | CONFIG_EXPOLINE_AUTO=y | 52 | CONFIG_EXPOLINE_AUTO=y |
| 51 | CONFIG_CHSC_SCH=y | 53 | CONFIG_CHSC_SCH=y |
| 52 | CONFIG_VFIO_CCW=m | 54 | CONFIG_VFIO_CCW=m |
| 53 | CONFIG_VFIO_AP=m | 55 | CONFIG_VFIO_AP=m |
| 54 | CONFIG_CRASH_DUMP=y | ||
| 55 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y | 56 | CONFIG_PROTECTED_VIRTUALIZATION_GUEST=y |
| 56 | CONFIG_CMM=m | 57 | CONFIG_CMM=m |
| 57 | CONFIG_APPLDATA_BASE=y | 58 | CONFIG_APPLDATA_BASE=y |
| 59 | CONFIG_S390_HYPFS_FS=y | ||
| 58 | CONFIG_KVM=m | 60 | CONFIG_KVM=m |
| 59 | CONFIG_S390_UNWIND_SELFTEST=m | 61 | CONFIG_S390_UNWIND_SELFTEST=m |
| 60 | CONFIG_S390_KPROBES_SANITY_TEST=m | 62 | CONFIG_S390_KPROBES_SANITY_TEST=m |
| @@ -424,6 +426,7 @@ CONFIG_SCSI_DH_EMC=m · 363 unmodified lines | |||
| 424 | CONFIG_SCSI_DH_ALUA=m | 426 | CONFIG_SCSI_DH_ALUA=m |
| 425 | CONFIG_MD=y | 427 | CONFIG_MD=y |
| 426 | CONFIG_BLK_DEV_MD=y | 428 | CONFIG_BLK_DEV_MD=y |
| 429 | # CONFIG_MD_BITMAP_FILE is not set | ||
| 427 | CONFIG_MD_LINEAR=m | 430 | CONFIG_MD_LINEAR=m |
| 428 | CONFIG_MD_MULTIPATH=m | 431 | CONFIG_MD_MULTIPATH=m |
| 429 | CONFIG_MD_FAULTY=m | 432 | CONFIG_MD_FAULTY=m |
| @@ -566,6 +569,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y · 136 unmodified lines | |||
| 566 | CONFIG_SOFT_WATCHDOG=m | 569 | CONFIG_SOFT_WATCHDOG=m |
| 567 | CONFIG_DIAG288_WATCHDOG=m | 570 | CONFIG_DIAG288_WATCHDOG=m |
| 568 | CONFIG_FB=y | 571 | CONFIG_FB=y |
| 572 | # CONFIG_FB_DEVICE is not set | ||
| 569 | CONFIG_FRAMEBUFFER_CONSOLE=y | 573 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 570 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y | 574 | CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y |
| 571 | # CONFIG_HID_SUPPORT is not set | 575 | # CONFIG_HID_SUPPORT is not set |
| @@ -632,6 +636,7 @@ CONFIG_PROC_KCORE=y · 60 unmodified lines | |||
| 632 | CONFIG_TMPFS=y | 636 | CONFIG_TMPFS=y |
| 633 | CONFIG_TMPFS_POSIX_ACL=y | 637 | CONFIG_TMPFS_POSIX_ACL=y |
| 634 | CONFIG_TMPFS_INODE64=y | 638 | CONFIG_TMPFS_INODE64=y |
| 639 | CONFIG_TMPFS_QUOTA=y | ||
| 635 | CONFIG_HUGETLBFS=y | 640 | CONFIG_HUGETLBFS=y |
| 636 | CONFIG_CONFIGFS_FS=m | 641 | CONFIG_CONFIGFS_FS=m |
| 637 | CONFIG_ECRYPT_FS=m | 642 | CONFIG_ECRYPT_FS=m |
| @@ -687,6 +692,7 @@ CONFIG_IMA_WRITE_POLICY=y · 49 unmodified lines | |||
| 687 | CONFIG_IMA_APPRAISE=y | 692 | CONFIG_IMA_APPRAISE=y |
| 688 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" | 693 | CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" |
| 689 | CONFIG_INIT_STACK_NONE=y | 694 | CONFIG_INIT_STACK_NONE=y |
| 695 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 690 | CONFIG_CRYPTO_FIPS=y | 696 | CONFIG_CRYPTO_FIPS=y |
| 691 | CONFIG_CRYPTO_USER=m | 697 | CONFIG_CRYPTO_USER=m |
| 692 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set | 698 | # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set |
| @@ -781,7 +787,6 @@ CONFIG_PTDUMP_DEBUGFS=y · 88 unmodified lines | |||
| 781 | CONFIG_DEBUG_MEMORY_INIT=y | 787 | CONFIG_DEBUG_MEMORY_INIT=y |
| 782 | CONFIG_PANIC_ON_OOPS=y | 788 | CONFIG_PANIC_ON_OOPS=y |
| 783 | CONFIG_TEST_LOCKUP=m | 789 | CONFIG_TEST_LOCKUP=m |
| 784 | CONFIG_BUG_ON_DATA_CORRUPTION=y | ||
| 785 | CONFIG_RCU_TORTURE_TEST=m | 790 | CONFIG_RCU_TORTURE_TEST=m |
| 786 | CONFIG_RCU_REF_SCALE_TEST=m | 791 | CONFIG_RCU_REF_SCALE_TEST=m |
| 787 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 792 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
| @@ -8,6 +8,7 @@ CONFIG_BPF_SYSCALL=y · 7 unmodified lines | |||
| 8 | # CONFIG_NET_NS is not set | 8 | # CONFIG_NET_NS is not set |
| 9 | CONFIG_BLK_DEV_INITRD=y | 9 | CONFIG_BLK_DEV_INITRD=y |
| 10 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 10 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| 11 | CONFIG_CRASH_DUMP=y | ||
| 11 | CONFIG_MARCH_ZEC12=y | 12 | CONFIG_MARCH_ZEC12=y |
| 12 | CONFIG_TUNE_ZEC12=y | 13 | CONFIG_TUNE_ZEC12=y |
| 13 | # CONFIG_COMPAT is not set | 14 | # CONFIG_COMPAT is not set |
| @@ -15,9 +16,8 @@ CONFIG_NR_CPUS=2 · 1 unmodified line | |||
| 15 | CONFIG_HZ_100=y | 16 | CONFIG_HZ_100=y |
| 16 | # CONFIG_CHSC_SCH is not set | 17 | # CONFIG_CHSC_SCH is not set |
| 17 | # CONFIG_SCM_BUS is not set | 18 | # CONFIG_SCM_BUS is not set |
| 18 | CONFIG_CRASH_DUMP=y | ||
| 19 | # CONFIG_PFAULT is not set | 19 | # CONFIG_PFAULT is not set |
| 20 | # CONFIG_S390_HYPFS_FS is not set | 20 | # CONFIG_S390_HYPFS is not set |
| 21 | # CONFIG_VIRTUALIZATION is not set | 21 | # CONFIG_VIRTUALIZATION is not set |
| 22 | # CONFIG_S390_GUEST is not set | 22 | # CONFIG_S390_GUEST is not set |
| 23 | # CONFIG_SECCOMP is not set | 23 | # CONFIG_SECCOMP is not set |
| @@ -16,6 +16,8 @@ · 15 unmodified lines | |||
| 16 | #define hugepages_supported() (MACHINE_HAS_EDAT1) | 16 | #define hugepages_supported() (MACHINE_HAS_EDAT1) |
| 17 | 17 | ||
| 18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 19 | pte_t *ptep, pte_t pte, unsigned long sz); | ||
| 20 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 19 | pte_t *ptep, pte_t pte); | 21 | pte_t *ptep, pte_t pte); |
| 20 | pte_t huge_ptep_get(pte_t *ptep); | 22 | pte_t huge_ptep_get(pte_t *ptep); |
| 21 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 23 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
| @@ -65,7 +67,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 43 unmodified lines | |||
| 65 | int changed = !pte_same(huge_ptep_get(ptep), pte); | 67 | int changed = !pte_same(huge_ptep_get(ptep), pte); |
| 66 | if (changed) { | 68 | if (changed) { |
| 67 | huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); | 69 | huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); |
| 68 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 70 | __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); |
| 69 | } | 71 | } |
| 70 | return changed; | 72 | return changed; |
| 71 | } | 73 | } |
| @@ -74,7 +76,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, · 2 unmodified lines | |||
| 74 | unsigned long addr, pte_t *ptep) | 76 | unsigned long addr, pte_t *ptep) |
| 75 | { | 77 | { |
| 76 | pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); | 78 | pte_t pte = huge_ptep_get_and_clear(mm, addr, ptep); |
| 77 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); | 79 | __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte)); |
| 78 | } | 80 | } |
| 79 | 81 | ||
| 80 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) | 82 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) |
| @@ -432,15 +432,16 @@ static char *get_key_description(struct vcssb *vcssb, const struct vce *vce) · 431 unmodified lines | |||
| 432 | char *desc; | 432 | char *desc; |
| 433 | 433 | ||
| 434 | cs_token = vcssb->cs_token; | 434 | cs_token = vcssb->cs_token; |
| 435 | /* Description string contains "%64s:%04u:%08u\0". */ | 435 | /* Description string contains "%64s:%05u:%010u\0". */ |
| 436 | name_len = sizeof(vce->vce_hdr.vc_name); | 436 | name_len = sizeof(vce->vce_hdr.vc_name); |
| 437 | len = name_len + 1 + 4 + 1 + 8 + 1; | 437 | len = name_len + 1 + 5 + 1 + 10 + 1; |
| 438 | desc = kmalloc(len, GFP_KERNEL); | 438 | desc = kmalloc(len, GFP_KERNEL); |
| 439 | if (!desc) | 439 | if (!desc) |
| 440 | return NULL; | 440 | return NULL; |
| 441 | 441 | ||
| 442 | memcpy(desc, vce->vce_hdr.vc_name, name_len); | 442 | memcpy(desc, vce->vce_hdr.vc_name, name_len); |
| 443 | sprintf(desc + name_len, ":%04u:%08u", vce->vce_hdr.vc_index, cs_token); | 443 | snprintf(desc + name_len, len - name_len, ":%05u:%010u", |
| 444 | vce->vce_hdr.vc_index, cs_token); | ||
| 444 | 445 | ||
| 445 | return desc; | 446 | return desc; |
| 446 | } | 447 | } |
| @@ -142,7 +142,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste) · 141 unmodified lines | |||
| 142 | __storage_key_init_range(paddr, paddr + size - 1); | 142 | __storage_key_init_range(paddr, paddr + size - 1); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 145 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 146 | pte_t *ptep, pte_t pte) | 146 | pte_t *ptep, pte_t pte) |
| 147 | { | 147 | { |
| 148 | unsigned long rste; | 148 | unsigned long rste; |
| @@ -163,6 +163,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 14 unmodified lines | |||
| 163 | set_pte(ptep, __pte(rste)); | 163 | set_pte(ptep, __pte(rste)); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 167 | pte_t *ptep, pte_t pte, unsigned long sz) | ||
| 168 | { | ||
| 169 | __set_huge_pte_at(mm, addr, ptep, pte); | ||
| 170 | } | ||
| 171 | |||
| 166 | pte_t huge_ptep_get(pte_t *ptep) | 172 | pte_t huge_ptep_get(pte_t *ptep) |
| 167 | { | 173 | { |
| 168 | return __rste_to_pte(pte_val(*ptep)); | 174 | return __rste_to_pte(pte_val(*ptep)); |
| @@ -72,8 +72,8 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot) · 71 unmodified lines | |||
| 72 | #define __ioremap_29bit(offset, size, prot) NULL | 72 | #define __ioremap_29bit(offset, size, prot) NULL |
| 73 | #endif /* CONFIG_29BIT */ | 73 | #endif /* CONFIG_29BIT */ |
| 74 | 74 | ||
| 75 | void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, | 75 | void __iomem __ref *ioremap_prot(phys_addr_t phys_addr, size_t size, |
| 76 | unsigned long prot) | 76 | unsigned long prot) |
| 77 | { | 77 | { |
| 78 | void __iomem *mapped; | 78 | void __iomem *mapped; |
| 79 | pgprot_t pgprot = __pgprot(prot); | 79 | pgprot_t pgprot = __pgprot(prot); |
| @@ -14,6 +14,8 @@ extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_end; · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT | 15 | #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT |
| 16 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 16 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 17 | pte_t *ptep, pte_t pte, unsigned long sz); | ||
| 18 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 17 | pte_t *ptep, pte_t pte); | 19 | pte_t *ptep, pte_t pte); |
| 18 | 20 | ||
| 19 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR | 21 | #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR |
| @@ -32,7 +34,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, · 12 unmodified lines | |||
| 32 | unsigned long addr, pte_t *ptep) | 34 | unsigned long addr, pte_t *ptep) |
| 33 | { | 35 | { |
| 34 | pte_t old_pte = *ptep; | 36 | pte_t old_pte = *ptep; |
| 35 | set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | 37 | __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS | 40 | #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS |
| @@ -42,7 +44,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 3 unmodified lines | |||
| 42 | { | 44 | { |
| 43 | int changed = !pte_same(*ptep, pte); | 45 | int changed = !pte_same(*ptep, pte); |
| 44 | if (changed) { | 46 | if (changed) { |
| 45 | set_huge_pte_at(vma->vm_mm, addr, ptep, pte); | 47 | __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); |
| 46 | flush_tlb_page(vma, addr); | 48 | flush_tlb_page(vma, addr); |
| 47 | } | 49 | } |
| 48 | return changed; | 50 | return changed; |
| @@ -328,7 +328,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, · 327 unmodified lines | |||
| 328 | return pte_offset_huge(pmd, addr); | 328 | return pte_offset_huge(pmd, addr); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 331 | void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
| 332 | pte_t *ptep, pte_t entry) | 332 | pte_t *ptep, pte_t entry) |
| 333 | { | 333 | { |
| 334 | unsigned int nptes, orig_shift, shift; | 334 | unsigned int nptes, orig_shift, shift; |
| @@ -364,6 +364,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 29 unmodified lines | |||
| 364 | orig_shift); | 364 | orig_shift); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
| 368 | pte_t *ptep, pte_t entry, unsigned long sz) | ||
| 369 | { | ||
| 370 | __set_huge_pte_at(mm, addr, ptep, entry); | ||
| 371 | } | ||
| 372 | |||
| 367 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, | 373 | pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, |
| 368 | pte_t *ptep) | 374 | pte_t *ptep) |
| 369 | { | 375 | { |
| @@ -1945,6 +1945,7 @@ config EFI · 1944 unmodified lines | |||
| 1945 | select UCS2_STRING | 1945 | select UCS2_STRING |
| 1946 | select EFI_RUNTIME_WRAPPERS | 1946 | select EFI_RUNTIME_WRAPPERS |
| 1947 | select ARCH_USE_MEMREMAP_PROT | 1947 | select ARCH_USE_MEMREMAP_PROT |
| 1948 | select EFI_RUNTIME_MAP if KEXEC_CORE | ||
| 1948 | help | 1949 | help |
| 1949 | This enables the kernel to use EFI runtime services that are | 1950 | This enables the kernel to use EFI runtime services that are |
| 1950 | available (such as the EFI variable services). | 1951 | available (such as the EFI variable services). |
| @@ -2020,7 +2021,6 @@ config EFI_MAX_FAKE_MEM · 69 unmodified lines | |||
| 2020 | config EFI_RUNTIME_MAP | 2021 | config EFI_RUNTIME_MAP |
| 2021 | bool "Export EFI runtime maps to sysfs" if EXPERT | 2022 | bool "Export EFI runtime maps to sysfs" if EXPERT |
| 2022 | depends on EFI | 2023 | depends on EFI |
| 2023 | default KEXEC_CORE | ||
| 2024 | help | 2024 | help |
| 2025 | Export EFI runtime memory regions to /sys/firmware/efi/runtime-map. | 2025 | Export EFI runtime memory regions to /sys/firmware/efi/runtime-map. |
| 2026 | That memory map is required by the 2nd kernel to set up EFI virtual | 2026 | That memory map is required by the 2nd kernel to set up EFI virtual |
| @@ -59,6 +59,14 @@ static void *alloc_pgt_page(void *context) · 58 unmodified lines | |||
| 59 | return NULL; | 59 | return NULL; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | /* Consumed more tables than expected? */ | ||
| 63 | if (pages->pgt_buf_offset == BOOT_PGT_SIZE_WARN) { | ||
| 64 | debug_putstr("pgt_buf running low in " __FILE__ "\n"); | ||
| 65 | debug_putstr("Need to raise BOOT_PGT_SIZE?\n"); | ||
| 66 | debug_putaddr(pages->pgt_buf_offset); | ||
| 67 | debug_putaddr(pages->pgt_buf_size); | ||
| 68 | } | ||
| 69 | |||
| 62 | entry = pages->pgt_buf + pages->pgt_buf_offset; | 70 | entry = pages->pgt_buf + pages->pgt_buf_offset; |
| 63 | pages->pgt_buf_offset += PAGE_SIZE; | 71 | pages->pgt_buf_offset += PAGE_SIZE; |
| 64 | 72 | ||
| @@ -294,7 +294,7 @@ static void __xen_pv_evtchn_do_upcall(struct pt_regs *regs) · 293 unmodified lines | |||
| 294 | 294 | ||
| 295 | inc_irq_stat(irq_hv_callback_count); | 295 | inc_irq_stat(irq_hv_callback_count); |
| 296 | 296 | ||
| 297 | xen_hvm_evtchn_do_upcall(); | 297 | xen_evtchn_do_upcall(); |
| 298 | 298 | ||
| 299 | set_irq_regs(old_regs); | 299 | set_irq_regs(old_regs); |
| 300 | } | 300 | } |
| @@ -534,8 +534,12 @@ static void amd_pmu_cpu_reset(int cpu) · 533 unmodified lines | |||
| 534 | /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ | 534 | /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ |
| 535 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); | 535 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); |
| 536 | 536 | ||
| 537 | /* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */ | 537 | /* |
| 538 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask); | 538 | * Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze |
| 539 | * and PerfCntrGLobalStatus.PerfCntrOvfl | ||
| 540 | */ | ||
| 541 | wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, | ||
| 542 | GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask); | ||
| 539 | } | 543 | } |
| 540 | 544 | ||
| 541 | static int amd_pmu_cpu_prepare(int cpu) | 545 | static int amd_pmu_cpu_prepare(int cpu) |
| @@ -570,6 +574,7 @@ static void amd_pmu_cpu_starting(int cpu) · 28 unmodified lines | |||
| 570 | int i, nb_id; | 574 | int i, nb_id; |
| 571 | 575 | ||
| 572 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; | 576 | cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; |
| 577 | amd_pmu_cpu_reset(cpu); | ||
| 573 | 578 | ||
| 574 | if (!x86_pmu.amd_nb_constraints) | 579 | if (!x86_pmu.amd_nb_constraints) |
| 575 | return; | 580 | return; |
| @@ -591,8 +596,6 @@ static void amd_pmu_cpu_starting(int cpu) · 15 unmodified lines | |||
| 591 | 596 | ||
| 592 | cpuc->amd_nb->nb_id = nb_id; | 597 | cpuc->amd_nb->nb_id = nb_id; |
| 593 | cpuc->amd_nb->refcnt++; | 598 | cpuc->amd_nb->refcnt++; |
| 594 | |||
| 595 | amd_pmu_cpu_reset(cpu); | ||
| 596 | } | 599 | } |
| 597 | 600 | ||
| 598 | static void amd_pmu_cpu_dead(int cpu) | 601 | static void amd_pmu_cpu_dead(int cpu) |
| @@ -601,6 +604,7 @@ static void amd_pmu_cpu_dead(int cpu) · 2 unmodified lines | |||
| 601 | 604 | ||
| 602 | kfree(cpuhw->lbr_sel); | 605 | kfree(cpuhw->lbr_sel); |
| 603 | cpuhw->lbr_sel = NULL; | 606 | cpuhw->lbr_sel = NULL; |
| 607 | amd_pmu_cpu_reset(cpu); | ||
| 604 | 608 | ||
| 605 | if (!x86_pmu.amd_nb_constraints) | 609 | if (!x86_pmu.amd_nb_constraints) |
| 606 | return; | 610 | return; |
| @@ -613,8 +617,6 @@ static void amd_pmu_cpu_dead(int cpu) · 6 unmodified lines | |||
| 613 | 617 | ||
| 614 | cpuhw->amd_nb = NULL; | 618 | cpuhw->amd_nb = NULL; |
| 615 | } | 619 | } |
| 616 | |||
| 617 | amd_pmu_cpu_reset(cpu); | ||
| 618 | } | 620 | } |
| 619 | 621 | ||
| 620 | static inline void amd_pmu_set_global_ctl(u64 ctl) | 622 | static inline void amd_pmu_set_global_ctl(u64 ctl) |
| @@ -884,7 +886,7 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) · 263 unmodified lines | |||
| 884 | struct hw_perf_event *hwc; | 886 | struct hw_perf_event *hwc; |
| 885 | struct perf_event *event; | 887 | struct perf_event *event; |
| 886 | int handled = 0, idx; | 888 | int handled = 0, idx; |
| 887 | u64 status, mask; | 889 | u64 reserved, status, mask; |
| 888 | bool pmu_enabled; | 890 | bool pmu_enabled; |
| 889 | 891 | ||
| 890 | /* | 892 | /* |
| @@ -909,6 +911,14 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs) · 18 unmodified lines | |||
| 909 | status &= ~GLOBAL_STATUS_LBRS_FROZEN; | 911 | status &= ~GLOBAL_STATUS_LBRS_FROZEN; |
| 910 | } | 912 | } |
| 911 | 913 | ||
| 914 | reserved = status & ~amd_pmu_global_cntr_mask; | ||
| 915 | if (reserved) | ||
| 916 | pr_warn_once("Reserved PerfCntrGlobalStatus bits are set (0x%llx), please consider updating microcode\n", | ||
| 917 | reserved); | ||
| 918 | |||
| 919 | /* Clear any reserved bits set by buggy microcode */ | ||
| 920 | status &= amd_pmu_global_cntr_mask; | ||
| 921 | |||
| 912 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 922 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
| 913 | if (!test_bit(idx, cpuc->active_mask)) | 923 | if (!test_bit(idx, cpuc->active_mask)) |
| 914 | continue; | 924 | continue; |
| @@ -40,23 +40,40 @@ · 39 unmodified lines | |||
| 40 | #ifdef CONFIG_X86_64 | 40 | #ifdef CONFIG_X86_64 |
| 41 | # define BOOT_STACK_SIZE 0x4000 | 41 | # define BOOT_STACK_SIZE 0x4000 |
| 42 | 42 | ||
| 43 | /* | ||
| 44 | * Used by decompressor's startup_32() to allocate page tables for identity | ||
| 45 | * mapping of the 4G of RAM in 4-level paging mode: | ||
| 46 | * - 1 level4 table; | ||
| 47 | * - 1 level3 table; | ||
| 48 | * - 4 level2 table that maps everything with 2M pages; | ||
| 49 | * | ||
| 50 | * The additional level5 table needed for 5-level paging is allocated from | ||
| 51 | * trampoline_32bit memory. | ||
| 52 | */ | ||
| 43 | # define BOOT_INIT_PGT_SIZE (6*4096) | 53 | # define BOOT_INIT_PGT_SIZE (6*4096) |
| 44 | # ifdef CONFIG_RANDOMIZE_BASE | 54 | |
| 45 | /* | 55 | /* |
| 46 | * Assuming all cross the 512GB boundary: | 56 | * Total number of page tables kernel_add_identity_map() can allocate, |
| 47 | * 1 page for level4 | 57 | * including page tables consumed by startup_32(). |
| 48 | * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel | 58 | * |
| 49 | * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). | 59 | * Worst-case scenario: |
| 50 | * Total is 19 pages. | 60 | * - 5-level paging needs 1 level5 table; |
| 61 | * - KASLR needs to map kernel, boot_params, cmdline and randomized kernel, | ||
| 62 | * assuming all of them cross 256T boundary: | ||
| 63 | * + 4*2 level4 table; | ||
| 64 | * + 4*2 level3 table; | ||
| 65 | * + 4*2 level2 table; | ||
| 66 | * - X86_VERBOSE_BOOTUP needs to map the first 2M (video RAM): | ||
| 67 | * + 1 level4 table; | ||
| 68 | * + 1 level3 table; | ||
| 69 | * + 1 level2 table; | ||
| 70 | * Total: 28 tables | ||
| 71 | * | ||
| 72 | * Add 4 spare table in case decompressor touches anything beyond what is | ||
| 73 | * accounted above. Warn if it happens. | ||
| 51 | */ | 74 | */ |
| 52 | # ifdef CONFIG_X86_VERBOSE_BOOTUP | 75 | # define BOOT_PGT_SIZE_WARN (28*4096) |
| 53 | # define BOOT_PGT_SIZE (19*4096) | 76 | # define BOOT_PGT_SIZE (32*4096) |
| 54 | # else /* !CONFIG_X86_VERBOSE_BOOTUP */ | ||
| 55 | # define BOOT_PGT_SIZE (17*4096) | ||
| 56 | # endif | ||
| 57 | # else /* !CONFIG_RANDOMIZE_BASE */ | ||
| 58 | # define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE | ||
| 59 | # endif | ||
| 60 | 77 | ||
| 61 | #else /* !CONFIG_X86_64 */ | 78 | #else /* !CONFIG_X86_64 */ |
| 62 | # define BOOT_STACK_SIZE 0x1000 | 79 | # define BOOT_STACK_SIZE 0x1000 |
| @@ -91,19 +91,6 @@ static inline void efi_fpu_end(void) · 90 unmodified lines | |||
| 91 | 91 | ||
| 92 | #ifdef CONFIG_X86_32 | 92 | #ifdef CONFIG_X86_32 |
| 93 | #define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) | 93 | #define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) |
| 94 | |||
| 95 | #define arch_efi_call_virt_setup() \ | ||
| 96 | ({ \ | ||
| 97 | efi_fpu_begin(); \ | ||
| 98 | firmware_restrict_branch_speculation_start(); \ | ||
| 99 | }) | ||
| 100 | |||
| 101 | #define arch_efi_call_virt_teardown() \ | ||
| 102 | ({ \ | ||
| 103 | firmware_restrict_branch_speculation_end(); \ | ||
| 104 | efi_fpu_end(); \ | ||
| 105 | }) | ||
| 106 | |||
| 107 | #else /* !CONFIG_X86_32 */ | 94 | #else /* !CONFIG_X86_32 */ |
| 108 | #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT | 95 | #define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT |
| 109 | 96 | ||
| @@ -116,14 +103,6 @@ extern bool efi_disable_ibt_for_runtime; · 6 unmodified lines | |||
| 116 | __efi_call(__VA_ARGS__); \ | 103 | __efi_call(__VA_ARGS__); \ |
| 117 | }) | 104 | }) |
| 118 | 105 | ||
| 119 | #define arch_efi_call_virt_setup() \ | ||
| 120 | ({ \ | ||
| 121 | efi_sync_low_kernel_mappings(); \ | ||
| 122 | efi_fpu_begin(); \ | ||
| 123 | firmware_restrict_branch_speculation_start(); \ | ||
| 124 | efi_enter_mm(); \ | ||
| 125 | }) | ||
| 126 | |||
| 127 | #undef arch_efi_call_virt | 106 | #undef arch_efi_call_virt |
| 128 | #define arch_efi_call_virt(p, f, args...) ({ \ | 107 | #define arch_efi_call_virt(p, f, args...) ({ \ |
| 129 | u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ | 108 | u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ |
| @@ -132,13 +111,6 @@ extern bool efi_disable_ibt_for_runtime; · 2 unmodified lines | |||
| 132 | ret; \ | 111 | ret; \ |
| 133 | }) | 112 | }) |
| 134 | 113 | ||
| 135 | #define arch_efi_call_virt_teardown() \ | ||
| 136 | ({ \ | ||
| 137 | efi_leave_mm(); \ | ||
| 138 | firmware_restrict_branch_speculation_end(); \ | ||
| 139 | efi_fpu_end(); \ | ||
| 140 | }) | ||
| 141 | |||
| 142 | #ifdef CONFIG_KASAN | 114 | #ifdef CONFIG_KASAN |
| 143 | /* | 115 | /* |
| 144 | * CONFIG_KASAN may redefine memset to __memset. __memset function is present | 116 | * CONFIG_KASAN may redefine memset to __memset. __memset function is present |
| @@ -168,8 +140,8 @@ extern void efi_delete_dummy_variable(void); · 23 unmodified lines | |||
| 168 | extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); | 140 | extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); |
| 169 | extern void efi_free_boot_services(void); | 141 | extern void efi_free_boot_services(void); |
| 170 | 142 | ||
| 171 | void efi_enter_mm(void); | 143 | void arch_efi_call_virt_setup(void); |
| 172 | void efi_leave_mm(void); | 144 | void arch_efi_call_virt_teardown(void); |
| 173 | 145 | ||
| 174 | /* kexec external ABI */ | 146 | /* kexec external ABI */ |
| 175 | struct efi_setup_data { | 147 | struct efi_setup_data { |
| @@ -1419,7 +1419,6 @@ struct kvm_arch { · 1418 unmodified lines | |||
| 1419 | * the thread holds the MMU lock in write mode. | 1419 | * the thread holds the MMU lock in write mode. |
| 1420 | */ | 1420 | */ |
| 1421 | spinlock_t tdp_mmu_pages_lock; | 1421 | spinlock_t tdp_mmu_pages_lock; |
| 1422 | struct workqueue_struct *tdp_mmu_zap_wq; | ||
| 1423 | #endif /* CONFIG_X86_64 */ | 1422 | #endif /* CONFIG_X86_64 */ |
| 1424 | 1423 | ||
| 1425 | /* | 1424 | /* |
| @@ -1835,7 +1834,7 @@ void kvm_mmu_vendor_module_exit(void); · 409 unmodified lines | |||
| 1835 | 1834 | ||
| 1836 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); | 1835 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); |
| 1837 | int kvm_mmu_create(struct kvm_vcpu *vcpu); | 1836 | int kvm_mmu_create(struct kvm_vcpu *vcpu); |
| 1838 | int kvm_mmu_init_vm(struct kvm *kvm); | 1837 | void kvm_mmu_init_vm(struct kvm *kvm); |
| 1839 | void kvm_mmu_uninit_vm(struct kvm *kvm); | 1838 | void kvm_mmu_uninit_vm(struct kvm *kvm); |
| 1840 | 1839 | ||
| 1841 | void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); | 1840 | void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); |
| @@ -8,6 +8,14 @@ · 7 unmodified lines | |||
| 8 | #undef notrace | 8 | #undef notrace |
| 9 | #define notrace __attribute__((no_instrument_function)) | 9 | #define notrace __attribute__((no_instrument_function)) |
| 10 | 10 | ||
| 11 | #ifdef CONFIG_64BIT | ||
| 12 | /* | ||
| 13 | * The generic version tends to create spurious ENDBR instructions under | ||
| 14 | * certain conditions. | ||
| 15 | */ | ||
| 16 | #define _THIS_IP_ ({ unsigned long __here; asm ("lea 0(%%rip), %0" : "=r" (__here)); __here; }) | ||
| 17 | #endif | ||
| 18 | |||
| 11 | #ifdef CONFIG_X86_32 | 19 | #ifdef CONFIG_X86_32 |
| 12 | #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) | 20 | #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) |
| 13 | #endif /* CONFIG_X86_32 */ | 21 | #endif /* CONFIG_X86_32 */ |
| @@ -97,6 +105,13 @@ · 83 unmodified lines | |||
| 97 | CFI_POST_PADDING \ | 105 | CFI_POST_PADDING \ |
| 98 | SYM_FUNC_END(__cfi_##name) | 106 | SYM_FUNC_END(__cfi_##name) |
| 99 | 107 | ||
| 108 | /* UML needs to be able to override memcpy() and friends for KASAN. */ | ||
| 109 | #ifdef CONFIG_UML | ||
| 110 | # define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS_WEAK | ||
| 111 | #else | ||
| 112 | # define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS | ||
| 113 | #endif | ||
| 114 | |||
| 100 | /* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */ | 115 | /* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */ |
| 101 | #define SYM_TYPED_FUNC_START(name) \ | 116 | #define SYM_TYPED_FUNC_START(name) \ |
| 102 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \ | 117 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \ |
| @@ -186,8 +186,7 @@ do { \ · 185 unmodified lines | |||
| 186 | #else | 186 | #else |
| 187 | #define deactivate_mm(tsk, mm) \ | 187 | #define deactivate_mm(tsk, mm) \ |
| 188 | do { \ | 188 | do { \ |
| 189 | if (!tsk->vfork_done) \ | 189 | shstk_free(tsk); \ |
| 190 | shstk_free(tsk); \ | ||
| 191 | load_gs_index(0); \ | 190 | load_gs_index(0); \ |
| 192 | loadsegment(fs, 0); \ | 191 | loadsegment(fs, 0); \ |
| 193 | } while (0) | 192 | } while (0) |
| @@ -9,13 +9,6 @@ struct paravirt_patch_site { · 8 unmodified lines | |||
| 9 | u8 type; /* type of this instruction */ | 9 | u8 type; /* type of this instruction */ |
| 10 | u8 len; /* length of original instruction */ | 10 | u8 len; /* length of original instruction */ |
| 11 | }; | 11 | }; |
| 12 | |||
| 13 | /* Lazy mode for batching updates / context switch */ | ||
| 14 | enum paravirt_lazy_mode { | ||
| 15 | PARAVIRT_LAZY_NONE, | ||
| 16 | PARAVIRT_LAZY_MMU, | ||
| 17 | PARAVIRT_LAZY_CPU, | ||
| 18 | }; | ||
| 19 | #endif | 12 | #endif |
| 20 | 13 | ||
| 21 | #ifdef CONFIG_PARAVIRT | 14 | #ifdef CONFIG_PARAVIRT |
| @@ -549,14 +542,6 @@ int paravirt_disable_iospace(void); · 527 unmodified lines | |||
| 549 | __PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | 542 | __PVOP_VCALL(op, PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ |
| 550 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) | 543 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) |
| 551 | 544 | ||
| 552 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void); | ||
| 553 | void paravirt_start_context_switch(struct task_struct *prev); | ||
| 554 | void paravirt_end_context_switch(struct task_struct *next); | ||
| 555 | |||
| 556 | void paravirt_enter_lazy_mmu(void); | ||
| 557 | void paravirt_leave_lazy_mmu(void); | ||
| 558 | void paravirt_flush_lazy_mmu(void); | ||
| 559 | |||
| 560 | void _paravirt_nop(void); | 545 | void _paravirt_nop(void); |
| 561 | void paravirt_BUG(void); | 546 | void paravirt_BUG(void); |
| 562 | unsigned long paravirt_ret0(void); | 547 | unsigned long paravirt_ret0(void); |
| @@ -955,6 +955,14 @@ static inline int pte_same(pte_t a, pte_t b) · 954 unmodified lines | |||
| 955 | return a.pte == b.pte; | 955 | return a.pte == b.pte; |
| 956 | } | 956 | } |
| 957 | 957 | ||
| 958 | static inline pte_t pte_next_pfn(pte_t pte) | ||
| 959 | { | ||
| 960 | if (__pte_needs_invert(pte_val(pte))) | ||
| 961 | return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT)); | ||
| 962 | return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT)); | ||
| 963 | } | ||
| 964 | #define pte_next_pfn pte_next_pfn | ||
| 965 | |||
| 958 | static inline int pte_present(pte_t a) | 966 | static inline int pte_present(pte_t a) |
| 959 | { | 967 | { |
| 960 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE); | 968 | return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE); |
| @@ -683,13 +683,11 @@ extern u16 get_llc_id(unsigned int cpu); · 682 unmodified lines | |||
| 683 | #ifdef CONFIG_CPU_SUP_AMD | 683 | #ifdef CONFIG_CPU_SUP_AMD |
| 684 | extern u32 amd_get_nodes_per_socket(void); | 684 | extern u32 amd_get_nodes_per_socket(void); |
| 685 | extern u32 amd_get_highest_perf(void); | 685 | extern u32 amd_get_highest_perf(void); |
| 686 | extern bool cpu_has_ibpb_brtype_microcode(void); | ||
| 687 | extern void amd_clear_divider(void); | 686 | extern void amd_clear_divider(void); |
| 688 | extern void amd_check_microcode(void); | 687 | extern void amd_check_microcode(void); |
| 689 | #else | 688 | #else |
| 690 | static inline u32 amd_get_nodes_per_socket(void) { return 0; } | 689 | static inline u32 amd_get_nodes_per_socket(void) { return 0; } |
| 691 | static inline u32 amd_get_highest_perf(void) { return 0; } | 690 | static inline u32 amd_get_highest_perf(void) { return 0; } |
| 692 | static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } | ||
| 693 | static inline void amd_clear_divider(void) { } | 691 | static inline void amd_clear_divider(void) { } |
| 694 | static inline void amd_check_microcode(void) { } | 692 | static inline void amd_check_microcode(void) { } |
| 695 | #endif | 693 | #endif |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | |||
| 36 | extern struct shared_info *HYPERVISOR_shared_info; | 36 | extern struct shared_info *HYPERVISOR_shared_info; |
| 37 | extern struct start_info *xen_start_info; | 37 | extern struct start_info *xen_start_info; |
| 38 | 38 | ||
| 39 | #include <asm/bug.h> | ||
| 39 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
| 40 | 41 | ||
| 41 | #define XEN_SIGNATURE "XenVMMXenVMM" | 42 | #define XEN_SIGNATURE "XenVMMXenVMM" |
| @@ -63,4 +64,40 @@ void __init xen_pvh_init(struct boot_params *boot_params); · 21 unmodified lines | |||
| 63 | void __init mem_map_via_hcall(struct boot_params *boot_params_p); | 64 | void __init mem_map_via_hcall(struct boot_params *boot_params_p); |
| 64 | #endif | 65 | #endif |
| 65 | 66 | ||
| 67 | /* Lazy mode for batching updates / context switch */ | ||
| 68 | enum xen_lazy_mode { | ||
| 69 | XEN_LAZY_NONE, | ||
| 70 | XEN_LAZY_MMU, | ||
| 71 | XEN_LAZY_CPU, | ||
| 72 | }; | ||
| 73 | |||
| 74 | DECLARE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode); | ||
| 75 | DECLARE_PER_CPU(unsigned int, xen_lazy_nesting); | ||
| 76 | |||
| 77 | static inline void enter_lazy(enum xen_lazy_mode mode) | ||
| 78 | { | ||
| 79 | enum xen_lazy_mode old_mode = this_cpu_read(xen_lazy_mode); | ||
| 80 | |||
| 81 | if (mode == old_mode) { | ||
| 82 | this_cpu_inc(xen_lazy_nesting); | ||
| 83 | return; | ||
| 84 | } | ||
| 85 | |||
| 86 | BUG_ON(old_mode != XEN_LAZY_NONE); | ||
| 87 | |||
| 88 | this_cpu_write(xen_lazy_mode, mode); | ||
| 89 | } | ||
| 90 | |||
| 91 | static inline void leave_lazy(enum xen_lazy_mode mode) | ||
| 92 | { | ||
| 93 | BUG_ON(this_cpu_read(xen_lazy_mode) != mode); | ||
| 94 | |||
| 95 | if (this_cpu_read(xen_lazy_nesting) == 0) | ||
| 96 | this_cpu_write(xen_lazy_mode, XEN_LAZY_NONE); | ||
| 97 | else | ||
| 98 | this_cpu_dec(xen_lazy_nesting); | ||
| 99 | } | ||
| 100 | |||
| 101 | enum xen_lazy_mode xen_get_lazy_mode(void); | ||
| 102 | |||
| 66 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ | 103 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ |
| @@ -720,13 +720,8 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end) · 719 unmodified lines | |||
| 720 | { | 720 | { |
| 721 | s32 *s; | 721 | s32 *s; |
| 722 | 722 | ||
| 723 | /* | 723 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) |
| 724 | * Do not patch out the default return thunks if those needed are the | 724 | static_call_force_reinit(); |
| 725 | * ones generated by the compiler. | ||
| 726 | */ | ||
| 727 | if (cpu_feature_enabled(X86_FEATURE_RETHUNK) && | ||
| 728 | (x86_return_thunk == __x86_return_thunk)) | ||
| 729 | return; | ||
| 730 | 725 | ||
| 731 | for (s = start; s < end; s++) { | 726 | for (s = start; s < end; s++) { |
| 732 | void *dest = NULL, *addr = (void *)s + *s; | 727 | void *dest = NULL, *addr = (void *)s + *s; |
| @@ -1533,7 +1533,7 @@ static void __init build_socket_tables(void) · 1532 unmodified lines | |||
| 1533 | { | 1533 | { |
| 1534 | struct uv_gam_range_entry *gre = uv_gre_table; | 1534 | struct uv_gam_range_entry *gre = uv_gre_table; |
| 1535 | int nums, numn, nump; | 1535 | int nums, numn, nump; |
| 1536 | int cpu, i, lnid; | 1536 | int i, lnid, apicid; |
| 1537 | int minsock = _min_socket; | 1537 | int minsock = _min_socket; |
| 1538 | int maxsock = _max_socket; | 1538 | int maxsock = _max_socket; |
| 1539 | int minpnode = _min_pnode; | 1539 | int minpnode = _min_pnode; |
| @@ -1584,15 +1584,14 @@ static void __init build_socket_tables(void) · 44 unmodified lines | |||
| 1584 | 1584 | ||
| 1585 | /* Set socket -> node values: */ | 1585 | /* Set socket -> node values: */ |
| 1586 | lnid = NUMA_NO_NODE; | 1586 | lnid = NUMA_NO_NODE; |
| 1587 | for_each_possible_cpu(cpu) { | 1587 | for (apicid = 0; apicid < ARRAY_SIZE(__apicid_to_node); apicid++) { |
| 1588 | int nid = cpu_to_node(cpu); | 1588 | int nid = __apicid_to_node[apicid]; |
| 1589 | int apicid, sockid; | 1589 | int sockid; |
| 1590 | 1590 | ||
| 1591 | if (lnid == nid) | 1591 | if ((nid == NUMA_NO_NODE) || (lnid == nid)) |
| 1592 | continue; | 1592 | continue; |
| 1593 | lnid = nid; | 1593 | lnid = nid; |
| 1594 | 1594 | ||
| 1595 | apicid = per_cpu(x86_cpu_to_apicid, cpu); | ||
| 1596 | sockid = apicid >> uv_cpuid.socketid_shift; | 1595 | sockid = apicid >> uv_cpuid.socketid_shift; |
| 1597 | 1596 | ||
| 1598 | if (_socket_to_node[sockid - minsock] == SOCK_EMPTY) | 1597 | if (_socket_to_node[sockid - minsock] == SOCK_EMPTY) |
| @@ -272,7 +272,6 @@ void __init callthunks_patch_builtin_calls(void) · 271 unmodified lines | |||
| 272 | pr_info("Setting up call depth tracking\n"); | 272 | pr_info("Setting up call depth tracking\n"); |
| 273 | mutex_lock(&text_mutex); | 273 | mutex_lock(&text_mutex); |
| 274 | callthunks_setup(&cs, &builtin_coretext); | 274 | callthunks_setup(&cs, &builtin_coretext); |
| 275 | static_call_force_reinit(); | ||
| 276 | thunks_initialized = true; | 275 | thunks_initialized = true; |
| 277 | mutex_unlock(&text_mutex); | 276 | mutex_unlock(&text_mutex); |
| 278 | } | 277 | } |
| @@ -766,6 +766,15 @@ static void early_init_amd(struct cpuinfo_x86 *c) · 765 unmodified lines | |||
| 766 | 766 | ||
| 767 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) | 767 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) |
| 768 | smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; | 768 | smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; |
| 769 | |||
| 770 | if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) { | ||
| 771 | if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB)) | ||
| 772 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 773 | else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { | ||
| 774 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 775 | setup_force_cpu_cap(X86_FEATURE_SBPB); | ||
| 776 | } | ||
| 777 | } | ||
| 769 | } | 778 | } |
| 770 | 779 | ||
| 771 | static void init_amd_k8(struct cpuinfo_x86 *c) | 780 | static void init_amd_k8(struct cpuinfo_x86 *c) |
| @@ -1301,25 +1310,6 @@ void amd_check_microcode(void) · 529 unmodified lines | |||
| 1301 | on_each_cpu(zenbleed_check_cpu, NULL, 1); | 1310 | on_each_cpu(zenbleed_check_cpu, NULL, 1); |
| 1302 | } | 1311 | } |
| 1303 | 1312 | ||
| 1304 | bool cpu_has_ibpb_brtype_microcode(void) | ||
| 1305 | { | ||
| 1306 | switch (boot_cpu_data.x86) { | ||
| 1307 | /* Zen1/2 IBPB flushes branch type predictions too. */ | ||
| 1308 | case 0x17: | ||
| 1309 | return boot_cpu_has(X86_FEATURE_AMD_IBPB); | ||
| 1310 | case 0x19: | ||
| 1311 | /* Poke the MSR bit on Zen3/4 to check its presence. */ | ||
| 1312 | if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { | ||
| 1313 | setup_force_cpu_cap(X86_FEATURE_SBPB); | ||
| 1314 | return true; | ||
| 1315 | } else { | ||
| 1316 | return false; | ||
| 1317 | } | ||
| 1318 | default: | ||
| 1319 | return false; | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | /* | 1313 | /* |
| 1324 | * Issue a DIV 0/1 insn to clear any division data from previous DIV | 1314 | * Issue a DIV 0/1 insn to clear any division data from previous DIV |
| 1325 | * operations. | 1315 | * operations. |
| @@ -2404,26 +2404,15 @@ early_param("spec_rstack_overflow", srso_parse_cmdline); · 2403 unmodified lines | |||
| 2404 | 2404 | ||
| 2405 | static void __init srso_select_mitigation(void) | 2405 | static void __init srso_select_mitigation(void) |
| 2406 | { | 2406 | { |
| 2407 | bool has_microcode; | 2407 | bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE); |
| 2408 | 2408 | ||
| 2409 | if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) | 2409 | if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) |
| 2410 | goto pred_cmd; | 2410 | goto pred_cmd; |
| 2411 | 2411 | ||
| 2412 | /* | ||
| 2413 | * The first check is for the kernel running as a guest in order | ||
| 2414 | * for guests to verify whether IBPB is a viable mitigation. | ||
| 2415 | */ | ||
| 2416 | has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); | ||
| 2417 | if (!has_microcode) { | 2412 | if (!has_microcode) { |
| 2418 | pr_warn("IBPB-extending microcode not applied!\n"); | 2413 | pr_warn("IBPB-extending microcode not applied!\n"); |
| 2419 | pr_warn(SRSO_NOTICE); | 2414 | pr_warn(SRSO_NOTICE); |
| 2420 | } else { | 2415 | } else { |
| 2421 | /* | ||
| 2422 | * Enable the synthetic (even if in a real CPUID leaf) | ||
| 2423 | * flags for guests. | ||
| 2424 | */ | ||
| 2425 | setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); | ||
| 2426 | |||
| 2427 | /* | 2416 | /* |
| 2428 | * Zen1/2 with SMT off aren't vulnerable after the right | 2417 | * Zen1/2 with SMT off aren't vulnerable after the right |
| 2429 | * IBPB microcode has been applied. | 2418 | * IBPB microcode has been applied. |
| @@ -2444,7 +2433,7 @@ static void __init srso_select_mitigation(void) · 14 unmodified lines | |||
| 2444 | 2433 | ||
| 2445 | switch (srso_cmd) { | 2434 | switch (srso_cmd) { |
| 2446 | case SRSO_CMD_OFF: | 2435 | case SRSO_CMD_OFF: |
| 2447 | return; | 2436 | goto pred_cmd; |
| 2448 | 2437 | ||
| 2449 | case SRSO_CMD_MICROCODE: | 2438 | case SRSO_CMD_MICROCODE: |
| 2450 | if (has_microcode) { | 2439 | if (has_microcode) { |
| @@ -2717,7 +2706,7 @@ static ssize_t srso_show_state(char *buf) · 266 unmodified lines | |||
| 2717 | 2706 | ||
| 2718 | return sysfs_emit(buf, "%s%s\n", | 2707 | return sysfs_emit(buf, "%s%s\n", |
| 2719 | srso_strings[srso_mitigation], | 2708 | srso_strings[srso_mitigation], |
| 2720 | (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); | 2709 | boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); |
| 2721 | } | 2710 | } |
| 2722 | 2711 | ||
| 2723 | static ssize_t gds_show_state(char *buf) | 2712 | static ssize_t gds_show_state(char *buf) |
| @@ -1303,7 +1303,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { · 1302 unmodified lines | |||
| 1303 | VULNBL_AMD(0x15, RETBLEED), | 1303 | VULNBL_AMD(0x15, RETBLEED), |
| 1304 | VULNBL_AMD(0x16, RETBLEED), | 1304 | VULNBL_AMD(0x16, RETBLEED), |
| 1305 | VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), | 1305 | VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), |
| 1306 | VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), | 1306 | VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), |
| 1307 | VULNBL_AMD(0x19, SRSO), | 1307 | VULNBL_AMD(0x19, SRSO), |
| 1308 | {} | 1308 | {} |
| 1309 | }; | 1309 | }; |
| @@ -235,6 +235,21 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page, · 234 unmodified lines | |||
| 235 | return epc_page; | 235 | return epc_page; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /* | ||
| 239 | * Ensure the SECS page is not swapped out. Must be called with encl->lock | ||
| 240 | * to protect the enclave states including SECS and ensure the SECS page is | ||
| 241 | * not swapped out again while being used. | ||
| 242 | */ | ||
| 243 | static struct sgx_epc_page *sgx_encl_load_secs(struct sgx_encl *encl) | ||
| 244 | { | ||
| 245 | struct sgx_epc_page *epc_page = encl->secs.epc_page; | ||
| 246 | |||
| 247 | if (!epc_page) | ||
| 248 | epc_page = sgx_encl_eldu(&encl->secs, NULL); | ||
| 249 | |||
| 250 | return epc_page; | ||
| 251 | } | ||
| 252 | |||
| 238 | static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, | 253 | static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, |
| 239 | struct sgx_encl_page *entry) | 254 | struct sgx_encl_page *entry) |
| 240 | { | 255 | { |
| @@ -248,11 +263,9 @@ static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, · 7 unmodified lines | |||
| 248 | return entry; | 263 | return entry; |
| 249 | } | 264 | } |
| 250 | 265 | ||
| 251 | if (!(encl->secs.epc_page)) { | 266 | epc_page = sgx_encl_load_secs(encl); |
| 252 | epc_page = sgx_encl_eldu(&encl->secs, NULL); | 267 | if (IS_ERR(epc_page)) |
| 253 | if (IS_ERR(epc_page)) | 268 | return ERR_CAST(epc_page); |
| 254 | return ERR_CAST(epc_page); | ||
| 255 | } | ||
| 256 | 269 | ||
| 257 | epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); | 270 | epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); |
| 258 | if (IS_ERR(epc_page)) | 271 | if (IS_ERR(epc_page)) |
| @@ -339,6 +352,13 @@ static vm_fault_t sgx_encl_eaug_page(struct vm_area_struct *vma, · 80 unmodified lines | |||
| 339 | 352 | ||
| 340 | mutex_lock(&encl->lock); | 353 | mutex_lock(&encl->lock); |
| 341 | 354 | ||
| 355 | epc_page = sgx_encl_load_secs(encl); | ||
| 356 | if (IS_ERR(epc_page)) { | ||
| 357 | if (PTR_ERR(epc_page) == -EBUSY) | ||
| 358 | vmret = VM_FAULT_NOPAGE; | ||
| 359 | goto err_out_unlock; | ||
| 360 | } | ||
| 361 | |||
| 342 | epc_page = sgx_alloc_epc_page(encl_page, false); | 362 | epc_page = sgx_alloc_epc_page(encl_page, false); |
| 343 | if (IS_ERR(epc_page)) { | 363 | if (IS_ERR(epc_page)) { |
| 344 | if (PTR_ERR(epc_page) == -EBUSY) | 364 | if (PTR_ERR(epc_page) == -EBUSY) |
| @@ -695,7 +695,6 @@ void kgdb_arch_exit(void) · 694 unmodified lines | |||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | /** | 697 | /** |
| 698 | * | ||
| 699 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. | 698 | * kgdb_skipexception - Bail out of KGDB when we've been triggered. |
| 700 | * @exception: Exception vector number | 699 | * @exception: Exception vector number |
| 701 | * @regs: Current &struct pt_regs. | 700 | * @regs: Current &struct pt_regs. |
| @@ -143,66 +143,7 @@ int paravirt_disable_iospace(void) · 142 unmodified lines | |||
| 143 | return request_resource(&ioport_resource, &reserve_ioports); | 143 | return request_resource(&ioport_resource, &reserve_ioports); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE; | ||
| 147 | |||
| 148 | static inline void enter_lazy(enum paravirt_lazy_mode mode) | ||
| 149 | { | ||
| 150 | BUG_ON(this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); | ||
| 151 | |||
| 152 | this_cpu_write(paravirt_lazy_mode, mode); | ||
| 153 | } | ||
| 154 | |||
| 155 | static void leave_lazy(enum paravirt_lazy_mode mode) | ||
| 156 | { | ||
| 157 | BUG_ON(this_cpu_read(paravirt_lazy_mode) != mode); | ||
| 158 | |||
| 159 | this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE); | ||
| 160 | } | ||
| 161 | |||
| 162 | void paravirt_enter_lazy_mmu(void) | ||
| 163 | { | ||
| 164 | enter_lazy(PARAVIRT_LAZY_MMU); | ||
| 165 | } | ||
| 166 | |||
| 167 | void paravirt_leave_lazy_mmu(void) | ||
| 168 | { | ||
| 169 | leave_lazy(PARAVIRT_LAZY_MMU); | ||
| 170 | } | ||
| 171 | |||
| 172 | void paravirt_flush_lazy_mmu(void) | ||
| 173 | { | ||
| 174 | preempt_disable(); | ||
| 175 | |||
| 176 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
| 177 | arch_leave_lazy_mmu_mode(); | ||
| 178 | arch_enter_lazy_mmu_mode(); | ||
| 179 | } | ||
| 180 | |||
| 181 | preempt_enable(); | ||
| 182 | } | ||
| 183 | |||
| 184 | #ifdef CONFIG_PARAVIRT_XXL | 146 | #ifdef CONFIG_PARAVIRT_XXL |
| 185 | void paravirt_start_context_switch(struct task_struct *prev) | ||
| 186 | { | ||
| 187 | BUG_ON(preemptible()); | ||
| 188 | |||
| 189 | if (this_cpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) { | ||
| 190 | arch_leave_lazy_mmu_mode(); | ||
| 191 | set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); | ||
| 192 | } | ||
| 193 | enter_lazy(PARAVIRT_LAZY_CPU); | ||
| 194 | } | ||
| 195 | |||
| 196 | void paravirt_end_context_switch(struct task_struct *next) | ||
| 197 | { | ||
| 198 | BUG_ON(preemptible()); | ||
| 199 | |||
| 200 | leave_lazy(PARAVIRT_LAZY_CPU); | ||
| 201 | |||
| 202 | if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) | ||
| 203 | arch_enter_lazy_mmu_mode(); | ||
| 204 | } | ||
| 205 | |||
| 206 | static noinstr void pv_native_write_cr2(unsigned long val) | 147 | static noinstr void pv_native_write_cr2(unsigned long val) |
| 207 | { | 148 | { |
| 208 | native_write_cr2(val); | 149 | native_write_cr2(val); |
| @@ -229,14 +170,6 @@ static noinstr void pv_native_safe_halt(void) · 20 unmodified lines | |||
| 229 | } | 170 | } |
| 230 | #endif | 171 | #endif |
| 231 | 172 | ||
| 232 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | ||
| 233 | { | ||
| 234 | if (in_interrupt()) | ||
| 235 | return PARAVIRT_LAZY_NONE; | ||
| 236 | |||
| 237 | return this_cpu_read(paravirt_lazy_mode); | ||
| 238 | } | ||
| 239 | |||
| 240 | struct pv_info pv_info = { | 173 | struct pv_info pv_info = { |
| 241 | .name = "bare hardware", | 174 | .name = "bare hardware", |
| 242 | #ifdef CONFIG_PARAVIRT_XXL | 175 | #ifdef CONFIG_PARAVIRT_XXL |
| @@ -257,13 +257,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 256 unmodified lines | |||
| 257 | if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP))) | 257 | if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP))) |
| 258 | io_bitmap_share(p); | 258 | io_bitmap_share(p); |
| 259 | 259 | ||
| 260 | /* | ||
| 261 | * If copy_thread() if failing, don't leak the shadow stack possibly | ||
| 262 | * allocated in shstk_alloc_thread_stack() above. | ||
| 263 | */ | ||
| 264 | if (ret) | ||
| 265 | shstk_free(p); | ||
| 266 | |||
| 267 | return ret; | 260 | return ret; |
| 268 | } | 261 | } |
| 269 | 262 | ||
| @@ -358,15 +358,11 @@ static void __init add_early_ima_buffer(u64 phys_addr) · 357 unmodified lines | |||
| 358 | #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) | 358 | #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) |
| 359 | int __init ima_free_kexec_buffer(void) | 359 | int __init ima_free_kexec_buffer(void) |
| 360 | { | 360 | { |
| 361 | int rc; | ||
| 362 | |||
| 363 | if (!ima_kexec_buffer_size) | 361 | if (!ima_kexec_buffer_size) |
| 364 | return -ENOENT; | 362 | return -ENOENT; |
| 365 | 363 | ||
| 366 | rc = memblock_phys_free(ima_kexec_buffer_phys, | 364 | memblock_free_late(ima_kexec_buffer_phys, |
| 367 | ima_kexec_buffer_size); | 365 | ima_kexec_buffer_size); |
| 368 | if (rc) | ||
| 369 | return rc; | ||
| 370 | 366 | ||
| 371 | ima_kexec_buffer_phys = 0; | 367 | ima_kexec_buffer_phys = 0; |
| 372 | ima_kexec_buffer_size = 0; | 368 | ima_kexec_buffer_size = 0; |
| @@ -205,10 +205,21 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long cl · 204 unmodified lines | |||
| 205 | return 0; | 205 | return 0; |
| 206 | 206 | ||
| 207 | /* | 207 | /* |
| 208 | * For CLONE_VM, except vfork, the child needs a separate shadow | 208 | * For CLONE_VFORK the child will share the parents shadow stack. |
| 209 | * Make sure to clear the internal tracking of the thread shadow | ||
| 210 | * stack so the freeing logic run for child knows to leave it alone. | ||
| 211 | */ | ||
| 212 | if (clone_flags & CLONE_VFORK) { | ||
| 213 | shstk->base = 0; | ||
| 214 | shstk->size = 0; | ||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* | ||
| 219 | * For !CLONE_VM the child will use a copy of the parents shadow | ||
| 209 | * stack. | 220 | * stack. |
| 210 | */ | 221 | */ |
| 211 | if ((clone_flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM) | 222 | if (!(clone_flags & CLONE_VM)) |
| 212 | return 0; | 223 | return 0; |
| 213 | 224 | ||
| 214 | size = adjust_shstk_size(stack_size); | 225 | size = adjust_shstk_size(stack_size); |
| @@ -408,7 +419,25 @@ void shstk_free(struct task_struct *tsk) · 193 unmodified lines | |||
| 408 | if (!tsk->mm || tsk->mm != current->mm) | 419 | if (!tsk->mm || tsk->mm != current->mm) |
| 409 | return; | 420 | return; |
| 410 | 421 | ||
| 422 | /* | ||
| 423 | * If shstk->base is NULL, then this task is not managing its | ||
| 424 | * own shadow stack (CLONE_VFORK). So skip freeing it. | ||
| 425 | */ | ||
| 426 | if (!shstk->base) | ||
| 427 | return; | ||
| 428 | |||
| 429 | /* | ||
| 430 | * shstk->base is NULL for CLONE_VFORK child tasks, and so is | ||
| 431 | * normal. But size = 0 on a shstk->base is not normal and | ||
| 432 | * indicated an attempt to free the thread shadow stack twice. | ||
| 433 | * Warn about it. | ||
| 434 | */ | ||
| 435 | if (WARN_ON(!shstk->size)) | ||
| 436 | return; | ||
| 437 | |||
| 411 | unmap_shadow_stack(shstk->base, shstk->size); | 438 | unmap_shadow_stack(shstk->base, shstk->size); |
| 439 | |||
| 440 | shstk->size = 0; | ||
| 412 | } | 441 | } |
| 413 | 442 | ||
| 414 | static int wrss_control(bool enable) | 443 | static int wrss_control(bool enable) |
| @@ -579,7 +579,6 @@ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) · 578 unmodified lines | |||
| 579 | } | 579 | } |
| 580 | 580 | ||
| 581 | 581 | ||
| 582 | #if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_CLUSTER) || defined(CONFIG_SCHED_MC) | ||
| 583 | static inline int x86_sched_itmt_flags(void) | 582 | static inline int x86_sched_itmt_flags(void) |
| 584 | { | 583 | { |
| 585 | return sysctl_sched_itmt_enabled ? SD_ASYM_PACKING : 0; | 584 | return sysctl_sched_itmt_enabled ? SD_ASYM_PACKING : 0; |
| @@ -603,7 +602,14 @@ static int x86_cluster_flags(void) · 17 unmodified lines | |||
| 603 | return cpu_cluster_flags() | x86_sched_itmt_flags(); | 602 | return cpu_cluster_flags() | x86_sched_itmt_flags(); |
| 604 | } | 603 | } |
| 605 | #endif | 604 | #endif |
| 606 | #endif | 605 | |
| 606 | static int x86_die_flags(void) | ||
| 607 | { | ||
| 608 | if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) | ||
| 609 | return x86_sched_itmt_flags(); | ||
| 610 | |||
| 611 | return 0; | ||
| 612 | } | ||
| 607 | 613 | ||
| 608 | /* | 614 | /* |
| 609 | * Set if a package/die has multiple NUMA nodes inside. | 615 | * Set if a package/die has multiple NUMA nodes inside. |
| @@ -640,7 +646,7 @@ static void __init build_sched_topology(void) · 30 unmodified lines | |||
| 640 | */ | 646 | */ |
| 641 | if (!x86_has_numa_in_package) { | 647 | if (!x86_has_numa_in_package) { |
| 642 | x86_topology[i++] = (struct sched_domain_topology_level){ | 648 | x86_topology[i++] = (struct sched_domain_topology_level){ |
| 643 | cpu_cpu_mask, SD_INIT_NAME(DIE) | 649 | cpu_cpu_mask, x86_die_flags, SD_INIT_NAME(DIE) |
| 644 | }; | 650 | }; |
| 645 | } | 651 | } |
| 646 | 652 | ||
| @@ -6167,20 +6167,15 @@ static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm) · 6166 unmodified lines | |||
| 6167 | return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages)); | 6167 | return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages)); |
| 6168 | } | 6168 | } |
| 6169 | 6169 | ||
| 6170 | int kvm_mmu_init_vm(struct kvm *kvm) | 6170 | void kvm_mmu_init_vm(struct kvm *kvm) |
| 6171 | { | 6171 | { |
| 6172 | int r; | ||
| 6173 | |||
| 6174 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); | 6172 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); |
| 6175 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); | 6173 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); |
| 6176 | INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages); | 6174 | INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages); |
| 6177 | spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); | 6175 | spin_lock_init(&kvm->arch.mmu_unsync_pages_lock); |
| 6178 | 6176 | ||
| 6179 | if (tdp_mmu_enabled) { | 6177 | if (tdp_mmu_enabled) |
| 6180 | r = kvm_mmu_init_tdp_mmu(kvm); | 6178 | kvm_mmu_init_tdp_mmu(kvm); |
| 6181 | if (r < 0) | ||
| 6182 | return r; | ||
| 6183 | } | ||
| 6184 | 6179 | ||
| 6185 | kvm->arch.split_page_header_cache.kmem_cache = mmu_page_header_cache; | 6180 | kvm->arch.split_page_header_cache.kmem_cache = mmu_page_header_cache; |
| 6186 | kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO; | 6181 | kvm->arch.split_page_header_cache.gfp_zero = __GFP_ZERO; |
| @@ -6189,8 +6184,6 @@ int kvm_mmu_init_vm(struct kvm *kvm) · 2 unmodified lines | |||
| 6189 | 6184 | ||
| 6190 | kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; | 6185 | kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache; |
| 6191 | kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; | 6186 | kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO; |
| 6192 | |||
| 6193 | return 0; | ||
| 6194 | } | 6187 | } |
| 6195 | 6188 | ||
| 6196 | static void mmu_free_vm_memory_caches(struct kvm *kvm) | 6189 | static void mmu_free_vm_memory_caches(struct kvm *kvm) |
| @@ -6246,7 +6239,6 @@ static bool kvm_rmap_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_e · 49 unmodified lines | |||
| 6246 | void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) | 6239 | void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) |
| 6247 | { | 6240 | { |
| 6248 | bool flush; | 6241 | bool flush; |
| 6249 | int i; | ||
| 6250 | 6242 | ||
| 6251 | if (WARN_ON_ONCE(gfn_end <= gfn_start)) | 6243 | if (WARN_ON_ONCE(gfn_end <= gfn_start)) |
| 6252 | return; | 6244 | return; |
| @@ -6257,11 +6249,8 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) · 4 unmodified lines | |||
| 6257 | 6249 | ||
| 6258 | flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); | 6250 | flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); |
| 6259 | 6251 | ||
| 6260 | if (tdp_mmu_enabled) { | 6252 | if (tdp_mmu_enabled) |
| 6261 | for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) | 6253 | flush = kvm_tdp_mmu_zap_leafs(kvm, gfn_start, gfn_end, flush); |
| 6262 | flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start, | ||
| 6263 | gfn_end, true, flush); | ||
| 6264 | } | ||
| 6265 | 6254 | ||
| 6266 | if (flush) | 6255 | if (flush) |
| 6267 | kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - gfn_start); | 6256 | kvm_flush_remote_tlbs_range(kvm, gfn_start, gfn_end - gfn_start); |
| @@ -58,7 +58,12 @@ struct kvm_mmu_page { · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | bool tdp_mmu_page; | 59 | bool tdp_mmu_page; |
| 60 | bool unsync; | 60 | bool unsync; |
| 61 | u8 mmu_valid_gen; | 61 | union { |
| 62 | u8 mmu_valid_gen; | ||
| 63 | |||
| 64 | /* Only accessed under slots_lock. */ | ||
| 65 | bool tdp_mmu_scheduled_root_to_zap; | ||
| 66 | }; | ||
| 62 | 67 | ||
| 63 | /* | 68 | /* |
| 64 | * The shadow page can't be replaced by an equivalent huge page | 69 | * The shadow page can't be replaced by an equivalent huge page |
| @@ -100,13 +105,7 @@ struct kvm_mmu_page { · 35 unmodified lines | |||
| 100 | struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ | 105 | struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */ |
| 101 | tdp_ptep_t ptep; | 106 | tdp_ptep_t ptep; |
| 102 | }; | 107 | }; |
| 103 | union { | 108 | DECLARE_BITMAP(unsync_child_bitmap, 512); |
| 104 | DECLARE_BITMAP(unsync_child_bitmap, 512); | ||
| 105 | struct { | ||
| 106 | struct work_struct tdp_mmu_async_work; | ||
| 107 | void *tdp_mmu_async_data; | ||
| 108 | }; | ||
| 109 | }; | ||
| 110 | 109 | ||
| 111 | /* | 110 | /* |
| 112 | * Tracks shadow pages that, if zapped, would allow KVM to create an NX | 111 | * Tracks shadow pages that, if zapped, would allow KVM to create an NX |
| @@ -12,18 +12,10 @@ · 11 unmodified lines | |||
| 12 | #include <trace/events/kvm.h> | 12 | #include <trace/events/kvm.h> |
| 13 | 13 | ||
| 14 | /* Initializes the TDP MMU for the VM, if enabled. */ | 14 | /* Initializes the TDP MMU for the VM, if enabled. */ |
| 15 | int kvm_mmu_init_tdp_mmu(struct kvm *kvm) | 15 | void kvm_mmu_init_tdp_mmu(struct kvm *kvm) |
| 16 | { | 16 | { |
| 17 | struct workqueue_struct *wq; | ||
| 18 | |||
| 19 | wq = alloc_workqueue("kvm", WQ_UNBOUND|WQ_MEM_RECLAIM|WQ_CPU_INTENSIVE, 0); | ||
| 20 | if (!wq) | ||
| 21 | return -ENOMEM; | ||
| 22 | |||
| 23 | INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); | 17 | INIT_LIST_HEAD(&kvm->arch.tdp_mmu_roots); |
| 24 | spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); | 18 | spin_lock_init(&kvm->arch.tdp_mmu_pages_lock); |
| 25 | kvm->arch.tdp_mmu_zap_wq = wq; | ||
| 26 | return 1; | ||
| 27 | } | 19 | } |
| 28 | 20 | ||
| 29 | /* Arbitrarily returns true so that this may be used in if statements. */ | 21 | /* Arbitrarily returns true so that this may be used in if statements. */ |
| @@ -46,20 +38,15 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm) · 16 unmodified lines | |||
| 46 | * ultimately frees all roots. | 38 | * ultimately frees all roots. |
| 47 | */ | 39 | */ |
| 48 | kvm_tdp_mmu_invalidate_all_roots(kvm); | 40 | kvm_tdp_mmu_invalidate_all_roots(kvm); |
| 49 | 41 | kvm_tdp_mmu_zap_invalidated_roots(kvm); | |
| 50 | /* | ||
| 51 | * Destroying a workqueue also first flushes the workqueue, i.e. no | ||
| 52 | * need to invoke kvm_tdp_mmu_zap_invalidated_roots(). | ||
| 53 | */ | ||
| 54 | destroy_workqueue(kvm->arch.tdp_mmu_zap_wq); | ||
| 55 | 42 | ||
| 56 | WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); | 43 | WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages)); |
| 57 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); | 44 | WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots)); |
| 58 | 45 | ||
| 59 | /* | 46 | /* |
| 60 | * Ensure that all the outstanding RCU callbacks to free shadow pages | 47 | * Ensure that all the outstanding RCU callbacks to free shadow pages |
| 61 | * can run before the VM is torn down. Work items on tdp_mmu_zap_wq | 48 | * can run before the VM is torn down. Putting the last reference to |
| 62 | * can call kvm_tdp_mmu_put_root and create new callbacks. | 49 | * zapped roots will create new callbacks. |
| 63 | */ | 50 | */ |
| 64 | rcu_barrier(); | 51 | rcu_barrier(); |
| 65 | } | 52 | } |
| @@ -86,46 +73,6 @@ static void tdp_mmu_free_sp_rcu_callback(struct rcu_head *head) · 20 unmodified lines | |||
| 86 | tdp_mmu_free_sp(sp); | 73 | tdp_mmu_free_sp(sp); |
| 87 | } | 74 | } |
| 88 | 75 | ||
| 89 | static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, | ||
| 90 | bool shared); | ||
| 91 | |||
| 92 | static void tdp_mmu_zap_root_work(struct work_struct *work) | ||
| 93 | { | ||
| 94 | struct kvm_mmu_page *root = container_of(work, struct kvm_mmu_page, | ||
| 95 | tdp_mmu_async_work); | ||
| 96 | struct kvm *kvm = root->tdp_mmu_async_data; | ||
| 97 | |||
| 98 | read_lock(&kvm->mmu_lock); | ||
| 99 | |||
| 100 | /* | ||
| 101 | * A TLB flush is not necessary as KVM performs a local TLB flush when | ||
| 102 | * allocating a new root (see kvm_mmu_load()), and when migrating vCPU | ||
| 103 | * to a different pCPU. Note, the local TLB flush on reuse also | ||
| 104 | * invalidates any paging-structure-cache entries, i.e. TLB entries for | ||
| 105 | * intermediate paging structures, that may be zapped, as such entries | ||
| 106 | * are associated with the ASID on both VMX and SVM. | ||
| 107 | */ | ||
| 108 | tdp_mmu_zap_root(kvm, root, true); | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Drop the refcount using kvm_tdp_mmu_put_root() to test its logic for | ||
| 112 | * avoiding an infinite loop. By design, the root is reachable while | ||
| 113 | * it's being asynchronously zapped, thus a different task can put its | ||
| 114 | * last reference, i.e. flowing through kvm_tdp_mmu_put_root() for an | ||
| 115 | * asynchronously zapped root is unavoidable. | ||
| 116 | */ | ||
| 117 | kvm_tdp_mmu_put_root(kvm, root, true); | ||
| 118 | |||
| 119 | read_unlock(&kvm->mmu_lock); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void tdp_mmu_schedule_zap_root(struct kvm *kvm, struct kvm_mmu_page *root) | ||
| 123 | { | ||
| 124 | root->tdp_mmu_async_data = kvm; | ||
| 125 | INIT_WORK(&root->tdp_mmu_async_work, tdp_mmu_zap_root_work); | ||
| 126 | queue_work(kvm->arch.tdp_mmu_zap_wq, &root->tdp_mmu_async_work); | ||
| 127 | } | ||
| 128 | |||
| 129 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, | 76 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, |
| 130 | bool shared) | 77 | bool shared) |
| 131 | { | 78 | { |
| @@ -211,8 +158,12 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm, · 79 unmodified lines | |||
| 211 | #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ | 158 | #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ |
| 212 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) | 159 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) |
| 213 | 160 | ||
| 214 | #define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \ | 161 | #define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _shared) \ |
| 215 | __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false) | 162 | for (_root = tdp_mmu_next_root(_kvm, NULL, _shared, false); \ |
| 163 | _root; \ | ||
| 164 | _root = tdp_mmu_next_root(_kvm, _root, _shared, false)) \ | ||
| 165 | if (!kvm_lockdep_assert_mmu_lock_held(_kvm, _shared)) { \ | ||
| 166 | } else | ||
| 216 | 167 | ||
| 217 | /* | 168 | /* |
| 218 | * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, | 169 | * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, |
| @@ -292,7 +243,7 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu) · 73 unmodified lines | |||
| 292 | * by a memslot update or by the destruction of the VM. Initialize the | 243 | * by a memslot update or by the destruction of the VM. Initialize the |
| 293 | * refcount to two; one reference for the vCPU, and one reference for | 244 | * refcount to two; one reference for the vCPU, and one reference for |
| 294 | * the TDP MMU itself, which is held until the root is invalidated and | 245 | * the TDP MMU itself, which is held until the root is invalidated and |
| 295 | * is ultimately put by tdp_mmu_zap_root_work(). | 246 | * is ultimately put by kvm_tdp_mmu_zap_invalidated_roots(). |
| 296 | */ | 247 | */ |
| 297 | refcount_set(&root->tdp_mmu_root_count, 2); | 248 | refcount_set(&root->tdp_mmu_root_count, 2); |
| 298 | 249 | ||
| @@ -877,13 +828,12 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root, · 578 unmodified lines | |||
| 877 | * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or | 828 | * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or |
| 878 | * more SPTEs were zapped since the MMU lock was last acquired. | 829 | * more SPTEs were zapped since the MMU lock was last acquired. |
| 879 | */ | 830 | */ |
| 880 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, | 831 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) |
| 881 | bool can_yield, bool flush) | ||
| 882 | { | 832 | { |
| 883 | struct kvm_mmu_page *root; | 833 | struct kvm_mmu_page *root; |
| 884 | 834 | ||
| 885 | for_each_tdp_mmu_root_yield_safe(kvm, root, as_id) | 835 | for_each_tdp_mmu_root_yield_safe(kvm, root, false) |
| 886 | flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush); | 836 | flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); |
| 887 | 837 | ||
| 888 | return flush; | 838 | return flush; |
| 889 | } | 839 | } |
| @@ -891,7 +841,6 @@ bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, · 1 unmodified line | |||
| 891 | void kvm_tdp_mmu_zap_all(struct kvm *kvm) | 841 | void kvm_tdp_mmu_zap_all(struct kvm *kvm) |
| 892 | { | 842 | { |
| 893 | struct kvm_mmu_page *root; | 843 | struct kvm_mmu_page *root; |
| 894 | int i; | ||
| 895 | 844 | ||
| 896 | /* | 845 | /* |
| 897 | * Zap all roots, including invalid roots, as all SPTEs must be dropped | 846 | * Zap all roots, including invalid roots, as all SPTEs must be dropped |
| @@ -905,10 +854,8 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) · 7 unmodified lines | |||
| 905 | * is being destroyed or the userspace VMM has exited. In both cases, | 854 | * is being destroyed or the userspace VMM has exited. In both cases, |
| 906 | * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. | 855 | * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. |
| 907 | */ | 856 | */ |
| 908 | for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { | 857 | for_each_tdp_mmu_root_yield_safe(kvm, root, false) |
| 909 | for_each_tdp_mmu_root_yield_safe(kvm, root, i) | 858 | tdp_mmu_zap_root(kvm, root, false); |
| 910 | tdp_mmu_zap_root(kvm, root, false); | ||
| 911 | } | ||
| 912 | } | 859 | } |
| 913 | 860 | ||
| 914 | /* | 861 | /* |
| @@ -917,18 +864,47 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) · 2 unmodified lines | |||
| 917 | */ | 864 | */ |
| 918 | void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) | 865 | void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm) |
| 919 | { | 866 | { |
| 920 | flush_workqueue(kvm->arch.tdp_mmu_zap_wq); | 867 | struct kvm_mmu_page *root; |
| 868 | |||
| 869 | read_lock(&kvm->mmu_lock); | ||
| 870 | |||
| 871 | for_each_tdp_mmu_root_yield_safe(kvm, root, true) { | ||
| 872 | if (!root->tdp_mmu_scheduled_root_to_zap) | ||
| 873 | continue; | ||
| 874 | |||
| 875 | root->tdp_mmu_scheduled_root_to_zap = false; | ||
| 876 | KVM_BUG_ON(!root->role.invalid, kvm); | ||
| 877 | |||
| 878 | /* | ||
| 879 | * A TLB flush is not necessary as KVM performs a local TLB | ||
| 880 | * flush when allocating a new root (see kvm_mmu_load()), and | ||
| 881 | * when migrating a vCPU to a different pCPU. Note, the local | ||
| 882 | * TLB flush on reuse also invalidates paging-structure-cache | ||
| 883 | * entries, i.e. TLB entries for intermediate paging structures, | ||
| 884 | * that may be zapped, as such entries are associated with the | ||
| 885 | * ASID on both VMX and SVM. | ||
| 886 | */ | ||
| 887 | tdp_mmu_zap_root(kvm, root, true); | ||
| 888 | |||
| 889 | /* | ||
| 890 | * The referenced needs to be put *after* zapping the root, as | ||
| 891 | * the root must be reachable by mmu_notifiers while it's being | ||
| 892 | * zapped | ||
| 893 | */ | ||
| 894 | kvm_tdp_mmu_put_root(kvm, root, true); | ||
| 895 | } | ||
| 896 | |||
| 897 | read_unlock(&kvm->mmu_lock); | ||
| 921 | } | 898 | } |
| 922 | 899 | ||
| 923 | /* | 900 | /* |
| 924 | * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that | 901 | * Mark each TDP MMU root as invalid to prevent vCPUs from reusing a root that |
| 925 | * is about to be zapped, e.g. in response to a memslots update. The actual | 902 | * is about to be zapped, e.g. in response to a memslots update. The actual |
| 926 | * zapping is performed asynchronously. Using a separate workqueue makes it | 903 | * zapping is done separately so that it happens with mmu_lock with read, |
| 927 | * easy to ensure that the destruction is performed before the "fast zap" | 904 | * whereas invalidating roots must be done with mmu_lock held for write (unless |
| 928 | * completes, without keeping a separate list of invalidated roots; the list is | 905 | * the VM is being destroyed). |
| 929 | * effectively the list of work items in the workqueue. | ||
| 930 | * | 906 | * |
| 931 | * Note, the asynchronous worker is gifted the TDP MMU's reference. | 907 | * Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference. |
| 932 | * See kvm_tdp_mmu_get_vcpu_root_hpa(). | 908 | * See kvm_tdp_mmu_get_vcpu_root_hpa(). |
| 933 | */ | 909 | */ |
| 934 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) | 910 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) |
| @@ -953,19 +929,20 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm) · 18 unmodified lines | |||
| 953 | /* | 929 | /* |
| 954 | * As above, mmu_lock isn't held when destroying the VM! There can't | 930 | * As above, mmu_lock isn't held when destroying the VM! There can't |
| 955 | * be other references to @kvm, i.e. nothing else can invalidate roots | 931 | * be other references to @kvm, i.e. nothing else can invalidate roots |
| 956 | * or be consuming roots, but walking the list of roots does need to be | 932 | * or get/put references to roots. |
| 957 | * guarded against roots being deleted by the asynchronous zap worker. | ||
| 958 | */ | 933 | */ |
| 959 | rcu_read_lock(); | 934 | list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) { |
| 960 | 935 | /* | |
| 961 | list_for_each_entry_rcu(root, &kvm->arch.tdp_mmu_roots, link) { | 936 | * Note, invalid roots can outlive a memslot update! Invalid |
| 937 | * roots must be *zapped* before the memslot update completes, | ||
| 938 | * but a different task can acquire a reference and keep the | ||
| 939 | * root alive after its been zapped. | ||
| 940 | */ | ||
| 962 | if (!root->role.invalid) { | 941 | if (!root->role.invalid) { |
| 942 | root->tdp_mmu_scheduled_root_to_zap = true; | ||
| 963 | root->role.invalid = true; | 943 | root->role.invalid = true; |
| 964 | tdp_mmu_schedule_zap_root(kvm, root); | ||
| 965 | } | 944 | } |
| 966 | } | 945 | } |
| 967 | |||
| 968 | rcu_read_unlock(); | ||
| 969 | } | 946 | } |
| 970 | 947 | ||
| 971 | /* | 948 | /* |
| @@ -1146,8 +1123,13 @@ retry: · 174 unmodified lines | |||
| 1146 | bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, | 1123 | bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, |
| 1147 | bool flush) | 1124 | bool flush) |
| 1148 | { | 1125 | { |
| 1149 | return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start, | 1126 | struct kvm_mmu_page *root; |
| 1150 | range->end, range->may_block, flush); | 1127 | |
| 1128 | __for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false, false) | ||
| 1129 | flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end, | ||
| 1130 | range->may_block, flush); | ||
| 1131 | |||
| 1132 | return flush; | ||
| 1151 | } | 1133 | } |
| 1152 | 1134 | ||
| 1153 | typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, | 1135 | typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include "spte.h" | 8 | #include "spte.h" |
| 9 | 9 | ||
| 10 | int kvm_mmu_init_tdp_mmu(struct kvm *kvm); | 10 | void kvm_mmu_init_tdp_mmu(struct kvm *kvm); |
| 11 | void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); | 11 | void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm); |
| 12 | 12 | ||
| 13 | hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); | 13 | hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu); |
| @@ -20,8 +20,7 @@ __must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root) · 6 unmodified lines | |||
| 20 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, | 20 | void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, |
| 21 | bool shared); | 21 | bool shared); |
| 22 | 22 | ||
| 23 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, | 23 | bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush); |
| 24 | gfn_t end, bool can_yield, bool flush); | ||
| 25 | bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); | 24 | bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); |
| 26 | void kvm_tdp_mmu_zap_all(struct kvm *kvm); | 25 | void kvm_tdp_mmu_zap_all(struct kvm *kvm); |
| 27 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); | 26 | void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); |
| @@ -2962,6 +2962,32 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in) · 2961 unmodified lines | |||
| 2962 | count, in); | 2962 | count, in); |
| 2963 | } | 2963 | } |
| 2964 | 2964 | ||
| 2965 | static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm) | ||
| 2966 | { | ||
| 2967 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
| 2968 | |||
| 2969 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { | ||
| 2970 | bool v_tsc_aux = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP) || | ||
| 2971 | guest_cpuid_has(vcpu, X86_FEATURE_RDPID); | ||
| 2972 | |||
| 2973 | set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux); | ||
| 2974 | } | ||
| 2975 | } | ||
| 2976 | |||
| 2977 | void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm) | ||
| 2978 | { | ||
| 2979 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
| 2980 | struct kvm_cpuid_entry2 *best; | ||
| 2981 | |||
| 2982 | /* For sev guests, the memory encryption bit is not reserved in CR3. */ | ||
| 2983 | best = kvm_find_cpuid_entry(vcpu, 0x8000001F); | ||
| 2984 | if (best) | ||
| 2985 | vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); | ||
| 2986 | |||
| 2987 | if (sev_es_guest(svm->vcpu.kvm)) | ||
| 2988 | sev_es_vcpu_after_set_cpuid(svm); | ||
| 2989 | } | ||
| 2990 | |||
| 2965 | static void sev_es_init_vmcb(struct vcpu_svm *svm) | 2991 | static void sev_es_init_vmcb(struct vcpu_svm *svm) |
| 2966 | { | 2992 | { |
| 2967 | struct vmcb *vmcb = svm->vmcb01.ptr; | 2993 | struct vmcb *vmcb = svm->vmcb01.ptr; |
| @@ -3024,14 +3050,6 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm) · 56 unmodified lines | |||
| 3024 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); | 3050 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); |
| 3025 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); | 3051 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); |
| 3026 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); | 3052 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); |
| 3027 | |||
| 3028 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && | ||
| 3029 | (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP) || | ||
| 3030 | guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDPID))) { | ||
| 3031 | set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, 1, 1); | ||
| 3032 | if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP)) | ||
| 3033 | svm_clr_intercept(svm, INTERCEPT_RDTSCP); | ||
| 3034 | } | ||
| 3035 | } | 3053 | } |
| 3036 | 3054 | ||
| 3037 | void sev_init_vmcb(struct vcpu_svm *svm) | 3055 | void sev_init_vmcb(struct vcpu_svm *svm) |
| @@ -683,6 +683,21 @@ static int svm_hardware_enable(void) · 682 unmodified lines | |||
| 683 | 683 | ||
| 684 | amd_pmu_enable_virt(); | 684 | amd_pmu_enable_virt(); |
| 685 | 685 | ||
| 686 | /* | ||
| 687 | * If TSC_AUX virtualization is supported, TSC_AUX becomes a swap type | ||
| 688 | * "B" field (see sev_es_prepare_switch_to_guest()) for SEV-ES guests. | ||
| 689 | * Since Linux does not change the value of TSC_AUX once set, prime the | ||
| 690 | * TSC_AUX field now to avoid a RDMSR on every vCPU run. | ||
| 691 | */ | ||
| 692 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { | ||
| 693 | struct sev_es_save_area *hostsa; | ||
| 694 | u32 msr_hi; | ||
| 695 | |||
| 696 | hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400); | ||
| 697 | |||
| 698 | rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi); | ||
| 699 | } | ||
| 700 | |||
| 686 | return 0; | 701 | return 0; |
| 687 | } | 702 | } |
| 688 | 703 | ||
| @@ -1532,7 +1547,14 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) · 843 unmodified lines | |||
| 1532 | if (tsc_scaling) | 1547 | if (tsc_scaling) |
| 1533 | __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); | 1548 | __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); |
| 1534 | 1549 | ||
| 1535 | if (likely(tsc_aux_uret_slot >= 0)) | 1550 | /* |
| 1551 | * TSC_AUX is always virtualized for SEV-ES guests when the feature is | ||
| 1552 | * available. The user return MSR support is not required in this case | ||
| 1553 | * because TSC_AUX is restored on #VMEXIT from the host save area | ||
| 1554 | * (which has been initialized in svm_hardware_enable()). | ||
| 1555 | */ | ||
| 1556 | if (likely(tsc_aux_uret_slot >= 0) && | ||
| 1557 | (!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm))) | ||
| 1536 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); | 1558 | kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); |
| 1537 | 1559 | ||
| 1538 | svm->guest_state_loaded = true; | 1560 | svm->guest_state_loaded = true; |
| @@ -3086,6 +3108,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) · 1547 unmodified lines | |||
| 3086 | svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0; | 3108 | svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0; |
| 3087 | break; | 3109 | break; |
| 3088 | case MSR_TSC_AUX: | 3110 | case MSR_TSC_AUX: |
| 3111 | /* | ||
| 3112 | * TSC_AUX is always virtualized for SEV-ES guests when the | ||
| 3113 | * feature is available. The user return MSR support is not | ||
| 3114 | * required in this case because TSC_AUX is restored on #VMEXIT | ||
| 3115 | * from the host save area (which has been initialized in | ||
| 3116 | * svm_hardware_enable()). | ||
| 3117 | */ | ||
| 3118 | if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && sev_es_guest(vcpu->kvm)) | ||
| 3119 | break; | ||
| 3120 | |||
| 3089 | /* | 3121 | /* |
| 3090 | * TSC_AUX is usually changed only during boot and never read | 3122 | * TSC_AUX is usually changed only during boot and never read |
| 3091 | * directly. Intercept TSC_AUX instead of exposing it to the | 3123 | * directly. Intercept TSC_AUX instead of exposing it to the |
| @@ -4284,7 +4316,6 @@ static bool svm_has_emulated_msr(struct kvm *kvm, u32 index) · 1192 unmodified lines | |||
| 4284 | static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) | 4316 | static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) |
| 4285 | { | 4317 | { |
| 4286 | struct vcpu_svm *svm = to_svm(vcpu); | 4318 | struct vcpu_svm *svm = to_svm(vcpu); |
| 4287 | struct kvm_cpuid_entry2 *best; | ||
| 4288 | 4319 | ||
| 4289 | /* | 4320 | /* |
| 4290 | * SVM doesn't provide a way to disable just XSAVES in the guest, KVM | 4321 | * SVM doesn't provide a way to disable just XSAVES in the guest, KVM |
| @@ -4328,12 +4359,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) · 37 unmodified lines | |||
| 4328 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_FLUSH_CMD, 0, | 4359 | set_msr_interception(vcpu, svm->msrpm, MSR_IA32_FLUSH_CMD, 0, |
| 4329 | !!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D)); | 4360 | !!guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D)); |
| 4330 | 4361 | ||
| 4331 | /* For sev guests, the memory encryption bit is not reserved in CR3. */ | 4362 | if (sev_guest(vcpu->kvm)) |
| 4332 | if (sev_guest(vcpu->kvm)) { | 4363 | sev_vcpu_after_set_cpuid(svm); |
| 4333 | best = kvm_find_cpuid_entry(vcpu, 0x8000001F); | ||
| 4334 | if (best) | ||
| 4335 | vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); | ||
| 4336 | } | ||
| 4337 | 4364 | ||
| 4338 | init_vmcb_after_set_cpuid(vcpu); | 4365 | init_vmcb_after_set_cpuid(vcpu); |
| 4339 | } | 4366 | } |
| @@ -684,6 +684,7 @@ void __init sev_hardware_setup(void); · 683 unmodified lines | |||
| 684 | void sev_hardware_unsetup(void); | 684 | void sev_hardware_unsetup(void); |
| 685 | int sev_cpu_init(struct svm_cpu_data *sd); | 685 | int sev_cpu_init(struct svm_cpu_data *sd); |
| 686 | void sev_init_vmcb(struct vcpu_svm *svm); | 686 | void sev_init_vmcb(struct vcpu_svm *svm); |
| 687 | void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm); | ||
| 687 | void sev_free_vcpu(struct kvm_vcpu *vcpu); | 688 | void sev_free_vcpu(struct kvm_vcpu *vcpu); |
| 688 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); | 689 | int sev_handle_vmgexit(struct kvm_vcpu *vcpu); |
| 689 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); | 690 | int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); |
| @@ -12308,9 +12308,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 12307 unmodified lines | |||
| 12308 | if (ret) | 12308 | if (ret) |
| 12309 | goto out; | 12309 | goto out; |
| 12310 | 12310 | ||
| 12311 | ret = kvm_mmu_init_vm(kvm); | 12311 | kvm_mmu_init_vm(kvm); |
| 12312 | if (ret) | ||
| 12313 | goto out_page_track; | ||
| 12314 | 12312 | ||
| 12315 | ret = static_call(kvm_x86_vm_init)(kvm); | 12313 | ret = static_call(kvm_x86_vm_init)(kvm); |
| 12316 | if (ret) | 12314 | if (ret) |
| @@ -12355,7 +12353,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 38 unmodified lines | |||
| 12355 | 12353 | ||
| 12356 | out_uninit_mmu: | 12354 | out_uninit_mmu: |
| 12357 | kvm_mmu_uninit_vm(kvm); | 12355 | kvm_mmu_uninit_vm(kvm); |
| 12358 | out_page_track: | ||
| 12359 | kvm_page_track_cleanup(kvm); | 12356 | kvm_page_track_cleanup(kvm); |
| 12360 | out: | 12357 | out: |
| 12361 | return ret; | 12358 | return ret; |
| @@ -40,7 +40,7 @@ SYM_TYPED_FUNC_START(__memcpy) · 39 unmodified lines | |||
| 40 | SYM_FUNC_END(__memcpy) | 40 | SYM_FUNC_END(__memcpy) |
| 41 | EXPORT_SYMBOL(__memcpy) | 41 | EXPORT_SYMBOL(__memcpy) |
| 42 | 42 | ||
| 43 | SYM_FUNC_ALIAS(memcpy, __memcpy) | 43 | SYM_FUNC_ALIAS_MEMFUNC(memcpy, __memcpy) |
| 44 | EXPORT_SYMBOL(memcpy) | 44 | EXPORT_SYMBOL(memcpy) |
| 45 | 45 | ||
| 46 | SYM_FUNC_START_LOCAL(memcpy_orig) | 46 | SYM_FUNC_START_LOCAL(memcpy_orig) |
| @@ -212,5 +212,5 @@ SYM_FUNC_START(__memmove) · 211 unmodified lines | |||
| 212 | SYM_FUNC_END(__memmove) | 212 | SYM_FUNC_END(__memmove) |
| 213 | EXPORT_SYMBOL(__memmove) | 213 | EXPORT_SYMBOL(__memmove) |
| 214 | 214 | ||
| 215 | SYM_FUNC_ALIAS(memmove, __memmove) | 215 | SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove) |
| 216 | EXPORT_SYMBOL(memmove) | 216 | EXPORT_SYMBOL(memmove) |
| @@ -40,7 +40,7 @@ SYM_FUNC_START(__memset) · 39 unmodified lines | |||
| 40 | SYM_FUNC_END(__memset) | 40 | SYM_FUNC_END(__memset) |
| 41 | EXPORT_SYMBOL(__memset) | 41 | EXPORT_SYMBOL(__memset) |
| 42 | 42 | ||
| 43 | SYM_FUNC_ALIAS(memset, __memset) | 43 | SYM_FUNC_ALIAS_MEMFUNC(memset, __memset) |
| 44 | EXPORT_SYMBOL(memset) | 44 | EXPORT_SYMBOL(memset) |
| 45 | 45 | ||
| 46 | SYM_FUNC_START_LOCAL(memset_orig) | 46 | SYM_FUNC_START_LOCAL(memset_orig) |
| @@ -56,7 +56,6 @@ SYM_FUNC_END(__put_user_1) · 55 unmodified lines | |||
| 56 | EXPORT_SYMBOL(__put_user_1) | 56 | EXPORT_SYMBOL(__put_user_1) |
| 57 | 57 | ||
| 58 | SYM_FUNC_START(__put_user_nocheck_1) | 58 | SYM_FUNC_START(__put_user_nocheck_1) |
| 59 | ENDBR | ||
| 60 | ASM_STAC | 59 | ASM_STAC |
| 61 | 2: movb %al,(%_ASM_CX) | 60 | 2: movb %al,(%_ASM_CX) |
| 62 | xor %ecx,%ecx | 61 | xor %ecx,%ecx |
| @@ -76,7 +75,6 @@ SYM_FUNC_END(__put_user_2) · 13 unmodified lines | |||
| 76 | EXPORT_SYMBOL(__put_user_2) | 75 | EXPORT_SYMBOL(__put_user_2) |
| 77 | 76 | ||
| 78 | SYM_FUNC_START(__put_user_nocheck_2) | 77 | SYM_FUNC_START(__put_user_nocheck_2) |
| 79 | ENDBR | ||
| 80 | ASM_STAC | 78 | ASM_STAC |
| 81 | 4: movw %ax,(%_ASM_CX) | 79 | 4: movw %ax,(%_ASM_CX) |
| 82 | xor %ecx,%ecx | 80 | xor %ecx,%ecx |
| @@ -96,7 +94,6 @@ SYM_FUNC_END(__put_user_4) · 13 unmodified lines | |||
| 96 | EXPORT_SYMBOL(__put_user_4) | 94 | EXPORT_SYMBOL(__put_user_4) |
| 97 | 95 | ||
| 98 | SYM_FUNC_START(__put_user_nocheck_4) | 96 | SYM_FUNC_START(__put_user_nocheck_4) |
| 99 | ENDBR | ||
| 100 | ASM_STAC | 97 | ASM_STAC |
| 101 | 6: movl %eax,(%_ASM_CX) | 98 | 6: movl %eax,(%_ASM_CX) |
| 102 | xor %ecx,%ecx | 99 | xor %ecx,%ecx |
| @@ -119,7 +116,6 @@ SYM_FUNC_END(__put_user_8) · 16 unmodified lines | |||
| 119 | EXPORT_SYMBOL(__put_user_8) | 116 | EXPORT_SYMBOL(__put_user_8) |
| 120 | 117 | ||
| 121 | SYM_FUNC_START(__put_user_nocheck_8) | 118 | SYM_FUNC_START(__put_user_nocheck_8) |
| 122 | ENDBR | ||
| 123 | ASM_STAC | 119 | ASM_STAC |
| 124 | 9: mov %_ASM_AX,(%_ASM_CX) | 120 | 9: mov %_ASM_AX,(%_ASM_CX) |
| 125 | #ifdef CONFIG_X86_32 | 121 | #ifdef CONFIG_X86_32 |
| @@ -140,3 +140,15 @@ void __init efi_runtime_update_mappings(void) · 139 unmodified lines | |||
| 140 | } | 140 | } |
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | |||
| 144 | void arch_efi_call_virt_setup(void) | ||
| 145 | { | ||
| 146 | efi_fpu_begin(); | ||
| 147 | firmware_restrict_branch_speculation_start(); | ||
| 148 | } | ||
| 149 | |||
| 150 | void arch_efi_call_virt_teardown(void) | ||
| 151 | { | ||
| 152 | firmware_restrict_branch_speculation_end(); | ||
| 153 | efi_fpu_end(); | ||
| 154 | } | ||
| @@ -474,19 +474,34 @@ void __init efi_dump_pagetable(void) · 473 unmodified lines | |||
| 474 | * can not change under us. | 474 | * can not change under us. |
| 475 | * It should be ensured that there are no concurrent calls to this function. | 475 | * It should be ensured that there are no concurrent calls to this function. |
| 476 | */ | 476 | */ |
| 477 | void efi_enter_mm(void) | 477 | static void efi_enter_mm(void) |
| 478 | { | 478 | { |
| 479 | efi_prev_mm = current->active_mm; | 479 | efi_prev_mm = current->active_mm; |
| 480 | current->active_mm = &efi_mm; | 480 | current->active_mm = &efi_mm; |
| 481 | switch_mm(efi_prev_mm, &efi_mm, NULL); | 481 | switch_mm(efi_prev_mm, &efi_mm, NULL); |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | void efi_leave_mm(void) | 484 | static void efi_leave_mm(void) |
| 485 | { | 485 | { |
| 486 | current->active_mm = efi_prev_mm; | 486 | current->active_mm = efi_prev_mm; |
| 487 | switch_mm(&efi_mm, efi_prev_mm, NULL); | 487 | switch_mm(&efi_mm, efi_prev_mm, NULL); |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | void arch_efi_call_virt_setup(void) | ||
| 491 | { | ||
| 492 | efi_sync_low_kernel_mappings(); | ||
| 493 | efi_fpu_begin(); | ||
| 494 | firmware_restrict_branch_speculation_start(); | ||
| 495 | efi_enter_mm(); | ||
| 496 | } | ||
| 497 | |||
| 498 | void arch_efi_call_virt_teardown(void) | ||
| 499 | { | ||
| 500 | efi_leave_mm(); | ||
| 501 | firmware_restrict_branch_speculation_end(); | ||
| 502 | efi_fpu_end(); | ||
| 503 | } | ||
| 504 | |||
| 490 | static DEFINE_SPINLOCK(efi_runtime_lock); | 505 | static DEFINE_SPINLOCK(efi_runtime_lock); |
| 491 | 506 | ||
| 492 | /* | 507 | /* |
| @@ -19,6 +19,10 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY · 18 unmodified lines | |||
| 19 | # optimization flags. | 19 | # optimization flags. |
| 20 | KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS)) | 20 | KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS)) |
| 21 | 21 | ||
| 22 | # When LTO is enabled, llvm emits many text sections, which is not supported | ||
| 23 | # by kexec. Remove -flto=* flags. | ||
| 24 | KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) | ||
| 25 | |||
| 22 | # When linking purgatory.ro with -r unresolved symbols are not checked, | 26 | # When linking purgatory.ro with -r unresolved symbols are not checked, |
| 23 | # also link a purgatory.chk binary without -r to check for unresolved symbols. | 27 | # also link a purgatory.chk binary without -r to check for unresolved symbols. |
| 24 | PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib | 28 | PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib |
| @@ -138,7 +138,7 @@ void __init xen_efi_init(struct boot_params *boot_params) · 137 unmodified lines | |||
| 138 | if (efi_systab_xen == NULL) | 138 | if (efi_systab_xen == NULL) |
| 139 | return; | 139 | return; |
| 140 | 140 | ||
| 141 | strncpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen", | 141 | strscpy((char *)&boot_params->efi_info.efi_loader_signature, "Xen", |
| 142 | sizeof(boot_params->efi_info.efi_loader_signature)); | 142 | sizeof(boot_params->efi_info.efi_loader_signature)); |
| 143 | boot_params->efi_info.efi_systab = (__u32)__pa(efi_systab_xen); | 143 | boot_params->efi_info.efi_systab = (__u32)__pa(efi_systab_xen); |
| 144 | boot_params->efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32); | 144 | boot_params->efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32); |
| @@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(hypercall_page); · 31 unmodified lines | |||
| 32 | * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info | 32 | * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info |
| 33 | * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info | 33 | * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info |
| 34 | * but during boot it is switched to point to xen_vcpu_info. | 34 | * but during boot it is switched to point to xen_vcpu_info. |
| 35 | * The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events. | 35 | * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events. |
| 36 | */ | 36 | */ |
| 37 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | 37 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); |
| 38 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); | 38 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); |
| @@ -136,7 +136,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback) · 135 unmodified lines | |||
| 136 | 136 | ||
| 137 | inc_irq_stat(irq_hv_callback_count); | 137 | inc_irq_stat(irq_hv_callback_count); |
| 138 | 138 | ||
| 139 | xen_hvm_evtchn_do_upcall(); | 139 | xen_evtchn_do_upcall(); |
| 140 | 140 | ||
| 141 | set_irq_regs(old_regs); | 141 | set_irq_regs(old_regs); |
| 142 | } | 142 | } |
| @@ -101,6 +101,17 @@ struct tls_descs { · 100 unmodified lines | |||
| 101 | struct desc_struct desc[3]; | 101 | struct desc_struct desc[3]; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE; | ||
| 105 | DEFINE_PER_CPU(unsigned int, xen_lazy_nesting); | ||
| 106 | |||
| 107 | enum xen_lazy_mode xen_get_lazy_mode(void) | ||
| 108 | { | ||
| 109 | if (in_interrupt()) | ||
| 110 | return XEN_LAZY_NONE; | ||
| 111 | |||
| 112 | return this_cpu_read(xen_lazy_mode); | ||
| 113 | } | ||
| 114 | |||
| 104 | /* | 115 | /* |
| 105 | * Updating the 3 TLS descriptors in the GDT on every task switch is | 116 | * Updating the 3 TLS descriptors in the GDT on every task switch is |
| 106 | * surprisingly expensive so we avoid updating them if they haven't | 117 | * surprisingly expensive so we avoid updating them if they haven't |
| @@ -362,10 +373,25 @@ static noinstr unsigned long xen_get_debugreg(int reg) · 255 unmodified lines | |||
| 362 | return HYPERVISOR_get_debugreg(reg); | 373 | return HYPERVISOR_get_debugreg(reg); |
| 363 | } | 374 | } |
| 364 | 375 | ||
| 376 | static void xen_start_context_switch(struct task_struct *prev) | ||
| 377 | { | ||
| 378 | BUG_ON(preemptible()); | ||
| 379 | |||
| 380 | if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) { | ||
| 381 | arch_leave_lazy_mmu_mode(); | ||
| 382 | set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); | ||
| 383 | } | ||
| 384 | enter_lazy(XEN_LAZY_CPU); | ||
| 385 | } | ||
| 386 | |||
| 365 | static void xen_end_context_switch(struct task_struct *next) | 387 | static void xen_end_context_switch(struct task_struct *next) |
| 366 | { | 388 | { |
| 389 | BUG_ON(preemptible()); | ||
| 390 | |||
| 367 | xen_mc_flush(); | 391 | xen_mc_flush(); |
| 368 | paravirt_end_context_switch(next); | 392 | leave_lazy(XEN_LAZY_CPU); |
| 393 | if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) | ||
| 394 | arch_enter_lazy_mmu_mode(); | ||
| 369 | } | 395 | } |
| 370 | 396 | ||
| 371 | static unsigned long xen_store_tr(void) | 397 | static unsigned long xen_store_tr(void) |
| @@ -472,7 +498,7 @@ static void xen_set_ldt(const void *addr, unsigned entries) · 100 unmodified lines | |||
| 472 | 498 | ||
| 473 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | 499 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); |
| 474 | 500 | ||
| 475 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 501 | xen_mc_issue(XEN_LAZY_CPU); |
| 476 | } | 502 | } |
| 477 | 503 | ||
| 478 | static void xen_load_gdt(const struct desc_ptr *dtr) | 504 | static void xen_load_gdt(const struct desc_ptr *dtr) |
| @@ -568,7 +594,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) · 89 unmodified lines | |||
| 568 | * exception between the new %fs descriptor being loaded and | 594 | * exception between the new %fs descriptor being loaded and |
| 569 | * %fs being effectively cleared at __switch_to(). | 595 | * %fs being effectively cleared at __switch_to(). |
| 570 | */ | 596 | */ |
| 571 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) | 597 | if (xen_get_lazy_mode() == XEN_LAZY_CPU) |
| 572 | loadsegment(fs, 0); | 598 | loadsegment(fs, 0); |
| 573 | 599 | ||
| 574 | xen_mc_batch(); | 600 | xen_mc_batch(); |
| @@ -577,7 +603,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) · 2 unmodified lines | |||
| 577 | load_TLS_descriptor(t, cpu, 1); | 603 | load_TLS_descriptor(t, cpu, 1); |
| 578 | load_TLS_descriptor(t, cpu, 2); | 604 | load_TLS_descriptor(t, cpu, 2); |
| 579 | 605 | ||
| 580 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 606 | xen_mc_issue(XEN_LAZY_CPU); |
| 581 | } | 607 | } |
| 582 | 608 | ||
| 583 | static void xen_load_gs_index(unsigned int idx) | 609 | static void xen_load_gs_index(unsigned int idx) |
| @@ -909,7 +935,7 @@ static void xen_load_sp0(unsigned long sp0) · 325 unmodified lines | |||
| 909 | 935 | ||
| 910 | mcs = xen_mc_entry(0); | 936 | mcs = xen_mc_entry(0); |
| 911 | MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0); | 937 | MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0); |
| 912 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 938 | xen_mc_issue(XEN_LAZY_CPU); |
| 913 | this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0); | 939 | this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0); |
| 914 | } | 940 | } |
| 915 | 941 | ||
| @@ -973,7 +999,7 @@ static void xen_write_cr0(unsigned long cr0) · 57 unmodified lines | |||
| 973 | 999 | ||
| 974 | MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0); | 1000 | MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0); |
| 975 | 1001 | ||
| 976 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 1002 | xen_mc_issue(XEN_LAZY_CPU); |
| 977 | } | 1003 | } |
| 978 | 1004 | ||
| 979 | static void xen_write_cr4(unsigned long cr4) | 1005 | static void xen_write_cr4(unsigned long cr4) |
| @@ -1156,7 +1182,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = { · 176 unmodified lines | |||
| 1156 | #endif | 1182 | #endif |
| 1157 | .io_delay = xen_io_delay, | 1183 | .io_delay = xen_io_delay, |
| 1158 | 1184 | ||
| 1159 | .start_context_switch = paravirt_start_context_switch, | 1185 | .start_context_switch = xen_start_context_switch, |
| 1160 | .end_context_switch = xen_end_context_switch, | 1186 | .end_context_switch = xen_end_context_switch, |
| 1161 | }, | 1187 | }, |
| 1162 | }; | 1188 | }; |
| @@ -236,7 +236,7 @@ static void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val) · 235 unmodified lines | |||
| 236 | u.val = pmd_val_ma(val); | 236 | u.val = pmd_val_ma(val); |
| 237 | xen_extend_mmu_update(&u); | 237 | xen_extend_mmu_update(&u); |
| 238 | 238 | ||
| 239 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 239 | xen_mc_issue(XEN_LAZY_MMU); |
| 240 | 240 | ||
| 241 | preempt_enable(); | 241 | preempt_enable(); |
| 242 | } | 242 | } |
| @@ -270,7 +270,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval) · 27 unmodified lines | |||
| 270 | { | 270 | { |
| 271 | struct mmu_update u; | 271 | struct mmu_update u; |
| 272 | 272 | ||
| 273 | if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) | 273 | if (xen_get_lazy_mode() != XEN_LAZY_MMU) |
| 274 | return false; | 274 | return false; |
| 275 | 275 | ||
| 276 | xen_mc_batch(); | 276 | xen_mc_batch(); |
| @@ -279,7 +279,7 @@ static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval) · 2 unmodified lines | |||
| 279 | u.val = pte_val_ma(pteval); | 279 | u.val = pte_val_ma(pteval); |
| 280 | xen_extend_mmu_update(&u); | 280 | xen_extend_mmu_update(&u); |
| 281 | 281 | ||
| 282 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 282 | xen_mc_issue(XEN_LAZY_MMU); |
| 283 | 283 | ||
| 284 | return true; | 284 | return true; |
| 285 | } | 285 | } |
| @@ -325,7 +325,7 @@ void xen_ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, · 39 unmodified lines | |||
| 325 | u.val = pte_val_ma(pte); | 325 | u.val = pte_val_ma(pte); |
| 326 | xen_extend_mmu_update(&u); | 326 | xen_extend_mmu_update(&u); |
| 327 | 327 | ||
| 328 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 328 | xen_mc_issue(XEN_LAZY_MMU); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | /* Assume pteval_t is equivalent to all the other *val_t types. */ | 331 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
| @@ -419,7 +419,7 @@ static void xen_set_pud_hyper(pud_t *ptr, pud_t val) · 87 unmodified lines | |||
| 419 | u.val = pud_val_ma(val); | 419 | u.val = pud_val_ma(val); |
| 420 | xen_extend_mmu_update(&u); | 420 | xen_extend_mmu_update(&u); |
| 421 | 421 | ||
| 422 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 422 | xen_mc_issue(XEN_LAZY_MMU); |
| 423 | 423 | ||
| 424 | preempt_enable(); | 424 | preempt_enable(); |
| 425 | } | 425 | } |
| @@ -499,7 +499,7 @@ static void __init xen_set_p4d_hyper(p4d_t *ptr, p4d_t val) · 73 unmodified lines | |||
| 499 | 499 | ||
| 500 | __xen_set_p4d_hyper(ptr, val); | 500 | __xen_set_p4d_hyper(ptr, val); |
| 501 | 501 | ||
| 502 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 502 | xen_mc_issue(XEN_LAZY_MMU); |
| 503 | 503 | ||
| 504 | preempt_enable(); | 504 | preempt_enable(); |
| 505 | } | 505 | } |
| @@ -531,7 +531,7 @@ static void xen_set_p4d(p4d_t *ptr, p4d_t val) · 25 unmodified lines | |||
| 531 | if (user_ptr) | 531 | if (user_ptr) |
| 532 | __xen_set_p4d_hyper((p4d_t *)user_ptr, val); | 532 | __xen_set_p4d_hyper((p4d_t *)user_ptr, val); |
| 533 | 533 | ||
| 534 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 534 | xen_mc_issue(XEN_LAZY_MMU); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | #if CONFIG_PGTABLE_LEVELS >= 5 | 537 | #if CONFIG_PGTABLE_LEVELS >= 5 |
| @@ -1245,7 +1245,7 @@ static noinline void xen_flush_tlb(void) · 707 unmodified lines | |||
| 1245 | op->cmd = MMUEXT_TLB_FLUSH_LOCAL; | 1245 | op->cmd = MMUEXT_TLB_FLUSH_LOCAL; |
| 1246 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | 1246 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); |
| 1247 | 1247 | ||
| 1248 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1248 | xen_mc_issue(XEN_LAZY_MMU); |
| 1249 | 1249 | ||
| 1250 | preempt_enable(); | 1250 | preempt_enable(); |
| 1251 | } | 1251 | } |
| @@ -1265,7 +1265,7 @@ static void xen_flush_tlb_one_user(unsigned long addr) · 13 unmodified lines | |||
| 1265 | op->arg1.linear_addr = addr & PAGE_MASK; | 1265 | op->arg1.linear_addr = addr & PAGE_MASK; |
| 1266 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | 1266 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); |
| 1267 | 1267 | ||
| 1268 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1268 | xen_mc_issue(XEN_LAZY_MMU); |
| 1269 | 1269 | ||
| 1270 | preempt_enable(); | 1270 | preempt_enable(); |
| 1271 | } | 1271 | } |
| @@ -1302,7 +1302,7 @@ static void xen_flush_tlb_multi(const struct cpumask *cpus, · 30 unmodified lines | |||
| 1302 | 1302 | ||
| 1303 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); | 1303 | MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF); |
| 1304 | 1304 | ||
| 1305 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1305 | xen_mc_issue(XEN_LAZY_MMU); |
| 1306 | } | 1306 | } |
| 1307 | 1307 | ||
| 1308 | static unsigned long xen_read_cr3(void) | 1308 | static unsigned long xen_read_cr3(void) |
| @@ -1361,7 +1361,7 @@ static void xen_write_cr3(unsigned long cr3) · 52 unmodified lines | |||
| 1361 | else | 1361 | else |
| 1362 | __xen_write_cr3(false, 0); | 1362 | __xen_write_cr3(false, 0); |
| 1363 | 1363 | ||
| 1364 | xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */ | 1364 | xen_mc_issue(XEN_LAZY_CPU); /* interrupts restored */ |
| 1365 | } | 1365 | } |
| 1366 | 1366 | ||
| 1367 | /* | 1367 | /* |
| @@ -1396,7 +1396,7 @@ static void __init xen_write_cr3_init(unsigned long cr3) · 28 unmodified lines | |||
| 1396 | 1396 | ||
| 1397 | __xen_write_cr3(true, cr3); | 1397 | __xen_write_cr3(true, cr3); |
| 1398 | 1398 | ||
| 1399 | xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */ | 1399 | xen_mc_issue(XEN_LAZY_CPU); /* interrupts restored */ |
| 1400 | } | 1400 | } |
| 1401 | 1401 | ||
| 1402 | static int xen_pgd_alloc(struct mm_struct *mm) | 1402 | static int xen_pgd_alloc(struct mm_struct *mm) |
| @@ -1557,7 +1557,7 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, · 154 unmodified lines | |||
| 1557 | if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned) | 1557 | if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS && !pinned) |
| 1558 | __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); | 1558 | __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); |
| 1559 | 1559 | ||
| 1560 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1560 | xen_mc_issue(XEN_LAZY_MMU); |
| 1561 | } | 1561 | } |
| 1562 | } | 1562 | } |
| 1563 | 1563 | ||
| @@ -1587,7 +1587,7 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level) · 23 unmodified lines | |||
| 1587 | 1587 | ||
| 1588 | __set_pfn_prot(pfn, PAGE_KERNEL); | 1588 | __set_pfn_prot(pfn, PAGE_KERNEL); |
| 1589 | 1589 | ||
| 1590 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 1590 | xen_mc_issue(XEN_LAZY_MMU); |
| 1591 | 1591 | ||
| 1592 | ClearPagePinned(page); | 1592 | ClearPagePinned(page); |
| 1593 | } | 1593 | } |
| @@ -1804,7 +1804,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) · 210 unmodified lines | |||
| 1804 | */ | 1804 | */ |
| 1805 | xen_mc_batch(); | 1805 | xen_mc_batch(); |
| 1806 | __xen_write_cr3(true, __pa(init_top_pgt)); | 1806 | __xen_write_cr3(true, __pa(init_top_pgt)); |
| 1807 | xen_mc_issue(PARAVIRT_LAZY_CPU); | 1807 | xen_mc_issue(XEN_LAZY_CPU); |
| 1808 | 1808 | ||
| 1809 | /* We can't that easily rip out L3 and L2, as the Xen pagetables are | 1809 | /* We can't that easily rip out L3 and L2, as the Xen pagetables are |
| 1810 | * set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ... for | 1810 | * set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ... for |
| @@ -2083,6 +2083,23 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) · 272 unmodified lines | |||
| 2083 | #endif | 2083 | #endif |
| 2084 | } | 2084 | } |
| 2085 | 2085 | ||
| 2086 | static void xen_enter_lazy_mmu(void) | ||
| 2087 | { | ||
| 2088 | enter_lazy(XEN_LAZY_MMU); | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | static void xen_flush_lazy_mmu(void) | ||
| 2092 | { | ||
| 2093 | preempt_disable(); | ||
| 2094 | |||
| 2095 | if (xen_get_lazy_mode() == XEN_LAZY_MMU) { | ||
| 2096 | arch_leave_lazy_mmu_mode(); | ||
| 2097 | arch_enter_lazy_mmu_mode(); | ||
| 2098 | } | ||
| 2099 | |||
| 2100 | preempt_enable(); | ||
| 2101 | } | ||
| 2102 | |||
| 2086 | static void __init xen_post_allocator_init(void) | 2103 | static void __init xen_post_allocator_init(void) |
| 2087 | { | 2104 | { |
| 2088 | pv_ops.mmu.set_pte = xen_set_pte; | 2105 | pv_ops.mmu.set_pte = xen_set_pte; |
| @@ -2107,7 +2124,7 @@ static void xen_leave_lazy_mmu(void) · 18 unmodified lines | |||
| 2107 | { | 2124 | { |
| 2108 | preempt_disable(); | 2125 | preempt_disable(); |
| 2109 | xen_mc_flush(); | 2126 | xen_mc_flush(); |
| 2110 | paravirt_leave_lazy_mmu(); | 2127 | leave_lazy(XEN_LAZY_MMU); |
| 2111 | preempt_enable(); | 2128 | preempt_enable(); |
| 2112 | } | 2129 | } |
| 2113 | 2130 | ||
| @@ -2166,9 +2183,9 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = { · 52 unmodified lines | |||
| 2166 | .exit_mmap = xen_exit_mmap, | 2183 | .exit_mmap = xen_exit_mmap, |
| 2167 | 2184 | ||
| 2168 | .lazy_mode = { | 2185 | .lazy_mode = { |
| 2169 | .enter = paravirt_enter_lazy_mmu, | 2186 | .enter = xen_enter_lazy_mmu, |
| 2170 | .leave = xen_leave_lazy_mmu, | 2187 | .leave = xen_leave_lazy_mmu, |
| 2171 | .flush = paravirt_flush_lazy_mmu, | 2188 | .flush = xen_flush_lazy_mmu, |
| 2172 | }, | 2189 | }, |
| 2173 | 2190 | ||
| 2174 | .set_fixmap = xen_set_fixmap, | 2191 | .set_fixmap = xen_set_fixmap, |
| @@ -2385,7 +2402,7 @@ static noinline void xen_flush_tlb_all(void) · 210 unmodified lines | |||
| 2385 | op->cmd = MMUEXT_TLB_FLUSH_ALL; | 2402 | op->cmd = MMUEXT_TLB_FLUSH_ALL; |
| 2386 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | 2403 | MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); |
| 2387 | 2404 | ||
| 2388 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 2405 | xen_mc_issue(XEN_LAZY_MMU); |
| 2389 | 2406 | ||
| 2390 | preempt_enable(); | 2407 | preempt_enable(); |
| 2391 | } | 2408 | } |
| @@ -26,7 +26,7 @@ static inline void xen_mc_batch(void) · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | /* need to disable interrupts until this entry is complete */ | 27 | /* need to disable interrupts until this entry is complete */ |
| 28 | local_irq_save(flags); | 28 | local_irq_save(flags); |
| 29 | trace_xen_mc_batch(paravirt_get_lazy_mode()); | 29 | trace_xen_mc_batch(xen_get_lazy_mode()); |
| 30 | __this_cpu_write(xen_mc_irq_flags, flags); | 30 | __this_cpu_write(xen_mc_irq_flags, flags); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| @@ -44,7 +44,7 @@ static inline void xen_mc_issue(unsigned mode) · 11 unmodified lines | |||
| 44 | { | 44 | { |
| 45 | trace_xen_mc_issue(mode); | 45 | trace_xen_mc_issue(mode); |
| 46 | 46 | ||
| 47 | if ((paravirt_get_lazy_mode() & mode) == 0) | 47 | if ((xen_get_lazy_mode() & mode) == 0) |
| 48 | xen_mc_flush(); | 48 | xen_mc_flush(); |
| 49 | 49 | ||
| 50 | /* restore flags saved in xen_mc_batch */ | 50 | /* restore flags saved in xen_mc_batch */ |
| @@ -9,8 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) | 11 | # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) |
| 12 | KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include | 12 | KBUILD_CFLAGS += -fno-builtin |
| 13 | HOSTFLAGS += -Iarch/$(ARCH)/boot/include | ||
| 14 | 13 | ||
| 15 | subdir-y := lib | 14 | subdir-y := lib |
| 16 | targets += vmlinux.bin vmlinux.bin.gz | 15 | targets += vmlinux.bin vmlinux.bin.gz |
| @@ -4,13 +4,14 @@ · 3 unmodified lines | |||
| 4 | /* bits taken from ppc */ | 4 | /* bits taken from ppc */ |
| 5 | 5 | ||
| 6 | extern void *avail_ram, *end_avail; | 6 | extern void *avail_ram, *end_avail; |
| 7 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); | ||
| 7 | 8 | ||
| 8 | void exit (void) | 9 | static void exit(void) |
| 9 | { | 10 | { |
| 10 | for (;;); | 11 | for (;;); |
| 11 | } | 12 | } |
| 12 | 13 | ||
| 13 | void *zalloc(unsigned size) | 14 | static void *zalloc(unsigned int size) |
| 14 | { | 15 | { |
| 15 | void *p = avail_ram; | 16 | void *p = avail_ram; |
| 16 | 17 | ||
| @@ -6,6 +6,10 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <variant/core.h> | 7 | #include <variant/core.h> |
| 8 | 8 | ||
| 9 | #ifndef XCHAL_HAVE_DIV32 | ||
| 10 | #define XCHAL_HAVE_DIV32 0 | ||
| 11 | #endif | ||
| 12 | |||
| 9 | #ifndef XCHAL_HAVE_EXCLUSIVE | 13 | #ifndef XCHAL_HAVE_EXCLUSIVE |
| 10 | #define XCHAL_HAVE_EXCLUSIVE 0 | 14 | #define XCHAL_HAVE_EXCLUSIVE 0 |
| 11 | #endif | 15 | #endif |
| @@ -48,6 +48,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp); · 47 unmodified lines | |||
| 48 | void hw_breakpoint_pmu_read(struct perf_event *bp); | 48 | void hw_breakpoint_pmu_read(struct perf_event *bp); |
| 49 | int check_hw_breakpoint(struct pt_regs *regs); | 49 | int check_hw_breakpoint(struct pt_regs *regs); |
| 50 | void clear_ptrace_hw_breakpoint(struct task_struct *tsk); | 50 | void clear_ptrace_hw_breakpoint(struct task_struct *tsk); |
| 51 | void restore_dbreak(void); | ||
| 51 | 52 | ||
| 52 | #else | 53 | #else |
| 53 | 54 | ||
| @@ -14,6 +14,8 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
| 16 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
| 17 | |||
| 18 | #include <asm/bootparam.h> | ||
| 17 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
| 18 | #include <asm/types.h> | 20 | #include <asm/types.h> |
| 19 | #include <asm/regs.h> | 21 | #include <asm/regs.h> |
| @@ -217,6 +219,9 @@ struct mm_struct; · 197 unmodified lines | |||
| 217 | 219 | ||
| 218 | extern unsigned long __get_wchan(struct task_struct *p); | 220 | extern unsigned long __get_wchan(struct task_struct *p); |
| 219 | 221 | ||
| 222 | void init_arch(bp_tag_t *bp_start); | ||
| 223 | void do_notify_resume(struct pt_regs *regs); | ||
| 224 | |||
| 220 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) | 225 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) |
| 221 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) | 226 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) |
| 222 | 227 | ||
| @@ -106,6 +106,9 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) · 105 unmodified lines | |||
| 106 | return regs->areg[2]; | 106 | return regs->areg[2]; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | int do_syscall_trace_enter(struct pt_regs *regs); | ||
| 110 | void do_syscall_trace_leave(struct pt_regs *regs); | ||
| 111 | |||
| 109 | #else /* __ASSEMBLY__ */ | 112 | #else /* __ASSEMBLY__ */ |
| 110 | 113 | ||
| 111 | # include <asm/asm-offsets.h> | 114 | # include <asm/asm-offsets.h> |
| @@ -23,6 +23,7 @@ struct cpumask; · 22 unmodified lines | |||
| 23 | void arch_send_call_function_ipi_mask(const struct cpumask *mask); | 23 | void arch_send_call_function_ipi_mask(const struct cpumask *mask); |
| 24 | void arch_send_call_function_single_ipi(int cpu); | 24 | void arch_send_call_function_single_ipi(int cpu); |
| 25 | 25 | ||
| 26 | void secondary_start_kernel(void); | ||
| 26 | void smp_init_cpus(void); | 27 | void smp_init_cpus(void); |
| 27 | void secondary_init_irq(void); | 28 | void secondary_init_irq(void); |
| 28 | void ipi_init(void); | 29 | void ipi_init(void); |
| @@ -18,4 +18,6 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) | 19 | #define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte) |
| 20 | 20 | ||
| 21 | void check_tlb_sanity(void); | ||
| 22 | |||
| 21 | #endif /* _XTENSA_TLB_H */ | 23 | #endif /* _XTENSA_TLB_H */ |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
| 14 | #include <linux/perf_event.h> | 14 | #include <linux/perf_event.h> |
| 15 | #include <asm/core.h> | 15 | #include <asm/core.h> |
| 16 | #include <asm/hw_breakpoint.h> | ||
| 16 | 17 | ||
| 17 | /* Breakpoint currently in use for each IBREAKA. */ | 18 | /* Breakpoint currently in use for each IBREAKA. */ |
| 18 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); | 19 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | |||
| 28 | #include <asm/mxregs.h> | 28 | #include <asm/mxregs.h> |
| 29 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
| 30 | #include <asm/platform.h> | 30 | #include <asm/platform.h> |
| 31 | #include <asm/traps.h> | ||
| 31 | 32 | ||
| 32 | DECLARE_PER_CPU(unsigned long, nmi_count); | 33 | DECLARE_PER_CPU(unsigned long, nmi_count); |
| 33 | 34 | ||
| @@ -541,7 +541,6 @@ long arch_ptrace(struct task_struct *child, long request, · 540 unmodified lines | |||
| 541 | return ret; | 541 | return ret; |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | void do_syscall_trace_leave(struct pt_regs *regs); | ||
| 545 | int do_syscall_trace_enter(struct pt_regs *regs) | 544 | int do_syscall_trace_enter(struct pt_regs *regs) |
| 546 | { | 545 | { |
| 547 | if (regs->syscall == NO_SYSCALL) | 546 | if (regs->syscall == NO_SYSCALL) |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | |||
| 26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
| 27 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
| 28 | #include <asm/coprocessor.h> | 28 | #include <asm/coprocessor.h> |
| 29 | #include <asm/processor.h> | ||
| 30 | #include <asm/syscall.h> | ||
| 29 | #include <asm/unistd.h> | 31 | #include <asm/unistd.h> |
| 30 | 32 | ||
| 31 | extern struct task_struct *coproc_owners[]; | 33 | extern struct task_struct *coproc_owners[]; |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
| 22 | #include <linux/kdebug.h> | 22 | #include <linux/kdebug.h> |
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/profile.h> | ||
| 24 | #include <linux/sched/mm.h> | 25 | #include <linux/sched/mm.h> |
| 25 | #include <linux/sched/hotplug.h> | 26 | #include <linux/sched/hotplug.h> |
| 26 | #include <linux/sched/task_stack.h> | 27 | #include <linux/sched/task_stack.h> |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/stacktrace.h> | 13 | #include <linux/stacktrace.h> |
| 14 | 14 | ||
| 15 | #include <asm/ftrace.h> | ||
| 15 | #include <asm/stacktrace.h> | 16 | #include <asm/stacktrace.h> |
| 16 | #include <asm/traps.h> | 17 | #include <asm/traps.h> |
| 17 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | * for more details. | 23 | * for more details. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/cpu.h> | ||
| 26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 27 | #include <linux/sched/signal.h> | 28 | #include <linux/sched/signal.h> |
| 28 | #include <linux/sched/debug.h> | 29 | #include <linux/sched/debug.h> |
| @@ -3,7 +3,9 @@ · 2 unmodified lines | |||
| 3 | #include <asm/asmmacro.h> | 3 | #include <asm/asmmacro.h> |
| 4 | #include <asm/core.h> | 4 | #include <asm/core.h> |
| 5 | 5 | ||
| 6 | #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16 | 6 | #if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32 || XCHAL_HAVE_MAC16 |
| 7 | #define XCHAL_NO_MUL 0 | ||
| 8 | #else | ||
| 7 | #define XCHAL_NO_MUL 1 | 9 | #define XCHAL_NO_MUL 1 |
| 8 | #endif | 10 | #endif |
| 9 | 11 | ||
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
| 21 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
| 22 | #include <asm/hardirq.h> | 22 | #include <asm/hardirq.h> |
| 23 | #include <asm/traps.h> | ||
| 23 | 24 | ||
| 24 | void bad_page_fault(struct pt_regs*, unsigned long, int); | 25 | void bad_page_fault(struct pt_regs*, unsigned long, int); |
| 25 | 26 | ||
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
| 19 | #include <asm/mmu_context.h> | 19 | #include <asm/mmu_context.h> |
| 20 | #include <asm/tlb.h> | ||
| 20 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
| 21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 22 | 23 | ||
| @@ -201,7 +201,7 @@ static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb) · 200 unmodified lines | |||
| 201 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); | 201 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | unsigned short tuntap_protocol(struct sk_buff *skb) | 204 | static unsigned short tuntap_protocol(struct sk_buff *skb) |
| 205 | { | 205 | { |
| 206 | return eth_type_trans(skb, skb->dev); | 206 | return eth_type_trans(skb, skb->dev); |
| 207 | } | 207 | } |
| @@ -441,7 +441,7 @@ static int iss_net_change_mtu(struct net_device *dev, int new_mtu) · 233 unmodified lines | |||
| 441 | return -EINVAL; | 441 | return -EINVAL; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | void iss_net_user_timer_expire(struct timer_list *unused) | 444 | static void iss_net_user_timer_expire(struct timer_list *unused) |
| 445 | { | 445 | { |
| 446 | } | 446 | } |
| 447 | 447 | ||
| @@ -4405,11 +4405,8 @@ static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set, · 4404 unmodified lines | |||
| 4405 | struct blk_mq_tags **new_tags; | 4405 | struct blk_mq_tags **new_tags; |
| 4406 | int i; | 4406 | int i; |
| 4407 | 4407 | ||
| 4408 | if (set->nr_hw_queues >= new_nr_hw_queues) { | 4408 | if (set->nr_hw_queues >= new_nr_hw_queues) |
| 4409 | for (i = new_nr_hw_queues; i < set->nr_hw_queues; i++) | ||
| 4410 | __blk_mq_free_map_and_rqs(set, i); | ||
| 4411 | goto done; | 4409 | goto done; |
| 4412 | } | ||
| 4413 | 4410 | ||
| 4414 | new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), | 4411 | new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), |
| 4415 | GFP_KERNEL, set->numa_node); | 4412 | GFP_KERNEL, set->numa_node); |
| @@ -4719,7 +4716,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 303 unmodified lines | |||
| 4719 | { | 4716 | { |
| 4720 | struct request_queue *q; | 4717 | struct request_queue *q; |
| 4721 | LIST_HEAD(head); | 4718 | LIST_HEAD(head); |
| 4722 | int prev_nr_hw_queues; | 4719 | int prev_nr_hw_queues = set->nr_hw_queues; |
| 4720 | int i; | ||
| 4723 | 4721 | ||
| 4724 | lockdep_assert_held(&set->tag_list_lock); | 4722 | lockdep_assert_held(&set->tag_list_lock); |
| 4725 | 4723 | ||
| @@ -4746,7 +4744,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 20 unmodified lines | |||
| 4746 | blk_mq_sysfs_unregister_hctxs(q); | 4744 | blk_mq_sysfs_unregister_hctxs(q); |
| 4747 | } | 4745 | } |
| 4748 | 4746 | ||
| 4749 | prev_nr_hw_queues = set->nr_hw_queues; | ||
| 4750 | if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) | 4747 | if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) |
| 4751 | goto reregister; | 4748 | goto reregister; |
| 4752 | 4749 | ||
| @@ -4781,6 +4778,10 @@ switch_back: · 28 unmodified lines | |||
| 4781 | 4778 | ||
| 4782 | list_for_each_entry(q, &set->tag_list, tag_set_list) | 4779 | list_for_each_entry(q, &set->tag_list, tag_set_list) |
| 4783 | blk_mq_unfreeze_queue(q); | 4780 | blk_mq_unfreeze_queue(q); |
| 4781 | |||
| 4782 | /* Free the excess tags when nr_hw_queues shrink. */ | ||
| 4783 | for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++) | ||
| 4784 | __blk_mq_free_map_and_rqs(set, i); | ||
| 4784 | } | 4785 | } |
| 4785 | 4786 | ||
| 4786 | void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) | 4787 | void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) |
| @@ -270,7 +270,7 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data, · 269 unmodified lines | |||
| 270 | finish_wait(&rqw->wait, &data.wq); | 270 | finish_wait(&rqw->wait, &data.wq); |
| 271 | 271 | ||
| 272 | /* | 272 | /* |
| 273 | * We raced with wbt_wake_function() getting a token, | 273 | * We raced with rq_qos_wake_function() getting a token, |
| 274 | * which means we now have two. Put our local token | 274 | * which means we now have two. Put our local token |
| 275 | * and wake anyone else potentially waiting for one. | 275 | * and wake anyone else potentially waiting for one. |
| 276 | */ | 276 | */ |
| @@ -290,7 +290,6 @@ EXPORT_SYMBOL(disk_check_media_change); · 289 unmodified lines | |||
| 290 | /** | 290 | /** |
| 291 | * disk_force_media_change - force a media change event | 291 | * disk_force_media_change - force a media change event |
| 292 | * @disk: the disk which will raise the event | 292 | * @disk: the disk which will raise the event |
| 293 | * @events: the events to raise | ||
| 294 | * | 293 | * |
| 295 | * Should be called when the media changes for @disk. Generates a uevent | 294 | * Should be called when the media changes for @disk. Generates a uevent |
| 296 | * and attempts to free all dentries and inodes and invalidates all block | 295 | * and attempts to free all dentries and inodes and invalidates all block |
| @@ -278,10 +278,14 @@ int sm2_compute_z_digest(struct shash_desc *desc, · 277 unmodified lines | |||
| 278 | if (!ec) | 278 | if (!ec) |
| 279 | return -ENOMEM; | 279 | return -ENOMEM; |
| 280 | 280 | ||
| 281 | err = __sm2_set_pub_key(ec, key, keylen); | 281 | err = sm2_ec_ctx_init(ec); |
| 282 | if (err) | 282 | if (err) |
| 283 | goto out_free_ec; | 283 | goto out_free_ec; |
| 284 | 284 | ||
| 285 | err = __sm2_set_pub_key(ec, key, keylen); | ||
| 286 | if (err) | ||
| 287 | goto out_deinit_ec; | ||
| 288 | |||
| 285 | bits_len = SM2_DEFAULT_USERID_LEN * 8; | 289 | bits_len = SM2_DEFAULT_USERID_LEN * 8; |
| 286 | entl[0] = bits_len >> 8; | 290 | entl[0] = bits_len >> 8; |
| 287 | entl[1] = bits_len & 0xff; | 291 | entl[1] = bits_len & 0xff; |
| @@ -46,7 +46,7 @@ obj-$(CONFIG_DMADEVICES) += dma/ · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | # SOC specific infrastructure drivers. | 47 | # SOC specific infrastructure drivers. |
| 48 | obj-y += soc/ | 48 | obj-y += soc/ |
| 49 | obj-$(CONFIG_PM_GENERIC_DOMAINS) += genpd/ | 49 | obj-$(CONFIG_PM_GENERIC_DOMAINS) += pmdomain/ |
| 50 | 50 | ||
| 51 | obj-y += virtio/ | 51 | obj-y += virtio/ |
| 52 | obj-$(CONFIG_VDPA) += vdpa/ | 52 | obj-$(CONFIG_VDPA) += vdpa/ |
| @@ -327,7 +327,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev) · 326 unmodified lines | |||
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | if (!ret) | 329 | if (!ret) |
| 330 | ivpu_info(vdev, "VPU ready message received successfully\n"); | 330 | ivpu_dbg(vdev, PM, "VPU ready message received successfully\n"); |
| 331 | else | 331 | else |
| 332 | ivpu_hw_diagnose_failure(vdev); | 332 | ivpu_hw_diagnose_failure(vdev); |
| 333 | 333 | ||
| @@ -634,6 +634,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) · 300 unmodified lines | |||
| 634 | 634 | ||
| 635 | static struct pci_device_id ivpu_pci_ids[] = { | 635 | static struct pci_device_id ivpu_pci_ids[] = { |
| 636 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, | 636 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_MTL) }, |
| 637 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_ARL) }, | ||
| 637 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, | 638 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_LNL) }, |
| 638 | { } | 639 | { } |
| 639 | }; | 640 | }; |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #define DRIVER_DATE "20230117" | 23 | #define DRIVER_DATE "20230117" |
| 24 | 24 | ||
| 25 | #define PCI_DEVICE_ID_MTL 0x7d1d | 25 | #define PCI_DEVICE_ID_MTL 0x7d1d |
| 26 | #define PCI_DEVICE_ID_ARL 0xad1d | ||
| 26 | #define PCI_DEVICE_ID_LNL 0x643e | 27 | #define PCI_DEVICE_ID_LNL 0x643e |
| 27 | 28 | ||
| 28 | #define IVPU_HW_37XX 37 | 29 | #define IVPU_HW_37XX 37 |
| @@ -165,6 +166,7 @@ static inline int ivpu_hw_gen(struct ivpu_device *vdev) · 136 unmodified lines | |||
| 165 | { | 166 | { |
| 166 | switch (ivpu_device_id(vdev)) { | 167 | switch (ivpu_device_id(vdev)) { |
| 167 | case PCI_DEVICE_ID_MTL: | 168 | case PCI_DEVICE_ID_MTL: |
| 169 | case PCI_DEVICE_ID_ARL: | ||
| 168 | return IVPU_HW_37XX; | 170 | return IVPU_HW_37XX; |
| 169 | case PCI_DEVICE_ID_LNL: | 171 | case PCI_DEVICE_ID_LNL: |
| 170 | return IVPU_HW_40XX; | 172 | return IVPU_HW_40XX; |
| @@ -220,7 +220,8 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev) · 219 unmodified lines | |||
| 220 | if (ret) | 220 | if (ret) |
| 221 | return ret; | 221 | return ret; |
| 222 | 222 | ||
| 223 | fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, DRM_IVPU_BO_WC); | 223 | fw->mem = ivpu_bo_alloc_internal(vdev, fw->runtime_addr, fw->runtime_size, |
| 224 | DRM_IVPU_BO_CACHED | DRM_IVPU_BO_NOSNOOP); | ||
| 224 | if (!fw->mem) { | 225 | if (!fw->mem) { |
| 225 | ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); | 226 | ivpu_err(vdev, "Failed to allocate firmware runtime memory\n"); |
| 226 | return -ENOMEM; | 227 | return -ENOMEM; |
| @@ -330,7 +331,7 @@ int ivpu_fw_load(struct ivpu_device *vdev) · 103 unmodified lines | |||
| 330 | memset(start, 0, size); | 331 | memset(start, 0, size); |
| 331 | } | 332 | } |
| 332 | 333 | ||
| 333 | wmb(); /* Flush WC buffers after writing fw->mem */ | 334 | clflush_cache_range(fw->mem->kvaddr, fw->mem->base.size); |
| 334 | 335 | ||
| 335 | return 0; | 336 | return 0; |
| 336 | } | 337 | } |
| @@ -432,6 +433,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 95 unmodified lines | |||
| 432 | if (!ivpu_fw_is_cold_boot(vdev)) { | 433 | if (!ivpu_fw_is_cold_boot(vdev)) { |
| 433 | boot_params->save_restore_ret_address = 0; | 434 | boot_params->save_restore_ret_address = 0; |
| 434 | vdev->pm->is_warmboot = true; | 435 | vdev->pm->is_warmboot = true; |
| 436 | clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); | ||
| 435 | return; | 437 | return; |
| 436 | } | 438 | } |
| 437 | 439 | ||
| @@ -493,7 +495,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params · 55 unmodified lines | |||
| 493 | boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); | 495 | boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); |
| 494 | boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); | 496 | boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev); |
| 495 | 497 | ||
| 496 | wmb(); /* Flush WC buffers after writing bootparams */ | 498 | clflush_cache_range(vdev->fw->mem->kvaddr, SZ_4K); |
| 497 | 499 | ||
| 498 | ivpu_fw_boot_params_print(vdev, boot_params); | 500 | ivpu_fw_boot_params_print(vdev, boot_params); |
| 499 | } | 501 | } |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_gem.h> | 8 | #include <drm/drm_gem.h> |
| 9 | #include <drm/drm_mm.h> | 9 | #include <drm/drm_mm.h> |
| 10 | 10 | ||
| 11 | #define DRM_IVPU_BO_NOSNOOP 0x10000000 | ||
| 12 | |||
| 11 | struct dma_buf; | 13 | struct dma_buf; |
| 12 | struct ivpu_bo_ops; | 14 | struct ivpu_bo_ops; |
| 13 | struct ivpu_file_priv; | 15 | struct ivpu_file_priv; |
| @@ -83,6 +85,9 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo) · 69 unmodified lines | |||
| 83 | 85 | ||
| 84 | static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) | 86 | static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo) |
| 85 | { | 87 | { |
| 88 | if (bo->flags & DRM_IVPU_BO_NOSNOOP) | ||
| 89 | return false; | ||
| 90 | |||
| 86 | return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; | 91 | return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED; |
| 87 | } | 92 | } |
| 88 | 93 | ||
| @@ -57,8 +57,7 @@ · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | #define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK) | 58 | #define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK) |
| 59 | 59 | ||
| 60 | #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \ | 60 | #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \ |
| 61 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \ | ||
| 62 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \ | 61 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \ |
| 63 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \ | 62 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \ |
| 64 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \ | 63 | (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \ |
| @@ -196,6 +195,14 @@ static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev) · 131 unmodified lines | |||
| 196 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US); | 195 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US); |
| 197 | } | 196 | } |
| 198 | 197 | ||
| 198 | static int ivpu_wait_for_clock_own_resource_ack(struct ivpu_device *vdev) | ||
| 199 | { | ||
| 200 | if (ivpu_is_simics(vdev)) | ||
| 201 | return 0; | ||
| 202 | |||
| 203 | return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US); | ||
| 204 | } | ||
| 205 | |||
| 199 | static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev) | 206 | static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev) |
| 200 | { | 207 | { |
| 201 | struct ivpu_hw_info *hw = vdev->hw; | 208 | struct ivpu_hw_info *hw = vdev->hw; |
| @@ -556,6 +563,12 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev) · 354 unmodified lines | |||
| 556 | { | 563 | { |
| 557 | int ret; | 564 | int ret; |
| 558 | 565 | ||
| 566 | ret = ivpu_wait_for_clock_own_resource_ack(vdev); | ||
| 567 | if (ret) { | ||
| 568 | ivpu_err(vdev, "Timed out waiting for clock own resource ACK\n"); | ||
| 569 | return ret; | ||
| 570 | } | ||
| 571 | |||
| 559 | ivpu_boot_pwr_island_trickle_drive(vdev, true); | 572 | ivpu_boot_pwr_island_trickle_drive(vdev, true); |
| 560 | ivpu_boot_pwr_island_drive(vdev, true); | 573 | ivpu_boot_pwr_island_drive(vdev, true); |
| 561 | 574 | ||
| @@ -1046,8 +1059,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 484 unmodified lines | |||
| 1046 | if (status == 0) | 1059 | if (status == 0) |
| 1047 | return IRQ_NONE; | 1060 | return IRQ_NONE; |
| 1048 | 1061 | ||
| 1049 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); | ||
| 1050 | |||
| 1051 | if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status)) | 1062 | if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status)) |
| 1052 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE"); | 1063 | ivpu_dbg(vdev, IRQ, "FREQ_CHANGE"); |
| 1053 | 1064 | ||
| @@ -1092,6 +1103,9 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq) · 38 unmodified lines | |||
| 1092 | schedule_recovery = true; | 1103 | schedule_recovery = true; |
| 1093 | } | 1104 | } |
| 1094 | 1105 | ||
| 1106 | /* This must be done after interrupts are cleared at the source. */ | ||
| 1107 | REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status); | ||
| 1108 | |||
| 1095 | if (schedule_recovery) | 1109 | if (schedule_recovery) |
| 1096 | ivpu_pm_schedule_recovery(vdev); | 1110 | ivpu_pm_schedule_recovery(vdev); |
| 1097 | 1111 | ||
| @@ -1103,9 +1117,14 @@ static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr) · 5 unmodified lines | |||
| 1103 | struct ivpu_device *vdev = ptr; | 1117 | struct ivpu_device *vdev = ptr; |
| 1104 | irqreturn_t ret = IRQ_NONE; | 1118 | irqreturn_t ret = IRQ_NONE; |
| 1105 | 1119 | ||
| 1120 | REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1); | ||
| 1121 | |||
| 1106 | ret |= ivpu_hw_40xx_irqv_handler(vdev, irq); | 1122 | ret |= ivpu_hw_40xx_irqv_handler(vdev, irq); |
| 1107 | ret |= ivpu_hw_40xx_irqb_handler(vdev, irq); | 1123 | ret |= ivpu_hw_40xx_irqb_handler(vdev, irq); |
| 1108 | 1124 | ||
| 1125 | /* Re-enable global interrupts to re-trigger MSI for pending interrupts */ | ||
| 1126 | REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0); | ||
| 1127 | |||
| 1109 | if (ret & IRQ_WAKE_THREAD) | 1128 | if (ret & IRQ_WAKE_THREAD) |
| 1110 | return IRQ_WAKE_THREAD; | 1129 | return IRQ_WAKE_THREAD; |
| 1111 | 1130 | ||
| @@ -70,6 +70,8 @@ · 69 unmodified lines | |||
| 70 | #define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0) | 70 | #define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0) |
| 71 | #define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1) | 71 | #define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1) |
| 72 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2) | 72 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2) |
| 73 | #define VPU_40XX_BUTTRESS_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6) | ||
| 74 | #define VPU_40XX_BUTTRESS_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7) | ||
| 73 | #define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11) | 75 | #define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11) |
| 74 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12) | 76 | #define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12) |
| 75 | 77 | ||
| @@ -209,10 +209,10 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, · 208 unmodified lines | |||
| 209 | struct ivpu_ipc_rx_msg *rx_msg; | 209 | struct ivpu_ipc_rx_msg *rx_msg; |
| 210 | int wait_ret, ret = 0; | 210 | int wait_ret, ret = 0; |
| 211 | 211 | ||
| 212 | wait_ret = wait_event_interruptible_timeout(cons->rx_msg_wq, | 212 | wait_ret = wait_event_timeout(cons->rx_msg_wq, |
| 213 | (IS_KTHREAD() && kthread_should_stop()) || | 213 | (IS_KTHREAD() && kthread_should_stop()) || |
| 214 | !list_empty(&cons->rx_msg_list), | 214 | !list_empty(&cons->rx_msg_list), |
| 215 | msecs_to_jiffies(timeout_ms)); | 215 | msecs_to_jiffies(timeout_ms)); |
| 216 | 216 | ||
| 217 | if (IS_KTHREAD() && kthread_should_stop()) | 217 | if (IS_KTHREAD() && kthread_should_stop()) |
| 218 | return -EINTR; | 218 | return -EINTR; |
| @@ -220,9 +220,6 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, · 1 unmodified line | |||
| 220 | if (wait_ret == 0) | 220 | if (wait_ret == 0) |
| 221 | return -ETIMEDOUT; | 221 | return -ETIMEDOUT; |
| 222 | 222 | ||
| 223 | if (wait_ret < 0) | ||
| 224 | return -ERESTARTSYS; | ||
| 225 | |||
| 226 | spin_lock_irq(&cons->rx_msg_lock); | 223 | spin_lock_irq(&cons->rx_msg_lock); |
| 227 | rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link); | 224 | rx_msg = list_first_entry_or_null(&cons->rx_msg_list, struct ivpu_ipc_rx_msg, link); |
| 228 | if (!rx_msg) { | 225 | if (!rx_msg) { |
| @@ -2057,7 +2057,9 @@ static int acpi_video_bus_add(struct acpi_device *device) · 2056 unmodified lines | |||
| 2057 | !auto_detect) | 2057 | !auto_detect) |
| 2058 | acpi_video_bus_register_backlight(video); | 2058 | acpi_video_bus_register_backlight(video); |
| 2059 | 2059 | ||
| 2060 | acpi_video_bus_add_notify_handler(video); | 2060 | error = acpi_video_bus_add_notify_handler(video); |
| 2061 | if (error) | ||
| 2062 | goto err_del; | ||
| 2061 | 2063 | ||
| 2062 | error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, | 2064 | error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, |
| 2063 | acpi_video_bus_notify); | 2065 | acpi_video_bus_notify); |
| @@ -2067,10 +2069,11 @@ static int acpi_video_bus_add(struct acpi_device *device) · 3 unmodified lines | |||
| 2067 | return 0; | 2069 | return 0; |
| 2068 | 2070 | ||
| 2069 | err_remove: | 2071 | err_remove: |
| 2072 | acpi_video_bus_remove_notify_handler(video); | ||
| 2073 | err_del: | ||
| 2070 | mutex_lock(&video_list_lock); | 2074 | mutex_lock(&video_list_lock); |
| 2071 | list_del(&video->entry); | 2075 | list_del(&video->entry); |
| 2072 | mutex_unlock(&video_list_lock); | 2076 | mutex_unlock(&video_list_lock); |
| 2073 | acpi_video_bus_remove_notify_handler(video); | ||
| 2074 | acpi_video_bus_unregister_backlight(video); | 2077 | acpi_video_bus_unregister_backlight(video); |
| 2075 | err_put_video: | 2078 | err_put_video: |
| 2076 | acpi_video_bus_put_devices(video); | 2079 | acpi_video_bus_put_devices(video); |
| @@ -19,6 +19,7 @@ static void acpi_set_pdc_bits(u32 *buf) · 18 unmodified lines | |||
| 19 | { | 19 | { |
| 20 | buf[0] = ACPI_PDC_REVISION_ID; | 20 | buf[0] = ACPI_PDC_REVISION_ID; |
| 21 | buf[1] = 1; | 21 | buf[1] = 1; |
| 22 | buf[2] = 0; | ||
| 22 | 23 | ||
| 23 | /* Twiddle arch-specific bits needed for _PDC */ | 24 | /* Twiddle arch-specific bits needed for _PDC */ |
| 24 | arch_acpi_set_proc_cap_bits(&buf[2]); | 25 | arch_acpi_set_proc_cap_bits(&buf[2]); |
| @@ -492,7 +492,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) · 491 unmodified lines | |||
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static int thermal_get_trend(struct thermal_zone_device *thermal, | 494 | static int thermal_get_trend(struct thermal_zone_device *thermal, |
| 495 | struct thermal_trip *trip, | 495 | const struct thermal_trip *trip, |
| 496 | enum thermal_trend *trend) | 496 | enum thermal_trend *trend) |
| 497 | { | 497 | { |
| 498 | struct acpi_thermal *tz = thermal_zone_device_priv(thermal); | 498 | struct acpi_thermal *tz = thermal_zone_device_priv(thermal); |
| @@ -1883,6 +1883,15 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1882 unmodified lines | |||
| 1883 | else | 1883 | else |
| 1884 | dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); | 1884 | dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); |
| 1885 | 1885 | ||
| 1886 | if (!(hpriv->cap & HOST_CAP_PART)) | ||
| 1887 | host->flags |= ATA_HOST_NO_PART; | ||
| 1888 | |||
| 1889 | if (!(hpriv->cap & HOST_CAP_SSC)) | ||
| 1890 | host->flags |= ATA_HOST_NO_SSC; | ||
| 1891 | |||
| 1892 | if (!(hpriv->cap2 & HOST_CAP2_SDS)) | ||
| 1893 | host->flags |= ATA_HOST_NO_DEVSLP; | ||
| 1894 | |||
| 1886 | if (pi.flags & ATA_FLAG_EM) | 1895 | if (pi.flags & ATA_FLAG_EM) |
| 1887 | ahci_reset_em(host); | 1896 | ahci_reset_em(host); |
| 1888 | 1897 | ||
| @@ -1256,6 +1256,26 @@ static ssize_t ahci_activity_show(struct ata_device *dev, char *buf) · 1255 unmodified lines | |||
| 1256 | return sprintf(buf, "%d\n", emp->blink_policy); | 1256 | return sprintf(buf, "%d\n", emp->blink_policy); |
| 1257 | } | 1257 | } |
| 1258 | 1258 | ||
| 1259 | static void ahci_port_clear_pending_irq(struct ata_port *ap) | ||
| 1260 | { | ||
| 1261 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
| 1262 | void __iomem *port_mmio = ahci_port_base(ap); | ||
| 1263 | u32 tmp; | ||
| 1264 | |||
| 1265 | /* clear SError */ | ||
| 1266 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
| 1267 | dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); | ||
| 1268 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
| 1269 | |||
| 1270 | /* clear port IRQ */ | ||
| 1271 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
| 1272 | dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); | ||
| 1273 | if (tmp) | ||
| 1274 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
| 1275 | |||
| 1276 | writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); | ||
| 1277 | } | ||
| 1278 | |||
| 1259 | static void ahci_port_init(struct device *dev, struct ata_port *ap, | 1279 | static void ahci_port_init(struct device *dev, struct ata_port *ap, |
| 1260 | int port_no, void __iomem *mmio, | 1280 | int port_no, void __iomem *mmio, |
| 1261 | void __iomem *port_mmio) | 1281 | void __iomem *port_mmio) |
| @@ -1270,18 +1290,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap, · 8 unmodified lines | |||
| 1270 | if (rc) | 1290 | if (rc) |
| 1271 | dev_warn(dev, "%s (%d)\n", emsg, rc); | 1291 | dev_warn(dev, "%s (%d)\n", emsg, rc); |
| 1272 | 1292 | ||
| 1273 | /* clear SError */ | 1293 | ahci_port_clear_pending_irq(ap); |
| 1274 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
| 1275 | dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp); | ||
| 1276 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
| 1277 | |||
| 1278 | /* clear port IRQ */ | ||
| 1279 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
| 1280 | dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp); | ||
| 1281 | if (tmp) | ||
| 1282 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
| 1283 | |||
| 1284 | writel(1 << port_no, mmio + HOST_IRQ_STAT); | ||
| 1285 | 1294 | ||
| 1286 | /* mark esata ports */ | 1295 | /* mark esata ports */ |
| 1287 | tmp = readl(port_mmio + PORT_CMD); | 1296 | tmp = readl(port_mmio + PORT_CMD); |
| @@ -1603,6 +1612,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, · 315 unmodified lines | |||
| 1603 | tf.status = ATA_BUSY; | 1612 | tf.status = ATA_BUSY; |
| 1604 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 1613 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
| 1605 | 1614 | ||
| 1615 | ahci_port_clear_pending_irq(ap); | ||
| 1616 | |||
| 1606 | rc = sata_link_hardreset(link, timing, deadline, online, | 1617 | rc = sata_link_hardreset(link, timing, deadline, online, |
| 1607 | ahci_check_ready); | 1618 | ahci_check_ready); |
| 1608 | 1619 | ||
| @@ -1972,6 +1972,96 @@ retry: · 1971 unmodified lines | |||
| 1972 | return rc; | 1972 | return rc; |
| 1973 | } | 1973 | } |
| 1974 | 1974 | ||
| 1975 | /** | ||
| 1976 | * ata_dev_power_set_standby - Set a device power mode to standby | ||
| 1977 | * @dev: target device | ||
| 1978 | * | ||
| 1979 | * Issue a STANDBY IMMEDIATE command to set a device power mode to standby. | ||
| 1980 | * For an HDD device, this spins down the disks. | ||
| 1981 | * | ||
| 1982 | * LOCKING: | ||
| 1983 | * Kernel thread context (may sleep). | ||
| 1984 | */ | ||
| 1985 | void ata_dev_power_set_standby(struct ata_device *dev) | ||
| 1986 | { | ||
| 1987 | unsigned long ap_flags = dev->link->ap->flags; | ||
| 1988 | struct ata_taskfile tf; | ||
| 1989 | unsigned int err_mask; | ||
| 1990 | |||
| 1991 | /* Issue STANDBY IMMEDIATE command only if supported by the device */ | ||
| 1992 | if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) | ||
| 1993 | return; | ||
| 1994 | |||
| 1995 | /* | ||
| 1996 | * Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5) | ||
| 1997 | * causing some drives to spin up and down again. For these, do nothing | ||
| 1998 | * if we are being called on shutdown. | ||
| 1999 | */ | ||
| 2000 | if ((ap_flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && | ||
| 2001 | system_state == SYSTEM_POWER_OFF) | ||
| 2002 | return; | ||
| 2003 | |||
| 2004 | if ((ap_flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | ||
| 2005 | system_entering_hibernation()) | ||
| 2006 | return; | ||
| 2007 | |||
| 2008 | ata_tf_init(dev, &tf); | ||
| 2009 | tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
| 2010 | tf.protocol = ATA_PROT_NODATA; | ||
| 2011 | tf.command = ATA_CMD_STANDBYNOW1; | ||
| 2012 | |||
| 2013 | ata_dev_notice(dev, "Entering standby power mode\n"); | ||
| 2014 | |||
| 2015 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); | ||
| 2016 | if (err_mask) | ||
| 2017 | ata_dev_err(dev, "STANDBY IMMEDIATE failed (err_mask=0x%x)\n", | ||
| 2018 | err_mask); | ||
| 2019 | } | ||
| 2020 | |||
| 2021 | /** | ||
| 2022 | * ata_dev_power_set_active - Set a device power mode to active | ||
| 2023 | * @dev: target device | ||
| 2024 | * | ||
| 2025 | * Issue a VERIFY command to enter to ensure that the device is in the | ||
| 2026 | * active power mode. For a spun-down HDD (standby or idle power mode), | ||
| 2027 | * the VERIFY command will complete after the disk spins up. | ||
| 2028 | * | ||
| 2029 | * LOCKING: | ||
| 2030 | * Kernel thread context (may sleep). | ||
| 2031 | */ | ||
| 2032 | void ata_dev_power_set_active(struct ata_device *dev) | ||
| 2033 | { | ||
| 2034 | struct ata_taskfile tf; | ||
| 2035 | unsigned int err_mask; | ||
| 2036 | |||
| 2037 | /* | ||
| 2038 | * Issue READ VERIFY SECTORS command for 1 sector at lba=0 only | ||
| 2039 | * if supported by the device. | ||
| 2040 | */ | ||
| 2041 | if (dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) | ||
| 2042 | return; | ||
| 2043 | |||
| 2044 | ata_tf_init(dev, &tf); | ||
| 2045 | tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
| 2046 | tf.protocol = ATA_PROT_NODATA; | ||
| 2047 | tf.command = ATA_CMD_VERIFY; | ||
| 2048 | tf.nsect = 1; | ||
| 2049 | if (dev->flags & ATA_DFLAG_LBA) { | ||
| 2050 | tf.flags |= ATA_TFLAG_LBA; | ||
| 2051 | tf.device |= ATA_LBA; | ||
| 2052 | } else { | ||
| 2053 | /* CHS */ | ||
| 2054 | tf.lbal = 0x1; /* sect */ | ||
| 2055 | } | ||
| 2056 | |||
| 2057 | ata_dev_notice(dev, "Entering active power mode\n"); | ||
| 2058 | |||
| 2059 | err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); | ||
| 2060 | if (err_mask) | ||
| 2061 | ata_dev_err(dev, "VERIFY failed (err_mask=0x%x)\n", | ||
| 2062 | err_mask); | ||
| 2063 | } | ||
| 2064 | |||
| 1975 | /** | 2065 | /** |
| 1976 | * ata_read_log_page - read a specific log page | 2066 | * ata_read_log_page - read a specific log page |
| 1977 | * @dev: target device | 2067 | * @dev: target device |
| @@ -2529,7 +2619,7 @@ static int ata_dev_config_lba(struct ata_device *dev) · 551 unmodified lines | |||
| 2529 | { | 2619 | { |
| 2530 | const u16 *id = dev->id; | 2620 | const u16 *id = dev->id; |
| 2531 | const char *lba_desc; | 2621 | const char *lba_desc; |
| 2532 | char ncq_desc[24]; | 2622 | char ncq_desc[32]; |
| 2533 | int ret; | 2623 | int ret; |
| 2534 | 2624 | ||
| 2535 | dev->flags |= ATA_DFLAG_LBA; | 2625 | dev->flags |= ATA_DFLAG_LBA; |
| @@ -4783,11 +4873,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) · 2247 unmodified lines | |||
| 4783 | * been aborted by the device due to a limit timeout using the policy | 4873 | * been aborted by the device due to a limit timeout using the policy |
| 4784 | * 0xD. For these commands, invoke EH to get the command sense data. | 4874 | * 0xD. For these commands, invoke EH to get the command sense data. |
| 4785 | */ | 4875 | */ |
| 4786 | if (qc->result_tf.status & ATA_SENSE && | 4876 | if (qc->flags & ATA_QCFLAG_HAS_CDL && |
| 4787 | ((ata_is_ncq(qc->tf.protocol) && | 4877 | qc->result_tf.status & ATA_SENSE) { |
| 4788 | dev->flags & ATA_DFLAG_CDL_ENABLED) || | ||
| 4789 | (!ata_is_ncq(qc->tf.protocol) && | ||
| 4790 | ata_id_sense_reporting_enabled(dev->id)))) { | ||
| 4791 | /* | 4878 | /* |
| 4792 | * Tell SCSI EH to not overwrite scmd->result even if this | 4879 | * Tell SCSI EH to not overwrite scmd->result even if this |
| 4793 | * command is finished with result SAM_STAT_GOOD. | 4880 | * command is finished with result SAM_STAT_GOOD. |
| @@ -5040,17 +5127,19 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, · 246 unmodified lines | |||
| 5040 | struct ata_link *link; | 5127 | struct ata_link *link; |
| 5041 | unsigned long flags; | 5128 | unsigned long flags; |
| 5042 | 5129 | ||
| 5043 | /* Previous resume operation might still be in | 5130 | spin_lock_irqsave(ap->lock, flags); |
| 5044 | * progress. Wait for PM_PENDING to clear. | 5131 | |
| 5132 | /* | ||
| 5133 | * A previous PM operation might still be in progress. Wait for | ||
| 5134 | * ATA_PFLAG_PM_PENDING to clear. | ||
| 5045 | */ | 5135 | */ |
| 5046 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { | 5136 | if (ap->pflags & ATA_PFLAG_PM_PENDING) { |
| 5137 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 5047 | ata_port_wait_eh(ap); | 5138 | ata_port_wait_eh(ap); |
| 5048 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | 5139 | spin_lock_irqsave(ap->lock, flags); |
| 5049 | } | 5140 | } |
| 5050 | 5141 | ||
| 5051 | /* request PM ops to EH */ | 5142 | /* Request PM operation to EH */ |
| 5052 | spin_lock_irqsave(ap->lock, flags); | ||
| 5053 | |||
| 5054 | ap->pm_mesg = mesg; | 5143 | ap->pm_mesg = mesg; |
| 5055 | ap->pflags |= ATA_PFLAG_PM_PENDING; | 5144 | ap->pflags |= ATA_PFLAG_PM_PENDING; |
| 5056 | ata_for_each_link(link, ap, HOST_FIRST) { | 5145 | ata_for_each_link(link, ap, HOST_FIRST) { |
| @@ -5062,10 +5151,8 @@ static void ata_port_request_pm(struct ata_port *ap, pm_message_t mesg, · 5 unmodified lines | |||
| 5062 | 5151 | ||
| 5063 | spin_unlock_irqrestore(ap->lock, flags); | 5152 | spin_unlock_irqrestore(ap->lock, flags); |
| 5064 | 5153 | ||
| 5065 | if (!async) { | 5154 | if (!async) |
| 5066 | ata_port_wait_eh(ap); | 5155 | ata_port_wait_eh(ap); |
| 5067 | WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); | ||
| 5068 | } | ||
| 5069 | } | 5156 | } |
| 5070 | 5157 | ||
| 5071 | /* | 5158 | /* |
| @@ -5081,11 +5168,27 @@ static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET · 9 unmodified lines | |||
| 5081 | 5168 | ||
| 5082 | static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) | 5169 | static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) |
| 5083 | { | 5170 | { |
| 5171 | /* | ||
| 5172 | * We are about to suspend the port, so we do not care about | ||
| 5173 | * scsi_rescan_device() calls scheduled by previous resume operations. | ||
| 5174 | * The next resume will schedule the rescan again. So cancel any rescan | ||
| 5175 | * that is not done yet. | ||
| 5176 | */ | ||
| 5177 | cancel_delayed_work_sync(&ap->scsi_rescan_task); | ||
| 5178 | |||
| 5084 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); | 5179 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); |
| 5085 | } | 5180 | } |
| 5086 | 5181 | ||
| 5087 | static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) | 5182 | static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) |
| 5088 | { | 5183 | { |
| 5184 | /* | ||
| 5185 | * We are about to suspend the port, so we do not care about | ||
| 5186 | * scsi_rescan_device() calls scheduled by previous resume operations. | ||
| 5187 | * The next resume will schedule the rescan again. So cancel any rescan | ||
| 5188 | * that is not done yet. | ||
| 5189 | */ | ||
| 5190 | cancel_delayed_work_sync(&ap->scsi_rescan_task); | ||
| 5191 | |||
| 5089 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); | 5192 | ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); |
| 5090 | } | 5193 | } |
| 5091 | 5194 | ||
| @@ -5232,7 +5335,7 @@ EXPORT_SYMBOL_GPL(ata_host_resume); · 140 unmodified lines | |||
| 5232 | #endif | 5335 | #endif |
| 5233 | 5336 | ||
| 5234 | const struct device_type ata_port_type = { | 5337 | const struct device_type ata_port_type = { |
| 5235 | .name = "ata_port", | 5338 | .name = ATA_PORT_TYPE_NAME, |
| 5236 | #ifdef CONFIG_PM | 5339 | #ifdef CONFIG_PM |
| 5237 | .pm = &ata_port_pm_ops, | 5340 | .pm = &ata_port_pm_ops, |
| 5238 | #endif | 5341 | #endif |
| @@ -5951,11 +6054,30 @@ static void ata_port_detach(struct ata_port *ap) · 712 unmodified lines | |||
| 5951 | struct ata_link *link; | 6054 | struct ata_link *link; |
| 5952 | struct ata_device *dev; | 6055 | struct ata_device *dev; |
| 5953 | 6056 | ||
| 5954 | /* tell EH we're leaving & flush EH */ | 6057 | /* Wait for any ongoing EH */ |
| 6058 | ata_port_wait_eh(ap); | ||
| 6059 | |||
| 6060 | mutex_lock(&ap->scsi_scan_mutex); | ||
| 5955 | spin_lock_irqsave(ap->lock, flags); | 6061 | spin_lock_irqsave(ap->lock, flags); |
| 6062 | |||
| 6063 | /* Remove scsi devices */ | ||
| 6064 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
| 6065 | ata_for_each_dev(dev, link, ALL) { | ||
| 6066 | if (dev->sdev) { | ||
| 6067 | spin_unlock_irqrestore(ap->lock, flags); | ||
| 6068 | scsi_remove_device(dev->sdev); | ||
| 6069 | spin_lock_irqsave(ap->lock, flags); | ||
| 6070 | dev->sdev = NULL; | ||
| 6071 | } | ||
| 6072 | } | ||
| 6073 | } | ||
| 6074 | |||
| 6075 | /* Tell EH to disable all devices */ | ||
| 5956 | ap->pflags |= ATA_PFLAG_UNLOADING; | 6076 | ap->pflags |= ATA_PFLAG_UNLOADING; |
| 5957 | ata_port_schedule_eh(ap); | 6077 | ata_port_schedule_eh(ap); |
| 6078 | |||
| 5958 | spin_unlock_irqrestore(ap->lock, flags); | 6079 | spin_unlock_irqrestore(ap->lock, flags); |
| 6080 | mutex_unlock(&ap->scsi_scan_mutex); | ||
| 5959 | 6081 | ||
| 5960 | /* wait till EH commits suicide */ | 6082 | /* wait till EH commits suicide */ |
| 5961 | ata_port_wait_eh(ap); | 6083 | ata_port_wait_eh(ap); |
| @@ -147,6 +147,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { · 146 unmodified lines | |||
| 147 | .timeouts = ata_eh_other_timeouts, }, | 147 | .timeouts = ata_eh_other_timeouts, }, |
| 148 | { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), | 148 | { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), |
| 149 | .timeouts = ata_eh_flush_timeouts }, | 149 | .timeouts = ata_eh_flush_timeouts }, |
| 150 | { .commands = CMDS(ATA_CMD_VERIFY), | ||
| 151 | .timeouts = ata_eh_reset_timeouts }, | ||
| 150 | }; | 152 | }; |
| 151 | #undef CMDS | 153 | #undef CMDS |
| 152 | 154 | ||
| @@ -498,7 +500,19 @@ static void ata_eh_unload(struct ata_port *ap) · 345 unmodified lines | |||
| 498 | struct ata_device *dev; | 500 | struct ata_device *dev; |
| 499 | unsigned long flags; | 501 | unsigned long flags; |
| 500 | 502 | ||
| 501 | /* Restore SControl IPM and SPD for the next driver and | 503 | /* |
| 504 | * Unless we are restarting, transition all enabled devices to | ||
| 505 | * standby power mode. | ||
| 506 | */ | ||
| 507 | if (system_state != SYSTEM_RESTART) { | ||
| 508 | ata_for_each_link(link, ap, PMP_FIRST) { | ||
| 509 | ata_for_each_dev(dev, link, ENABLED) | ||
| 510 | ata_dev_power_set_standby(dev); | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Restore SControl IPM and SPD for the next driver and | ||
| 502 | * disable attached devices. | 516 | * disable attached devices. |
| 503 | */ | 517 | */ |
| 504 | ata_for_each_link(link, ap, PMP_FIRST) { | 518 | ata_for_each_link(link, ap, PMP_FIRST) { |
| @@ -684,6 +698,10 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) · 179 unmodified lines | |||
| 684 | ehc->saved_xfer_mode[devno] = dev->xfer_mode; | 698 | ehc->saved_xfer_mode[devno] = dev->xfer_mode; |
| 685 | if (ata_ncq_enabled(dev)) | 699 | if (ata_ncq_enabled(dev)) |
| 686 | ehc->saved_ncq_enabled |= 1 << devno; | 700 | ehc->saved_ncq_enabled |= 1 << devno; |
| 701 | |||
| 702 | /* If we are resuming, wake up the device */ | ||
| 703 | if (ap->pflags & ATA_PFLAG_RESUMING) | ||
| 704 | ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; | ||
| 687 | } | 705 | } |
| 688 | } | 706 | } |
| 689 | 707 | ||
| @@ -743,6 +761,8 @@ void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) · 53 unmodified lines | |||
| 743 | /* clean up */ | 761 | /* clean up */ |
| 744 | spin_lock_irqsave(ap->lock, flags); | 762 | spin_lock_irqsave(ap->lock, flags); |
| 745 | 763 | ||
| 764 | ap->pflags &= ~ATA_PFLAG_RESUMING; | ||
| 765 | |||
| 746 | if (ap->pflags & ATA_PFLAG_LOADING) | 766 | if (ap->pflags & ATA_PFLAG_LOADING) |
| 747 | ap->pflags &= ~ATA_PFLAG_LOADING; | 767 | ap->pflags &= ~ATA_PFLAG_LOADING; |
| 748 | else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && | 768 | else if ((ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) && |
| @@ -1218,6 +1238,13 @@ void ata_eh_detach_dev(struct ata_device *dev) · 469 unmodified lines | |||
| 1218 | struct ata_eh_context *ehc = &link->eh_context; | 1238 | struct ata_eh_context *ehc = &link->eh_context; |
| 1219 | unsigned long flags; | 1239 | unsigned long flags; |
| 1220 | 1240 | ||
| 1241 | /* | ||
| 1242 | * If the device is still enabled, transition it to standby power mode | ||
| 1243 | * (i.e. spin down HDDs). | ||
| 1244 | */ | ||
| 1245 | if (ata_dev_enabled(dev)) | ||
| 1246 | ata_dev_power_set_standby(dev); | ||
| 1247 | |||
| 1221 | ata_dev_disable(dev); | 1248 | ata_dev_disable(dev); |
| 1222 | 1249 | ||
| 1223 | spin_lock_irqsave(ap->lock, flags); | 1250 | spin_lock_irqsave(ap->lock, flags); |
| @@ -2305,7 +2332,7 @@ static void ata_eh_link_report(struct ata_link *link) · 1081 unmodified lines | |||
| 2305 | struct ata_eh_context *ehc = &link->eh_context; | 2332 | struct ata_eh_context *ehc = &link->eh_context; |
| 2306 | struct ata_queued_cmd *qc; | 2333 | struct ata_queued_cmd *qc; |
| 2307 | const char *frozen, *desc; | 2334 | const char *frozen, *desc; |
| 2308 | char tries_buf[6] = ""; | 2335 | char tries_buf[16] = ""; |
| 2309 | int tag, nr_failed = 0; | 2336 | int tag, nr_failed = 0; |
| 2310 | 2337 | ||
| 2311 | if (ehc->i.flags & ATA_EHI_QUIET) | 2338 | if (ehc->i.flags & ATA_EHI_QUIET) |
| @@ -2796,23 +2823,13 @@ int ata_eh_reset(struct ata_link *link, int classify, · 484 unmodified lines | |||
| 2796 | } | 2823 | } |
| 2797 | } | 2824 | } |
| 2798 | 2825 | ||
| 2799 | /* | 2826 | /* clear cached SError */ |
| 2800 | * Some controllers can't be frozen very well and may set spurious | ||
| 2801 | * error conditions during reset. Clear accumulated error | ||
| 2802 | * information and re-thaw the port if frozen. As reset is the | ||
| 2803 | * final recovery action and we cross check link onlineness against | ||
| 2804 | * device classification later, no hotplug event is lost by this. | ||
| 2805 | */ | ||
| 2806 | spin_lock_irqsave(link->ap->lock, flags); | 2827 | spin_lock_irqsave(link->ap->lock, flags); |
| 2807 | memset(&link->eh_info, 0, sizeof(link->eh_info)); | 2828 | link->eh_info.serror = 0; |
| 2808 | if (slave) | 2829 | if (slave) |
| 2809 | memset(&slave->eh_info, 0, sizeof(link->eh_info)); | 2830 | slave->eh_info.serror = 0; |
| 2810 | ap->pflags &= ~ATA_PFLAG_EH_PENDING; | ||
| 2811 | spin_unlock_irqrestore(link->ap->lock, flags); | 2831 | spin_unlock_irqrestore(link->ap->lock, flags); |
| 2812 | 2832 | ||
| 2813 | if (ata_port_is_frozen(ap)) | ||
| 2814 | ata_eh_thaw_port(ap); | ||
| 2815 | |||
| 2816 | /* | 2833 | /* |
| 2817 | * Make sure onlineness and classification result correspond. | 2834 | * Make sure onlineness and classification result correspond. |
| 2818 | * Hotplug could have happened during reset and some | 2835 | * Hotplug could have happened during reset and some |
| @@ -3026,6 +3043,15 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, · 207 unmodified lines | |||
| 3026 | if (ehc->i.flags & ATA_EHI_DID_RESET) | 3043 | if (ehc->i.flags & ATA_EHI_DID_RESET) |
| 3027 | readid_flags |= ATA_READID_POSTRESET; | 3044 | readid_flags |= ATA_READID_POSTRESET; |
| 3028 | 3045 | ||
| 3046 | /* | ||
| 3047 | * When resuming, before executing any command, make sure to | ||
| 3048 | * transition the device to the active power mode. | ||
| 3049 | */ | ||
| 3050 | if ((action & ATA_EH_SET_ACTIVE) && ata_dev_enabled(dev)) { | ||
| 3051 | ata_dev_power_set_active(dev); | ||
| 3052 | ata_eh_done(link, dev, ATA_EH_SET_ACTIVE); | ||
| 3053 | } | ||
| 3054 | |||
| 3029 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { | 3055 | if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { |
| 3030 | WARN_ON(dev->class == ATA_DEV_PMP); | 3056 | WARN_ON(dev->class == ATA_DEV_PMP); |
| 3031 | 3057 | ||
| @@ -3999,6 +4025,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 967 unmodified lines | |||
| 3999 | unsigned long flags; | 4025 | unsigned long flags; |
| 4000 | int rc = 0; | 4026 | int rc = 0; |
| 4001 | struct ata_device *dev; | 4027 | struct ata_device *dev; |
| 4028 | struct ata_link *link; | ||
| 4002 | 4029 | ||
| 4003 | /* are we suspending? */ | 4030 | /* are we suspending? */ |
| 4004 | spin_lock_irqsave(ap->lock, flags); | 4031 | spin_lock_irqsave(ap->lock, flags); |
| @@ -4011,6 +4038,12 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 6 unmodified lines | |||
| 4011 | 4038 | ||
| 4012 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); | 4039 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4013 | 4040 | ||
| 4041 | /* Set all devices attached to the port in standby mode */ | ||
| 4042 | ata_for_each_link(link, ap, HOST_FIRST) { | ||
| 4043 | ata_for_each_dev(dev, link, ENABLED) | ||
| 4044 | ata_dev_power_set_standby(dev); | ||
| 4045 | } | ||
| 4046 | |||
| 4014 | /* | 4047 | /* |
| 4015 | * If we have a ZPODD attached, check its zero | 4048 | * If we have a ZPODD attached, check its zero |
| 4016 | * power ready status before the port is frozen. | 4049 | * power ready status before the port is frozen. |
| @@ -4093,6 +4126,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) · 76 unmodified lines | |||
| 4093 | /* update the flags */ | 4126 | /* update the flags */ |
| 4094 | spin_lock_irqsave(ap->lock, flags); | 4127 | spin_lock_irqsave(ap->lock, flags); |
| 4095 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); | 4128 | ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); |
| 4129 | ap->pflags |= ATA_PFLAG_RESUMING; | ||
| 4096 | spin_unlock_irqrestore(ap->lock, flags); | 4130 | spin_unlock_irqrestore(ap->lock, flags); |
| 4097 | } | 4131 | } |
| 4098 | #endif /* CONFIG_PM */ | 4132 | #endif /* CONFIG_PM */ |
| @@ -396,10 +396,23 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, · 395 unmodified lines | |||
| 396 | case ATA_LPM_MED_POWER_WITH_DIPM: | 396 | case ATA_LPM_MED_POWER_WITH_DIPM: |
| 397 | case ATA_LPM_MIN_POWER_WITH_PARTIAL: | 397 | case ATA_LPM_MIN_POWER_WITH_PARTIAL: |
| 398 | case ATA_LPM_MIN_POWER: | 398 | case ATA_LPM_MIN_POWER: |
| 399 | if (ata_link_nr_enabled(link) > 0) | 399 | if (ata_link_nr_enabled(link) > 0) { |
| 400 | /* no restrictions on LPM transitions */ | 400 | /* assume no restrictions on LPM transitions */ |
| 401 | scontrol &= ~(0x7 << 8); | 401 | scontrol &= ~(0x7 << 8); |
| 402 | else { | 402 | |
| 403 | /* | ||
| 404 | * If the controller does not support partial, slumber, | ||
| 405 | * or devsleep, then disallow these transitions. | ||
| 406 | */ | ||
| 407 | if (link->ap->host->flags & ATA_HOST_NO_PART) | ||
| 408 | scontrol |= (0x1 << 8); | ||
| 409 | |||
| 410 | if (link->ap->host->flags & ATA_HOST_NO_SSC) | ||
| 411 | scontrol |= (0x2 << 8); | ||
| 412 | |||
| 413 | if (link->ap->host->flags & ATA_HOST_NO_DEVSLP) | ||
| 414 | scontrol |= (0x4 << 8); | ||
| 415 | } else { | ||
| 403 | /* empty port, power off */ | 416 | /* empty port, power off */ |
| 404 | scontrol &= ~0xf; | 417 | scontrol &= ~0xf; |
| 405 | scontrol |= (0x1 << 2); | 418 | scontrol |= (0x1 << 2); |
| @@ -1050,14 +1050,13 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 1049 unmodified lines | |||
| 1050 | } | 1050 | } |
| 1051 | } else { | 1051 | } else { |
| 1052 | sdev->sector_size = ata_id_logical_sector_size(dev->id); | 1052 | sdev->sector_size = ata_id_logical_sector_size(dev->id); |
| 1053 | |||
| 1053 | /* | 1054 | /* |
| 1054 | * Stop the drive on suspend but do not issue START STOP UNIT | 1055 | * Ask the sd driver to issue START STOP UNIT on runtime suspend |
| 1055 | * on resume as this is not necessary and may fail: the device | 1056 | * and resume only. For system level suspend/resume, devices |
| 1056 | * will be woken up by ata_port_pm_resume() with a port reset | 1057 | * power state is handled directly by libata EH. |
| 1057 | * and device revalidation. | ||
| 1058 | */ | 1058 | */ |
| 1059 | sdev->manage_start_stop = 1; | 1059 | sdev->manage_runtime_start_stop = true; |
| 1060 | sdev->no_start_on_resume = 1; | ||
| 1061 | } | 1060 | } |
| 1062 | 1061 | ||
| 1063 | /* | 1062 | /* |
| @@ -1089,6 +1088,42 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 25 unmodified lines | |||
| 1089 | return 0; | 1088 | return 0; |
| 1090 | } | 1089 | } |
| 1091 | 1090 | ||
| 1091 | /** | ||
| 1092 | * ata_scsi_slave_alloc - Early setup of SCSI device | ||
| 1093 | * @sdev: SCSI device to examine | ||
| 1094 | * | ||
| 1095 | * This is called from scsi_alloc_sdev() when the scsi device | ||
| 1096 | * associated with an ATA device is scanned on a port. | ||
| 1097 | * | ||
| 1098 | * LOCKING: | ||
| 1099 | * Defined by SCSI layer. We don't really care. | ||
| 1100 | */ | ||
| 1101 | |||
| 1102 | int ata_scsi_slave_alloc(struct scsi_device *sdev) | ||
| 1103 | { | ||
| 1104 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
| 1105 | struct device_link *link; | ||
| 1106 | |||
| 1107 | ata_scsi_sdev_config(sdev); | ||
| 1108 | |||
| 1109 | /* | ||
| 1110 | * Create a link from the ata_port device to the scsi device to ensure | ||
| 1111 | * that PM does suspend/resume in the correct order: the scsi device is | ||
| 1112 | * consumer (child) and the ata port the supplier (parent). | ||
| 1113 | */ | ||
| 1114 | link = device_link_add(&sdev->sdev_gendev, &ap->tdev, | ||
| 1115 | DL_FLAG_STATELESS | | ||
| 1116 | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); | ||
| 1117 | if (!link) { | ||
| 1118 | ata_port_err(ap, "Failed to create link to scsi device %s\n", | ||
| 1119 | dev_name(&sdev->sdev_gendev)); | ||
| 1120 | return -ENODEV; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | return 0; | ||
| 1124 | } | ||
| 1125 | EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); | ||
| 1126 | |||
| 1092 | /** | 1127 | /** |
| 1093 | * ata_scsi_slave_config - Set SCSI device attributes | 1128 | * ata_scsi_slave_config - Set SCSI device attributes |
| 1094 | * @sdev: SCSI device to examine | 1129 | * @sdev: SCSI device to examine |
| @@ -1105,14 +1140,11 @@ int ata_scsi_slave_config(struct scsi_device *sdev) · 10 unmodified lines | |||
| 1105 | { | 1140 | { |
| 1106 | struct ata_port *ap = ata_shost_to_port(sdev->host); | 1141 | struct ata_port *ap = ata_shost_to_port(sdev->host); |
| 1107 | struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); | 1142 | struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); |
| 1108 | int rc = 0; | ||
| 1109 | |||
| 1110 | ata_scsi_sdev_config(sdev); | ||
| 1111 | 1143 | ||
| 1112 | if (dev) | 1144 | if (dev) |
| 1113 | rc = ata_scsi_dev_config(sdev, dev); | 1145 | return ata_scsi_dev_config(sdev, dev); |
| 1114 | 1146 | ||
| 1115 | return rc; | 1147 | return 0; |
| 1116 | } | 1148 | } |
| 1117 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); | 1149 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); |
| 1118 | 1150 | ||
| @@ -1136,6 +1168,8 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) · 17 unmodified lines | |||
| 1136 | unsigned long flags; | 1168 | unsigned long flags; |
| 1137 | struct ata_device *dev; | 1169 | struct ata_device *dev; |
| 1138 | 1170 | ||
| 1171 | device_link_remove(&sdev->sdev_gendev, &ap->tdev); | ||
| 1172 | |||
| 1139 | spin_lock_irqsave(ap->lock, flags); | 1173 | spin_lock_irqsave(ap->lock, flags); |
| 1140 | dev = __ata_scsi_find_dev(ap, sdev); | 1174 | dev = __ata_scsi_find_dev(ap, sdev); |
| 1141 | if (dev && dev->sdev) { | 1175 | if (dev && dev->sdev) { |
| @@ -1195,7 +1229,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 53 unmodified lines | |||
| 1195 | } | 1229 | } |
| 1196 | 1230 | ||
| 1197 | if (cdb[4] & 0x1) { | 1231 | if (cdb[4] & 0x1) { |
| 1198 | tf->nsect = 1; /* 1 sector, lba=0 */ | 1232 | tf->nsect = 1; /* 1 sector, lba=0 */ |
| 1199 | 1233 | ||
| 1200 | if (qc->dev->flags & ATA_DFLAG_LBA) { | 1234 | if (qc->dev->flags & ATA_DFLAG_LBA) { |
| 1201 | tf->flags |= ATA_TFLAG_LBA; | 1235 | tf->flags |= ATA_TFLAG_LBA; |
| @@ -1211,7 +1245,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 9 unmodified lines | |||
| 1211 | tf->lbah = 0x0; /* cyl high */ | 1245 | tf->lbah = 0x0; /* cyl high */ |
| 1212 | } | 1246 | } |
| 1213 | 1247 | ||
| 1214 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | 1248 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ |
| 1215 | } else { | 1249 | } else { |
| 1216 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 | 1250 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 |
| 1217 | * or S5) causing some drives to spin up and down again. | 1251 | * or S5) causing some drives to spin up and down again. |
| @@ -1221,7 +1255,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) · 3 unmodified lines | |||
| 1221 | goto skip; | 1255 | goto skip; |
| 1222 | 1256 | ||
| 1223 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | 1257 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && |
| 1224 | system_entering_hibernation()) | 1258 | system_entering_hibernation()) |
| 1225 | goto skip; | 1259 | goto skip; |
| 1226 | 1260 | ||
| 1227 | /* Issue ATA STANDBY IMMEDIATE command */ | 1261 | /* Issue ATA STANDBY IMMEDIATE command */ |
| @@ -1835,6 +1869,9 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) · 607 unmodified lines | |||
| 1835 | hdr[2] = 0x7; /* claim SPC-5 version compatibility */ | 1869 | hdr[2] = 0x7; /* claim SPC-5 version compatibility */ |
| 1836 | } | 1870 | } |
| 1837 | 1871 | ||
| 1872 | if (args->dev->flags & ATA_DFLAG_CDL) | ||
| 1873 | hdr[2] = 0xd; /* claim SPC-6 version compatibility */ | ||
| 1874 | |||
| 1838 | memcpy(rbuf, hdr, sizeof(hdr)); | 1875 | memcpy(rbuf, hdr, sizeof(hdr)); |
| 1839 | memcpy(&rbuf[8], "ATA ", 8); | 1876 | memcpy(&rbuf[8], "ATA ", 8); |
| 1840 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); | 1877 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); |
| @@ -4312,7 +4349,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) · 2471 unmodified lines | |||
| 4312 | break; | 4349 | break; |
| 4313 | 4350 | ||
| 4314 | case MAINTENANCE_IN: | 4351 | case MAINTENANCE_IN: |
| 4315 | if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) | 4352 | if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) |
| 4316 | ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); | 4353 | ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); |
| 4317 | else | 4354 | else |
| 4318 | ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); | 4355 | ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); |
| @@ -4722,7 +4759,7 @@ void ata_scsi_dev_rescan(struct work_struct *work) · 403 unmodified lines | |||
| 4722 | struct ata_link *link; | 4759 | struct ata_link *link; |
| 4723 | struct ata_device *dev; | 4760 | struct ata_device *dev; |
| 4724 | unsigned long flags; | 4761 | unsigned long flags; |
| 4725 | bool delay_rescan = false; | 4762 | int ret = 0; |
| 4726 | 4763 | ||
| 4727 | mutex_lock(&ap->scsi_scan_mutex); | 4764 | mutex_lock(&ap->scsi_scan_mutex); |
| 4728 | spin_lock_irqsave(ap->lock, flags); | 4765 | spin_lock_irqsave(ap->lock, flags); |
| @@ -4731,37 +4768,34 @@ void ata_scsi_dev_rescan(struct work_struct *work) · 2 unmodified lines | |||
| 4731 | ata_for_each_dev(dev, link, ENABLED) { | 4768 | ata_for_each_dev(dev, link, ENABLED) { |
| 4732 | struct scsi_device *sdev = dev->sdev; | 4769 | struct scsi_device *sdev = dev->sdev; |
| 4733 | 4770 | ||
| 4771 | /* | ||
| 4772 | * If the port was suspended before this was scheduled, | ||
| 4773 | * bail out. | ||
| 4774 | */ | ||
| 4775 | if (ap->pflags & ATA_PFLAG_SUSPENDED) | ||
| 4776 | goto unlock; | ||
| 4777 | |||
| 4734 | if (!sdev) | 4778 | if (!sdev) |
| 4735 | continue; | 4779 | continue; |
| 4736 | if (scsi_device_get(sdev)) | 4780 | if (scsi_device_get(sdev)) |
| 4737 | continue; | 4781 | continue; |
| 4738 | 4782 | ||
| 4739 | /* | ||
| 4740 | * If the rescan work was scheduled because of a resume | ||
| 4741 | * event, the port is already fully resumed, but the | ||
| 4742 | * SCSI device may not yet be fully resumed. In such | ||
| 4743 | * case, executing scsi_rescan_device() may cause a | ||
| 4744 | * deadlock with the PM code on device_lock(). Prevent | ||
| 4745 | * this by giving up and retrying rescan after a short | ||
| 4746 | * delay. | ||
| 4747 | */ | ||
| 4748 | delay_rescan = sdev->sdev_gendev.power.is_suspended; | ||
| 4749 | if (delay_rescan) { | ||
| 4750 | scsi_device_put(sdev); | ||
| 4751 | break; | ||
| 4752 | } | ||
| 4753 | |||
| 4754 | spin_unlock_irqrestore(ap->lock, flags); | 4783 | spin_unlock_irqrestore(ap->lock, flags); |
| 4755 | scsi_rescan_device(sdev); | 4784 | ret = scsi_rescan_device(sdev); |
| 4756 | scsi_device_put(sdev); | 4785 | scsi_device_put(sdev); |
| 4757 | spin_lock_irqsave(ap->lock, flags); | 4786 | spin_lock_irqsave(ap->lock, flags); |
| 4787 | |||
| 4788 | if (ret) | ||
| 4789 | goto unlock; | ||
| 4758 | } | 4790 | } |
| 4759 | } | 4791 | } |
| 4760 | 4792 | ||
| 4793 | unlock: | ||
| 4761 | spin_unlock_irqrestore(ap->lock, flags); | 4794 | spin_unlock_irqrestore(ap->lock, flags); |
| 4762 | mutex_unlock(&ap->scsi_scan_mutex); | 4795 | mutex_unlock(&ap->scsi_scan_mutex); |
| 4763 | 4796 | ||
| 4764 | if (delay_rescan) | 4797 | /* Reschedule with a delay if scsi_rescan_device() returned an error */ |
| 4798 | if (ret) | ||
| 4765 | schedule_delayed_work(&ap->scsi_rescan_task, | 4799 | schedule_delayed_work(&ap->scsi_rescan_task, |
| 4766 | msecs_to_jiffies(5)); | 4800 | msecs_to_jiffies(5)); |
| 4767 | } | 4801 | } |
| @@ -266,6 +266,10 @@ void ata_tport_delete(struct ata_port *ap) · 265 unmodified lines | |||
| 266 | put_device(dev); | 266 | put_device(dev); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | static const struct device_type ata_port_sas_type = { | ||
| 270 | .name = ATA_PORT_TYPE_NAME, | ||
| 271 | }; | ||
| 272 | |||
| 269 | /** ata_tport_add - initialize a transport ATA port structure | 273 | /** ata_tport_add - initialize a transport ATA port structure |
| 270 | * | 274 | * |
| 271 | * @parent: parent device | 275 | * @parent: parent device |
| @@ -283,7 +287,10 @@ int ata_tport_add(struct device *parent, · 11 unmodified lines | |||
| 283 | struct device *dev = &ap->tdev; | 287 | struct device *dev = &ap->tdev; |
| 284 | 288 | ||
| 285 | device_initialize(dev); | 289 | device_initialize(dev); |
| 286 | dev->type = &ata_port_type; | 290 | if (ap->flags & ATA_FLAG_SAS_HOST) |
| 291 | dev->type = &ata_port_sas_type; | ||
| 292 | else | ||
| 293 | dev->type = &ata_port_type; | ||
| 287 | 294 | ||
| 288 | dev->parent = parent; | 295 | dev->parent = parent; |
| 289 | ata_host_get(ap->host); | 296 | ata_host_get(ap->host); |
| @@ -30,6 +30,8 @@ enum { · 29 unmodified lines | |||
| 30 | ATA_DNXFER_QUIET = (1 << 31), | 30 | ATA_DNXFER_QUIET = (1 << 31), |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define ATA_PORT_TYPE_NAME "ata_port" | ||
| 34 | |||
| 33 | extern atomic_t ata_print_id; | 35 | extern atomic_t ata_print_id; |
| 34 | extern int atapi_passthru16; | 36 | extern int atapi_passthru16; |
| 35 | extern int libata_fua; | 37 | extern int libata_fua; |
| @@ -60,6 +62,8 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags); · 24 unmodified lines | |||
| 60 | extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | 62 | extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, |
| 61 | unsigned int readid_flags); | 63 | unsigned int readid_flags); |
| 62 | extern int ata_dev_configure(struct ata_device *dev); | 64 | extern int ata_dev_configure(struct ata_device *dev); |
| 65 | extern void ata_dev_power_set_standby(struct ata_device *dev); | ||
| 66 | extern void ata_dev_power_set_active(struct ata_device *dev); | ||
| 63 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); | 67 | extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit); |
| 64 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); | 68 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); |
| 65 | extern unsigned int ata_dev_set_feature(struct ata_device *dev, | 69 | extern unsigned int ata_dev_set_feature(struct ata_device *dev, |
| @@ -37,7 +37,7 @@ static int comm_read_regr(struct pi_adapter *pi, int cont, int regr) · 36 unmodified lines | |||
| 37 | { | 37 | { |
| 38 | int l, h, r; | 38 | int l, h, r; |
| 39 | 39 | ||
| 40 | r = regr + cont_map[cont]; | 40 | r = regr + cont_map[cont]; |
| 41 | 41 | ||
| 42 | switch (pi->mode) { | 42 | switch (pi->mode) { |
| 43 | case 0: | 43 | case 0: |
| @@ -90,7 +90,6 @@ static void comm_connect(struct pi_adapter *pi) · 46 unmodified lines | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static void comm_disconnect(struct pi_adapter *pi) | 92 | static void comm_disconnect(struct pi_adapter *pi) |
| 93 | |||
| 94 | { | 93 | { |
| 95 | w2(0); w2(0); w2(0); w2(4); | 94 | w2(0); w2(0); w2(0); w2(4); |
| 96 | w0(pi->saved_r0); | 95 | w0(pi->saved_r0); |
| @@ -172,12 +171,12 @@ static void comm_write_block(struct pi_adapter *pi, char *buf, int count) · 75 unmodified lines | |||
| 172 | w4l(swab16(((u16 *)buf)[2 * k]) | | 171 | w4l(swab16(((u16 *)buf)[2 * k]) | |
| 173 | swab16(((u16 *)buf)[2 * k + 1]) << 16); | 172 | swab16(((u16 *)buf)[2 * k + 1]) << 16); |
| 174 | break; | 173 | break; |
| 175 | } | 174 | } |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | static void comm_log_adapter(struct pi_adapter *pi) | 177 | static void comm_log_adapter(struct pi_adapter *pi) |
| 179 | 178 | { | |
| 180 | { char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; | 179 | char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; |
| 181 | 180 | ||
| 182 | dev_info(&pi->dev, | 181 | dev_info(&pi->dev, |
| 183 | "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n", | 182 | "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n", |
| @@ -1255,8 +1255,8 @@ static void mv_dump_mem(struct device *dev, void __iomem *start, unsigned bytes) · 1254 unmodified lines | |||
| 1255 | 1255 | ||
| 1256 | for (b = 0; b < bytes; ) { | 1256 | for (b = 0; b < bytes; ) { |
| 1257 | for (w = 0, o = 0; b < bytes && w < 4; w++) { | 1257 | for (w = 0, o = 0; b < bytes && w < 4; w++) { |
| 1258 | o += snprintf(linebuf + o, sizeof(linebuf) - o, | 1258 | o += scnprintf(linebuf + o, sizeof(linebuf) - o, |
| 1259 | "%08x ", readl(start + b)); | 1259 | "%08x ", readl(start + b)); |
| 1260 | b += sizeof(u32); | 1260 | b += sizeof(u32); |
| 1261 | } | 1261 | } |
| 1262 | dev_dbg(dev, "%s: %p: %s\n", | 1262 | dev_dbg(dev, "%s: %p: %s\n", |
| @@ -3537,6 +3537,8 @@ int device_add(struct device *dev) · 3536 unmodified lines | |||
| 3537 | /* subsystems can specify simple device enumeration */ | 3537 | /* subsystems can specify simple device enumeration */ |
| 3538 | else if (dev->bus && dev->bus->dev_name) | 3538 | else if (dev->bus && dev->bus->dev_name) |
| 3539 | error = dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); | 3539 | error = dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id); |
| 3540 | else | ||
| 3541 | error = -EINVAL; | ||
| 3540 | if (error) | 3542 | if (error) |
| 3541 | goto name_error; | 3543 | goto name_error; |
| 3542 | 3544 | ||
| @@ -632,9 +632,8 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) · 631 unmodified lines | |||
| 632 | static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); | 632 | static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); |
| 633 | 633 | ||
| 634 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); | 634 | static int rbd_dev_refresh(struct rbd_device *rbd_dev); |
| 635 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); | 635 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, |
| 636 | static int rbd_dev_header_info(struct rbd_device *rbd_dev); | 636 | struct rbd_image_header *header); |
| 637 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); | ||
| 638 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, | 637 | static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, |
| 639 | u64 snap_id); | 638 | u64 snap_id); |
| 640 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, | 639 | static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, |
| @@ -995,15 +994,24 @@ static void rbd_init_layout(struct rbd_device *rbd_dev) · 354 unmodified lines | |||
| 995 | RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); | 994 | RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); |
| 996 | } | 995 | } |
| 997 | 996 | ||
| 997 | static void rbd_image_header_cleanup(struct rbd_image_header *header) | ||
| 998 | { | ||
| 999 | kfree(header->object_prefix); | ||
| 1000 | ceph_put_snap_context(header->snapc); | ||
| 1001 | kfree(header->snap_sizes); | ||
| 1002 | kfree(header->snap_names); | ||
| 1003 | |||
| 1004 | memset(header, 0, sizeof(*header)); | ||
| 1005 | } | ||
| 1006 | |||
| 998 | /* | 1007 | /* |
| 999 | * Fill an rbd image header with information from the given format 1 | 1008 | * Fill an rbd image header with information from the given format 1 |
| 1000 | * on-disk header. | 1009 | * on-disk header. |
| 1001 | */ | 1010 | */ |
| 1002 | static int rbd_header_from_disk(struct rbd_device *rbd_dev, | 1011 | static int rbd_header_from_disk(struct rbd_image_header *header, |
| 1003 | struct rbd_image_header_ondisk *ondisk) | 1012 | struct rbd_image_header_ondisk *ondisk, |
| 1013 | bool first_time) | ||
| 1004 | { | 1014 | { |
| 1005 | struct rbd_image_header *header = &rbd_dev->header; | ||
| 1006 | bool first_time = header->object_prefix == NULL; | ||
| 1007 | struct ceph_snap_context *snapc; | 1015 | struct ceph_snap_context *snapc; |
| 1008 | char *object_prefix = NULL; | 1016 | char *object_prefix = NULL; |
| 1009 | char *snap_names = NULL; | 1017 | char *snap_names = NULL; |
| @@ -1070,11 +1078,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, · 60 unmodified lines | |||
| 1070 | if (first_time) { | 1078 | if (first_time) { |
| 1071 | header->object_prefix = object_prefix; | 1079 | header->object_prefix = object_prefix; |
| 1072 | header->obj_order = ondisk->options.order; | 1080 | header->obj_order = ondisk->options.order; |
| 1073 | rbd_init_layout(rbd_dev); | ||
| 1074 | } else { | ||
| 1075 | ceph_put_snap_context(header->snapc); | ||
| 1076 | kfree(header->snap_names); | ||
| 1077 | kfree(header->snap_sizes); | ||
| 1078 | } | 1081 | } |
| 1079 | 1082 | ||
| 1080 | /* The remaining fields always get updated (when we refresh) */ | 1083 | /* The remaining fields always get updated (when we refresh) */ |
| @@ -4859,7 +4862,9 @@ out_req: · 3778 unmodified lines | |||
| 4859 | * return, the rbd_dev->header field will contain up-to-date | 4862 | * return, the rbd_dev->header field will contain up-to-date |
| 4860 | * information about the image. | 4863 | * information about the image. |
| 4861 | */ | 4864 | */ |
| 4862 | static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) | 4865 | static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, |
| 4866 | struct rbd_image_header *header, | ||
| 4867 | bool first_time) | ||
| 4863 | { | 4868 | { |
| 4864 | struct rbd_image_header_ondisk *ondisk = NULL; | 4869 | struct rbd_image_header_ondisk *ondisk = NULL; |
| 4865 | u32 snap_count = 0; | 4870 | u32 snap_count = 0; |
| @@ -4907,7 +4912,7 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) · 41 unmodified lines | |||
| 4907 | snap_count = le32_to_cpu(ondisk->snap_count); | 4912 | snap_count = le32_to_cpu(ondisk->snap_count); |
| 4908 | } while (snap_count != want_count); | 4913 | } while (snap_count != want_count); |
| 4909 | 4914 | ||
| 4910 | ret = rbd_header_from_disk(rbd_dev, ondisk); | 4915 | ret = rbd_header_from_disk(header, ondisk, first_time); |
| 4911 | out: | 4916 | out: |
| 4912 | kfree(ondisk); | 4917 | kfree(ondisk); |
| 4913 | 4918 | ||
| @@ -4931,39 +4936,6 @@ static void rbd_dev_update_size(struct rbd_device *rbd_dev) · 17 unmodified lines | |||
| 4931 | } | 4936 | } |
| 4932 | } | 4937 | } |
| 4933 | 4938 | ||
| 4934 | static int rbd_dev_refresh(struct rbd_device *rbd_dev) | ||
| 4935 | { | ||
| 4936 | u64 mapping_size; | ||
| 4937 | int ret; | ||
| 4938 | |||
| 4939 | down_write(&rbd_dev->header_rwsem); | ||
| 4940 | mapping_size = rbd_dev->mapping.size; | ||
| 4941 | |||
| 4942 | ret = rbd_dev_header_info(rbd_dev); | ||
| 4943 | if (ret) | ||
| 4944 | goto out; | ||
| 4945 | |||
| 4946 | /* | ||
| 4947 | * If there is a parent, see if it has disappeared due to the | ||
| 4948 | * mapped image getting flattened. | ||
| 4949 | */ | ||
| 4950 | if (rbd_dev->parent) { | ||
| 4951 | ret = rbd_dev_v2_parent_info(rbd_dev); | ||
| 4952 | if (ret) | ||
| 4953 | goto out; | ||
| 4954 | } | ||
| 4955 | |||
| 4956 | rbd_assert(!rbd_is_snap(rbd_dev)); | ||
| 4957 | rbd_dev->mapping.size = rbd_dev->header.image_size; | ||
| 4958 | |||
| 4959 | out: | ||
| 4960 | up_write(&rbd_dev->header_rwsem); | ||
| 4961 | if (!ret && mapping_size != rbd_dev->mapping.size) | ||
| 4962 | rbd_dev_update_size(rbd_dev); | ||
| 4963 | |||
| 4964 | return ret; | ||
| 4965 | } | ||
| 4966 | |||
| 4967 | static const struct blk_mq_ops rbd_mq_ops = { | 4939 | static const struct blk_mq_ops rbd_mq_ops = { |
| 4968 | .queue_rq = rbd_queue_rq, | 4940 | .queue_rq = rbd_queue_rq, |
| 4969 | }; | 4941 | }; |
| @@ -5503,17 +5475,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, · 533 unmodified lines | |||
| 5503 | return 0; | 5475 | return 0; |
| 5504 | } | 5476 | } |
| 5505 | 5477 | ||
| 5506 | static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) | 5478 | static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, |
| 5507 | { | 5479 | char **pobject_prefix) |
| 5508 | return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, | ||
| 5509 | &rbd_dev->header.obj_order, | ||
| 5510 | &rbd_dev->header.image_size); | ||
| 5511 | } | ||
| 5512 | |||
| 5513 | static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) | ||
| 5514 | { | 5480 | { |
| 5515 | size_t size; | 5481 | size_t size; |
| 5516 | void *reply_buf; | 5482 | void *reply_buf; |
| 5483 | char *object_prefix; | ||
| 5517 | int ret; | 5484 | int ret; |
| 5518 | void *p; | 5485 | void *p; |
| 5519 | 5486 | ||
| @@ -5531,16 +5498,16 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) · 11 unmodified lines | |||
| 5531 | goto out; | 5498 | goto out; |
| 5532 | 5499 | ||
| 5533 | p = reply_buf; | 5500 | p = reply_buf; |
| 5534 | rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, | 5501 | object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, |
| 5535 | p + ret, NULL, GFP_NOIO); | 5502 | GFP_NOIO); |
| 5503 | if (IS_ERR(object_prefix)) { | ||
| 5504 | ret = PTR_ERR(object_prefix); | ||
| 5505 | goto out; | ||
| 5506 | } | ||
| 5536 | ret = 0; | 5507 | ret = 0; |
| 5537 | 5508 | ||
| 5538 | if (IS_ERR(rbd_dev->header.object_prefix)) { | 5509 | *pobject_prefix = object_prefix; |
| 5539 | ret = PTR_ERR(rbd_dev->header.object_prefix); | 5510 | dout(" object_prefix = %s\n", object_prefix); |
| 5540 | rbd_dev->header.object_prefix = NULL; | ||
| 5541 | } else { | ||
| 5542 | dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); | ||
| 5543 | } | ||
| 5544 | out: | 5511 | out: |
| 5545 | kfree(reply_buf); | 5512 | kfree(reply_buf); |
| 5546 | 5513 | ||
| @@ -5591,13 +5558,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, · 44 unmodified lines | |||
| 5591 | return 0; | 5558 | return 0; |
| 5592 | } | 5559 | } |
| 5593 | 5560 | ||
| 5594 | static int rbd_dev_v2_features(struct rbd_device *rbd_dev) | ||
| 5595 | { | ||
| 5596 | return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, | ||
| 5597 | rbd_is_ro(rbd_dev), | ||
| 5598 | &rbd_dev->header.features); | ||
| 5599 | } | ||
| 5600 | |||
| 5601 | /* | 5561 | /* |
| 5602 | * These are generic image flags, but since they are used only for | 5562 | * These are generic image flags, but since they are used only for |
| 5603 | * object map, store them in rbd_dev->object_map_flags. | 5563 | * object map, store them in rbd_dev->object_map_flags. |
| @@ -5634,6 +5594,14 @@ struct parent_image_info { · 30 unmodified lines | |||
| 5634 | u64 overlap; | 5594 | u64 overlap; |
| 5635 | }; | 5595 | }; |
| 5636 | 5596 | ||
| 5597 | static void rbd_parent_info_cleanup(struct parent_image_info *pii) | ||
| 5598 | { | ||
| 5599 | kfree(pii->pool_ns); | ||
| 5600 | kfree(pii->image_id); | ||
| 5601 | |||
| 5602 | memset(pii, 0, sizeof(*pii)); | ||
| 5603 | } | ||
| 5604 | |||
| 5637 | /* | 5605 | /* |
| 5638 | * The caller is responsible for @pii. | 5606 | * The caller is responsible for @pii. |
| 5639 | */ | 5607 | */ |
| @@ -5703,6 +5671,9 @@ static int __get_parent_info(struct rbd_device *rbd_dev, · 63 unmodified lines | |||
| 5703 | if (pii->has_overlap) | 5671 | if (pii->has_overlap) |
| 5704 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); | 5672 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); |
| 5705 | 5673 | ||
| 5674 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | ||
| 5675 | __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, | ||
| 5676 | pii->has_overlap, pii->overlap); | ||
| 5706 | return 0; | 5677 | return 0; |
| 5707 | 5678 | ||
| 5708 | e_inval: | 5679 | e_inval: |
| @@ -5741,14 +5712,17 @@ static int __get_parent_info_legacy(struct rbd_device *rbd_dev, · 32 unmodified lines | |||
| 5741 | pii->has_overlap = true; | 5712 | pii->has_overlap = true; |
| 5742 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); | 5713 | ceph_decode_64_safe(&p, end, pii->overlap, e_inval); |
| 5743 | 5714 | ||
| 5715 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | ||
| 5716 | __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, | ||
| 5717 | pii->has_overlap, pii->overlap); | ||
| 5744 | return 0; | 5718 | return 0; |
| 5745 | 5719 | ||
| 5746 | e_inval: | 5720 | e_inval: |
| 5747 | return -EINVAL; | 5721 | return -EINVAL; |
| 5748 | } | 5722 | } |
| 5749 | 5723 | ||
| 5750 | static int get_parent_info(struct rbd_device *rbd_dev, | 5724 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, |
| 5751 | struct parent_image_info *pii) | 5725 | struct parent_image_info *pii) |
| 5752 | { | 5726 | { |
| 5753 | struct page *req_page, *reply_page; | 5727 | struct page *req_page, *reply_page; |
| 5754 | void *p; | 5728 | void *p; |
| @@ -5776,7 +5750,7 @@ static int get_parent_info(struct rbd_device *rbd_dev, · 21 unmodified lines | |||
| 5776 | return ret; | 5750 | return ret; |
| 5777 | } | 5751 | } |
| 5778 | 5752 | ||
| 5779 | static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | 5753 | static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) |
| 5780 | { | 5754 | { |
| 5781 | struct rbd_spec *parent_spec; | 5755 | struct rbd_spec *parent_spec; |
| 5782 | struct parent_image_info pii = { 0 }; | 5756 | struct parent_image_info pii = { 0 }; |
| @@ -5786,37 +5760,12 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 3 unmodified lines | |||
| 5786 | if (!parent_spec) | 5760 | if (!parent_spec) |
| 5787 | return -ENOMEM; | 5761 | return -ENOMEM; |
| 5788 | 5762 | ||
| 5789 | ret = get_parent_info(rbd_dev, &pii); | 5763 | ret = rbd_dev_v2_parent_info(rbd_dev, &pii); |
| 5790 | if (ret) | 5764 | if (ret) |
| 5791 | goto out_err; | 5765 | goto out_err; |
| 5792 | 5766 | ||
| 5793 | dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", | 5767 | if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) |
| 5794 | __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, | ||
| 5795 | pii.has_overlap, pii.overlap); | ||
| 5796 | |||
| 5797 | if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { | ||
| 5798 | /* | ||
| 5799 | * Either the parent never existed, or we have | ||
| 5800 | * record of it but the image got flattened so it no | ||
| 5801 | * longer has a parent. When the parent of a | ||
| 5802 | * layered image disappears we immediately set the | ||
| 5803 | * overlap to 0. The effect of this is that all new | ||
| 5804 | * requests will be treated as if the image had no | ||
| 5805 | * parent. | ||
| 5806 | * | ||
| 5807 | * If !pii.has_overlap, the parent image spec is not | ||
| 5808 | * applicable. It's there to avoid duplication in each | ||
| 5809 | * snapshot record. | ||
| 5810 | */ | ||
| 5811 | if (rbd_dev->parent_overlap) { | ||
| 5812 | rbd_dev->parent_overlap = 0; | ||
| 5813 | rbd_dev_parent_put(rbd_dev); | ||
| 5814 | pr_info("%s: clone image has been flattened\n", | ||
| 5815 | rbd_dev->disk->disk_name); | ||
| 5816 | } | ||
| 5817 | |||
| 5818 | goto out; /* No parent? No problem. */ | 5768 | goto out; /* No parent? No problem. */ |
| 5819 | } | ||
| 5820 | 5769 | ||
| 5821 | /* The ceph file layout needs to fit pool id in 32 bits */ | 5770 | /* The ceph file layout needs to fit pool id in 32 bits */ |
| 5822 | 5771 | ||
| @@ -5828,58 +5777,46 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) · 5 unmodified lines | |||
| 5828 | } | 5777 | } |
| 5829 | 5778 | ||
| 5830 | /* | 5779 | /* |
| 5831 | * The parent won't change (except when the clone is | 5780 | * The parent won't change except when the clone is flattened, |
| 5832 | * flattened, already handled that). So we only need to | 5781 | * so we only need to record the parent image spec once. |
| 5833 | * record the parent spec we have not already done so. | ||
| 5834 | */ | 5782 | */ |
| 5835 | if (!rbd_dev->parent_spec) { | 5783 | parent_spec->pool_id = pii.pool_id; |
| 5836 | parent_spec->pool_id = pii.pool_id; | 5784 | if (pii.pool_ns && *pii.pool_ns) { |
| 5837 | if (pii.pool_ns && *pii.pool_ns) { | 5785 | parent_spec->pool_ns = pii.pool_ns; |
| 5838 | parent_spec->pool_ns = pii.pool_ns; | 5786 | pii.pool_ns = NULL; |
| 5839 | pii.pool_ns = NULL; | ||
| 5840 | } | ||
| 5841 | parent_spec->image_id = pii.image_id; | ||
| 5842 | pii.image_id = NULL; | ||
| 5843 | parent_spec->snap_id = pii.snap_id; | ||
| 5844 | |||
| 5845 | rbd_dev->parent_spec = parent_spec; | ||
| 5846 | parent_spec = NULL; /* rbd_dev now owns this */ | ||
| 5847 | } | 5787 | } |
| 5788 | parent_spec->image_id = pii.image_id; | ||
| 5789 | pii.image_id = NULL; | ||
| 5790 | parent_spec->snap_id = pii.snap_id; | ||
| 5791 | |||
| 5792 | rbd_assert(!rbd_dev->parent_spec); | ||
| 5793 | rbd_dev->parent_spec = parent_spec; | ||
| 5794 | parent_spec = NULL; /* rbd_dev now owns this */ | ||
| 5848 | 5795 | ||
| 5849 | /* | 5796 | /* |
| 5850 | * We always update the parent overlap. If it's zero we issue | 5797 | * Record the parent overlap. If it's zero, issue a warning as |
| 5851 | * a warning, as we will proceed as if there was no parent. | 5798 | * we will proceed as if there is no parent. |
| 5852 | */ | 5799 | */ |
| 5853 | if (!pii.overlap) { | 5800 | if (!pii.overlap) |
| 5854 | if (parent_spec) { | 5801 | rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); |
| 5855 | /* refresh, careful to warn just once */ | ||
| 5856 | if (rbd_dev->parent_overlap) | ||
| 5857 | rbd_warn(rbd_dev, | ||
| 5858 | "clone now standalone (overlap became 0)"); | ||
| 5859 | } else { | ||
| 5860 | /* initial probe */ | ||
| 5861 | rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); | ||
| 5862 | } | ||
| 5863 | } | ||
| 5864 | rbd_dev->parent_overlap = pii.overlap; | 5802 | rbd_dev->parent_overlap = pii.overlap; |
| 5865 | 5803 | ||
| 5866 | out: | 5804 | out: |
| 5867 | ret = 0; | 5805 | ret = 0; |
| 5868 | out_err: | 5806 | out_err: |
| 5869 | kfree(pii.pool_ns); | 5807 | rbd_parent_info_cleanup(&pii); |
| 5870 | kfree(pii.image_id); | ||
| 5871 | rbd_spec_put(parent_spec); | 5808 | rbd_spec_put(parent_spec); |
| 5872 | return ret; | 5809 | return ret; |
| 5873 | } | 5810 | } |
| 5874 | 5811 | ||
| 5875 | static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) | 5812 | static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, |
| 5813 | u64 *stripe_unit, u64 *stripe_count) | ||
| 5876 | { | 5814 | { |
| 5877 | struct { | 5815 | struct { |
| 5878 | __le64 stripe_unit; | 5816 | __le64 stripe_unit; |
| 5879 | __le64 stripe_count; | 5817 | __le64 stripe_count; |
| 5880 | } __attribute__ ((packed)) striping_info_buf = { 0 }; | 5818 | } __attribute__ ((packed)) striping_info_buf = { 0 }; |
| 5881 | size_t size = sizeof (striping_info_buf); | 5819 | size_t size = sizeof (striping_info_buf); |
| 5882 | void *p; | ||
| 5883 | int ret; | 5820 | int ret; |
| 5884 | 5821 | ||
| 5885 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, | 5822 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, |
| @@ -5891,27 +5828,33 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) · 5 unmodified lines | |||
| 5891 | if (ret < size) | 5828 | if (ret < size) |
| 5892 | return -ERANGE; | 5829 | return -ERANGE; |
| 5893 | 5830 | ||
| 5894 | p = &striping_info_buf; | 5831 | *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); |
| 5895 | rbd_dev->header.stripe_unit = ceph_decode_64(&p); | 5832 | *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); |
| 5896 | rbd_dev->header.stripe_count = ceph_decode_64(&p); | 5833 | dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, |
| 5834 | *stripe_count); | ||
| 5835 | |||
| 5897 | return 0; | 5836 | return 0; |
| 5898 | } | 5837 | } |
| 5899 | 5838 | ||
| 5900 | static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) | 5839 | static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) |
| 5901 | { | 5840 | { |
| 5902 | __le64 data_pool_id; | 5841 | __le64 data_pool_buf; |
| 5903 | int ret; | 5842 | int ret; |
| 5904 | 5843 | ||
| 5905 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, | 5844 | ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, |
| 5906 | &rbd_dev->header_oloc, "get_data_pool", | 5845 | &rbd_dev->header_oloc, "get_data_pool", |
| 5907 | NULL, 0, &data_pool_id, sizeof(data_pool_id)); | 5846 | NULL, 0, &data_pool_buf, |
| 5847 | sizeof(data_pool_buf)); | ||
| 5848 | dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); | ||
| 5908 | if (ret < 0) | 5849 | if (ret < 0) |
| 5909 | return ret; | 5850 | return ret; |
| 5910 | if (ret < sizeof(data_pool_id)) | 5851 | if (ret < sizeof(data_pool_buf)) |
| 5911 | return -EBADMSG; | 5852 | return -EBADMSG; |
| 5912 | 5853 | ||
| 5913 | rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); | 5854 | *data_pool_id = le64_to_cpu(data_pool_buf); |
| 5914 | WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); | 5855 | dout(" data_pool_id = %lld\n", *data_pool_id); |
| 5856 | WARN_ON(*data_pool_id == CEPH_NOPOOL); | ||
| 5857 | |||
| 5915 | return 0; | 5858 | return 0; |
| 5916 | } | 5859 | } |
| 5917 | 5860 | ||
| @@ -6103,7 +6046,8 @@ out_err: · 185 unmodified lines | |||
| 6103 | return ret; | 6046 | return ret; |
| 6104 | } | 6047 | } |
| 6105 | 6048 | ||
| 6106 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) | 6049 | static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, |
| 6050 | struct ceph_snap_context **psnapc) | ||
| 6107 | { | 6051 | { |
| 6108 | size_t size; | 6052 | size_t size; |
| 6109 | int ret; | 6053 | int ret; |
| @@ -6164,9 +6108,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) · 54 unmodified lines | |||
| 6164 | for (i = 0; i < snap_count; i++) | 6108 | for (i = 0; i < snap_count; i++) |
| 6165 | snapc->snaps[i] = ceph_decode_64(&p); | 6109 | snapc->snaps[i] = ceph_decode_64(&p); |
| 6166 | 6110 | ||
| 6167 | ceph_put_snap_context(rbd_dev->header.snapc); | 6111 | *psnapc = snapc; |
| 6168 | rbd_dev->header.snapc = snapc; | ||
| 6169 | |||
| 6170 | dout(" snap context seq = %llu, snap_count = %u\n", | 6112 | dout(" snap context seq = %llu, snap_count = %u\n", |
| 6171 | (unsigned long long)seq, (unsigned int)snap_count); | 6113 | (unsigned long long)seq, (unsigned int)snap_count); |
| 6172 | out: | 6114 | out: |
| @@ -6215,38 +6157,42 @@ out: · 42 unmodified lines | |||
| 6215 | return snap_name; | 6157 | return snap_name; |
| 6216 | } | 6158 | } |
| 6217 | 6159 | ||
| 6218 | static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) | 6160 | static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, |
| 6161 | struct rbd_image_header *header, | ||
| 6162 | bool first_time) | ||
| 6219 | { | 6163 | { |
| 6220 | bool first_time = rbd_dev->header.object_prefix == NULL; | ||
| 6221 | int ret; | 6164 | int ret; |
| 6222 | 6165 | ||
| 6223 | ret = rbd_dev_v2_image_size(rbd_dev); | 6166 | ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, |
| 6167 | first_time ? &header->obj_order : NULL, | ||
| 6168 | &header->image_size); | ||
| 6224 | if (ret) | 6169 | if (ret) |
| 6225 | return ret; | 6170 | return ret; |
| 6226 | 6171 | ||
| 6227 | if (first_time) { | 6172 | if (first_time) { |
| 6228 | ret = rbd_dev_v2_header_onetime(rbd_dev); | 6173 | ret = rbd_dev_v2_header_onetime(rbd_dev, header); |
| 6229 | if (ret) | 6174 | if (ret) |
| 6230 | return ret; | 6175 | return ret; |
| 6231 | } | 6176 | } |
| 6232 | 6177 | ||
| 6233 | ret = rbd_dev_v2_snap_context(rbd_dev); | 6178 | ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); |
| 6234 | if (ret && first_time) { | 6179 | if (ret) |
| 6235 | kfree(rbd_dev->header.object_prefix); | 6180 | return ret; |
| 6236 | rbd_dev->header.object_prefix = NULL; | ||
| 6237 | } | ||
| 6238 | 6181 | ||
| 6239 | return ret; | 6182 | return 0; |
| 6240 | } | 6183 | } |
| 6241 | 6184 | ||
| 6242 | static int rbd_dev_header_info(struct rbd_device *rbd_dev) | 6185 | static int rbd_dev_header_info(struct rbd_device *rbd_dev, |
| 6186 | struct rbd_image_header *header, | ||
| 6187 | bool first_time) | ||
| 6243 | { | 6188 | { |
| 6244 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); | 6189 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); |
| 6190 | rbd_assert(!header->object_prefix && !header->snapc); | ||
| 6245 | 6191 | ||
| 6246 | if (rbd_dev->image_format == 1) | 6192 | if (rbd_dev->image_format == 1) |
| 6247 | return rbd_dev_v1_header_info(rbd_dev); | 6193 | return rbd_dev_v1_header_info(rbd_dev, header, first_time); |
| 6248 | 6194 | ||
| 6249 | return rbd_dev_v2_header_info(rbd_dev); | 6195 | return rbd_dev_v2_header_info(rbd_dev, header, first_time); |
| 6250 | } | 6196 | } |
| 6251 | 6197 | ||
| 6252 | /* | 6198 | /* |
| @@ -6734,60 +6680,49 @@ out: · 481 unmodified lines | |||
| 6734 | */ | 6680 | */ |
| 6735 | static void rbd_dev_unprobe(struct rbd_device *rbd_dev) | 6681 | static void rbd_dev_unprobe(struct rbd_device *rbd_dev) |
| 6736 | { | 6682 | { |
| 6737 | struct rbd_image_header *header; | ||
| 6738 | |||
| 6739 | rbd_dev_parent_put(rbd_dev); | 6683 | rbd_dev_parent_put(rbd_dev); |
| 6740 | rbd_object_map_free(rbd_dev); | 6684 | rbd_object_map_free(rbd_dev); |
| 6741 | rbd_dev_mapping_clear(rbd_dev); | 6685 | rbd_dev_mapping_clear(rbd_dev); |
| 6742 | 6686 | ||
| 6743 | /* Free dynamic fields from the header, then zero it out */ | 6687 | /* Free dynamic fields from the header, then zero it out */ |
| 6744 | 6688 | ||
| 6745 | header = &rbd_dev->header; | 6689 | rbd_image_header_cleanup(&rbd_dev->header); |
| 6746 | ceph_put_snap_context(header->snapc); | ||
| 6747 | kfree(header->snap_sizes); | ||
| 6748 | kfree(header->snap_names); | ||
| 6749 | kfree(header->object_prefix); | ||
| 6750 | memset(header, 0, sizeof (*header)); | ||
| 6751 | } | 6690 | } |
| 6752 | 6691 | ||
| 6753 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) | 6692 | static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, |
| 6693 | struct rbd_image_header *header) | ||
| 6754 | { | 6694 | { |
| 6755 | int ret; | 6695 | int ret; |
| 6756 | 6696 | ||
| 6757 | ret = rbd_dev_v2_object_prefix(rbd_dev); | 6697 | ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); |
| 6758 | if (ret) | 6698 | if (ret) |
| 6759 | goto out_err; | 6699 | return ret; |
| 6760 | 6700 | ||
| 6761 | /* | 6701 | /* |
| 6762 | * Get the and check features for the image. Currently the | 6702 | * Get the and check features for the image. Currently the |
| 6763 | * features are assumed to never change. | 6703 | * features are assumed to never change. |
| 6764 | */ | 6704 | */ |
| 6765 | ret = rbd_dev_v2_features(rbd_dev); | 6705 | ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, |
| 6706 | rbd_is_ro(rbd_dev), &header->features); | ||
| 6766 | if (ret) | 6707 | if (ret) |
| 6767 | goto out_err; | 6708 | return ret; |
| 6768 | 6709 | ||
| 6769 | /* If the image supports fancy striping, get its parameters */ | 6710 | /* If the image supports fancy striping, get its parameters */ |
| 6770 | 6711 | ||
| 6771 | if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { | 6712 | if (header->features & RBD_FEATURE_STRIPINGV2) { |
| 6772 | ret = rbd_dev_v2_striping_info(rbd_dev); | 6713 | ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, |
| 6773 | if (ret < 0) | 6714 | &header->stripe_count); |
| 6774 | goto out_err; | 6715 | if (ret) |
| 6716 | return ret; | ||
| 6775 | } | 6717 | } |
| 6776 | 6718 | ||
| 6777 | if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { | 6719 | if (header->features & RBD_FEATURE_DATA_POOL) { |
| 6778 | ret = rbd_dev_v2_data_pool(rbd_dev); | 6720 | ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); |
| 6779 | if (ret) | 6721 | if (ret) |
| 6780 | goto out_err; | 6722 | return ret; |
| 6781 | } | 6723 | } |
| 6782 | 6724 | ||
| 6783 | rbd_init_layout(rbd_dev); | ||
| 6784 | return 0; | 6725 | return 0; |
| 6785 | |||
| 6786 | out_err: | ||
| 6787 | rbd_dev->header.features = 0; | ||
| 6788 | kfree(rbd_dev->header.object_prefix); | ||
| 6789 | rbd_dev->header.object_prefix = NULL; | ||
| 6790 | return ret; | ||
| 6791 | } | 6726 | } |
| 6792 | 6727 | ||
| 6793 | /* | 6728 | /* |
| @@ -6982,13 +6917,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) · 188 unmodified lines | |||
| 6982 | if (!depth) | 6917 | if (!depth) |
| 6983 | down_write(&rbd_dev->header_rwsem); | 6918 | down_write(&rbd_dev->header_rwsem); |
| 6984 | 6919 | ||
| 6985 | ret = rbd_dev_header_info(rbd_dev); | 6920 | ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); |
| 6986 | if (ret) { | 6921 | if (ret) { |
| 6987 | if (ret == -ENOENT && !need_watch) | 6922 | if (ret == -ENOENT && !need_watch) |
| 6988 | rbd_print_dne(rbd_dev, false); | 6923 | rbd_print_dne(rbd_dev, false); |
| 6989 | goto err_out_probe; | 6924 | goto err_out_probe; |
| 6990 | } | 6925 | } |
| 6991 | 6926 | ||
| 6927 | rbd_init_layout(rbd_dev); | ||
| 6928 | |||
| 6992 | /* | 6929 | /* |
| 6993 | * If this image is the one being mapped, we have pool name and | 6930 | * If this image is the one being mapped, we have pool name and |
| 6994 | * id, image name and id, and snap name - need to fill snap id. | 6931 | * id, image name and id, and snap name - need to fill snap id. |
| @@ -7017,7 +6954,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) · 22 unmodified lines | |||
| 7017 | } | 6954 | } |
| 7018 | 6955 | ||
| 7019 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { | 6956 | if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { |
| 7020 | ret = rbd_dev_v2_parent_info(rbd_dev); | 6957 | ret = rbd_dev_setup_parent(rbd_dev); |
| 7021 | if (ret) | 6958 | if (ret) |
| 7022 | goto err_out_probe; | 6959 | goto err_out_probe; |
| 7023 | } | 6960 | } |
| @@ -7043,6 +6980,107 @@ err_out_format: · 19 unmodified lines | |||
| 7043 | return ret; | 6980 | return ret; |
| 7044 | } | 6981 | } |
| 7045 | 6982 | ||
| 6983 | static void rbd_dev_update_header(struct rbd_device *rbd_dev, | ||
| 6984 | struct rbd_image_header *header) | ||
| 6985 | { | ||
| 6986 | rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); | ||
| 6987 | rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ | ||
| 6988 | |||
| 6989 | if (rbd_dev->header.image_size != header->image_size) { | ||
| 6990 | rbd_dev->header.image_size = header->image_size; | ||
| 6991 | |||
| 6992 | if (!rbd_is_snap(rbd_dev)) { | ||
| 6993 | rbd_dev->mapping.size = header->image_size; | ||
| 6994 | rbd_dev_update_size(rbd_dev); | ||
| 6995 | } | ||
| 6996 | } | ||
| 6997 | |||
| 6998 | ceph_put_snap_context(rbd_dev->header.snapc); | ||
| 6999 | rbd_dev->header.snapc = header->snapc; | ||
| 7000 | header->snapc = NULL; | ||
| 7001 | |||
| 7002 | if (rbd_dev->image_format == 1) { | ||
| 7003 | kfree(rbd_dev->header.snap_names); | ||
| 7004 | rbd_dev->header.snap_names = header->snap_names; | ||
| 7005 | header->snap_names = NULL; | ||
| 7006 | |||
| 7007 | kfree(rbd_dev->header.snap_sizes); | ||
| 7008 | rbd_dev->header.snap_sizes = header->snap_sizes; | ||
| 7009 | header->snap_sizes = NULL; | ||
| 7010 | } | ||
| 7011 | } | ||
| 7012 | |||
| 7013 | static void rbd_dev_update_parent(struct rbd_device *rbd_dev, | ||
| 7014 | struct parent_image_info *pii) | ||
| 7015 | { | ||
| 7016 | if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { | ||
| 7017 | /* | ||
| 7018 | * Either the parent never existed, or we have | ||
| 7019 | * record of it but the image got flattened so it no | ||
| 7020 | * longer has a parent. When the parent of a | ||
| 7021 | * layered image disappears we immediately set the | ||
| 7022 | * overlap to 0. The effect of this is that all new | ||
| 7023 | * requests will be treated as if the image had no | ||
| 7024 | * parent. | ||
| 7025 | * | ||
| 7026 | * If !pii.has_overlap, the parent image spec is not | ||
| 7027 | * applicable. It's there to avoid duplication in each | ||
| 7028 | * snapshot record. | ||
| 7029 | */ | ||
| 7030 | if (rbd_dev->parent_overlap) { | ||
| 7031 | rbd_dev->parent_overlap = 0; | ||
| 7032 | rbd_dev_parent_put(rbd_dev); | ||
| 7033 | pr_info("%s: clone has been flattened\n", | ||
| 7034 | rbd_dev->disk->disk_name); | ||
| 7035 | } | ||
| 7036 | } else { | ||
| 7037 | rbd_assert(rbd_dev->parent_spec); | ||
| 7038 | |||
| 7039 | /* | ||
| 7040 | * Update the parent overlap. If it became zero, issue | ||
| 7041 | * a warning as we will proceed as if there is no parent. | ||
| 7042 | */ | ||
| 7043 | if (!pii->overlap && rbd_dev->parent_overlap) | ||
| 7044 | rbd_warn(rbd_dev, | ||
| 7045 | "clone has become standalone (overlap 0)"); | ||
| 7046 | rbd_dev->parent_overlap = pii->overlap; | ||
| 7047 | } | ||
| 7048 | } | ||
| 7049 | |||
| 7050 | static int rbd_dev_refresh(struct rbd_device *rbd_dev) | ||
| 7051 | { | ||
| 7052 | struct rbd_image_header header = { 0 }; | ||
| 7053 | struct parent_image_info pii = { 0 }; | ||
| 7054 | int ret; | ||
| 7055 | |||
| 7056 | dout("%s rbd_dev %p\n", __func__, rbd_dev); | ||
| 7057 | |||
| 7058 | ret = rbd_dev_header_info(rbd_dev, &header, false); | ||
| 7059 | if (ret) | ||
| 7060 | goto out; | ||
| 7061 | |||
| 7062 | /* | ||
| 7063 | * If there is a parent, see if it has disappeared due to the | ||
| 7064 | * mapped image getting flattened. | ||
| 7065 | */ | ||
| 7066 | if (rbd_dev->parent) { | ||
| 7067 | ret = rbd_dev_v2_parent_info(rbd_dev, &pii); | ||
| 7068 | if (ret) | ||
| 7069 | goto out; | ||
| 7070 | } | ||
| 7071 | |||
| 7072 | down_write(&rbd_dev->header_rwsem); | ||
| 7073 | rbd_dev_update_header(rbd_dev, &header); | ||
| 7074 | if (rbd_dev->parent) | ||
| 7075 | rbd_dev_update_parent(rbd_dev, &pii); | ||
| 7076 | up_write(&rbd_dev->header_rwsem); | ||
| 7077 | |||
| 7078 | out: | ||
| 7079 | rbd_parent_info_cleanup(&pii); | ||
| 7080 | rbd_image_header_cleanup(&header); | ||
| 7081 | return ret; | ||
| 7082 | } | ||
| 7083 | |||
| 7046 | static ssize_t do_rbd_add(const char *buf, size_t count) | 7084 | static ssize_t do_rbd_add(const char *buf, size_t count) |
| 7047 | { | 7085 | { |
| 7048 | struct rbd_device *rbd_dev = NULL; | 7086 | struct rbd_device *rbd_dev = NULL; |
| @@ -38,6 +38,7 @@ enum sysc_soc { · 37 unmodified lines | |||
| 38 | SOC_2420, | 38 | SOC_2420, |
| 39 | SOC_2430, | 39 | SOC_2430, |
| 40 | SOC_3430, | 40 | SOC_3430, |
| 41 | SOC_AM35, | ||
| 41 | SOC_3630, | 42 | SOC_3630, |
| 42 | SOC_4430, | 43 | SOC_4430, |
| 43 | SOC_4460, | 44 | SOC_4460, |
| @@ -1097,6 +1098,11 @@ static int sysc_enable_module(struct device *dev) · 1053 unmodified lines | |||
| 1097 | if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | | 1098 | if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | |
| 1098 | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { | 1099 | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { |
| 1099 | best_mode = SYSC_IDLE_NO; | 1100 | best_mode = SYSC_IDLE_NO; |
| 1101 | |||
| 1102 | /* Clear WAKEUP */ | ||
| 1103 | if (regbits->enwkup_shift >= 0 && | ||
| 1104 | ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) | ||
| 1105 | reg &= ~BIT(regbits->enwkup_shift); | ||
| 1100 | } else { | 1106 | } else { |
| 1101 | best_mode = fls(ddata->cfg.sidlemodes) - 1; | 1107 | best_mode = fls(ddata->cfg.sidlemodes) - 1; |
| 1102 | if (best_mode > SYSC_IDLE_MASK) { | 1108 | if (best_mode > SYSC_IDLE_MASK) { |
| @@ -1224,6 +1230,13 @@ set_sidle: · 121 unmodified lines | |||
| 1224 | } | 1230 | } |
| 1225 | } | 1231 | } |
| 1226 | 1232 | ||
| 1233 | if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { | ||
| 1234 | /* Set WAKEUP */ | ||
| 1235 | if (regbits->enwkup_shift >= 0 && | ||
| 1236 | ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) | ||
| 1237 | reg |= BIT(regbits->enwkup_shift); | ||
| 1238 | } | ||
| 1239 | |||
| 1227 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); | 1240 | reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); |
| 1228 | reg |= best_mode << regbits->sidle_shift; | 1241 | reg |= best_mode << regbits->sidle_shift; |
| 1229 | if (regbits->autoidle_shift >= 0 && | 1242 | if (regbits->autoidle_shift >= 0 && |
| @@ -1518,16 +1531,16 @@ struct sysc_revision_quirk { · 288 unmodified lines | |||
| 1518 | static const struct sysc_revision_quirk sysc_revision_quirks[] = { | 1531 | static const struct sysc_revision_quirk sysc_revision_quirks[] = { |
| 1519 | /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ | 1532 | /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ |
| 1520 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, | 1533 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, |
| 1521 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1534 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1522 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, | 1535 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, |
| 1523 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1536 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1524 | /* Uarts on omap4 and later */ | 1537 | /* Uarts on omap4 and later */ |
| 1525 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, | 1538 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, |
| 1526 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1539 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1527 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, | 1540 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, |
| 1528 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1541 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1529 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, | 1542 | SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, |
| 1530 | SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), | 1543 | SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), |
| 1531 | 1544 | ||
| 1532 | /* Quirks that need to be set based on the module address */ | 1545 | /* Quirks that need to be set based on the module address */ |
| 1533 | SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, | 1546 | SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, |
| @@ -1862,7 +1875,7 @@ static void sysc_pre_reset_quirk_dss(struct sysc *ddata) · 328 unmodified lines | |||
| 1862 | dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", | 1875 | dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", |
| 1863 | __func__, val, irq_mask); | 1876 | __func__, val, irq_mask); |
| 1864 | 1877 | ||
| 1865 | if (sysc_soc->soc == SOC_3430) { | 1878 | if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) { |
| 1866 | /* Clear DSS_SDI_CONTROL */ | 1879 | /* Clear DSS_SDI_CONTROL */ |
| 1867 | sysc_write(ddata, 0x44, 0); | 1880 | sysc_write(ddata, 0x44, 0); |
| 1868 | 1881 | ||
| @@ -2150,8 +2163,7 @@ static int sysc_reset(struct sysc *ddata) · 281 unmodified lines | |||
| 2150 | } | 2163 | } |
| 2151 | 2164 | ||
| 2152 | if (ddata->cfg.srst_udelay) | 2165 | if (ddata->cfg.srst_udelay) |
| 2153 | usleep_range(ddata->cfg.srst_udelay, | 2166 | fsleep(ddata->cfg.srst_udelay); |
| 2154 | ddata->cfg.srst_udelay * 2); | ||
| 2155 | 2167 | ||
| 2156 | if (ddata->post_reset_quirk) | 2168 | if (ddata->post_reset_quirk) |
| 2157 | ddata->post_reset_quirk(ddata); | 2169 | ddata->post_reset_quirk(ddata); |
| @@ -3025,6 +3037,7 @@ static void ti_sysc_idle(struct work_struct *work) · 867 unmodified lines | |||
| 3025 | static const struct soc_device_attribute sysc_soc_match[] = { | 3037 | static const struct soc_device_attribute sysc_soc_match[] = { |
| 3026 | SOC_FLAG("OMAP242*", SOC_2420), | 3038 | SOC_FLAG("OMAP242*", SOC_2420), |
| 3027 | SOC_FLAG("OMAP243*", SOC_2430), | 3039 | SOC_FLAG("OMAP243*", SOC_2430), |
| 3040 | SOC_FLAG("AM35*", SOC_AM35), | ||
| 3028 | SOC_FLAG("OMAP3[45]*", SOC_3430), | 3041 | SOC_FLAG("OMAP3[45]*", SOC_3430), |
| 3029 | SOC_FLAG("OMAP3[67]*", SOC_3630), | 3042 | SOC_FLAG("OMAP3[67]*", SOC_3630), |
| 3030 | SOC_FLAG("OMAP443*", SOC_4430), | 3043 | SOC_FLAG("OMAP443*", SOC_4430), |
| @@ -3229,7 +3242,7 @@ static int sysc_check_active_timer(struct sysc *ddata) · 198 unmodified lines | |||
| 3229 | * can be dropped if we stop supporting old beagleboard revisions | 3242 | * can be dropped if we stop supporting old beagleboard revisions |
| 3230 | * A to B4 at some point. | 3243 | * A to B4 at some point. |
| 3231 | */ | 3244 | */ |
| 3232 | if (sysc_soc->soc == SOC_3430) | 3245 | if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) |
| 3233 | error = -ENXIO; | 3246 | error = -ENXIO; |
| 3234 | else | 3247 | else |
| 3235 | error = -EBUSY; | 3248 | error = -EBUSY; |
| @@ -394,8 +394,6 @@ find_quicksilver(struct device *dev, void *data) · 393 unmodified lines | |||
| 394 | static int __init | 394 | static int __init |
| 395 | parisc_agp_init(void) | 395 | parisc_agp_init(void) |
| 396 | { | 396 | { |
| 397 | extern struct sba_device *sba_list; | ||
| 398 | |||
| 399 | int err = -1; | 397 | int err = -1; |
| 400 | struct parisc_device *sba = NULL, *lba = NULL; | 398 | struct parisc_device *sba = NULL, *lba = NULL; |
| 401 | struct lba_device *lbadev = NULL; | 399 | struct lba_device *lbadev = NULL; |
| @@ -33,7 +33,7 @@ const struct class tpm_class = { · 32 unmodified lines | |||
| 33 | .shutdown_pre = tpm_class_shutdown, | 33 | .shutdown_pre = tpm_class_shutdown, |
| 34 | }; | 34 | }; |
| 35 | const struct class tpmrm_class = { | 35 | const struct class tpmrm_class = { |
| 36 | .name = "tmprm", | 36 | .name = "tpmrm", |
| 37 | }; | 37 | }; |
| 38 | dev_t tpm_devt; | 38 | dev_t tpm_devt; |
| 39 | 39 | ||
| @@ -96,7 +96,7 @@ static int si521xx_regmap_i2c_write(void *context, unsigned int reg, · 95 unmodified lines | |||
| 96 | unsigned int val) | 96 | unsigned int val) |
| 97 | { | 97 | { |
| 98 | struct i2c_client *i2c = context; | 98 | struct i2c_client *i2c = context; |
| 99 | const u8 data[3] = { reg, 1, val }; | 99 | const u8 data[2] = { reg, val }; |
| 100 | const int count = ARRAY_SIZE(data); | 100 | const int count = ARRAY_SIZE(data); |
| 101 | int ret; | 101 | int ret; |
| 102 | 102 | ||
| @@ -146,7 +146,7 @@ static int si521xx_regmap_i2c_read(void *context, unsigned int reg, · 43 unmodified lines | |||
| 146 | static const struct regmap_config si521xx_regmap_config = { | 146 | static const struct regmap_config si521xx_regmap_config = { |
| 147 | .reg_bits = 8, | 147 | .reg_bits = 8, |
| 148 | .val_bits = 8, | 148 | .val_bits = 8, |
| 149 | .cache_type = REGCACHE_NONE, | 149 | .cache_type = REGCACHE_FLAT, |
| 150 | .max_register = SI521XX_REG_DA, | 150 | .max_register = SI521XX_REG_DA, |
| 151 | .rd_table = &si521xx_readable_table, | 151 | .rd_table = &si521xx_readable_table, |
| 152 | .wr_table = &si521xx_writeable_table, | 152 | .wr_table = &si521xx_writeable_table, |
| @@ -281,9 +281,10 @@ static int si521xx_probe(struct i2c_client *client) · 128 unmodified lines | |||
| 281 | { | 281 | { |
| 282 | const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); | 282 | const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); |
| 283 | const struct clk_parent_data clk_parent_data = { .index = 0 }; | 283 | const struct clk_parent_data clk_parent_data = { .index = 0 }; |
| 284 | struct si521xx *si; | 284 | const u8 data[3] = { SI521XX_REG_BC, 1, 1 }; |
| 285 | unsigned char name[6] = "DIFF0"; | 285 | unsigned char name[6] = "DIFF0"; |
| 286 | struct clk_init_data init = {}; | 286 | struct clk_init_data init = {}; |
| 287 | struct si521xx *si; | ||
| 287 | int i, ret; | 288 | int i, ret; |
| 288 | 289 | ||
| 289 | if (!chip_info) | 290 | if (!chip_info) |
| @@ -308,7 +309,7 @@ static int si521xx_probe(struct i2c_client *client) · 18 unmodified lines | |||
| 308 | "Failed to allocate register map\n"); | 309 | "Failed to allocate register map\n"); |
| 309 | 310 | ||
| 310 | /* Always read back 1 Byte via I2C */ | 311 | /* Always read back 1 Byte via I2C */ |
| 311 | ret = regmap_write(si->regmap, SI521XX_REG_BC, 1); | 312 | ret = i2c_master_send(client, data, ARRAY_SIZE(data)); |
| 312 | if (ret < 0) | 313 | if (ret < 0) |
| 313 | return ret; | 314 | return ret; |
| 314 | 315 | ||
| @@ -118,21 +118,21 @@ enum vc3_div { · 117 unmodified lines | |||
| 118 | VC3_DIV5, | 118 | VC3_DIV5, |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | enum vc3_clk_mux { | ||
| 122 | VC3_DIFF2_MUX, | ||
| 123 | VC3_DIFF1_MUX, | ||
| 124 | VC3_SE3_MUX, | ||
| 125 | VC3_SE2_MUX, | ||
| 126 | VC3_SE1_MUX, | ||
| 127 | }; | ||
| 128 | |||
| 129 | enum vc3_clk { | 121 | enum vc3_clk { |
| 130 | VC3_DIFF2, | ||
| 131 | VC3_DIFF1, | ||
| 132 | VC3_SE3, | ||
| 133 | VC3_SE2, | ||
| 134 | VC3_SE1, | ||
| 135 | VC3_REF, | 122 | VC3_REF, |
| 123 | VC3_SE1, | ||
| 124 | VC3_SE2, | ||
| 125 | VC3_SE3, | ||
| 126 | VC3_DIFF1, | ||
| 127 | VC3_DIFF2, | ||
| 128 | }; | ||
| 129 | |||
| 130 | enum vc3_clk_mux { | ||
| 131 | VC3_SE1_MUX = VC3_SE1 - 1, | ||
| 132 | VC3_SE2_MUX = VC3_SE2 - 1, | ||
| 133 | VC3_SE3_MUX = VC3_SE3 - 1, | ||
| 134 | VC3_DIFF1_MUX = VC3_DIFF1 - 1, | ||
| 135 | VC3_DIFF2_MUX = VC3_DIFF2 - 1, | ||
| 136 | }; | 136 | }; |
| 137 | 137 | ||
| 138 | struct vc3_clk_data { | 138 | struct vc3_clk_data { |
| @@ -401,11 +401,10 @@ static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate, · 262 unmodified lines | |||
| 401 | /* Determine best fractional part, which is 16 bit wide */ | 401 | /* Determine best fractional part, which is 16 bit wide */ |
| 402 | div_frc = rate % *parent_rate; | 402 | div_frc = rate % *parent_rate; |
| 403 | div_frc *= BIT(16) - 1; | 403 | div_frc *= BIT(16) - 1; |
| 404 | do_div(div_frc, *parent_rate); | ||
| 405 | 404 | ||
| 406 | vc3->div_frc = (u32)div_frc; | 405 | vc3->div_frc = min_t(u64, div64_ul(div_frc, *parent_rate), U16_MAX); |
| 407 | rate = (*parent_rate * | 406 | rate = (*parent_rate * |
| 408 | (vc3->div_int * VC3_2_POW_16 + div_frc) / VC3_2_POW_16); | 407 | (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16); |
| 409 | } else { | 408 | } else { |
| 410 | rate = *parent_rate * vc3->div_int; | 409 | rate = *parent_rate * vc3->div_int; |
| 411 | } | 410 | } |
| @@ -897,33 +896,33 @@ static struct vc3_hw_data clk_div[] = { · 485 unmodified lines | |||
| 897 | }; | 896 | }; |
| 898 | 897 | ||
| 899 | static struct vc3_hw_data clk_mux[] = { | 898 | static struct vc3_hw_data clk_mux[] = { |
| 900 | [VC3_DIFF2_MUX] = { | 899 | [VC3_SE1_MUX] = { |
| 901 | .data = &(struct vc3_clk_data) { | 900 | .data = &(struct vc3_clk_data) { |
| 902 | .offs = VC3_DIFF2_CTRL_REG, | 901 | .offs = VC3_SE1_DIV4_CTRL, |
| 903 | .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL | 902 | .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL |
| 904 | }, | 903 | }, |
| 905 | .hw.init = &(struct clk_init_data){ | 904 | .hw.init = &(struct clk_init_data){ |
| 906 | .name = "diff2_mux", | 905 | .name = "se1_mux", |
| 907 | .ops = &vc3_clk_mux_ops, | 906 | .ops = &vc3_clk_mux_ops, |
| 908 | .parent_hws = (const struct clk_hw *[]) { | 907 | .parent_hws = (const struct clk_hw *[]) { |
| 909 | &clk_div[VC3_DIV1].hw, | 908 | &clk_div[VC3_DIV5].hw, |
| 910 | &clk_div[VC3_DIV3].hw | 909 | &clk_div[VC3_DIV4].hw |
| 911 | }, | 910 | }, |
| 912 | .num_parents = 2, | 911 | .num_parents = 2, |
| 913 | .flags = CLK_SET_RATE_PARENT | 912 | .flags = CLK_SET_RATE_PARENT |
| 914 | } | 913 | } |
| 915 | }, | 914 | }, |
| 916 | [VC3_DIFF1_MUX] = { | 915 | [VC3_SE2_MUX] = { |
| 917 | .data = &(struct vc3_clk_data) { | 916 | .data = &(struct vc3_clk_data) { |
| 918 | .offs = VC3_DIFF1_CTRL_REG, | 917 | .offs = VC3_SE2_CTRL_REG0, |
| 919 | .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL | 918 | .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL |
| 920 | }, | 919 | }, |
| 921 | .hw.init = &(struct clk_init_data){ | 920 | .hw.init = &(struct clk_init_data){ |
| 922 | .name = "diff1_mux", | 921 | .name = "se2_mux", |
| 923 | .ops = &vc3_clk_mux_ops, | 922 | .ops = &vc3_clk_mux_ops, |
| 924 | .parent_hws = (const struct clk_hw *[]) { | 923 | .parent_hws = (const struct clk_hw *[]) { |
| 925 | &clk_div[VC3_DIV1].hw, | 924 | &clk_div[VC3_DIV5].hw, |
| 926 | &clk_div[VC3_DIV3].hw | 925 | &clk_div[VC3_DIV4].hw |
| 927 | }, | 926 | }, |
| 928 | .num_parents = 2, | 927 | .num_parents = 2, |
| 929 | .flags = CLK_SET_RATE_PARENT | 928 | .flags = CLK_SET_RATE_PARENT |
| @@ -945,33 +944,33 @@ static struct vc3_hw_data clk_mux[] = { · 15 unmodified lines | |||
| 945 | .flags = CLK_SET_RATE_PARENT | 944 | .flags = CLK_SET_RATE_PARENT |
| 946 | } | 945 | } |
| 947 | }, | 946 | }, |
| 948 | [VC3_SE2_MUX] = { | 947 | [VC3_DIFF1_MUX] = { |
| 949 | .data = &(struct vc3_clk_data) { | 948 | .data = &(struct vc3_clk_data) { |
| 950 | .offs = VC3_SE2_CTRL_REG0, | 949 | .offs = VC3_DIFF1_CTRL_REG, |
| 951 | .bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL | 950 | .bitmsk = VC3_DIFF1_CTRL_REG_DIFF1_CLK_SEL |
| 952 | }, | 951 | }, |
| 953 | .hw.init = &(struct clk_init_data){ | 952 | .hw.init = &(struct clk_init_data){ |
| 954 | .name = "se2_mux", | 953 | .name = "diff1_mux", |
| 955 | .ops = &vc3_clk_mux_ops, | 954 | .ops = &vc3_clk_mux_ops, |
| 956 | .parent_hws = (const struct clk_hw *[]) { | 955 | .parent_hws = (const struct clk_hw *[]) { |
| 957 | &clk_div[VC3_DIV5].hw, | 956 | &clk_div[VC3_DIV1].hw, |
| 958 | &clk_div[VC3_DIV4].hw | 957 | &clk_div[VC3_DIV3].hw |
| 959 | }, | 958 | }, |
| 960 | .num_parents = 2, | 959 | .num_parents = 2, |
| 961 | .flags = CLK_SET_RATE_PARENT | 960 | .flags = CLK_SET_RATE_PARENT |
| 962 | } | 961 | } |
| 963 | }, | 962 | }, |
| 964 | [VC3_SE1_MUX] = { | 963 | [VC3_DIFF2_MUX] = { |
| 965 | .data = &(struct vc3_clk_data) { | 964 | .data = &(struct vc3_clk_data) { |
| 966 | .offs = VC3_SE1_DIV4_CTRL, | 965 | .offs = VC3_DIFF2_CTRL_REG, |
| 967 | .bitmsk = VC3_SE1_DIV4_CTRL_SE1_CLK_SEL | 966 | .bitmsk = VC3_DIFF2_CTRL_REG_DIFF2_CLK_SEL |
| 968 | }, | 967 | }, |
| 969 | .hw.init = &(struct clk_init_data){ | 968 | .hw.init = &(struct clk_init_data){ |
| 970 | .name = "se1_mux", | 969 | .name = "diff2_mux", |
| 971 | .ops = &vc3_clk_mux_ops, | 970 | .ops = &vc3_clk_mux_ops, |
| 972 | .parent_hws = (const struct clk_hw *[]) { | 971 | .parent_hws = (const struct clk_hw *[]) { |
| 973 | &clk_div[VC3_DIV5].hw, | 972 | &clk_div[VC3_DIV1].hw, |
| 974 | &clk_div[VC3_DIV4].hw | 973 | &clk_div[VC3_DIV3].hw |
| 975 | }, | 974 | }, |
| 976 | .num_parents = 2, | 975 | .num_parents = 2, |
| 977 | .flags = CLK_SET_RATE_PARENT | 976 | .flags = CLK_SET_RATE_PARENT |
| @@ -1110,7 +1109,7 @@ static int vc3_probe(struct i2c_client *client) · 132 unmodified lines | |||
| 1110 | name, 0, CLK_SET_RATE_PARENT, 1, 1); | 1109 | name, 0, CLK_SET_RATE_PARENT, 1, 1); |
| 1111 | else | 1110 | else |
| 1112 | clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev, | 1111 | clk_out[i] = devm_clk_hw_register_fixed_factor_parent_hw(dev, |
| 1113 | name, &clk_mux[i].hw, CLK_SET_RATE_PARENT, 1, 1); | 1112 | name, &clk_mux[i - 1].hw, CLK_SET_RATE_PARENT, 1, 1); |
| 1114 | 1113 | ||
| 1115 | if (IS_ERR(clk_out[i])) | 1114 | if (IS_ERR(clk_out[i])) |
| 1116 | return PTR_ERR(clk_out[i]); | 1115 | return PTR_ERR(clk_out[i]); |
| @@ -800,7 +800,7 @@ static SPRD_MUX_CLK_DATA(uart1_clk, "uart1-clk", uart_parents, · 799 unmodified lines | |||
| 800 | 0x250, 0, 3, UMS512_MUX_FLAG); | 800 | 0x250, 0, 3, UMS512_MUX_FLAG); |
| 801 | 801 | ||
| 802 | static const struct clk_parent_data thm_parents[] = { | 802 | static const struct clk_parent_data thm_parents[] = { |
| 803 | { .fw_name = "ext-32m" }, | 803 | { .fw_name = "ext-32k" }, |
| 804 | { .hw = &clk_250k.hw }, | 804 | { .hw = &clk_250k.hw }, |
| 805 | }; | 805 | }; |
| 806 | static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, | 806 | static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, |
| @@ -159,7 +159,7 @@ static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw, · 158 unmodified lines | |||
| 159 | 159 | ||
| 160 | err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); | 160 | err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); |
| 161 | if (err < 0) | 161 | if (err < 0) |
| 162 | return err; | 162 | return 0; |
| 163 | 163 | ||
| 164 | return response.rate; | 164 | return response.rate; |
| 165 | } | 165 | } |
| @@ -67,7 +67,6 @@ config COMEDI_TEST · 66 unmodified lines | |||
| 67 | 67 | ||
| 68 | config COMEDI_PARPORT | 68 | config COMEDI_PARPORT |
| 69 | tristate "Parallel port support" | 69 | tristate "Parallel port support" |
| 70 | depends on HAS_IOPORT | ||
| 71 | help | 70 | help |
| 72 | Enable support for the standard parallel port. | 71 | Enable support for the standard parallel port. |
| 73 | A cheap and easy way to get a few more digital I/O lines. Steal | 72 | A cheap and easy way to get a few more digital I/O lines. Steal |
| @@ -80,7 +79,6 @@ config COMEDI_PARPORT · 6 unmodified lines | |||
| 80 | config COMEDI_SSV_DNP | 79 | config COMEDI_SSV_DNP |
| 81 | tristate "SSV Embedded Systems DIL/Net-PC support" | 80 | tristate "SSV Embedded Systems DIL/Net-PC support" |
| 82 | depends on X86_32 || COMPILE_TEST | 81 | depends on X86_32 || COMPILE_TEST |
| 83 | depends on HAS_IOPORT | ||
| 84 | help | 82 | help |
| 85 | Enable support for SSV Embedded Systems DIL/Net-PC | 83 | Enable support for SSV Embedded Systems DIL/Net-PC |
| 86 | 84 | ||
| @@ -91,7 +89,6 @@ endif # COMEDI_MISC_DRIVERS · 4 unmodified lines | |||
| 91 | 89 | ||
| 92 | menuconfig COMEDI_ISA_DRIVERS | 90 | menuconfig COMEDI_ISA_DRIVERS |
| 93 | bool "Comedi ISA and PC/104 drivers" | 91 | bool "Comedi ISA and PC/104 drivers" |
| 94 | depends on ISA | ||
| 95 | help | 92 | help |
| 96 | Enable comedi ISA and PC/104 drivers to be built | 93 | Enable comedi ISA and PC/104 drivers to be built |
| 97 | 94 | ||
| @@ -103,8 +100,7 @@ if COMEDI_ISA_DRIVERS · 5 unmodified lines | |||
| 103 | 100 | ||
| 104 | config COMEDI_PCL711 | 101 | config COMEDI_PCL711 |
| 105 | tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support" | 102 | tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support" |
| 106 | depends on HAS_IOPORT | 103 | select COMEDI_8254 |
| 107 | depends on COMEDI_8254 | ||
| 108 | help | 104 | help |
| 109 | Enable support for Advantech PCL-711 and 711b, ADlink ACL-8112 | 105 | Enable support for Advantech PCL-711 and 711b, ADlink ACL-8112 |
| 110 | 106 | ||
| @@ -165,9 +161,8 @@ config COMEDI_PCL730 · 54 unmodified lines | |||
| 165 | 161 | ||
| 166 | config COMEDI_PCL812 | 162 | config COMEDI_PCL812 |
| 167 | tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" | 163 | tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" |
| 168 | depends on HAS_IOPORT | ||
| 169 | select COMEDI_ISADMA if ISA_DMA_API | 164 | select COMEDI_ISADMA if ISA_DMA_API |
| 170 | depends on COMEDI_8254 | 165 | select COMEDI_8254 |
| 171 | help | 166 | help |
| 172 | Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink | 167 | Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink |
| 173 | ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, | 168 | ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, |
| @@ -178,9 +173,8 @@ config COMEDI_PCL812 · 4 unmodified lines | |||
| 178 | 173 | ||
| 179 | config COMEDI_PCL816 | 174 | config COMEDI_PCL816 |
| 180 | tristate "Advantech PCL-814 and PCL-816 ISA card support" | 175 | tristate "Advantech PCL-814 and PCL-816 ISA card support" |
| 181 | depends on HAS_IOPORT | ||
| 182 | select COMEDI_ISADMA if ISA_DMA_API | 176 | select COMEDI_ISADMA if ISA_DMA_API |
| 183 | depends on COMEDI_8254 | 177 | select COMEDI_8254 |
| 184 | help | 178 | help |
| 185 | Enable support for Advantech PCL-814 and PCL-816 ISA cards | 179 | Enable support for Advantech PCL-814 and PCL-816 ISA cards |
| 186 | 180 | ||
| @@ -189,9 +183,8 @@ config COMEDI_PCL816 · 2 unmodified lines | |||
| 189 | 183 | ||
| 190 | config COMEDI_PCL818 | 184 | config COMEDI_PCL818 |
| 191 | tristate "Advantech PCL-718 and PCL-818 ISA card support" | 185 | tristate "Advantech PCL-718 and PCL-818 ISA card support" |
| 192 | depends on HAS_IOPORT | ||
| 193 | select COMEDI_ISADMA if ISA_DMA_API | 186 | select COMEDI_ISADMA if ISA_DMA_API |
| 194 | depends on COMEDI_8254 | 187 | select COMEDI_8254 |
| 195 | help | 188 | help |
| 196 | Enable support for Advantech PCL-818 ISA cards | 189 | Enable support for Advantech PCL-818 ISA cards |
| 197 | PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 | 190 | PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 |
| @@ -210,7 +203,7 @@ config COMEDI_PCM3724 · 12 unmodified lines | |||
| 210 | 203 | ||
| 211 | config COMEDI_AMPLC_DIO200_ISA | 204 | config COMEDI_AMPLC_DIO200_ISA |
| 212 | tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E" | 205 | tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E" |
| 213 | depends on COMEDI_AMPLC_DIO200 | 206 | select COMEDI_AMPLC_DIO200 |
| 214 | help | 207 | help |
| 215 | Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and | 208 | Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and |
| 216 | PC272E ISA DIO boards | 209 | PC272E ISA DIO boards |
| @@ -262,8 +255,7 @@ config COMEDI_DAC02 · 45 unmodified lines | |||
| 262 | 255 | ||
| 263 | config COMEDI_DAS16M1 | 256 | config COMEDI_DAS16M1 |
| 264 | tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support" | 257 | tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support" |
| 265 | depends on HAS_IOPORT | 258 | select COMEDI_8254 |
| 266 | depends on COMEDI_8254 | ||
| 267 | select COMEDI_8255 | 259 | select COMEDI_8255 |
| 268 | help | 260 | help |
| 269 | Enable support for Measurement Computing CIO-DAS16/M1 ISA cards. | 261 | Enable support for Measurement Computing CIO-DAS16/M1 ISA cards. |
| @@ -273,7 +265,7 @@ config COMEDI_DAS16M1 · 3 unmodified lines | |||
| 273 | 265 | ||
| 274 | config COMEDI_DAS08_ISA | 266 | config COMEDI_DAS08_ISA |
| 275 | tristate "DAS-08 compatible ISA and PC/104 card support" | 267 | tristate "DAS-08 compatible ISA and PC/104 card support" |
| 276 | depends on COMEDI_DAS08 | 268 | select COMEDI_DAS08 |
| 277 | help | 269 | help |
| 278 | Enable support for Keithley Metrabyte/ComputerBoards DAS08 | 270 | Enable support for Keithley Metrabyte/ComputerBoards DAS08 |
| 279 | and compatible ISA and PC/104 cards: | 271 | and compatible ISA and PC/104 cards: |
| @@ -286,9 +278,8 @@ config COMEDI_DAS08_ISA · 6 unmodified lines | |||
| 286 | 278 | ||
| 287 | config COMEDI_DAS16 | 279 | config COMEDI_DAS16 |
| 288 | tristate "DAS-16 compatible ISA and PC/104 card support" | 280 | tristate "DAS-16 compatible ISA and PC/104 card support" |
| 289 | depends on HAS_IOPORT | ||
| 290 | select COMEDI_ISADMA if ISA_DMA_API | 281 | select COMEDI_ISADMA if ISA_DMA_API |
| 291 | depends on COMEDI_8254 | 282 | select COMEDI_8254 |
| 292 | select COMEDI_8255 | 283 | select COMEDI_8255 |
| 293 | help | 284 | help |
| 294 | Enable support for Keithley Metrabyte/ComputerBoards DAS16 | 285 | Enable support for Keithley Metrabyte/ComputerBoards DAS16 |
| @@ -305,8 +296,7 @@ config COMEDI_DAS16 · 10 unmodified lines | |||
| 305 | 296 | ||
| 306 | config COMEDI_DAS800 | 297 | config COMEDI_DAS800 |
| 307 | tristate "DAS800 and compatible ISA card support" | 298 | tristate "DAS800 and compatible ISA card support" |
| 308 | depends on HAS_IOPORT | 299 | select COMEDI_8254 |
| 309 | depends on COMEDI_8254 | ||
| 310 | help | 300 | help |
| 311 | Enable support for Keithley Metrabyte DAS800 and compatible ISA cards | 301 | Enable support for Keithley Metrabyte DAS800 and compatible ISA cards |
| 312 | Keithley Metrabyte DAS-800, DAS-801, DAS-802 | 302 | Keithley Metrabyte DAS-800, DAS-801, DAS-802 |
| @@ -318,9 +308,8 @@ config COMEDI_DAS800 · 5 unmodified lines | |||
| 318 | 308 | ||
| 319 | config COMEDI_DAS1800 | 309 | config COMEDI_DAS1800 |
| 320 | tristate "DAS1800 and compatible ISA card support" | 310 | tristate "DAS1800 and compatible ISA card support" |
| 321 | depends on HAS_IOPORT | ||
| 322 | select COMEDI_ISADMA if ISA_DMA_API | 311 | select COMEDI_ISADMA if ISA_DMA_API |
| 323 | depends on COMEDI_8254 | 312 | select COMEDI_8254 |
| 324 | help | 313 | help |
| 325 | Enable support for DAS1800 and compatible ISA cards | 314 | Enable support for DAS1800 and compatible ISA cards |
| 326 | Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, | 315 | Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, |
| @@ -334,8 +323,7 @@ config COMEDI_DAS1800 · 7 unmodified lines | |||
| 334 | 323 | ||
| 335 | config COMEDI_DAS6402 | 324 | config COMEDI_DAS6402 |
| 336 | tristate "DAS6402 and compatible ISA card support" | 325 | tristate "DAS6402 and compatible ISA card support" |
| 337 | depends on HAS_IOPORT | 326 | select COMEDI_8254 |
| 338 | depends on COMEDI_8254 | ||
| 339 | help | 327 | help |
| 340 | Enable support for DAS6402 and compatible ISA cards | 328 | Enable support for DAS6402 and compatible ISA cards |
| 341 | Computerboards, Keithley Metrabyte DAS6402 and compatibles | 329 | Computerboards, Keithley Metrabyte DAS6402 and compatibles |
| @@ -414,8 +402,7 @@ config COMEDI_FL512 · 72 unmodified lines | |||
| 414 | 402 | ||
| 415 | config COMEDI_AIO_AIO12_8 | 403 | config COMEDI_AIO_AIO12_8 |
| 416 | tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support" | 404 | tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support" |
| 417 | depends on HAS_IOPORT | 405 | select COMEDI_8254 |
| 418 | depends on COMEDI_8254 | ||
| 419 | select COMEDI_8255 | 406 | select COMEDI_8255 |
| 420 | help | 407 | help |
| 421 | Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board | 408 | Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board |
| @@ -469,9 +456,8 @@ config COMEDI_ADQ12B · 47 unmodified lines | |||
| 469 | 456 | ||
| 470 | config COMEDI_NI_AT_A2150 | 457 | config COMEDI_NI_AT_A2150 |
| 471 | tristate "NI AT-A2150 ISA card support" | 458 | tristate "NI AT-A2150 ISA card support" |
| 472 | depends on HAS_IOPORT | ||
| 473 | select COMEDI_ISADMA if ISA_DMA_API | 459 | select COMEDI_ISADMA if ISA_DMA_API |
| 474 | depends on COMEDI_8254 | 460 | select COMEDI_8254 |
| 475 | help | 461 | help |
| 476 | Enable support for National Instruments AT-A2150 cards | 462 | Enable support for National Instruments AT-A2150 cards |
| 477 | 463 | ||
| @@ -480,8 +466,7 @@ config COMEDI_NI_AT_A2150 · 2 unmodified lines | |||
| 480 | 466 | ||
| 481 | config COMEDI_NI_AT_AO | 467 | config COMEDI_NI_AT_AO |
| 482 | tristate "NI AT-AO-6/10 EISA card support" | 468 | tristate "NI AT-AO-6/10 EISA card support" |
| 483 | depends on HAS_IOPORT | 469 | select COMEDI_8254 |
| 484 | depends on COMEDI_8254 | ||
| 485 | help | 470 | help |
| 486 | Enable support for National Instruments AT-AO-6/10 cards | 471 | Enable support for National Instruments AT-AO-6/10 cards |
| 487 | 472 | ||
| @@ -512,7 +497,7 @@ config COMEDI_NI_ATMIO16D · 24 unmodified lines | |||
| 512 | 497 | ||
| 513 | config COMEDI_NI_LABPC_ISA | 498 | config COMEDI_NI_LABPC_ISA |
| 514 | tristate "NI Lab-PC and compatibles ISA support" | 499 | tristate "NI Lab-PC and compatibles ISA support" |
| 515 | depends on COMEDI_NI_LABPC | 500 | select COMEDI_NI_LABPC |
| 516 | help | 501 | help |
| 517 | Enable support for National Instruments Lab-PC and compatibles | 502 | Enable support for National Instruments Lab-PC and compatibles |
| 518 | Lab-PC-1200, Lab-PC-1200AI, Lab-PC+. | 503 | Lab-PC-1200, Lab-PC-1200AI, Lab-PC+. |
| @@ -576,7 +561,7 @@ endif # COMEDI_ISA_DRIVERS · 57 unmodified lines | |||
| 576 | 561 | ||
| 577 | menuconfig COMEDI_PCI_DRIVERS | 562 | menuconfig COMEDI_PCI_DRIVERS |
| 578 | tristate "Comedi PCI drivers" | 563 | tristate "Comedi PCI drivers" |
| 579 | depends on PCI && HAS_IOPORT | 564 | depends on PCI |
| 580 | help | 565 | help |
| 581 | Enable support for comedi PCI drivers. | 566 | Enable support for comedi PCI drivers. |
| 582 | 567 | ||
| @@ -725,8 +710,7 @@ config COMEDI_ADL_PCI8164 · 142 unmodified lines | |||
| 725 | 710 | ||
| 726 | config COMEDI_ADL_PCI9111 | 711 | config COMEDI_ADL_PCI9111 |
| 727 | tristate "ADLink PCI-9111HR support" | 712 | tristate "ADLink PCI-9111HR support" |
| 728 | depends on HAS_IOPORT | 713 | select COMEDI_8254 |
| 729 | depends on COMEDI_8254 | ||
| 730 | help | 714 | help |
| 731 | Enable support for ADlink PCI9111 cards | 715 | Enable support for ADlink PCI9111 cards |
| 732 | 716 | ||
| @@ -736,7 +720,7 @@ config COMEDI_ADL_PCI9111 · 3 unmodified lines | |||
| 736 | config COMEDI_ADL_PCI9118 | 720 | config COMEDI_ADL_PCI9118 |
| 737 | tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" | 721 | tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" |
| 738 | depends on HAS_DMA | 722 | depends on HAS_DMA |
| 739 | depends on COMEDI_8254 | 723 | select COMEDI_8254 |
| 740 | help | 724 | help |
| 741 | Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards | 725 | Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards |
| 742 | 726 | ||
| @@ -745,8 +729,7 @@ config COMEDI_ADL_PCI9118 · 2 unmodified lines | |||
| 745 | 729 | ||
| 746 | config COMEDI_ADV_PCI1710 | 730 | config COMEDI_ADV_PCI1710 |
| 747 | tristate "Advantech PCI-171x and PCI-1731 support" | 731 | tristate "Advantech PCI-171x and PCI-1731 support" |
| 748 | depends on HAS_IOPORT | 732 | select COMEDI_8254 |
| 749 | depends on COMEDI_8254 | ||
| 750 | help | 733 | help |
| 751 | Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, | 734 | Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, |
| 752 | PCI-1713 and PCI-1731 | 735 | PCI-1713 and PCI-1731 |
| @@ -790,8 +773,7 @@ config COMEDI_ADV_PCI1760 · 37 unmodified lines | |||
| 790 | 773 | ||
| 791 | config COMEDI_ADV_PCI_DIO | 774 | config COMEDI_ADV_PCI_DIO |
| 792 | tristate "Advantech PCI DIO card support" | 775 | tristate "Advantech PCI DIO card support" |
| 793 | depends on HAS_IOPORT | 776 | select COMEDI_8254 |
| 794 | depends on COMEDI_8254 | ||
| 795 | select COMEDI_8255 | 777 | select COMEDI_8255 |
| 796 | help | 778 | help |
| 797 | Enable support for Advantech PCI DIO cards | 779 | Enable support for Advantech PCI DIO cards |
| @@ -804,7 +786,7 @@ config COMEDI_ADV_PCI_DIO · 6 unmodified lines | |||
| 804 | 786 | ||
| 805 | config COMEDI_AMPLC_DIO200_PCI | 787 | config COMEDI_AMPLC_DIO200_PCI |
| 806 | tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support" | 788 | tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support" |
| 807 | depends on COMEDI_AMPLC_DIO200 | 789 | select COMEDI_AMPLC_DIO200 |
| 808 | help | 790 | help |
| 809 | Enable support for Amplicon PCI215, PCI272, PCIe215, PCIe236 | 791 | Enable support for Amplicon PCI215, PCI272, PCIe215, PCIe236 |
| 810 | and PCIe296 DIO boards. | 792 | and PCIe296 DIO boards. |
| @@ -832,8 +814,7 @@ config COMEDI_AMPLC_PC263_PCI · 21 unmodified lines | |||
| 832 | 814 | ||
| 833 | config COMEDI_AMPLC_PCI224 | 815 | config COMEDI_AMPLC_PCI224 |
| 834 | tristate "Amplicon PCI224 and PCI234 support" | 816 | tristate "Amplicon PCI224 and PCI234 support" |
| 835 | depends on HAS_IOPORT | 817 | select COMEDI_8254 |
| 836 | depends on COMEDI_8254 | ||
| 837 | help | 818 | help |
| 838 | Enable support for Amplicon PCI224 and PCI234 AO boards | 819 | Enable support for Amplicon PCI224 and PCI234 AO boards |
| 839 | 820 | ||
| @@ -842,8 +823,7 @@ config COMEDI_AMPLC_PCI224 · 2 unmodified lines | |||
| 842 | 823 | ||
| 843 | config COMEDI_AMPLC_PCI230 | 824 | config COMEDI_AMPLC_PCI230 |
| 844 | tristate "Amplicon PCI230 and PCI260 support" | 825 | tristate "Amplicon PCI230 and PCI260 support" |
| 845 | depends on HAS_IOPORT | 826 | select COMEDI_8254 |
| 846 | depends on COMEDI_8254 | ||
| 847 | select COMEDI_8255 | 827 | select COMEDI_8255 |
| 848 | help | 828 | help |
| 849 | Enable support for Amplicon PCI230 and PCI260 Multifunction I/O | 829 | Enable support for Amplicon PCI230 and PCI260 Multifunction I/O |
| @@ -862,7 +842,7 @@ config COMEDI_CONTEC_PCI_DIO · 12 unmodified lines | |||
| 862 | 842 | ||
| 863 | config COMEDI_DAS08_PCI | 843 | config COMEDI_DAS08_PCI |
| 864 | tristate "DAS-08 PCI support" | 844 | tristate "DAS-08 PCI support" |
| 865 | depends on COMEDI_DAS08 | 845 | select COMEDI_DAS08 |
| 866 | help | 846 | help |
| 867 | Enable support for PCI DAS-08 cards. | 847 | Enable support for PCI DAS-08 cards. |
| 868 | 848 | ||
| @@ -949,8 +929,7 @@ config COMEDI_CB_PCIDAS64 · 80 unmodified lines | |||
| 949 | 929 | ||
| 950 | config COMEDI_CB_PCIDAS | 930 | config COMEDI_CB_PCIDAS |
| 951 | tristate "MeasurementComputing PCI-DAS support" | 931 | tristate "MeasurementComputing PCI-DAS support" |
| 952 | depends on HAS_IOPORT | 932 | select COMEDI_8254 |
| 953 | depends on COMEDI_8254 | ||
| 954 | select COMEDI_8255 | 933 | select COMEDI_8255 |
| 955 | help | 934 | help |
| 956 | Enable support for ComputerBoards/MeasurementComputing PCI-DAS with | 935 | Enable support for ComputerBoards/MeasurementComputing PCI-DAS with |
| @@ -974,8 +953,7 @@ config COMEDI_CB_PCIDDA · 17 unmodified lines | |||
| 974 | 953 | ||
| 975 | config COMEDI_CB_PCIMDAS | 954 | config COMEDI_CB_PCIMDAS |
| 976 | tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support" | 955 | tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support" |
| 977 | depends on HAS_IOPORT | 956 | select COMEDI_8254 |
| 978 | depends on COMEDI_8254 | ||
| 979 | select COMEDI_8255 | 957 | select COMEDI_8255 |
| 980 | help | 958 | help |
| 981 | Enable support for ComputerBoards/MeasurementComputing PCI Migration | 959 | Enable support for ComputerBoards/MeasurementComputing PCI Migration |
| @@ -995,8 +973,7 @@ config COMEDI_CB_PCIMDDA · 13 unmodified lines | |||
| 995 | 973 | ||
| 996 | config COMEDI_ME4000 | 974 | config COMEDI_ME4000 |
| 997 | tristate "Meilhaus ME-4000 support" | 975 | tristate "Meilhaus ME-4000 support" |
| 998 | depends on HAS_IOPORT | 976 | select COMEDI_8254 |
| 999 | depends on COMEDI_8254 | ||
| 1000 | help | 977 | help |
| 1001 | Enable support for Meilhaus PCI data acquisition cards | 978 | Enable support for Meilhaus PCI data acquisition cards |
| 1002 | ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is | 979 | ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is |
| @@ -1054,7 +1031,7 @@ config COMEDI_NI_670X · 51 unmodified lines | |||
| 1054 | 1031 | ||
| 1055 | config COMEDI_NI_LABPC_PCI | 1032 | config COMEDI_NI_LABPC_PCI |
| 1056 | tristate "NI Lab-PC PCI-1200 support" | 1033 | tristate "NI Lab-PC PCI-1200 support" |
| 1057 | depends on COMEDI_NI_LABPC | 1034 | select COMEDI_NI_LABPC |
| 1058 | help | 1035 | help |
| 1059 | Enable support for National Instruments Lab-PC PCI-1200. | 1036 | Enable support for National Instruments Lab-PC PCI-1200. |
| 1060 | 1037 | ||
| @@ -1076,7 +1053,6 @@ config COMEDI_NI_PCIDIO · 15 unmodified lines | |||
| 1076 | config COMEDI_NI_PCIMIO | 1053 | config COMEDI_NI_PCIMIO |
| 1077 | tristate "NI PCI-MIO-E series and M series support" | 1054 | tristate "NI PCI-MIO-E series and M series support" |
| 1078 | depends on HAS_DMA | 1055 | depends on HAS_DMA |
| 1079 | depends on HAS_IOPORT | ||
| 1080 | select COMEDI_NI_TIOCMD | 1056 | select COMEDI_NI_TIOCMD |
| 1081 | select COMEDI_8255 | 1057 | select COMEDI_8255 |
| 1082 | help | 1058 | help |
| @@ -1098,8 +1074,7 @@ config COMEDI_NI_PCIMIO · 15 unmodified lines | |||
| 1098 | 1074 | ||
| 1099 | config COMEDI_RTD520 | 1075 | config COMEDI_RTD520 |
| 1100 | tristate "Real Time Devices PCI4520/DM7520 support" | 1076 | tristate "Real Time Devices PCI4520/DM7520 support" |
| 1101 | depends on HAS_IOPORT | 1077 | select COMEDI_8254 |
| 1102 | depends on COMEDI_8254 | ||
| 1103 | help | 1078 | help |
| 1104 | Enable support for Real Time Devices PCI4520/DM7520 | 1079 | Enable support for Real Time Devices PCI4520/DM7520 |
| 1105 | 1080 | ||
| @@ -1139,8 +1114,7 @@ if COMEDI_PCMCIA_DRIVERS · 33 unmodified lines | |||
| 1139 | 1114 | ||
| 1140 | config COMEDI_CB_DAS16_CS | 1115 | config COMEDI_CB_DAS16_CS |
| 1141 | tristate "CB DAS16 series PCMCIA support" | 1116 | tristate "CB DAS16 series PCMCIA support" |
| 1142 | depends on HAS_IOPORT | 1117 | select COMEDI_8254 |
| 1143 | depends on COMEDI_8254 | ||
| 1144 | help | 1118 | help |
| 1145 | Enable support for the ComputerBoards/MeasurementComputing PCMCIA | 1119 | Enable support for the ComputerBoards/MeasurementComputing PCMCIA |
| 1146 | cards DAS16/16, PCM-DAS16D/12 and PCM-DAS16s/16 | 1120 | cards DAS16/16, PCM-DAS16D/12 and PCM-DAS16s/16 |
| @@ -1150,7 +1124,7 @@ config COMEDI_CB_DAS16_CS · 3 unmodified lines | |||
| 1150 | 1124 | ||
| 1151 | config COMEDI_DAS08_CS | 1125 | config COMEDI_DAS08_CS |
| 1152 | tristate "CB DAS08 PCMCIA support" | 1126 | tristate "CB DAS08 PCMCIA support" |
| 1153 | depends on COMEDI_DAS08 | 1127 | select COMEDI_DAS08 |
| 1154 | help | 1128 | help |
| 1155 | Enable support for the ComputerBoards/MeasurementComputing DAS-08 | 1129 | Enable support for the ComputerBoards/MeasurementComputing DAS-08 |
| 1156 | PCMCIA card | 1130 | PCMCIA card |
| @@ -1160,7 +1134,6 @@ config COMEDI_DAS08_CS · 3 unmodified lines | |||
| 1160 | 1134 | ||
| 1161 | config COMEDI_NI_DAQ_700_CS | 1135 | config COMEDI_NI_DAQ_700_CS |
| 1162 | tristate "NI DAQCard-700 PCMCIA support" | 1136 | tristate "NI DAQCard-700 PCMCIA support" |
| 1163 | depends on HAS_IOPORT | ||
| 1164 | help | 1137 | help |
| 1165 | Enable support for the National Instruments PCMCIA DAQCard-700 DIO | 1138 | Enable support for the National Instruments PCMCIA DAQCard-700 DIO |
| 1166 | 1139 | ||
| @@ -1169,7 +1142,6 @@ config COMEDI_NI_DAQ_700_CS · 2 unmodified lines | |||
| 1169 | 1142 | ||
| 1170 | config COMEDI_NI_DAQ_DIO24_CS | 1143 | config COMEDI_NI_DAQ_DIO24_CS |
| 1171 | tristate "NI DAQ-Card DIO-24 PCMCIA support" | 1144 | tristate "NI DAQ-Card DIO-24 PCMCIA support" |
| 1172 | depends on HAS_IOPORT | ||
| 1173 | select COMEDI_8255 | 1145 | select COMEDI_8255 |
| 1174 | help | 1146 | help |
| 1175 | Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 | 1147 | Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 |
| @@ -1179,7 +1151,7 @@ config COMEDI_NI_DAQ_DIO24_CS · 3 unmodified lines | |||
| 1179 | 1151 | ||
| 1180 | config COMEDI_NI_LABPC_CS | 1152 | config COMEDI_NI_LABPC_CS |
| 1181 | tristate "NI DAQCard-1200 PCMCIA support" | 1153 | tristate "NI DAQCard-1200 PCMCIA support" |
| 1182 | depends on COMEDI_NI_LABPC | 1154 | select COMEDI_NI_LABPC |
| 1183 | help | 1155 | help |
| 1184 | Enable support for the National Instruments PCMCIA DAQCard-1200 | 1156 | Enable support for the National Instruments PCMCIA DAQCard-1200 |
| 1185 | 1157 | ||
| @@ -1188,7 +1160,6 @@ config COMEDI_NI_LABPC_CS · 2 unmodified lines | |||
| 1188 | 1160 | ||
| 1189 | config COMEDI_NI_MIO_CS | 1161 | config COMEDI_NI_MIO_CS |
| 1190 | tristate "NI DAQCard E series PCMCIA support" | 1162 | tristate "NI DAQCard E series PCMCIA support" |
| 1191 | depends on HAS_IOPORT | ||
| 1192 | select COMEDI_NI_TIO | 1163 | select COMEDI_NI_TIO |
| 1193 | select COMEDI_8255 | 1164 | select COMEDI_8255 |
| 1194 | help | 1165 | help |
| @@ -1201,7 +1172,6 @@ config COMEDI_NI_MIO_CS · 6 unmodified lines | |||
| 1201 | 1172 | ||
| 1202 | config COMEDI_QUATECH_DAQP_CS | 1173 | config COMEDI_QUATECH_DAQP_CS |
| 1203 | tristate "Quatech DAQP PCMCIA data capture card support" | 1174 | tristate "Quatech DAQP PCMCIA data capture card support" |
| 1204 | depends on HAS_IOPORT | ||
| 1205 | help | 1175 | help |
| 1206 | Enable support for the Quatech DAQP PCMCIA data capture cards | 1176 | Enable support for the Quatech DAQP PCMCIA data capture cards |
| 1207 | DAQP-208 and DAQP-308 | 1177 | DAQP-208 and DAQP-308 |
| @@ -1278,14 +1248,12 @@ endif # COMEDI_USB_DRIVERS · 70 unmodified lines | |||
| 1278 | 1248 | ||
| 1279 | config COMEDI_8254 | 1249 | config COMEDI_8254 |
| 1280 | tristate | 1250 | tristate |
| 1281 | depends on HAS_IOPORT | ||
| 1282 | 1251 | ||
| 1283 | config COMEDI_8255 | 1252 | config COMEDI_8255 |
| 1284 | tristate | 1253 | tristate |
| 1285 | 1254 | ||
| 1286 | config COMEDI_8255_SA | 1255 | config COMEDI_8255_SA |
| 1287 | tristate "Standalone 8255 support" | 1256 | tristate "Standalone 8255 support" |
| 1288 | depends on HAS_IOPORT | ||
| 1289 | select COMEDI_8255 | 1257 | select COMEDI_8255 |
| 1290 | help | 1258 | help |
| 1291 | Enable support for 8255 digital I/O as a standalone driver. | 1259 | Enable support for 8255 digital I/O as a standalone driver. |
| @@ -1317,7 +1285,7 @@ config COMEDI_KCOMEDILIB · 25 unmodified lines | |||
| 1317 | called kcomedilib. | 1285 | called kcomedilib. |
| 1318 | 1286 | ||
| 1319 | config COMEDI_AMPLC_DIO200 | 1287 | config COMEDI_AMPLC_DIO200 |
| 1320 | depends on COMEDI_8254 | 1288 | select COMEDI_8254 |
| 1321 | tristate | 1289 | tristate |
| 1322 | 1290 | ||
| 1323 | config COMEDI_AMPLC_PC236 | 1291 | config COMEDI_AMPLC_PC236 |
| @@ -1326,7 +1294,7 @@ config COMEDI_AMPLC_PC236 · 2 unmodified lines | |||
| 1326 | 1294 | ||
| 1327 | config COMEDI_DAS08 | 1295 | config COMEDI_DAS08 |
| 1328 | tristate | 1296 | tristate |
| 1329 | depends on COMEDI_8254 | 1297 | select COMEDI_8254 |
| 1330 | select COMEDI_8255 | 1298 | select COMEDI_8255 |
| 1331 | 1299 | ||
| 1332 | config COMEDI_ISADMA | 1300 | config COMEDI_ISADMA |
| @@ -1334,8 +1302,7 @@ config COMEDI_ISADMA · 1 unmodified line | |||
| 1334 | 1302 | ||
| 1335 | config COMEDI_NI_LABPC | 1303 | config COMEDI_NI_LABPC |
| 1336 | tristate | 1304 | tristate |
| 1337 | depends on HAS_IOPORT | 1305 | select COMEDI_8254 |
| 1338 | depends on COMEDI_8254 | ||
| 1339 | select COMEDI_8255 | 1306 | select COMEDI_8255 |
| 1340 | 1307 | ||
| 1341 | config COMEDI_NI_LABPC_ISADMA | 1308 | config COMEDI_NI_LABPC_ISADMA |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | struct cxl_cxims_data { | 15 | struct cxl_cxims_data { |
| 16 | int nr_maps; | 16 | int nr_maps; |
| 17 | u64 xormaps[]; | 17 | u64 xormaps[] __counted_by(nr_maps); |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | /* | 20 | /* |
| @@ -112,9 +112,9 @@ static int cxl_parse_cxims(union acpi_subtable_headers *header, void *arg, · 91 unmodified lines | |||
| 112 | GFP_KERNEL); | 112 | GFP_KERNEL); |
| 113 | if (!cximsd) | 113 | if (!cximsd) |
| 114 | return -ENOMEM; | 114 | return -ENOMEM; |
| 115 | cximsd->nr_maps = nr_maps; | ||
| 115 | memcpy(cximsd->xormaps, cxims->xormap_list, | 116 | memcpy(cximsd->xormaps, cxims->xormap_list, |
| 116 | nr_maps * sizeof(*cximsd->xormaps)); | 117 | nr_maps * sizeof(*cximsd->xormaps)); |
| 117 | cximsd->nr_maps = nr_maps; | ||
| 118 | cxlrd->platform_data = cximsd; | 118 | cxlrd->platform_data = cximsd; |
| 119 | 119 | ||
| 120 | return 0; | 120 | return 0; |
| @@ -715,24 +715,25 @@ static void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel) · 714 unmodified lines | |||
| 715 | for (i = 0; i < cel_entries; i++) { | 715 | for (i = 0; i < cel_entries; i++) { |
| 716 | u16 opcode = le16_to_cpu(cel_entry[i].opcode); | 716 | u16 opcode = le16_to_cpu(cel_entry[i].opcode); |
| 717 | struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); | 717 | struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); |
| 718 | int enabled = 0; | ||
| 718 | 719 | ||
| 719 | if (!cmd && (!cxl_is_poison_command(opcode) || | 720 | if (cmd) { |
| 720 | !cxl_is_security_command(opcode))) { | ||
| 721 | dev_dbg(dev, | ||
| 722 | "Opcode 0x%04x unsupported by driver\n", opcode); | ||
| 723 | continue; | ||
| 724 | } | ||
| 725 | |||
| 726 | if (cmd) | ||
| 727 | set_bit(cmd->info.id, mds->enabled_cmds); | 721 | set_bit(cmd->info.id, mds->enabled_cmds); |
| 722 | enabled++; | ||
| 723 | } | ||
| 728 | 724 | ||
| 729 | if (cxl_is_poison_command(opcode)) | 725 | if (cxl_is_poison_command(opcode)) { |
| 730 | cxl_set_poison_cmd_enabled(&mds->poison, opcode); | 726 | cxl_set_poison_cmd_enabled(&mds->poison, opcode); |
| 727 | enabled++; | ||
| 728 | } | ||
| 731 | 729 | ||
| 732 | if (cxl_is_security_command(opcode)) | 730 | if (cxl_is_security_command(opcode)) { |
| 733 | cxl_set_security_cmd_enabled(&mds->security, opcode); | 731 | cxl_set_security_cmd_enabled(&mds->security, opcode); |
| 732 | enabled++; | ||
| 733 | } | ||
| 734 | 734 | ||
| 735 | dev_dbg(dev, "Opcode 0x%04x enabled\n", opcode); | 735 | dev_dbg(dev, "Opcode 0x%04x %s\n", opcode, |
| 736 | enabled ? "enabled" : "unsupported by driver"); | ||
| 736 | } | 737 | } |
| 737 | } | 738 | } |
| 738 | 739 | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ | 2 | /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ |
| 3 | #include <linux/platform_device.h> | ||
| 3 | #include <linux/memregion.h> | 4 | #include <linux/memregion.h> |
| 4 | #include <linux/workqueue.h> | 5 | #include <linux/workqueue.h> |
| 5 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
| @@ -706,16 +707,20 @@ static int cxl_setup_comp_regs(struct device *dev, struct cxl_register_map *map, · 700 unmodified lines | |||
| 706 | return cxl_setup_regs(map); | 707 | return cxl_setup_regs(map); |
| 707 | } | 708 | } |
| 708 | 709 | ||
| 709 | static inline int cxl_port_setup_regs(struct cxl_port *port, | 710 | static int cxl_port_setup_regs(struct cxl_port *port, |
| 710 | resource_size_t component_reg_phys) | 711 | resource_size_t component_reg_phys) |
| 711 | { | 712 | { |
| 713 | if (dev_is_platform(port->uport_dev)) | ||
| 714 | return 0; | ||
| 712 | return cxl_setup_comp_regs(&port->dev, &port->comp_map, | 715 | return cxl_setup_comp_regs(&port->dev, &port->comp_map, |
| 713 | component_reg_phys); | 716 | component_reg_phys); |
| 714 | } | 717 | } |
| 715 | 718 | ||
| 716 | static inline int cxl_dport_setup_regs(struct cxl_dport *dport, | 719 | static int cxl_dport_setup_regs(struct cxl_dport *dport, |
| 717 | resource_size_t component_reg_phys) | 720 | resource_size_t component_reg_phys) |
| 718 | { | 721 | { |
| 722 | if (dev_is_platform(dport->dport_dev)) | ||
| 723 | return 0; | ||
| 719 | return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, | 724 | return cxl_setup_comp_regs(dport->dport_dev, &dport->comp_map, |
| 720 | component_reg_phys); | 725 | component_reg_phys); |
| 721 | } | 726 | } |
| @@ -717,13 +717,35 @@ static int match_free_decoder(struct device *dev, void *data) · 716 unmodified lines | |||
| 717 | return 0; | 717 | return 0; |
| 718 | } | 718 | } |
| 719 | 719 | ||
| 720 | static int match_auto_decoder(struct device *dev, void *data) | ||
| 721 | { | ||
| 722 | struct cxl_region_params *p = data; | ||
| 723 | struct cxl_decoder *cxld; | ||
| 724 | struct range *r; | ||
| 725 | |||
| 726 | if (!is_switch_decoder(dev)) | ||
| 727 | return 0; | ||
| 728 | |||
| 729 | cxld = to_cxl_decoder(dev); | ||
| 730 | r = &cxld->hpa_range; | ||
| 731 | |||
| 732 | if (p->res && p->res->start == r->start && p->res->end == r->end) | ||
| 733 | return 1; | ||
| 734 | |||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 720 | static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port, | 738 | static struct cxl_decoder *cxl_region_find_decoder(struct cxl_port *port, |
| 721 | struct cxl_region *cxlr) | 739 | struct cxl_region *cxlr) |
| 722 | { | 740 | { |
| 723 | struct device *dev; | 741 | struct device *dev; |
| 724 | int id = 0; | 742 | int id = 0; |
| 725 | 743 | ||
| 726 | dev = device_find_child(&port->dev, &id, match_free_decoder); | 744 | if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) |
| 745 | dev = device_find_child(&port->dev, &cxlr->params, | ||
| 746 | match_auto_decoder); | ||
| 747 | else | ||
| 748 | dev = device_find_child(&port->dev, &id, match_free_decoder); | ||
| 727 | if (!dev) | 749 | if (!dev) |
| 728 | return NULL; | 750 | return NULL; |
| 729 | /* | 751 | /* |
| @@ -1154,16 +1176,15 @@ static int cxl_port_setup_targets(struct cxl_port *port, · 424 unmodified lines | |||
| 1154 | } | 1176 | } |
| 1155 | 1177 | ||
| 1156 | /* | 1178 | /* |
| 1157 | * If @parent_port is masking address bits, pick the next unused address | 1179 | * Interleave granularity is a multiple of @parent_port granularity. |
| 1158 | * bit to route @port's targets. | 1180 | * Multiplier is the parent port interleave ways. |
| 1159 | */ | 1181 | */ |
| 1160 | if (parent_iw > 1 && cxl_rr->nr_targets > 1) { | 1182 | rc = granularity_to_eig(parent_ig * parent_iw, &eig); |
| 1161 | u32 address_bit = max(peig + peiw, eiw + peig); | 1183 | if (rc) { |
| 1162 | 1184 | dev_dbg(&cxlr->dev, | |
| 1163 | eig = address_bit - eiw + 1; | 1185 | "%s: invalid granularity calculation (%d * %d)\n", |
| 1164 | } else { | 1186 | dev_name(&parent_port->dev), parent_ig, parent_iw); |
| 1165 | eiw = peiw; | 1187 | return rc; |
| 1166 | eig = peig; | ||
| 1167 | } | 1188 | } |
| 1168 | 1189 | ||
| 1169 | rc = eig_to_granularity(eig, &ig); | 1190 | rc = eig_to_granularity(eig, &ig); |
| @@ -529,7 +529,6 @@ static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, · 528 unmodified lines | |||
| 529 | 529 | ||
| 530 | static int cxl_pci_ras_unmask(struct pci_dev *pdev) | 530 | static int cxl_pci_ras_unmask(struct pci_dev *pdev) |
| 531 | { | 531 | { |
| 532 | struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus); | ||
| 533 | struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); | 532 | struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); |
| 534 | void __iomem *addr; | 533 | void __iomem *addr; |
| 535 | u32 orig_val, val, mask; | 534 | u32 orig_val, val, mask; |
| @@ -541,9 +540,9 @@ static int cxl_pci_ras_unmask(struct pci_dev *pdev) · 5 unmodified lines | |||
| 541 | return 0; | 540 | return 0; |
| 542 | } | 541 | } |
| 543 | 542 | ||
| 544 | /* BIOS has CXL error control */ | 543 | /* BIOS has PCIe AER error control */ |
| 545 | if (!host_bridge->native_cxl_error) | 544 | if (!pcie_aer_is_native(pdev)) |
| 546 | return -ENXIO; | 545 | return 0; |
| 547 | 546 | ||
| 548 | rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); | 547 | rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); |
| 549 | if (rc) | 548 | if (rc) |
| @@ -1211,7 +1211,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) · 1210 unmodified lines | |||
| 1211 | * without actually having a link. | 1211 | * without actually having a link. |
| 1212 | */ | 1212 | */ |
| 1213 | create: | 1213 | create: |
| 1214 | device = kzalloc(sizeof(*device), GFP_KERNEL); | 1214 | device = kzalloc(sizeof(*device), GFP_ATOMIC); |
| 1215 | if (device == NULL) | 1215 | if (device == NULL) |
| 1216 | break; | 1216 | break; |
| 1217 | 1217 | ||
| @@ -101,7 +101,7 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color) · 100 unmodified lines | |||
| 101 | { | 101 | { |
| 102 | struct fw_node *node; | 102 | struct fw_node *node; |
| 103 | 103 | ||
| 104 | node = kzalloc(struct_size(node, ports, port_count), GFP_KERNEL); | 104 | node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); |
| 105 | if (node == NULL) | 105 | if (node == NULL) |
| 106 | return NULL; | 106 | return NULL; |
| 107 | 107 | ||
| @@ -81,7 +81,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " · 80 unmodified lines | |||
| 81 | * | 81 | * |
| 82 | * - power condition | 82 | * - power condition |
| 83 | * Set the power condition field in the START STOP UNIT commands sent by | 83 | * Set the power condition field in the START STOP UNIT commands sent by |
| 84 | * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). | 84 | * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or |
| 85 | * manage_runtime_start_stop is on). | ||
| 85 | * Some disks need this to spin down or to resume properly. | 86 | * Some disks need this to spin down or to resume properly. |
| 86 | * | 87 | * |
| 87 | * - override internal blacklist | 88 | * - override internal blacklist |
| @@ -1517,8 +1518,10 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) · 1429 unmodified lines | |||
| 1517 | 1518 | ||
| 1518 | sdev->use_10_for_rw = 1; | 1519 | sdev->use_10_for_rw = 1; |
| 1519 | 1520 | ||
| 1520 | if (sbp2_param_exclusive_login) | 1521 | if (sbp2_param_exclusive_login) { |
| 1521 | sdev->manage_start_stop = 1; | 1522 | sdev->manage_system_start_stop = true; |
| 1523 | sdev->manage_runtime_start_stop = true; | ||
| 1524 | } | ||
| 1522 | 1525 | ||
| 1523 | if (sdev->type == TYPE_ROM) | 1526 | if (sdev->type == TYPE_ROM) |
| 1524 | sdev->use_10_for_ms = 1; | 1527 | sdev->use_10_for_ms = 1; |
| @@ -397,6 +397,19 @@ static u32 ffa_get_num_pages_sg(struct scatterlist *sg) · 396 unmodified lines | |||
| 397 | return num_pages; | 397 | return num_pages; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | static u8 ffa_memory_attributes_get(u32 func_id) | ||
| 401 | { | ||
| 402 | /* | ||
| 403 | * For the memory lend or donate operation, if the receiver is a PE or | ||
| 404 | * a proxy endpoint, the owner/sender must not specify the attributes | ||
| 405 | */ | ||
| 406 | if (func_id == FFA_FN_NATIVE(MEM_LEND) || | ||
| 407 | func_id == FFA_MEM_LEND) | ||
| 408 | return 0; | ||
| 409 | |||
| 410 | return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; | ||
| 411 | } | ||
| 412 | |||
| 400 | static int | 413 | static int |
| 401 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, | 414 | ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, |
| 402 | struct ffa_mem_ops_args *args) | 415 | struct ffa_mem_ops_args *args) |
| @@ -413,8 +426,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, · 10 unmodified lines | |||
| 413 | mem_region->tag = args->tag; | 426 | mem_region->tag = args->tag; |
| 414 | mem_region->flags = args->flags; | 427 | mem_region->flags = args->flags; |
| 415 | mem_region->sender_id = drv_info->vm_id; | 428 | mem_region->sender_id = drv_info->vm_id; |
| 416 | mem_region->attributes = FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | | 429 | mem_region->attributes = ffa_memory_attributes_get(func_id); |
| 417 | FFA_MEM_INNER_SHAREABLE; | ||
| 418 | ep_mem_access = &mem_region->ep_mem_access[0]; | 430 | ep_mem_access = &mem_region->ep_mem_access[0]; |
| 419 | 431 | ||
| 420 | for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { | 432 | for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { |
| @@ -1080,6 +1080,8 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) · 1079 unmodified lines | |||
| 1080 | if (!pinfo) | 1080 | if (!pinfo) |
| 1081 | return -ENOMEM; | 1081 | return -ENOMEM; |
| 1082 | 1082 | ||
| 1083 | pinfo->version = version; | ||
| 1084 | |||
| 1083 | ret = scmi_perf_attributes_get(ph, pinfo); | 1085 | ret = scmi_perf_attributes_get(ph, pinfo); |
| 1084 | if (ret) | 1086 | if (ret) |
| 1085 | return ret; | 1087 | return ret; |
| @@ -1104,8 +1106,6 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) · 18 unmodified lines | |||
| 1104 | if (ret) | 1106 | if (ret) |
| 1105 | return ret; | 1107 | return ret; |
| 1106 | 1108 | ||
| 1107 | pinfo->version = version; | ||
| 1108 | |||
| 1109 | return ph->set_priv(ph, pinfo); | 1109 | return ph->set_priv(ph, pinfo); |
| 1110 | } | 1110 | } |
| 1111 | 1111 | ||
| @@ -1863,15 +1863,15 @@ static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) · 1862 unmodified lines | |||
| 1863 | return PTR_ERR(adsp2_alg); | 1863 | return PTR_ERR(adsp2_alg); |
| 1864 | 1864 | ||
| 1865 | for (i = 0; i < n_algs; i++) { | 1865 | for (i = 0; i < n_algs; i++) { |
| 1866 | cs_dsp_info(dsp, | 1866 | cs_dsp_dbg(dsp, |
| 1867 | "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", | 1867 | "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", |
| 1868 | i, be32_to_cpu(adsp2_alg[i].alg.id), | 1868 | i, be32_to_cpu(adsp2_alg[i].alg.id), |
| 1869 | (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, | 1869 | (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, |
| 1870 | (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, | 1870 | (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, |
| 1871 | be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, | 1871 | be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, |
| 1872 | be32_to_cpu(adsp2_alg[i].xm), | 1872 | be32_to_cpu(adsp2_alg[i].xm), |
| 1873 | be32_to_cpu(adsp2_alg[i].ym), | 1873 | be32_to_cpu(adsp2_alg[i].ym), |
| 1874 | be32_to_cpu(adsp2_alg[i].zm)); | 1874 | be32_to_cpu(adsp2_alg[i].zm)); |
| 1875 | 1875 | ||
| 1876 | alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, | 1876 | alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, |
| 1877 | adsp2_alg[i].alg.id, | 1877 | adsp2_alg[i].alg.id, |
| @@ -1996,14 +1996,14 @@ static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) · 118 unmodified lines | |||
| 1996 | return PTR_ERR(halo_alg); | 1996 | return PTR_ERR(halo_alg); |
| 1997 | 1997 | ||
| 1998 | for (i = 0; i < n_algs; i++) { | 1998 | for (i = 0; i < n_algs; i++) { |
| 1999 | cs_dsp_info(dsp, | 1999 | cs_dsp_dbg(dsp, |
| 2000 | "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", | 2000 | "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", |
| 2001 | i, be32_to_cpu(halo_alg[i].alg.id), | 2001 | i, be32_to_cpu(halo_alg[i].alg.id), |
| 2002 | (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, | 2002 | (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, |
| 2003 | (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, | 2003 | (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, |
| 2004 | be32_to_cpu(halo_alg[i].alg.ver) & 0xff, | 2004 | be32_to_cpu(halo_alg[i].alg.ver) & 0xff, |
| 2005 | be32_to_cpu(halo_alg[i].xm_base), | 2005 | be32_to_cpu(halo_alg[i].xm_base), |
| 2006 | be32_to_cpu(halo_alg[i].ym_base)); | 2006 | be32_to_cpu(halo_alg[i].ym_base)); |
| 2007 | 2007 | ||
| 2008 | ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, | 2008 | ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, |
| 2009 | halo_alg[i].alg.ver, | 2009 | halo_alg[i].alg.ver, |
| @@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid, · 622 unmodified lines | |||
| 623 | return 0; | 623 | return 0; |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | /** | ||
| 627 | * reserve_unaccepted - Map and reserve unaccepted configuration table | ||
| 628 | * @unaccepted: Pointer to unaccepted memory table | ||
| 629 | * | ||
| 630 | * memblock_add() makes sure that the table is mapped in direct mapping. During | ||
| 631 | * normal boot it happens automatically because the table is allocated from | ||
| 632 | * usable memory. But during crashkernel boot only memory specifically reserved | ||
| 633 | * for crash scenario is mapped. memblock_add() forces the table to be mapped | ||
| 634 | * in crashkernel case. | ||
| 635 | * | ||
| 636 | * Align the range to the nearest page borders. Ranges smaller than page size | ||
| 637 | * are not going to be mapped. | ||
| 638 | * | ||
| 639 | * memblock_reserve() makes sure that future allocations will not touch the | ||
| 640 | * table. | ||
| 641 | */ | ||
| 642 | |||
| 643 | static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) | ||
| 644 | { | ||
| 645 | phys_addr_t start, size; | ||
| 646 | |||
| 647 | start = PAGE_ALIGN_DOWN(efi.unaccepted); | ||
| 648 | size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); | ||
| 649 | |||
| 650 | memblock_add(start, size); | ||
| 651 | memblock_reserve(start, size); | ||
| 652 | } | ||
| 653 | |||
| 626 | int __init efi_config_parse_tables(const efi_config_table_t *config_tables, | 654 | int __init efi_config_parse_tables(const efi_config_table_t *config_tables, |
| 627 | int count, | 655 | int count, |
| 628 | const efi_config_table_type_t *arch_tables) | 656 | const efi_config_table_type_t *arch_tables) |
| @@ -751,11 +779,9 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, · 122 unmodified lines | |||
| 751 | 779 | ||
| 752 | unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted)); | 780 | unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted)); |
| 753 | if (unaccepted) { | 781 | if (unaccepted) { |
| 754 | unsigned long size; | ||
| 755 | 782 | ||
| 756 | if (unaccepted->version == 1) { | 783 | if (unaccepted->version == 1) { |
| 757 | size = sizeof(*unaccepted) + unaccepted->size; | 784 | reserve_unaccepted(unaccepted); |
| 758 | memblock_reserve(efi.unaccepted, size); | ||
| 759 | } else { | 785 | } else { |
| 760 | efi.unaccepted = EFI_INVALID_TABLE_ADDR; | 786 | efi.unaccepted = EFI_INVALID_TABLE_ADDR; |
| 761 | } | 787 | } |
| @@ -62,7 +62,7 @@ efi_status_t allocate_unaccepted_bitmap(__u32 nr_desc, · 61 unmodified lines | |||
| 62 | bitmap_size = DIV_ROUND_UP(unaccepted_end - unaccepted_start, | 62 | bitmap_size = DIV_ROUND_UP(unaccepted_end - unaccepted_start, |
| 63 | EFI_UNACCEPTED_UNIT_SIZE * BITS_PER_BYTE); | 63 | EFI_UNACCEPTED_UNIT_SIZE * BITS_PER_BYTE); |
| 64 | 64 | ||
| 65 | status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, | 65 | status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, |
| 66 | sizeof(*unaccepted_table) + bitmap_size, | 66 | sizeof(*unaccepted_table) + bitmap_size, |
| 67 | (void **)&unaccepted_table); | 67 | (void **)&unaccepted_table); |
| 68 | if (status != EFI_SUCCESS) { | 68 | if (status != EFI_SUCCESS) { |
| @@ -114,6 +114,7 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) · 113 unmodified lines | |||
| 114 | dsp_chan->idx = i % 2; | 114 | dsp_chan->idx = i % 2; |
| 115 | dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); | 115 | dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); |
| 116 | if (IS_ERR(dsp_chan->ch)) { | 116 | if (IS_ERR(dsp_chan->ch)) { |
| 117 | kfree(dsp_chan->name); | ||
| 117 | ret = PTR_ERR(dsp_chan->ch); | 118 | ret = PTR_ERR(dsp_chan->ch); |
| 118 | if (ret != -EPROBE_DEFER) | 119 | if (ret != -EPROBE_DEFER) |
| 119 | dev_err(dev, "Failed to request mbox chan %s ret %d\n", | 120 | dev_err(dev, "Failed to request mbox chan %s ret %d\n", |
| @@ -352,6 +352,7 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) · 351 unmodified lines | |||
| 352 | pmic_eic->chip.set_config = sprd_pmic_eic_set_config; | 352 | pmic_eic->chip.set_config = sprd_pmic_eic_set_config; |
| 353 | pmic_eic->chip.set = sprd_pmic_eic_set; | 353 | pmic_eic->chip.set = sprd_pmic_eic_set; |
| 354 | pmic_eic->chip.get = sprd_pmic_eic_get; | 354 | pmic_eic->chip.get = sprd_pmic_eic_get; |
| 355 | pmic_eic->chip.can_sleep = true; | ||
| 355 | 356 | ||
| 356 | irq = &pmic_eic->chip.irq; | 357 | irq = &pmic_eic->chip.irq; |
| 357 | gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); | 358 | gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
| 20 | #include <linux/irq_sim.h> | 20 | #include <linux/irq_sim.h> |
| 21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
| 22 | #include <linux/minmax.h> | ||
| 22 | #include <linux/mod_devicetable.h> | 23 | #include <linux/mod_devicetable.h> |
| 23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| @@ -685,52 +686,32 @@ gpio_sim_device_config_live_show(struct config_item *item, char *page) · 660 unmodified lines | |||
| 685 | return sprintf(page, "%c\n", live ? '1' : '0'); | 686 | return sprintf(page, "%c\n", live ? '1' : '0'); |
| 686 | } | 687 | } |
| 687 | 688 | ||
| 688 | static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank, | 689 | static unsigned int gpio_sim_get_line_names_size(struct gpio_sim_bank *bank) |
| 689 | unsigned int *line_names_size) | ||
| 690 | { | 690 | { |
| 691 | unsigned int max_offset = 0; | ||
| 692 | bool has_line_names = false; | ||
| 693 | struct gpio_sim_line *line; | 691 | struct gpio_sim_line *line; |
| 694 | char **line_names; | 692 | unsigned int size = 0; |
| 695 | 693 | ||
| 696 | list_for_each_entry(line, &bank->line_list, siblings) { | 694 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 697 | if (line->offset >= bank->num_lines) | 695 | if (!line->name || (line->offset >= bank->num_lines)) |
| 698 | continue; | 696 | continue; |
| 699 | 697 | ||
| 700 | if (line->name) { | 698 | size = max(size, line->offset + 1); |
| 701 | if (line->offset > max_offset) | ||
| 702 | max_offset = line->offset; | ||
| 703 | |||
| 704 | /* | ||
| 705 | * max_offset can stay at 0 so it's not an indicator | ||
| 706 | * of whether line names were configured at all. | ||
| 707 | */ | ||
| 708 | has_line_names = true; | ||
| 709 | } | ||
| 710 | } | 699 | } |
| 711 | 700 | ||
| 712 | if (!has_line_names) | 701 | return size; |
| 713 | /* | 702 | } |
| 714 | * This is not an error - NULL means, there are no line | ||
| 715 | * names configured. | ||
| 716 | */ | ||
| 717 | return NULL; | ||
| 718 | |||
| 719 | *line_names_size = max_offset + 1; | ||
| 720 | 703 | ||
| 721 | line_names = kcalloc(*line_names_size, sizeof(*line_names), GFP_KERNEL); | 704 | static void |
| 722 | if (!line_names) | 705 | gpio_sim_set_line_names(struct gpio_sim_bank *bank, char **line_names) |
| 723 | return ERR_PTR(-ENOMEM); | 706 | { |
| 707 | struct gpio_sim_line *line; | ||
| 724 | 708 | ||
| 725 | list_for_each_entry(line, &bank->line_list, siblings) { | 709 | list_for_each_entry(line, &bank->line_list, siblings) { |
| 726 | if (line->offset >= bank->num_lines) | 710 | if (!line->name || (line->offset >= bank->num_lines)) |
| 727 | continue; | 711 | continue; |
| 728 | 712 | ||
| 729 | if (line->name && (line->offset <= max_offset)) | 713 | line_names[line->offset] = line->name; |
| 730 | line_names[line->offset] = line->name; | ||
| 731 | } | 714 | } |
| 732 | |||
| 733 | return line_names; | ||
| 734 | } | 715 | } |
| 735 | 716 | ||
| 736 | static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) | 717 | static void gpio_sim_remove_hogs(struct gpio_sim_device *dev) |
| @@ -834,7 +815,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 97 unmodified lines | |||
| 834 | struct fwnode_handle *parent) | 815 | struct fwnode_handle *parent) |
| 835 | { | 816 | { |
| 836 | struct property_entry properties[GPIO_SIM_PROP_MAX]; | 817 | struct property_entry properties[GPIO_SIM_PROP_MAX]; |
| 837 | unsigned int prop_idx = 0, line_names_size = 0; | 818 | unsigned int prop_idx = 0, line_names_size; |
| 838 | char **line_names __free(kfree) = NULL; | 819 | char **line_names __free(kfree) = NULL; |
| 839 | 820 | ||
| 840 | memset(properties, 0, sizeof(properties)); | 821 | memset(properties, 0, sizeof(properties)); |
| @@ -845,14 +826,19 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, · 4 unmodified lines | |||
| 845 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", | 826 | properties[prop_idx++] = PROPERTY_ENTRY_STRING("gpio-sim,label", |
| 846 | bank->label); | 827 | bank->label); |
| 847 | 828 | ||
| 848 | line_names = gpio_sim_make_line_names(bank, &line_names_size); | 829 | line_names_size = gpio_sim_get_line_names_size(bank); |
| 849 | if (IS_ERR(line_names)) | 830 | if (line_names_size) { |
| 850 | return ERR_CAST(line_names); | 831 | line_names = kcalloc(line_names_size, sizeof(*line_names), |
| 832 | GFP_KERNEL); | ||
| 833 | if (!line_names) | ||
| 834 | return ERR_PTR(-ENOMEM); | ||
| 835 | |||
| 836 | gpio_sim_set_line_names(bank, line_names); | ||
| 851 | 837 | ||
| 852 | if (line_names) | ||
| 853 | properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN( | 838 | properties[prop_idx++] = PROPERTY_ENTRY_STRING_ARRAY_LEN( |
| 854 | "gpio-line-names", | 839 | "gpio-line-names", |
| 855 | line_names, line_names_size); | 840 | line_names, line_names_size); |
| 841 | } | ||
| 856 | 842 | ||
| 857 | return fwnode_create_software_node(properties, parent); | 843 | return fwnode_create_software_node(properties, parent); |
| 858 | } | 844 | } |
| @@ -195,7 +195,7 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 194 unmodified lines | |||
| 195 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, | 195 | handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, |
| 196 | IRQ_GC_INIT_MASK_CACHE); | 196 | IRQ_GC_INIT_MASK_CACHE); |
| 197 | if (ret) | 197 | if (ret) |
| 198 | return ret; | 198 | goto err_remove_domain; |
| 199 | 199 | ||
| 200 | gc = tb10x_gpio->domain->gc->gc[0]; | 200 | gc = tb10x_gpio->domain->gc->gc[0]; |
| 201 | gc->reg_base = tb10x_gpio->base; | 201 | gc->reg_base = tb10x_gpio->base; |
| @@ -209,6 +209,10 @@ static int tb10x_gpio_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | return 0; | 211 | return 0; |
| 212 | |||
| 213 | err_remove_domain: | ||
| 214 | irq_domain_remove(tb10x_gpio->domain); | ||
| 215 | return ret; | ||
| 212 | } | 216 | } |
| 213 | 217 | ||
| 214 | static int tb10x_gpio_remove(struct platform_device *pdev) | 218 | static int tb10x_gpio_remove(struct platform_device *pdev) |
| @@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, · 42 unmodified lines | |||
| 43 | unsigned offset, bool enabled) | 43 | unsigned offset, bool enabled) |
| 44 | { | 44 | { |
| 45 | struct timbgpio *tgpio = gpiochip_get_data(gpio); | 45 | struct timbgpio *tgpio = gpiochip_get_data(gpio); |
| 46 | unsigned long flags; | ||
| 46 | u32 reg; | 47 | u32 reg; |
| 47 | 48 | ||
| 48 | spin_lock(&tgpio->lock); | 49 | spin_lock_irqsave(&tgpio->lock, flags); |
| 49 | reg = ioread32(tgpio->membase + offset); | 50 | reg = ioread32(tgpio->membase + offset); |
| 50 | 51 | ||
| 51 | if (enabled) | 52 | if (enabled) |
| @@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, · 2 unmodified lines | |||
| 54 | reg &= ~(1 << index); | 55 | reg &= ~(1 << index); |
| 55 | 56 | ||
| 56 | iowrite32(reg, tgpio->membase + offset); | 57 | iowrite32(reg, tgpio->membase + offset); |
| 57 | spin_unlock(&tgpio->lock); | 58 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 58 | 59 | ||
| 59 | return 0; | 60 | return 0; |
| 60 | } | 61 | } |
| @@ -136,7 +136,7 @@ config DRM_FBDEV_EMULATION · 135 unmodified lines | |||
| 136 | bool "Enable legacy fbdev support for your modesetting driver" | 136 | bool "Enable legacy fbdev support for your modesetting driver" |
| 137 | depends on DRM | 137 | depends on DRM |
| 138 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE | 138 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE |
| 139 | default y | 139 | default FB |
| 140 | help | 140 | help |
| 141 | Choose this option if you have a need for the legacy fbdev | 141 | Choose this option if you have a need for the legacy fbdev |
| 142 | support. Note that this support also provides the linux console | 142 | support. Note that this support also provides the linux console |
| @@ -1293,7 +1293,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 1292 unmodified lines | |||
| 1293 | void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); | 1293 | void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); |
| 1294 | int amdgpu_device_pci_reset(struct amdgpu_device *adev); | 1294 | int amdgpu_device_pci_reset(struct amdgpu_device *adev); |
| 1295 | bool amdgpu_device_need_post(struct amdgpu_device *adev); | 1295 | bool amdgpu_device_need_post(struct amdgpu_device *adev); |
| 1296 | bool amdgpu_sg_display_supported(struct amdgpu_device *adev); | ||
| 1297 | bool amdgpu_device_pcie_dynamic_switching_supported(void); | 1296 | bool amdgpu_device_pcie_dynamic_switching_supported(void); |
| 1298 | bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); | 1297 | bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); |
| 1299 | bool amdgpu_device_aspm_support_quirk(void); | 1298 | bool amdgpu_device_aspm_support_quirk(void); |
| @@ -478,7 +478,7 @@ void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, struct kfd_cu_info *c · 477 unmodified lines | |||
| 478 | cu_info->cu_active_number = acu_info.number; | 478 | cu_info->cu_active_number = acu_info.number; |
| 479 | cu_info->cu_ao_mask = acu_info.ao_cu_mask; | 479 | cu_info->cu_ao_mask = acu_info.ao_cu_mask; |
| 480 | memcpy(&cu_info->cu_bitmap[0], &acu_info.bitmap[0], | 480 | memcpy(&cu_info->cu_bitmap[0], &acu_info.bitmap[0], |
| 481 | sizeof(acu_info.bitmap)); | 481 | sizeof(cu_info->cu_bitmap)); |
| 482 | cu_info->num_shader_engines = adev->gfx.config.max_shader_engines; | 482 | cu_info->num_shader_engines = adev->gfx.config.max_shader_engines; |
| 483 | cu_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se; | 483 | cu_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se; |
| 484 | cu_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh; | 484 | cu_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh; |
| @@ -980,8 +980,7 @@ void kgd_gfx_v10_build_grace_period_packet_info(struct amdgpu_device *adev, · 979 unmodified lines | |||
| 980 | uint32_t wait_times, | 980 | uint32_t wait_times, |
| 981 | uint32_t grace_period, | 981 | uint32_t grace_period, |
| 982 | uint32_t *reg_offset, | 982 | uint32_t *reg_offset, |
| 983 | uint32_t *reg_data, | 983 | uint32_t *reg_data) |
| 984 | uint32_t inst) | ||
| 985 | { | 984 | { |
| 986 | *reg_data = wait_times; | 985 | *reg_data = wait_times; |
| 987 | 986 | ||
| @@ -55,5 +55,4 @@ void kgd_gfx_v10_build_grace_period_packet_info(struct amdgpu_device *adev, · 54 unmodified lines | |||
| 55 | uint32_t wait_times, | 55 | uint32_t wait_times, |
| 56 | uint32_t grace_period, | 56 | uint32_t grace_period, |
| 57 | uint32_t *reg_offset, | 57 | uint32_t *reg_offset, |
| 58 | uint32_t *reg_data, | 58 | uint32_t *reg_data); |
| 59 | uint32_t inst); | ||
| @@ -1103,8 +1103,7 @@ void kgd_gfx_v9_build_grace_period_packet_info(struct amdgpu_device *adev, · 1102 unmodified lines | |||
| 1103 | uint32_t wait_times, | 1103 | uint32_t wait_times, |
| 1104 | uint32_t grace_period, | 1104 | uint32_t grace_period, |
| 1105 | uint32_t *reg_offset, | 1105 | uint32_t *reg_offset, |
| 1106 | uint32_t *reg_data, | 1106 | uint32_t *reg_data) |
| 1107 | uint32_t inst) | ||
| 1108 | { | 1107 | { |
| 1109 | *reg_data = wait_times; | 1108 | *reg_data = wait_times; |
| 1110 | 1109 | ||
| @@ -1120,8 +1119,7 @@ void kgd_gfx_v9_build_grace_period_packet_info(struct amdgpu_device *adev, · 9 unmodified lines | |||
| 1120 | SCH_WAVE, | 1119 | SCH_WAVE, |
| 1121 | grace_period); | 1120 | grace_period); |
| 1122 | 1121 | ||
| 1123 | *reg_offset = SOC15_REG_OFFSET(GC, GET_INST(GC, inst), | 1122 | *reg_offset = SOC15_REG_OFFSET(GC, 0, mmCP_IQ_WAIT_TIME2); |
| 1124 | mmCP_IQ_WAIT_TIME2); | ||
| 1125 | } | 1123 | } |
| 1126 | 1124 | ||
| 1127 | void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev, | 1125 | void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev, |
| @@ -100,5 +100,4 @@ void kgd_gfx_v9_build_grace_period_packet_info(struct amdgpu_device *adev, · 99 unmodified lines | |||
| 100 | uint32_t wait_times, | 100 | uint32_t wait_times, |
| 101 | uint32_t grace_period, | 101 | uint32_t grace_period, |
| 102 | uint32_t *reg_offset, | 102 | uint32_t *reg_offset, |
| 103 | uint32_t *reg_data, | 103 | uint32_t *reg_data); |
| 104 | uint32_t inst); | ||
| @@ -1776,7 +1776,7 @@ static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev, · 1775 unmodified lines | |||
| 1776 | struct amdgpu_device *adev = drm_to_adev(ddev); | 1776 | struct amdgpu_device *adev = drm_to_adev(ddev); |
| 1777 | struct atom_context *ctx = adev->mode_info.atom_context; | 1777 | struct atom_context *ctx = adev->mode_info.atom_context; |
| 1778 | 1778 | ||
| 1779 | return sysfs_emit(buf, "%s\n", ctx->vbios_ver_str); | 1779 | return sysfs_emit(buf, "%s\n", ctx->vbios_pn); |
| 1780 | } | 1780 | } |
| 1781 | 1781 | ||
| 1782 | static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version, | 1782 | static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version, |
| @@ -1244,32 +1244,6 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev) · 1243 unmodified lines | |||
| 1244 | return true; | 1244 | return true; |
| 1245 | } | 1245 | } |
| 1246 | 1246 | ||
| 1247 | /* | ||
| 1248 | * On APUs with >= 64GB white flickering has been observed w/ SG enabled. | ||
| 1249 | * Disable S/G on such systems until we have a proper fix. | ||
| 1250 | * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 | ||
| 1251 | * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 | ||
| 1252 | */ | ||
| 1253 | bool amdgpu_sg_display_supported(struct amdgpu_device *adev) | ||
| 1254 | { | ||
| 1255 | switch (amdgpu_sg_display) { | ||
| 1256 | case -1: | ||
| 1257 | break; | ||
| 1258 | case 0: | ||
| 1259 | return false; | ||
| 1260 | case 1: | ||
| 1261 | return true; | ||
| 1262 | default: | ||
| 1263 | return false; | ||
| 1264 | } | ||
| 1265 | if ((totalram_pages() << (PAGE_SHIFT - 10)) + | ||
| 1266 | (adev->gmc.real_vram_size / 1024) >= 64000000) { | ||
| 1267 | DRM_WARN("Disabling S/G due to >=64GB RAM\n"); | ||
| 1268 | return false; | ||
| 1269 | } | ||
| 1270 | return true; | ||
| 1271 | } | ||
| 1272 | |||
| 1273 | /* | 1247 | /* |
| 1274 | * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic | 1248 | * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic |
| 1275 | * speed switching. Until we have confirmation from Intel that a specific host | 1249 | * speed switching. Until we have confirmation from Intel that a specific host |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | |||
| 43 | #define AMDGPU_GFX_LBPW_DISABLED_MODE 0x00000008L | 43 | #define AMDGPU_GFX_LBPW_DISABLED_MODE 0x00000008L |
| 44 | 44 | ||
| 45 | #define AMDGPU_MAX_GC_INSTANCES 8 | 45 | #define AMDGPU_MAX_GC_INSTANCES 8 |
| 46 | #define KGD_MAX_QUEUES 128 | ||
| 46 | 47 | ||
| 47 | #define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES | 48 | #define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES |
| 48 | #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES | 49 | #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES |
| @@ -257,7 +258,7 @@ struct amdgpu_cu_info { · 208 unmodified lines | |||
| 257 | uint32_t number; | 258 | uint32_t number; |
| 258 | uint32_t ao_cu_mask; | 259 | uint32_t ao_cu_mask; |
| 259 | uint32_t ao_cu_bitmap[4][4]; | 260 | uint32_t ao_cu_bitmap[4][4]; |
| 260 | uint32_t bitmap[4][4]; | 261 | uint32_t bitmap[AMDGPU_MAX_GC_INSTANCES][4][4]; |
| 261 | }; | 262 | }; |
| 262 | 263 | ||
| 263 | struct amdgpu_gfx_ras { | 264 | struct amdgpu_gfx_ras { |
| @@ -839,7 +839,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 838 unmodified lines | |||
| 839 | memcpy(&dev_info->cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0], | 839 | memcpy(&dev_info->cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0], |
| 840 | sizeof(adev->gfx.cu_info.ao_cu_bitmap)); | 840 | sizeof(adev->gfx.cu_info.ao_cu_bitmap)); |
| 841 | memcpy(&dev_info->cu_bitmap[0], &adev->gfx.cu_info.bitmap[0], | 841 | memcpy(&dev_info->cu_bitmap[0], &adev->gfx.cu_info.bitmap[0], |
| 842 | sizeof(adev->gfx.cu_info.bitmap)); | 842 | sizeof(dev_info->cu_bitmap)); |
| 843 | dev_info->vram_type = adev->gmc.vram_type; | 843 | dev_info->vram_type = adev->gmc.vram_type; |
| 844 | dev_info->vram_bit_width = adev->gmc.vram_width; | 844 | dev_info->vram_bit_width = adev->gmc.vram_width; |
| 845 | dev_info->vce_harvest_config = adev->vce.harvest_config; | 845 | dev_info->vce_harvest_config = adev->vce.harvest_config; |
| @@ -940,12 +940,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 94 unmodified lines | |||
| 940 | struct atom_context *atom_context; | 940 | struct atom_context *atom_context; |
| 941 | 941 | ||
| 942 | atom_context = adev->mode_info.atom_context; | 942 | atom_context = adev->mode_info.atom_context; |
| 943 | memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name)); | 943 | if (atom_context) { |
| 944 | memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn)); | 944 | memcpy(vbios_info.name, atom_context->name, |
| 945 | vbios_info.version = atom_context->version; | 945 | sizeof(atom_context->name)); |
| 946 | memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, | 946 | memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, |
| 947 | sizeof(atom_context->vbios_ver_str)); | 947 | sizeof(atom_context->vbios_pn)); |
| 948 | memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date)); | 948 | vbios_info.version = atom_context->version; |
| 949 | memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, | ||
| 950 | sizeof(atom_context->vbios_ver_str)); | ||
| 951 | memcpy(vbios_info.date, atom_context->date, | ||
| 952 | sizeof(atom_context->date)); | ||
| 953 | } | ||
| 949 | 954 | ||
| 950 | return copy_to_user(out, &vbios_info, | 955 | return copy_to_user(out, &vbios_info, |
| 951 | min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; | 956 | min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; |
| @@ -801,6 +801,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 800 unmodified lines | |||
| 801 | enable ? "enable":"disable", | 801 | enable ? "enable":"disable", |
| 802 | get_ras_block_str(head), | 802 | get_ras_block_str(head), |
| 803 | amdgpu_ras_is_poison_mode_supported(adev), ret); | 803 | amdgpu_ras_is_poison_mode_supported(adev), ret); |
| 804 | kfree(info); | ||
| 804 | return ret; | 805 | return ret; |
| 805 | } | 806 | } |
| 806 | 807 | ||
| @@ -1052,7 +1053,8 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, · 245 unmodified lines | |||
| 1052 | info->ce_count = obj->err_data.ce_count; | 1053 | info->ce_count = obj->err_data.ce_count; |
| 1053 | 1054 | ||
| 1054 | if (err_data.ce_count) { | 1055 | if (err_data.ce_count) { |
| 1055 | if (adev->smuio.funcs && | 1056 | if (!adev->aid_mask && |
| 1057 | adev->smuio.funcs && | ||
| 1056 | adev->smuio.funcs->get_socket_id && | 1058 | adev->smuio.funcs->get_socket_id && |
| 1057 | adev->smuio.funcs->get_die_id) { | 1059 | adev->smuio.funcs->get_die_id) { |
| 1058 | dev_info(adev->dev, "socket: %d, die: %d " | 1060 | dev_info(adev->dev, "socket: %d, die: %d " |
| @@ -1072,7 +1074,8 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, · 13 unmodified lines | |||
| 1072 | } | 1074 | } |
| 1073 | } | 1075 | } |
| 1074 | if (err_data.ue_count) { | 1076 | if (err_data.ue_count) { |
| 1075 | if (adev->smuio.funcs && | 1077 | if (!adev->aid_mask && |
| 1078 | adev->smuio.funcs && | ||
| 1076 | adev->smuio.funcs->get_socket_id && | 1079 | adev->smuio.funcs->get_socket_id && |
| 1077 | adev->smuio.funcs->get_die_id) { | 1080 | adev->smuio.funcs->get_die_id) { |
| 1078 | dev_info(adev->dev, "socket: %d, die: %d " | 1081 | dev_info(adev->dev, "socket: %d, die: %d " |
| @@ -81,7 +81,7 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, · 80 unmodified lines | |||
| 81 | unsigned int size) | 81 | unsigned int size) |
| 82 | { | 82 | { |
| 83 | struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size, | 83 | struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size, |
| 84 | GFP_KERNEL, true, 0); | 84 | GFP_KERNEL, false, 0); |
| 85 | 85 | ||
| 86 | if (IS_ERR(sa)) { | 86 | if (IS_ERR(sa)) { |
| 87 | *sa_bo = NULL; | 87 | *sa_bo = NULL; |
| @@ -9449,7 +9449,7 @@ static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev, · 9448 unmodified lines | |||
| 9449 | gfx_v10_0_set_user_wgp_inactive_bitmap_per_sh( | 9449 | gfx_v10_0_set_user_wgp_inactive_bitmap_per_sh( |
| 9450 | adev, disable_masks[i * 2 + j]); | 9450 | adev, disable_masks[i * 2 + j]); |
| 9451 | bitmap = gfx_v10_0_get_cu_active_bitmap_per_sh(adev); | 9451 | bitmap = gfx_v10_0_get_cu_active_bitmap_per_sh(adev); |
| 9452 | cu_info->bitmap[i][j] = bitmap; | 9452 | cu_info->bitmap[0][i][j] = bitmap; |
| 9453 | 9453 | ||
| 9454 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { | 9454 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { |
| 9455 | if (bitmap & mask) { | 9455 | if (bitmap & mask) { |
| @@ -6368,7 +6368,7 @@ static int gfx_v11_0_get_cu_info(struct amdgpu_device *adev, · 6367 unmodified lines | |||
| 6368 | * SE6: {SH0,SH1} --> {bitmap[2][2], bitmap[2][3]} | 6368 | * SE6: {SH0,SH1} --> {bitmap[2][2], bitmap[2][3]} |
| 6369 | * SE7: {SH0,SH1} --> {bitmap[3][2], bitmap[3][3]} | 6369 | * SE7: {SH0,SH1} --> {bitmap[3][2], bitmap[3][3]} |
| 6370 | */ | 6370 | */ |
| 6371 | cu_info->bitmap[i % 4][j + (i / 4) * 2] = bitmap; | 6371 | cu_info->bitmap[0][i % 4][j + (i / 4) * 2] = bitmap; |
| 6372 | 6372 | ||
| 6373 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { | 6373 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { |
| 6374 | if (bitmap & mask) | 6374 | if (bitmap & mask) |
| @@ -3577,7 +3577,7 @@ static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev) · 3576 unmodified lines | |||
| 3577 | gfx_v6_0_set_user_cu_inactive_bitmap( | 3577 | gfx_v6_0_set_user_cu_inactive_bitmap( |
| 3578 | adev, disable_masks[i * 2 + j]); | 3578 | adev, disable_masks[i * 2 + j]); |
| 3579 | bitmap = gfx_v6_0_get_cu_enabled(adev); | 3579 | bitmap = gfx_v6_0_get_cu_enabled(adev); |
| 3580 | cu_info->bitmap[i][j] = bitmap; | 3580 | cu_info->bitmap[0][i][j] = bitmap; |
| 3581 | 3581 | ||
| 3582 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { | 3582 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { |
| 3583 | if (bitmap & mask) { | 3583 | if (bitmap & mask) { |
| @@ -5119,7 +5119,7 @@ static void gfx_v7_0_get_cu_info(struct amdgpu_device *adev) · 5118 unmodified lines | |||
| 5119 | gfx_v7_0_set_user_cu_inactive_bitmap( | 5119 | gfx_v7_0_set_user_cu_inactive_bitmap( |
| 5120 | adev, disable_masks[i * 2 + j]); | 5120 | adev, disable_masks[i * 2 + j]); |
| 5121 | bitmap = gfx_v7_0_get_cu_active_bitmap(adev); | 5121 | bitmap = gfx_v7_0_get_cu_active_bitmap(adev); |
| 5122 | cu_info->bitmap[i][j] = bitmap; | 5122 | cu_info->bitmap[0][i][j] = bitmap; |
| 5123 | 5123 | ||
| 5124 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { | 5124 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { |
| 5125 | if (bitmap & mask) { | 5125 | if (bitmap & mask) { |
| @@ -7121,7 +7121,7 @@ static void gfx_v8_0_get_cu_info(struct amdgpu_device *adev) · 7120 unmodified lines | |||
| 7121 | gfx_v8_0_set_user_cu_inactive_bitmap( | 7121 | gfx_v8_0_set_user_cu_inactive_bitmap( |
| 7122 | adev, disable_masks[i * 2 + j]); | 7122 | adev, disable_masks[i * 2 + j]); |
| 7123 | bitmap = gfx_v8_0_get_cu_active_bitmap(adev); | 7123 | bitmap = gfx_v8_0_get_cu_active_bitmap(adev); |
| 7124 | cu_info->bitmap[i][j] = bitmap; | 7124 | cu_info->bitmap[0][i][j] = bitmap; |
| 7125 | 7125 | ||
| 7126 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { | 7126 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { |
| 7127 | if (bitmap & mask) { | 7127 | if (bitmap & mask) { |
| @@ -1499,7 +1499,7 @@ static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev) · 1498 unmodified lines | |||
| 1499 | amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff, 0); | 1499 | amdgpu_gfx_select_se_sh(adev, i, j, 0xffffffff, 0); |
| 1500 | 1500 | ||
| 1501 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { | 1501 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { |
| 1502 | if (cu_info->bitmap[i][j] & mask) { | 1502 | if (cu_info->bitmap[0][i][j] & mask) { |
| 1503 | if (counter == pg_always_on_cu_num) | 1503 | if (counter == pg_always_on_cu_num) |
| 1504 | WREG32_SOC15(GC, 0, mmRLC_PG_ALWAYS_ON_CU_MASK, cu_bitmap); | 1504 | WREG32_SOC15(GC, 0, mmRLC_PG_ALWAYS_ON_CU_MASK, cu_bitmap); |
| 1505 | if (counter < always_on_cu_num) | 1505 | if (counter < always_on_cu_num) |
| @@ -7233,7 +7233,7 @@ static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev, · 5727 unmodified lines | |||
| 7233 | * SE6,SH0 --> bitmap[2][1] | 7233 | * SE6,SH0 --> bitmap[2][1] |
| 7234 | * SE7,SH0 --> bitmap[3][1] | 7234 | * SE7,SH0 --> bitmap[3][1] |
| 7235 | */ | 7235 | */ |
| 7236 | cu_info->bitmap[i % 4][j + i / 4] = bitmap; | 7236 | cu_info->bitmap[0][i % 4][j + i / 4] = bitmap; |
| 7237 | 7237 | ||
| 7238 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { | 7238 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { |
| 7239 | if (bitmap & mask) { | 7239 | if (bitmap & mask) { |
| @@ -4259,7 +4259,7 @@ static void gfx_v9_4_3_set_gds_init(struct amdgpu_device *adev) · 4258 unmodified lines | |||
| 4259 | } | 4259 | } |
| 4260 | 4260 | ||
| 4261 | static void gfx_v9_4_3_set_user_cu_inactive_bitmap(struct amdgpu_device *adev, | 4261 | static void gfx_v9_4_3_set_user_cu_inactive_bitmap(struct amdgpu_device *adev, |
| 4262 | u32 bitmap) | 4262 | u32 bitmap, int xcc_id) |
| 4263 | { | 4263 | { |
| 4264 | u32 data; | 4264 | u32 data; |
| 4265 | 4265 | ||
| @@ -4269,15 +4269,15 @@ static void gfx_v9_4_3_set_user_cu_inactive_bitmap(struct amdgpu_device *adev, · 3 unmodified lines | |||
| 4269 | data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; | 4269 | data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; |
| 4270 | data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; | 4270 | data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; |
| 4271 | 4271 | ||
| 4272 | WREG32_SOC15(GC, GET_INST(GC, 0), regGC_USER_SHADER_ARRAY_CONFIG, data); | 4272 | WREG32_SOC15(GC, GET_INST(GC, xcc_id), regGC_USER_SHADER_ARRAY_CONFIG, data); |
| 4273 | } | 4273 | } |
| 4274 | 4274 | ||
| 4275 | static u32 gfx_v9_4_3_get_cu_active_bitmap(struct amdgpu_device *adev) | 4275 | static u32 gfx_v9_4_3_get_cu_active_bitmap(struct amdgpu_device *adev, int xcc_id) |
| 4276 | { | 4276 | { |
| 4277 | u32 data, mask; | 4277 | u32 data, mask; |
| 4278 | 4278 | ||
| 4279 | data = RREG32_SOC15(GC, GET_INST(GC, 0), regCC_GC_SHADER_ARRAY_CONFIG); | 4279 | data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCC_GC_SHADER_ARRAY_CONFIG); |
| 4280 | data |= RREG32_SOC15(GC, GET_INST(GC, 0), regGC_USER_SHADER_ARRAY_CONFIG); | 4280 | data |= RREG32_SOC15(GC, GET_INST(GC, xcc_id), regGC_USER_SHADER_ARRAY_CONFIG); |
| 4281 | 4281 | ||
| 4282 | data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; | 4282 | data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; |
| 4283 | data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; | 4283 | data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; |
| @@ -4290,7 +4290,7 @@ static u32 gfx_v9_4_3_get_cu_active_bitmap(struct amdgpu_device *adev) · 6 unmodified lines | |||
| 4290 | static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, | 4290 | static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, |
| 4291 | struct amdgpu_cu_info *cu_info) | 4291 | struct amdgpu_cu_info *cu_info) |
| 4292 | { | 4292 | { |
| 4293 | int i, j, k, counter, active_cu_number = 0; | 4293 | int i, j, k, counter, xcc_id, active_cu_number = 0; |
| 4294 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; | 4294 | u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; |
| 4295 | unsigned disable_masks[4 * 4]; | 4295 | unsigned disable_masks[4 * 4]; |
| 4296 | 4296 | ||
| @@ -4309,46 +4309,38 @@ static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, · 12 unmodified lines | |||
| 4309 | adev->gfx.config.max_sh_per_se); | 4309 | adev->gfx.config.max_sh_per_se); |
| 4310 | 4310 | ||
| 4311 | mutex_lock(&adev->grbm_idx_mutex); | 4311 | mutex_lock(&adev->grbm_idx_mutex); |
| 4312 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { | 4312 | for (xcc_id = 0; xcc_id < NUM_XCC(adev->gfx.xcc_mask); xcc_id++) { |
| 4313 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { | 4313 | for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { |
| 4314 | mask = 1; | 4314 | for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { |
| 4315 | ao_bitmap = 0; | 4315 | mask = 1; |
| 4316 | counter = 0; | 4316 | ao_bitmap = 0; |
| 4317 | gfx_v9_4_3_xcc_select_se_sh(adev, i, j, 0xffffffff, 0); | 4317 | counter = 0; |
| 4318 | gfx_v9_4_3_set_user_cu_inactive_bitmap( | 4318 | gfx_v9_4_3_xcc_select_se_sh(adev, i, j, 0xffffffff, xcc_id); |
| 4319 | adev, disable_masks[i * adev->gfx.config.max_sh_per_se + j]); | 4319 | gfx_v9_4_3_set_user_cu_inactive_bitmap( |
| 4320 | bitmap = gfx_v9_4_3_get_cu_active_bitmap(adev); | 4320 | adev, |
| 4321 | 4321 | disable_masks[i * adev->gfx.config.max_sh_per_se + j], | |
| 4322 | /* | 4322 | xcc_id); |
| 4323 | * The bitmap(and ao_cu_bitmap) in cu_info structure is | 4323 | bitmap = gfx_v9_4_3_get_cu_active_bitmap(adev, xcc_id); |
| 4324 | * 4x4 size array, and it's usually suitable for Vega | 4324 | |
| 4325 | * ASICs which has 4*2 SE/SH layout. | 4325 | cu_info->bitmap[xcc_id][i][j] = bitmap; |
| 4326 | * But for Arcturus, SE/SH layout is changed to 8*1. | 4326 | |
| 4327 | * To mostly reduce the impact, we make it compatible | 4327 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { |
| 4328 | * with current bitmap array as below: | 4328 | if (bitmap & mask) { |
| 4329 | * SE4,SH0 --> bitmap[0][1] | 4329 | if (counter < adev->gfx.config.max_cu_per_sh) |
| 4330 | * SE5,SH0 --> bitmap[1][1] | 4330 | ao_bitmap |= mask; |
| 4331 | * SE6,SH0 --> bitmap[2][1] | 4331 | counter++; |
| 4332 | * SE7,SH0 --> bitmap[3][1] | 4332 | } |
| 4333 | */ | 4333 | mask <<= 1; |
| 4334 | cu_info->bitmap[i % 4][j + i / 4] = bitmap; | ||
| 4335 | |||
| 4336 | for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) { | ||
| 4337 | if (bitmap & mask) { | ||
| 4338 | if (counter < adev->gfx.config.max_cu_per_sh) | ||
| 4339 | ao_bitmap |= mask; | ||
| 4340 | counter++; | ||
| 4341 | } | 4334 | } |
| 4342 | mask <<= 1; | 4335 | active_cu_number += counter; |
| 4336 | if (i < 2 && j < 2) | ||
| 4337 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); | ||
| 4338 | cu_info->ao_cu_bitmap[i][j] = ao_bitmap; | ||
| 4343 | } | 4339 | } |
| 4344 | active_cu_number += counter; | ||
| 4345 | if (i < 2 && j < 2) | ||
| 4346 | ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); | ||
| 4347 | cu_info->ao_cu_bitmap[i % 4][j + i / 4] = ao_bitmap; | ||
| 4348 | } | 4340 | } |
| 4341 | gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, | ||
| 4342 | xcc_id); | ||
| 4349 | } | 4343 | } |
| 4350 | gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, | ||
| 4351 | 0); | ||
| 4352 | mutex_unlock(&adev->grbm_idx_mutex); | 4344 | mutex_unlock(&adev->grbm_idx_mutex); |
| 4353 | 4345 | ||
| 4354 | cu_info->number = active_cu_number; | 4346 | cu_info->number = active_cu_number; |
| @@ -345,6 +345,9 @@ static void nbio_v4_3_init_registers(struct amdgpu_device *adev) · 344 unmodified lines | |||
| 345 | data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; | 345 | data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; |
| 346 | WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); | 346 | WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); |
| 347 | } | 347 | } |
| 348 | if (amdgpu_sriov_vf(adev)) | ||
| 349 | adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, | ||
| 350 | regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; | ||
| 348 | } | 351 | } |
| 349 | 352 | ||
| 350 | static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev) | 353 | static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev) |
| @@ -766,7 +766,7 @@ static int soc21_common_hw_init(void *handle) · 765 unmodified lines | |||
| 766 | * for the purpose of expose those registers | 766 | * for the purpose of expose those registers |
| 767 | * to process space | 767 | * to process space |
| 768 | */ | 768 | */ |
| 769 | if (adev->nbio.funcs->remap_hdp_registers) | 769 | if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) |
| 770 | adev->nbio.funcs->remap_hdp_registers(adev); | 770 | adev->nbio.funcs->remap_hdp_registers(adev); |
| 771 | /* enable the doorbell aperture */ | 771 | /* enable the doorbell aperture */ |
| 772 | adev->nbio.funcs->enable_doorbell_aperture(adev, true); | 772 | adev->nbio.funcs->enable_doorbell_aperture(adev, true); |
| @@ -2087,7 +2087,8 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, · 2086 unmodified lines | |||
| 2087 | 2087 | ||
| 2088 | amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info); | 2088 | amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info); |
| 2089 | cu->num_simd_per_cu = cu_info.simd_per_cu; | 2089 | cu->num_simd_per_cu = cu_info.simd_per_cu; |
| 2090 | cu->num_simd_cores = cu_info.simd_per_cu * cu_info.cu_active_number; | 2090 | cu->num_simd_cores = cu_info.simd_per_cu * |
| 2091 | (cu_info.cu_active_number / kdev->kfd->num_nodes); | ||
| 2091 | cu->max_waves_simd = cu_info.max_waves_per_simd; | 2092 | cu->max_waves_simd = cu_info.max_waves_per_simd; |
| 2092 | 2093 | ||
| 2093 | cu->wave_front_size = cu_info.wave_front_size; | 2094 | cu->wave_front_size = cu_info.wave_front_size; |
| @@ -79,6 +79,10 @@ struct crat_header { · 78 unmodified lines | |||
| 79 | #define CRAT_SUBTYPE_IOLINK_AFFINITY 5 | 79 | #define CRAT_SUBTYPE_IOLINK_AFFINITY 5 |
| 80 | #define CRAT_SUBTYPE_MAX 6 | 80 | #define CRAT_SUBTYPE_MAX 6 |
| 81 | 81 | ||
| 82 | /* | ||
| 83 | * Do not change the value of CRAT_SIBLINGMAP_SIZE from 32 | ||
| 84 | * as it breaks the ABI. | ||
| 85 | */ | ||
| 82 | #define CRAT_SIBLINGMAP_SIZE 32 | 86 | #define CRAT_SIBLINGMAP_SIZE 32 |
| 83 | 87 | ||
| 84 | /* | 88 | /* |
| @@ -216,7 +216,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, · 215 unmodified lines | |||
| 216 | 216 | ||
| 217 | if (q->wptr_bo) { | 217 | if (q->wptr_bo) { |
| 218 | wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); | 218 | wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); |
| 219 | queue_input.wptr_mc_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off; | 219 | queue_input.wptr_mc_addr = amdgpu_bo_gpu_offset(q->wptr_bo) + wptr_addr_off; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | queue_input.is_kfd_process = 1; | 222 | queue_input.is_kfd_process = 1; |
| @@ -1677,8 +1677,7 @@ static int start_cpsch(struct device_queue_manager *dqm) · 1454 unmodified lines | |||
| 1677 | dqm->dev->kfd2kgd->build_grace_period_packet_info( | 1677 | dqm->dev->kfd2kgd->build_grace_period_packet_info( |
| 1678 | dqm->dev->adev, dqm->wait_times, | 1678 | dqm->dev->adev, dqm->wait_times, |
| 1679 | grace_period, ®_offset, | 1679 | grace_period, ®_offset, |
| 1680 | &dqm->wait_times, | 1680 | &dqm->wait_times); |
| 1681 | ffs(dqm->dev->xcc_mask) - 1); | ||
| 1682 | } | 1681 | } |
| 1683 | 1682 | ||
| 1684 | dqm_unlock(dqm); | 1683 | dqm_unlock(dqm); |
| @@ -162,6 +162,7 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, · 161 unmodified lines | |||
| 162 | return NULL; | 162 | return NULL; |
| 163 | 163 | ||
| 164 | *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kfd->doorbells, inx); | 164 | *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kfd->doorbells, inx); |
| 165 | inx *= 2; | ||
| 165 | 166 | ||
| 166 | pr_debug("Get kernel queue doorbell\n" | 167 | pr_debug("Get kernel queue doorbell\n" |
| 167 | " doorbell offset == 0x%08X\n" | 168 | " doorbell offset == 0x%08X\n" |
| @@ -176,6 +177,7 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr) · 8 unmodified lines | |||
| 176 | unsigned int inx; | 177 | unsigned int inx; |
| 177 | 178 | ||
| 178 | inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr); | 179 | inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr); |
| 180 | inx /= 2; | ||
| 179 | 181 | ||
| 180 | mutex_lock(&kfd->doorbell_mutex); | 182 | mutex_lock(&kfd->doorbell_mutex); |
| 181 | __clear_bit(inx, kfd->doorbell_bitmap); | 183 | __clear_bit(inx, kfd->doorbell_bitmap); |
| @@ -97,18 +97,22 @@ void free_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd, · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, | 98 | void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, |
| 99 | const uint32_t *cu_mask, uint32_t cu_mask_count, | 99 | const uint32_t *cu_mask, uint32_t cu_mask_count, |
| 100 | uint32_t *se_mask) | 100 | uint32_t *se_mask, uint32_t inst) |
| 101 | { | 101 | { |
| 102 | struct kfd_cu_info cu_info; | 102 | struct kfd_cu_info cu_info; |
| 103 | uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0}; | 103 | uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0}; |
| 104 | bool wgp_mode_req = KFD_GC_VERSION(mm->dev) >= IP_VERSION(10, 0, 0); | 104 | bool wgp_mode_req = KFD_GC_VERSION(mm->dev) >= IP_VERSION(10, 0, 0); |
| 105 | uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1; | 105 | uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1; |
| 106 | int i, se, sh, cu, cu_bitmap_sh_mul, inc = wgp_mode_req ? 2 : 1; | 106 | int i, se, sh, cu, cu_bitmap_sh_mul, cu_inc = wgp_mode_req ? 2 : 1; |
| 107 | uint32_t cu_active_per_node; | ||
| 108 | int inc = cu_inc * NUM_XCC(mm->dev->xcc_mask); | ||
| 109 | int xcc_inst = inst + ffs(mm->dev->xcc_mask) - 1; | ||
| 107 | 110 | ||
| 108 | amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info); | 111 | amdgpu_amdkfd_get_cu_info(mm->dev->adev, &cu_info); |
| 109 | 112 | ||
| 110 | if (cu_mask_count > cu_info.cu_active_number) | 113 | cu_active_per_node = cu_info.cu_active_number / mm->dev->kfd->num_nodes; |
| 111 | cu_mask_count = cu_info.cu_active_number; | 114 | if (cu_mask_count > cu_active_per_node) |
| 115 | cu_mask_count = cu_active_per_node; | ||
| 112 | 116 | ||
| 113 | /* Exceeding these bounds corrupts the stack and indicates a coding error. | 117 | /* Exceeding these bounds corrupts the stack and indicates a coding error. |
| 114 | * Returning with no CU's enabled will hang the queue, which should be | 118 | * Returning with no CU's enabled will hang the queue, which should be |
| @@ -141,7 +145,8 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, · 26 unmodified lines | |||
| 141 | for (se = 0; se < cu_info.num_shader_engines; se++) | 145 | for (se = 0; se < cu_info.num_shader_engines; se++) |
| 142 | for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) | 146 | for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) |
| 143 | cu_per_sh[se][sh] = hweight32( | 147 | cu_per_sh[se][sh] = hweight32( |
| 144 | cu_info.cu_bitmap[se % 4][sh + (se / 4) * cu_bitmap_sh_mul]); | 148 | cu_info.cu_bitmap[xcc_inst][se % 4][sh + (se / 4) * |
| 149 | cu_bitmap_sh_mul]); | ||
| 145 | 150 | ||
| 146 | /* Symmetrically map cu_mask to all SEs & SHs: | 151 | /* Symmetrically map cu_mask to all SEs & SHs: |
| 147 | * se_mask programs up to 2 SH in the upper and lower 16 bits. | 152 | * se_mask programs up to 2 SH in the upper and lower 16 bits. |
| @@ -164,20 +169,33 @@ void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, · 16 unmodified lines | |||
| 164 | * cu_mask[0] bit8 -> se_mask[0] bit1 (SE0,SH0,CU1) | 169 | * cu_mask[0] bit8 -> se_mask[0] bit1 (SE0,SH0,CU1) |
| 165 | * ... | 170 | * ... |
| 166 | * | 171 | * |
| 172 | * For GFX 9.4.3, the following code only looks at a | ||
| 173 | * subset of the cu_mask corresponding to the inst parameter. | ||
| 174 | * If we have n XCCs under one GPU node | ||
| 175 | * cu_mask[0] bit0 -> XCC0 se_mask[0] bit0 (XCC0,SE0,SH0,CU0) | ||
| 176 | * cu_mask[0] bit1 -> XCC1 se_mask[0] bit0 (XCC1,SE0,SH0,CU0) | ||
| 177 | * .. | ||
| 178 | * cu_mask[0] bitn -> XCCn se_mask[0] bit0 (XCCn,SE0,SH0,CU0) | ||
| 179 | * cu_mask[0] bit n+1 -> XCC0 se_mask[1] bit0 (XCC0,SE1,SH0,CU0) | ||
| 180 | * | ||
| 181 | * For example, if there are 6 XCCs under 1 KFD node, this code | ||
| 182 | * running for each inst, will look at the bits as: | ||
| 183 | * inst, inst + 6, inst + 12... | ||
| 184 | * | ||
| 167 | * First ensure all CUs are disabled, then enable user specified CUs. | 185 | * First ensure all CUs are disabled, then enable user specified CUs. |
| 168 | */ | 186 | */ |
| 169 | for (i = 0; i < cu_info.num_shader_engines; i++) | 187 | for (i = 0; i < cu_info.num_shader_engines; i++) |
| 170 | se_mask[i] = 0; | 188 | se_mask[i] = 0; |
| 171 | 189 | ||
| 172 | i = 0; | 190 | i = inst; |
| 173 | for (cu = 0; cu < 16; cu += inc) { | 191 | for (cu = 0; cu < 16; cu += cu_inc) { |
| 174 | for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) { | 192 | for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) { |
| 175 | for (se = 0; se < cu_info.num_shader_engines; se++) { | 193 | for (se = 0; se < cu_info.num_shader_engines; se++) { |
| 176 | if (cu_per_sh[se][sh] > cu) { | 194 | if (cu_per_sh[se][sh] > cu) { |
| 177 | if (cu_mask[i / 32] & (en_mask << (i % 32))) | 195 | if (cu_mask[i / 32] & (en_mask << (i % 32))) |
| 178 | se_mask[se] |= en_mask << (cu + sh * 16); | 196 | se_mask[se] |= en_mask << (cu + sh * 16); |
| 179 | i += inc; | 197 | i += inc; |
| 180 | if (i == cu_mask_count) | 198 | if (i >= cu_mask_count) |
| 181 | return; | 199 | return; |
| 182 | } | 200 | } |
| 183 | } | 201 | } |
| @@ -138,7 +138,7 @@ void free_mqd_hiq_sdma(struct mqd_manager *mm, void *mqd, · 137 unmodified lines | |||
| 138 | 138 | ||
| 139 | void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, | 139 | void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm, |
| 140 | const uint32_t *cu_mask, uint32_t cu_mask_count, | 140 | const uint32_t *cu_mask, uint32_t cu_mask_count, |
| 141 | uint32_t *se_mask); | 141 | uint32_t *se_mask, uint32_t inst); |
| 142 | 142 | ||
| 143 | int kfd_hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd, | 143 | int kfd_hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd, |
| 144 | uint32_t pipe_id, uint32_t queue_id, | 144 | uint32_t pipe_id, uint32_t queue_id, |
| @@ -52,7 +52,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 51 unmodified lines | |||
| 52 | return; | 52 | return; |
| 53 | 53 | ||
| 54 | mqd_symmetrically_map_cu_mask(mm, | 54 | mqd_symmetrically_map_cu_mask(mm, |
| 55 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); | 55 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask, 0); |
| 56 | 56 | ||
| 57 | m = get_mqd(mqd); | 57 | m = get_mqd(mqd); |
| 58 | m->compute_static_thread_mgmt_se0 = se_mask[0]; | 58 | m->compute_static_thread_mgmt_se0 = se_mask[0]; |
| @@ -52,7 +52,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 51 unmodified lines | |||
| 52 | return; | 52 | return; |
| 53 | 53 | ||
| 54 | mqd_symmetrically_map_cu_mask(mm, | 54 | mqd_symmetrically_map_cu_mask(mm, |
| 55 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); | 55 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask, 0); |
| 56 | 56 | ||
| 57 | m = get_mqd(mqd); | 57 | m = get_mqd(mqd); |
| 58 | m->compute_static_thread_mgmt_se0 = se_mask[0]; | 58 | m->compute_static_thread_mgmt_se0 = se_mask[0]; |
| @@ -71,7 +71,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 70 unmodified lines | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | mqd_symmetrically_map_cu_mask(mm, | 73 | mqd_symmetrically_map_cu_mask(mm, |
| 74 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); | 74 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask, 0); |
| 75 | 75 | ||
| 76 | m->compute_static_thread_mgmt_se0 = se_mask[0]; | 76 | m->compute_static_thread_mgmt_se0 = se_mask[0]; |
| 77 | m->compute_static_thread_mgmt_se1 = se_mask[1]; | 77 | m->compute_static_thread_mgmt_se1 = se_mask[1]; |
| @@ -321,6 +321,43 @@ static int get_wave_state(struct mqd_manager *mm, void *mqd, · 243 unmodified lines | |||
| 321 | return 0; | 321 | return 0; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | static void checkpoint_mqd(struct mqd_manager *mm, void *mqd, void *mqd_dst, void *ctl_stack_dst) | ||
| 325 | { | ||
| 326 | struct v11_compute_mqd *m; | ||
| 327 | |||
| 328 | m = get_mqd(mqd); | ||
| 329 | |||
| 330 | memcpy(mqd_dst, m, sizeof(struct v11_compute_mqd)); | ||
| 331 | } | ||
| 332 | |||
| 333 | static void restore_mqd(struct mqd_manager *mm, void **mqd, | ||
| 334 | struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr, | ||
| 335 | struct queue_properties *qp, | ||
| 336 | const void *mqd_src, | ||
| 337 | const void *ctl_stack_src, const u32 ctl_stack_size) | ||
| 338 | { | ||
| 339 | uint64_t addr; | ||
| 340 | struct v11_compute_mqd *m; | ||
| 341 | |||
| 342 | m = (struct v11_compute_mqd *) mqd_mem_obj->cpu_ptr; | ||
| 343 | addr = mqd_mem_obj->gpu_addr; | ||
| 344 | |||
| 345 | memcpy(m, mqd_src, sizeof(*m)); | ||
| 346 | |||
| 347 | *mqd = m; | ||
| 348 | if (gart_addr) | ||
| 349 | *gart_addr = addr; | ||
| 350 | |||
| 351 | m->cp_hqd_pq_doorbell_control = | ||
| 352 | qp->doorbell_off << | ||
| 353 | CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT; | ||
| 354 | pr_debug("cp_hqd_pq_doorbell_control 0x%x\n", | ||
| 355 | m->cp_hqd_pq_doorbell_control); | ||
| 356 | |||
| 357 | qp->is_active = 0; | ||
| 358 | } | ||
| 359 | |||
| 360 | |||
| 324 | static void init_mqd_hiq(struct mqd_manager *mm, void **mqd, | 361 | static void init_mqd_hiq(struct mqd_manager *mm, void **mqd, |
| 325 | struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr, | 362 | struct kfd_mem_obj *mqd_mem_obj, uint64_t *gart_addr, |
| 326 | struct queue_properties *q) | 363 | struct queue_properties *q) |
| @@ -458,6 +495,8 @@ struct mqd_manager *mqd_manager_init_v11(enum KFD_MQD_TYPE type, · 131 unmodified lines | |||
| 458 | mqd->mqd_size = sizeof(struct v11_compute_mqd); | 495 | mqd->mqd_size = sizeof(struct v11_compute_mqd); |
| 459 | mqd->get_wave_state = get_wave_state; | 496 | mqd->get_wave_state = get_wave_state; |
| 460 | mqd->mqd_stride = kfd_mqd_stride; | 497 | mqd->mqd_stride = kfd_mqd_stride; |
| 498 | mqd->checkpoint_mqd = checkpoint_mqd; | ||
| 499 | mqd->restore_mqd = restore_mqd; | ||
| 461 | #if defined(CONFIG_DEBUG_FS) | 500 | #if defined(CONFIG_DEBUG_FS) |
| 462 | mqd->debugfs_show_mqd = debugfs_show_mqd; | 501 | mqd->debugfs_show_mqd = debugfs_show_mqd; |
| 463 | #endif | 502 | #endif |
| @@ -502,6 +541,8 @@ struct mqd_manager *mqd_manager_init_v11(enum KFD_MQD_TYPE type, · 38 unmodified lines | |||
| 502 | mqd->update_mqd = update_mqd_sdma; | 541 | mqd->update_mqd = update_mqd_sdma; |
| 503 | mqd->destroy_mqd = kfd_destroy_mqd_sdma; | 542 | mqd->destroy_mqd = kfd_destroy_mqd_sdma; |
| 504 | mqd->is_occupied = kfd_is_occupied_sdma; | 543 | mqd->is_occupied = kfd_is_occupied_sdma; |
| 544 | mqd->checkpoint_mqd = checkpoint_mqd; | ||
| 545 | mqd->restore_mqd = restore_mqd; | ||
| 505 | mqd->mqd_size = sizeof(struct v11_sdma_mqd); | 546 | mqd->mqd_size = sizeof(struct v11_sdma_mqd); |
| 506 | mqd->mqd_stride = kfd_mqd_stride; | 547 | mqd->mqd_stride = kfd_mqd_stride; |
| 507 | #if defined(CONFIG_DEBUG_FS) | 548 | #if defined(CONFIG_DEBUG_FS) |
| @@ -60,7 +60,7 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd) · 59 unmodified lines | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static void update_cu_mask(struct mqd_manager *mm, void *mqd, | 62 | static void update_cu_mask(struct mqd_manager *mm, void *mqd, |
| 63 | struct mqd_update_info *minfo) | 63 | struct mqd_update_info *minfo, uint32_t inst) |
| 64 | { | 64 | { |
| 65 | struct v9_mqd *m; | 65 | struct v9_mqd *m; |
| 66 | uint32_t se_mask[KFD_MAX_NUM_SE] = {0}; | 66 | uint32_t se_mask[KFD_MAX_NUM_SE] = {0}; |
| @@ -69,27 +69,36 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 2 unmodified lines | |||
| 69 | return; | 69 | return; |
| 70 | 70 | ||
| 71 | mqd_symmetrically_map_cu_mask(mm, | 71 | mqd_symmetrically_map_cu_mask(mm, |
| 72 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); | 72 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask, inst); |
| 73 | 73 | ||
| 74 | m = get_mqd(mqd); | 74 | m = get_mqd(mqd); |
| 75 | |||
| 75 | m->compute_static_thread_mgmt_se0 = se_mask[0]; | 76 | m->compute_static_thread_mgmt_se0 = se_mask[0]; |
| 76 | m->compute_static_thread_mgmt_se1 = se_mask[1]; | 77 | m->compute_static_thread_mgmt_se1 = se_mask[1]; |
| 77 | m->compute_static_thread_mgmt_se2 = se_mask[2]; | 78 | m->compute_static_thread_mgmt_se2 = se_mask[2]; |
| 78 | m->compute_static_thread_mgmt_se3 = se_mask[3]; | 79 | m->compute_static_thread_mgmt_se3 = se_mask[3]; |
| 79 | m->compute_static_thread_mgmt_se4 = se_mask[4]; | 80 | if (KFD_GC_VERSION(mm->dev) != IP_VERSION(9, 4, 3)) { |
| 80 | m->compute_static_thread_mgmt_se5 = se_mask[5]; | 81 | m->compute_static_thread_mgmt_se4 = se_mask[4]; |
| 81 | m->compute_static_thread_mgmt_se6 = se_mask[6]; | 82 | m->compute_static_thread_mgmt_se5 = se_mask[5]; |
| 82 | m->compute_static_thread_mgmt_se7 = se_mask[7]; | 83 | m->compute_static_thread_mgmt_se6 = se_mask[6]; |
| 83 | 84 | m->compute_static_thread_mgmt_se7 = se_mask[7]; | |
| 84 | pr_debug("update cu mask to %#x %#x %#x %#x %#x %#x %#x %#x\n", | 85 | |
| 85 | m->compute_static_thread_mgmt_se0, | 86 | pr_debug("update cu mask to %#x %#x %#x %#x %#x %#x %#x %#x\n", |
| 86 | m->compute_static_thread_mgmt_se1, | 87 | m->compute_static_thread_mgmt_se0, |
| 87 | m->compute_static_thread_mgmt_se2, | 88 | m->compute_static_thread_mgmt_se1, |
| 88 | m->compute_static_thread_mgmt_se3, | 89 | m->compute_static_thread_mgmt_se2, |
| 89 | m->compute_static_thread_mgmt_se4, | 90 | m->compute_static_thread_mgmt_se3, |
| 90 | m->compute_static_thread_mgmt_se5, | 91 | m->compute_static_thread_mgmt_se4, |
| 91 | m->compute_static_thread_mgmt_se6, | 92 | m->compute_static_thread_mgmt_se5, |
| 92 | m->compute_static_thread_mgmt_se7); | 93 | m->compute_static_thread_mgmt_se6, |
| 94 | m->compute_static_thread_mgmt_se7); | ||
| 95 | } else { | ||
| 96 | pr_debug("inst: %u, update cu mask to %#x %#x %#x %#x\n", | ||
| 97 | inst, m->compute_static_thread_mgmt_se0, | ||
| 98 | m->compute_static_thread_mgmt_se1, | ||
| 99 | m->compute_static_thread_mgmt_se2, | ||
| 100 | m->compute_static_thread_mgmt_se3); | ||
| 101 | } | ||
| 93 | } | 102 | } |
| 94 | 103 | ||
| 95 | static void set_priority(struct v9_mqd *m, struct queue_properties *q) | 104 | static void set_priority(struct v9_mqd *m, struct queue_properties *q) |
| @@ -290,7 +299,8 @@ static void update_mqd(struct mqd_manager *mm, void *mqd, · 194 unmodified lines | |||
| 290 | if (mm->dev->kfd->cwsr_enabled && q->ctx_save_restore_area_address) | 299 | if (mm->dev->kfd->cwsr_enabled && q->ctx_save_restore_area_address) |
| 291 | m->cp_hqd_ctx_save_control = 0; | 300 | m->cp_hqd_ctx_save_control = 0; |
| 292 | 301 | ||
| 293 | update_cu_mask(mm, mqd, minfo); | 302 | if (KFD_GC_VERSION(mm->dev) != IP_VERSION(9, 4, 3)) |
| 303 | update_cu_mask(mm, mqd, minfo, 0); | ||
| 294 | set_priority(m, q); | 304 | set_priority(m, q); |
| 295 | 305 | ||
| 296 | q->is_active = QUEUE_IS_ACTIVE(*q); | 306 | q->is_active = QUEUE_IS_ACTIVE(*q); |
| @@ -676,6 +686,8 @@ static void update_mqd_v9_4_3(struct mqd_manager *mm, void *mqd, · 379 unmodified lines | |||
| 676 | m = get_mqd(mqd + size * xcc); | 686 | m = get_mqd(mqd + size * xcc); |
| 677 | update_mqd(mm, m, q, minfo); | 687 | update_mqd(mm, m, q, minfo); |
| 678 | 688 | ||
| 689 | update_cu_mask(mm, mqd, minfo, xcc); | ||
| 690 | |||
| 679 | if (q->format == KFD_QUEUE_FORMAT_AQL) { | 691 | if (q->format == KFD_QUEUE_FORMAT_AQL) { |
| 680 | switch (xcc) { | 692 | switch (xcc) { |
| 681 | case 0: | 693 | case 0: |
| @@ -55,7 +55,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, · 54 unmodified lines | |||
| 55 | return; | 55 | return; |
| 56 | 56 | ||
| 57 | mqd_symmetrically_map_cu_mask(mm, | 57 | mqd_symmetrically_map_cu_mask(mm, |
| 58 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); | 58 | minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask, 0); |
| 59 | 59 | ||
| 60 | m = get_mqd(mqd); | 60 | m = get_mqd(mqd); |
| 61 | m->compute_static_thread_mgmt_se0 = se_mask[0]; | 61 | m->compute_static_thread_mgmt_se0 = se_mask[0]; |
| @@ -299,8 +299,7 @@ static int pm_set_grace_period_v9(struct packet_manager *pm, · 298 unmodified lines | |||
| 299 | pm->dqm->wait_times, | 299 | pm->dqm->wait_times, |
| 300 | grace_period, | 300 | grace_period, |
| 301 | ®_offset, | 301 | ®_offset, |
| 302 | ®_data, | 302 | ®_data); |
| 303 | 0); | ||
| 304 | 303 | ||
| 305 | if (grace_period == USE_DEFAULT_GRACE_PERIOD) | 304 | if (grace_period == USE_DEFAULT_GRACE_PERIOD) |
| 306 | reg_data = pm->dqm->wait_times; | 305 | reg_data = pm->dqm->wait_times; |
| @@ -1466,8 +1466,7 @@ void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type); · 1465 unmodified lines | |||
| 1466 | 1466 | ||
| 1467 | static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) | 1467 | static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) |
| 1468 | { | 1468 | { |
| 1469 | return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 3) || | 1469 | return KFD_GC_VERSION(dev) > IP_VERSION(9, 4, 2) || |
| 1470 | KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) || | ||
| 1471 | (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) || | 1470 | (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) || |
| 1472 | KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0); | 1471 | KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0); |
| 1473 | } | 1472 | } |
| @@ -450,8 +450,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, · 449 unmodified lines | |||
| 450 | sysfs_show_32bit_prop(buffer, offs, "cpu_cores_count", | 450 | sysfs_show_32bit_prop(buffer, offs, "cpu_cores_count", |
| 451 | dev->node_props.cpu_cores_count); | 451 | dev->node_props.cpu_cores_count); |
| 452 | sysfs_show_32bit_prop(buffer, offs, "simd_count", | 452 | sysfs_show_32bit_prop(buffer, offs, "simd_count", |
| 453 | dev->gpu ? (dev->node_props.simd_count * | 453 | dev->gpu ? dev->node_props.simd_count : 0); |
| 454 | NUM_XCC(dev->gpu->xcc_mask)) : 0); | ||
| 455 | sysfs_show_32bit_prop(buffer, offs, "mem_banks_count", | 454 | sysfs_show_32bit_prop(buffer, offs, "mem_banks_count", |
| 456 | dev->node_props.mem_banks_count); | 455 | dev->node_props.mem_banks_count); |
| 457 | sysfs_show_32bit_prop(buffer, offs, "caches_count", | 456 | sysfs_show_32bit_prop(buffer, offs, "caches_count", |
| @@ -1597,14 +1596,17 @@ static int fill_in_l1_pcache(struct kfd_cache_properties **props_ext, · 1139 unmodified lines | |||
| 1597 | static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, | 1596 | static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, |
| 1598 | struct kfd_gpu_cache_info *pcache_info, | 1597 | struct kfd_gpu_cache_info *pcache_info, |
| 1599 | struct kfd_cu_info *cu_info, | 1598 | struct kfd_cu_info *cu_info, |
| 1600 | int cache_type, unsigned int cu_processor_id) | 1599 | int cache_type, unsigned int cu_processor_id, |
| 1600 | struct kfd_node *knode) | ||
| 1601 | { | 1601 | { |
| 1602 | unsigned int cu_sibling_map_mask; | 1602 | unsigned int cu_sibling_map_mask; |
| 1603 | int first_active_cu; | 1603 | int first_active_cu; |
| 1604 | int i, j, k; | 1604 | int i, j, k, xcc, start, end; |
| 1605 | struct kfd_cache_properties *pcache = NULL; | 1605 | struct kfd_cache_properties *pcache = NULL; |
| 1606 | 1606 | ||
| 1607 | cu_sibling_map_mask = cu_info->cu_bitmap[0][0]; | 1607 | start = ffs(knode->xcc_mask) - 1; |
| 1608 | end = start + NUM_XCC(knode->xcc_mask); | ||
| 1609 | cu_sibling_map_mask = cu_info->cu_bitmap[start][0][0]; | ||
| 1608 | cu_sibling_map_mask &= | 1610 | cu_sibling_map_mask &= |
| 1609 | ((1 << pcache_info[cache_type].num_cu_shared) - 1); | 1611 | ((1 << pcache_info[cache_type].num_cu_shared) - 1); |
| 1610 | first_active_cu = ffs(cu_sibling_map_mask); | 1612 | first_active_cu = ffs(cu_sibling_map_mask); |
| @@ -1639,16 +1641,18 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, · 28 unmodified lines | |||
| 1639 | cu_sibling_map_mask = cu_sibling_map_mask >> (first_active_cu - 1); | 1641 | cu_sibling_map_mask = cu_sibling_map_mask >> (first_active_cu - 1); |
| 1640 | k = 0; | 1642 | k = 0; |
| 1641 | 1643 | ||
| 1642 | for (i = 0; i < cu_info->num_shader_engines; i++) { | 1644 | for (xcc = start; xcc < end; xcc++) { |
| 1643 | for (j = 0; j < cu_info->num_shader_arrays_per_engine; j++) { | 1645 | for (i = 0; i < cu_info->num_shader_engines; i++) { |
| 1644 | pcache->sibling_map[k] = (uint8_t)(cu_sibling_map_mask & 0xFF); | 1646 | for (j = 0; j < cu_info->num_shader_arrays_per_engine; j++) { |
| 1645 | pcache->sibling_map[k+1] = (uint8_t)((cu_sibling_map_mask >> 8) & 0xFF); | 1647 | pcache->sibling_map[k] = (uint8_t)(cu_sibling_map_mask & 0xFF); |
| 1646 | pcache->sibling_map[k+2] = (uint8_t)((cu_sibling_map_mask >> 16) & 0xFF); | 1648 | pcache->sibling_map[k+1] = (uint8_t)((cu_sibling_map_mask >> 8) & 0xFF); |
| 1647 | pcache->sibling_map[k+3] = (uint8_t)((cu_sibling_map_mask >> 24) & 0xFF); | 1649 | pcache->sibling_map[k+2] = (uint8_t)((cu_sibling_map_mask >> 16) & 0xFF); |
| 1648 | k += 4; | 1650 | pcache->sibling_map[k+3] = (uint8_t)((cu_sibling_map_mask >> 24) & 0xFF); |
| 1649 | 1651 | k += 4; | |
| 1650 | cu_sibling_map_mask = cu_info->cu_bitmap[i % 4][j + i / 4]; | 1652 | |
| 1651 | cu_sibling_map_mask &= ((1 << pcache_info[cache_type].num_cu_shared) - 1); | 1653 | cu_sibling_map_mask = cu_info->cu_bitmap[xcc][i % 4][j + i / 4]; |
| 1654 | cu_sibling_map_mask &= ((1 << pcache_info[cache_type].num_cu_shared) - 1); | ||
| 1655 | } | ||
| 1652 | } | 1656 | } |
| 1653 | } | 1657 | } |
| 1654 | pcache->sibling_map_size = k; | 1658 | pcache->sibling_map_size = k; |
| @@ -1666,7 +1670,7 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext, · 11 unmodified lines | |||
| 1666 | static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct kfd_node *kdev) | 1670 | static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct kfd_node *kdev) |
| 1667 | { | 1671 | { |
| 1668 | struct kfd_gpu_cache_info *pcache_info = NULL; | 1672 | struct kfd_gpu_cache_info *pcache_info = NULL; |
| 1669 | int i, j, k; | 1673 | int i, j, k, xcc, start, end; |
| 1670 | int ct = 0; | 1674 | int ct = 0; |
| 1671 | unsigned int cu_processor_id; | 1675 | unsigned int cu_processor_id; |
| 1672 | int ret; | 1676 | int ret; |
| @@ -1700,37 +1704,42 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct · 27 unmodified lines | |||
| 1700 | * then it will consider only one CU from | 1704 | * then it will consider only one CU from |
| 1701 | * the shared unit | 1705 | * the shared unit |
| 1702 | */ | 1706 | */ |
| 1707 | start = ffs(kdev->xcc_mask) - 1; | ||
| 1708 | end = start + NUM_XCC(kdev->xcc_mask); | ||
| 1709 | |||
| 1703 | for (ct = 0; ct < num_of_cache_types; ct++) { | 1710 | for (ct = 0; ct < num_of_cache_types; ct++) { |
| 1704 | cu_processor_id = gpu_processor_id; | 1711 | cu_processor_id = gpu_processor_id; |
| 1705 | if (pcache_info[ct].cache_level == 1) { | 1712 | if (pcache_info[ct].cache_level == 1) { |
| 1706 | for (i = 0; i < pcu_info->num_shader_engines; i++) { | 1713 | for (xcc = start; xcc < end; xcc++) { |
| 1707 | for (j = 0; j < pcu_info->num_shader_arrays_per_engine; j++) { | 1714 | for (i = 0; i < pcu_info->num_shader_engines; i++) { |
| 1708 | for (k = 0; k < pcu_info->num_cu_per_sh; k += pcache_info[ct].num_cu_shared) { | 1715 | for (j = 0; j < pcu_info->num_shader_arrays_per_engine; j++) { |
| 1716 | for (k = 0; k < pcu_info->num_cu_per_sh; k += pcache_info[ct].num_cu_shared) { | ||
| 1709 | 1717 | ||
| 1710 | ret = fill_in_l1_pcache(&props_ext, pcache_info, pcu_info, | 1718 | ret = fill_in_l1_pcache(&props_ext, pcache_info, pcu_info, |
| 1711 | pcu_info->cu_bitmap[i % 4][j + i / 4], ct, | 1719 | pcu_info->cu_bitmap[xcc][i % 4][j + i / 4], ct, |
| 1712 | cu_processor_id, k); | 1720 | cu_processor_id, k); |
| 1713 | 1721 | ||
| 1714 | if (ret < 0) | 1722 | if (ret < 0) |
| 1715 | break; | 1723 | break; |
| 1716 | 1724 | ||
| 1717 | if (!ret) { | 1725 | if (!ret) { |
| 1718 | num_of_entries++; | 1726 | num_of_entries++; |
| 1719 | list_add_tail(&props_ext->list, &dev->cache_props); | 1727 | list_add_tail(&props_ext->list, &dev->cache_props); |
| 1720 | } | 1728 | } |
| 1721 | 1729 | ||
| 1722 | /* Move to next CU block */ | 1730 | /* Move to next CU block */ |
| 1723 | num_cu_shared = ((k + pcache_info[ct].num_cu_shared) <= | 1731 | num_cu_shared = ((k + pcache_info[ct].num_cu_shared) <= |
| 1724 | pcu_info->num_cu_per_sh) ? | 1732 | pcu_info->num_cu_per_sh) ? |
| 1725 | pcache_info[ct].num_cu_shared : | 1733 | pcache_info[ct].num_cu_shared : |
| 1726 | (pcu_info->num_cu_per_sh - k); | 1734 | (pcu_info->num_cu_per_sh - k); |
| 1727 | cu_processor_id += num_cu_shared; | 1735 | cu_processor_id += num_cu_shared; |
| 1736 | } | ||
| 1728 | } | 1737 | } |
| 1729 | } | 1738 | } |
| 1730 | } | 1739 | } |
| 1731 | } else { | 1740 | } else { |
| 1732 | ret = fill_in_l2_l3_pcache(&props_ext, pcache_info, | 1741 | ret = fill_in_l2_l3_pcache(&props_ext, pcache_info, |
| 1733 | pcu_info, ct, cu_processor_id); | 1742 | pcu_info, ct, cu_processor_id, kdev); |
| 1734 | 1743 | ||
| 1735 | if (ret < 0) | 1744 | if (ret < 0) |
| 1736 | break; | 1745 | break; |
| @@ -89,7 +89,7 @@ struct kfd_mem_properties { · 88 unmodified lines | |||
| 89 | struct attribute attr; | 89 | struct attribute attr; |
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | #define CACHE_SIBLINGMAP_SIZE 64 | 92 | #define CACHE_SIBLINGMAP_SIZE 128 |
| 93 | 93 | ||
| 94 | struct kfd_cache_properties { | 94 | struct kfd_cache_properties { |
| 95 | struct list_head list; | 95 | struct list_head list; |
| @@ -1274,11 +1274,15 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_ · 1273 unmodified lines | |||
| 1274 | 1274 | ||
| 1275 | pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); | 1275 | pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); |
| 1276 | 1276 | ||
| 1277 | page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; | 1277 | page_table_start.high_part = upper_32_bits(adev->gmc.gart_start >> |
| 1278 | page_table_start.low_part = (u32)(adev->gmc.gart_start >> 12); | 1278 | AMDGPU_GPU_PAGE_SHIFT); |
| 1279 | page_table_end.high_part = (u32)(adev->gmc.gart_end >> 44) & 0xF; | 1279 | page_table_start.low_part = lower_32_bits(adev->gmc.gart_start >> |
| 1280 | page_table_end.low_part = (u32)(adev->gmc.gart_end >> 12); | 1280 | AMDGPU_GPU_PAGE_SHIFT); |
| 1281 | page_table_base.high_part = upper_32_bits(pt_base) & 0xF; | 1281 | page_table_end.high_part = upper_32_bits(adev->gmc.gart_end >> |
| 1282 | AMDGPU_GPU_PAGE_SHIFT); | ||
| 1283 | page_table_end.low_part = lower_32_bits(adev->gmc.gart_end >> | ||
| 1284 | AMDGPU_GPU_PAGE_SHIFT); | ||
| 1285 | page_table_base.high_part = upper_32_bits(pt_base); | ||
| 1282 | page_table_base.low_part = lower_32_bits(pt_base); | 1286 | page_table_base.low_part = lower_32_bits(pt_base); |
| 1283 | 1287 | ||
| 1284 | pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; | 1288 | pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; |
| @@ -1640,8 +1644,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 355 unmodified lines | |||
| 1640 | } | 1644 | } |
| 1641 | break; | 1645 | break; |
| 1642 | } | 1646 | } |
| 1643 | if (init_data.flags.gpu_vm_support) | 1647 | if (init_data.flags.gpu_vm_support && |
| 1644 | init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); | 1648 | (amdgpu_sg_display == 0)) |
| 1649 | init_data.flags.gpu_vm_support = false; | ||
| 1645 | 1650 | ||
| 1646 | if (init_data.flags.gpu_vm_support) | 1651 | if (init_data.flags.gpu_vm_support) |
| 1647 | adev->mode_info.gpu_vm_support = true; | 1652 | adev->mode_info.gpu_vm_support = true; |
| @@ -2335,14 +2340,62 @@ static int dm_late_init(void *handle) · 687 unmodified lines | |||
| 2335 | return detect_mst_link_for_all_connectors(adev_to_drm(adev)); | 2340 | return detect_mst_link_for_all_connectors(adev_to_drm(adev)); |
| 2336 | } | 2341 | } |
| 2337 | 2342 | ||
| 2343 | static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr) | ||
| 2344 | { | ||
| 2345 | int ret; | ||
| 2346 | u8 guid[16]; | ||
| 2347 | u64 tmp64; | ||
| 2348 | |||
| 2349 | mutex_lock(&mgr->lock); | ||
| 2350 | if (!mgr->mst_primary) | ||
| 2351 | goto out_fail; | ||
| 2352 | |||
| 2353 | if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) { | ||
| 2354 | drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); | ||
| 2355 | goto out_fail; | ||
| 2356 | } | ||
| 2357 | |||
| 2358 | ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, | ||
| 2359 | DP_MST_EN | | ||
| 2360 | DP_UP_REQ_EN | | ||
| 2361 | DP_UPSTREAM_IS_SRC); | ||
| 2362 | if (ret < 0) { | ||
| 2363 | drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n"); | ||
| 2364 | goto out_fail; | ||
| 2365 | } | ||
| 2366 | |||
| 2367 | /* Some hubs forget their guids after they resume */ | ||
| 2368 | ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); | ||
| 2369 | if (ret != 16) { | ||
| 2370 | drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); | ||
| 2371 | goto out_fail; | ||
| 2372 | } | ||
| 2373 | |||
| 2374 | if (memchr_inv(guid, 0, 16) == NULL) { | ||
| 2375 | tmp64 = get_jiffies_64(); | ||
| 2376 | memcpy(&guid[0], &tmp64, sizeof(u64)); | ||
| 2377 | memcpy(&guid[8], &tmp64, sizeof(u64)); | ||
| 2378 | |||
| 2379 | ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16); | ||
| 2380 | |||
| 2381 | if (ret != 16) { | ||
| 2382 | drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n"); | ||
| 2383 | goto out_fail; | ||
| 2384 | } | ||
| 2385 | } | ||
| 2386 | |||
| 2387 | memcpy(mgr->mst_primary->guid, guid, 16); | ||
| 2388 | |||
| 2389 | out_fail: | ||
| 2390 | mutex_unlock(&mgr->lock); | ||
| 2391 | } | ||
| 2392 | |||
| 2338 | static void s3_handle_mst(struct drm_device *dev, bool suspend) | 2393 | static void s3_handle_mst(struct drm_device *dev, bool suspend) |
| 2339 | { | 2394 | { |
| 2340 | struct amdgpu_dm_connector *aconnector; | 2395 | struct amdgpu_dm_connector *aconnector; |
| 2341 | struct drm_connector *connector; | 2396 | struct drm_connector *connector; |
| 2342 | struct drm_connector_list_iter iter; | 2397 | struct drm_connector_list_iter iter; |
| 2343 | struct drm_dp_mst_topology_mgr *mgr; | 2398 | struct drm_dp_mst_topology_mgr *mgr; |
| 2344 | int ret; | ||
| 2345 | bool need_hotplug = false; | ||
| 2346 | 2399 | ||
| 2347 | drm_connector_list_iter_begin(dev, &iter); | 2400 | drm_connector_list_iter_begin(dev, &iter); |
| 2348 | drm_for_each_connector_iter(connector, &iter) { | 2401 | drm_for_each_connector_iter(connector, &iter) { |
| @@ -2364,18 +2417,15 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) · 15 unmodified lines | |||
| 2364 | if (!dp_is_lttpr_present(aconnector->dc_link)) | 2417 | if (!dp_is_lttpr_present(aconnector->dc_link)) |
| 2365 | try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); | 2418 | try_to_configure_aux_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); |
| 2366 | 2419 | ||
| 2367 | ret = drm_dp_mst_topology_mgr_resume(mgr, true); | 2420 | /* TODO: move resume_mst_branch_status() into drm mst resume again |
| 2368 | if (ret < 0) { | 2421 | * once topology probing work is pulled out from mst resume into mst |
| 2369 | dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, | 2422 | * resume 2nd step. mst resume 2nd step should be called after old |
| 2370 | aconnector->dc_link); | 2423 | * state getting restored (i.e. drm_atomic_helper_resume()). |
| 2371 | need_hotplug = true; | 2424 | */ |
| 2372 | } | 2425 | resume_mst_branch_status(mgr); |
| 2373 | } | 2426 | } |
| 2374 | } | 2427 | } |
| 2375 | drm_connector_list_iter_end(&iter); | 2428 | drm_connector_list_iter_end(&iter); |
| 2376 | |||
| 2377 | if (need_hotplug) | ||
| 2378 | drm_kms_helper_hotplug_event(dev); | ||
| 2379 | } | 2429 | } |
| 2380 | 2430 | ||
| 2381 | static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) | 2431 | static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) |
| @@ -2769,7 +2819,8 @@ static int dm_resume(void *handle) · 387 unmodified lines | |||
| 2769 | struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); | 2819 | struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); |
| 2770 | enum dc_connection_type new_connection_type = dc_connection_none; | 2820 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 2771 | struct dc_state *dc_state; | 2821 | struct dc_state *dc_state; |
| 2772 | int i, r, j; | 2822 | int i, r, j, ret; |
| 2823 | bool need_hotplug = false; | ||
| 2773 | 2824 | ||
| 2774 | if (amdgpu_in_reset(adev)) { | 2825 | if (amdgpu_in_reset(adev)) { |
| 2775 | dc_state = dm->cached_dc_state; | 2826 | dc_state = dm->cached_dc_state; |
| @@ -2867,7 +2918,7 @@ static int dm_resume(void *handle) · 91 unmodified lines | |||
| 2867 | continue; | 2918 | continue; |
| 2868 | 2919 | ||
| 2869 | /* | 2920 | /* |
| 2870 | * this is the case when traversing through already created | 2921 | * this is the case when traversing through already created end sink |
| 2871 | * MST connectors, should be skipped | 2922 | * MST connectors, should be skipped |
| 2872 | */ | 2923 | */ |
| 2873 | if (aconnector && aconnector->mst_root) | 2924 | if (aconnector && aconnector->mst_root) |
| @@ -2927,6 +2978,27 @@ static int dm_resume(void *handle) · 53 unmodified lines | |||
| 2927 | 2978 | ||
| 2928 | dm->cached_state = NULL; | 2979 | dm->cached_state = NULL; |
| 2929 | 2980 | ||
| 2981 | /* Do mst topology probing after resuming cached state*/ | ||
| 2982 | drm_connector_list_iter_begin(ddev, &iter); | ||
| 2983 | drm_for_each_connector_iter(connector, &iter) { | ||
| 2984 | aconnector = to_amdgpu_dm_connector(connector); | ||
| 2985 | if (aconnector->dc_link->type != dc_connection_mst_branch || | ||
| 2986 | aconnector->mst_root) | ||
| 2987 | continue; | ||
| 2988 | |||
| 2989 | ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true); | ||
| 2990 | |||
| 2991 | if (ret < 0) { | ||
| 2992 | dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, | ||
| 2993 | aconnector->dc_link); | ||
| 2994 | need_hotplug = true; | ||
| 2995 | } | ||
| 2996 | } | ||
| 2997 | drm_connector_list_iter_end(&iter); | ||
| 2998 | |||
| 2999 | if (need_hotplug) | ||
| 3000 | drm_kms_helper_hotplug_event(ddev); | ||
| 3001 | |||
| 2930 | amdgpu_dm_irq_resume_late(adev); | 3002 | amdgpu_dm_irq_resume_late(adev); |
| 2931 | 3003 | ||
| 2932 | amdgpu_dm_smu_write_watermarks_table(adev); | 3004 | amdgpu_dm_smu_write_watermarks_table(adev); |
| @@ -6026,8 +6098,6 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 3093 unmodified lines | |||
| 6026 | 6098 | ||
| 6027 | if (recalculate_timing) | 6099 | if (recalculate_timing) |
| 6028 | drm_mode_set_crtcinfo(&saved_mode, 0); | 6100 | drm_mode_set_crtcinfo(&saved_mode, 0); |
| 6029 | else if (!old_stream) | ||
| 6030 | drm_mode_set_crtcinfo(&mode, 0); | ||
| 6031 | 6101 | ||
| 6032 | /* | 6102 | /* |
| 6033 | * If scaling is enabled and refresh rate didn't change | 6103 | * If scaling is enabled and refresh rate didn't change |
| @@ -6589,6 +6659,8 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec · 555 unmodified lines | |||
| 6589 | goto fail; | 6659 | goto fail; |
| 6590 | } | 6660 | } |
| 6591 | 6661 | ||
| 6662 | drm_mode_set_crtcinfo(mode, 0); | ||
| 6663 | |||
| 6592 | stream = create_validate_stream_for_sink(aconnector, mode, | 6664 | stream = create_validate_stream_for_sink(aconnector, mode, |
| 6593 | to_dm_connector_state(connector->state), | 6665 | to_dm_connector_state(connector->state), |
| 6594 | NULL); | 6666 | NULL); |
| @@ -8073,7 +8145,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1478 unmodified lines | |||
| 8073 | bundle->surface_updates[planes_count].plane_info = | 8145 | bundle->surface_updates[planes_count].plane_info = |
| 8074 | &bundle->plane_infos[planes_count]; | 8146 | &bundle->plane_infos[planes_count]; |
| 8075 | 8147 | ||
| 8076 | if (acrtc_state->stream->link->psr_settings.psr_feature_enabled) { | 8148 | if (acrtc_state->stream->link->psr_settings.psr_feature_enabled || |
| 8149 | acrtc_state->stream->link->replay_settings.replay_feature_enabled) { | ||
| 8077 | fill_dc_dirty_rects(plane, old_plane_state, | 8150 | fill_dc_dirty_rects(plane, old_plane_state, |
| 8078 | new_plane_state, new_crtc_state, | 8151 | new_plane_state, new_crtc_state, |
| 8079 | &bundle->flip_addrs[planes_count], | 8152 | &bundle->flip_addrs[planes_count], |
| @@ -620,7 +620,7 @@ struct amdgpu_hdmi_vsdb_info { · 619 unmodified lines | |||
| 620 | unsigned int max_refresh_rate_hz; | 620 | unsigned int max_refresh_rate_hz; |
| 621 | 621 | ||
| 622 | /** | 622 | /** |
| 623 | * @replay mode: Replay supported | 623 | * @replay_mode: Replay supported |
| 624 | */ | 624 | */ |
| 625 | bool replay_mode; | 625 | bool replay_mode; |
| 626 | }; | 626 | }; |
| @@ -169,11 +169,23 @@ static void add_link_enc_assignment( · 168 unmodified lines | |||
| 169 | /* Return first available DIG link encoder. */ | 169 | /* Return first available DIG link encoder. */ |
| 170 | static enum engine_id find_first_avail_link_enc( | 170 | static enum engine_id find_first_avail_link_enc( |
| 171 | const struct dc_context *ctx, | 171 | const struct dc_context *ctx, |
| 172 | const struct dc_state *state) | 172 | const struct dc_state *state, |
| 173 | enum engine_id eng_id_requested) | ||
| 173 | { | 174 | { |
| 174 | enum engine_id eng_id = ENGINE_ID_UNKNOWN; | 175 | enum engine_id eng_id = ENGINE_ID_UNKNOWN; |
| 175 | int i; | 176 | int i; |
| 176 | 177 | ||
| 178 | if (eng_id_requested != ENGINE_ID_UNKNOWN) { | ||
| 179 | |||
| 180 | for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { | ||
| 181 | eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i]; | ||
| 182 | if (eng_id == eng_id_requested) | ||
| 183 | return eng_id; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | eng_id = ENGINE_ID_UNKNOWN; | ||
| 188 | |||
| 177 | for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { | 189 | for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { |
| 178 | eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i]; | 190 | eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i]; |
| 179 | if (eng_id != ENGINE_ID_UNKNOWN) | 191 | if (eng_id != ENGINE_ID_UNKNOWN) |
| @@ -287,7 +299,7 @@ void link_enc_cfg_link_encs_assign( · 107 unmodified lines | |||
| 287 | struct dc_stream_state *streams[], | 299 | struct dc_stream_state *streams[], |
| 288 | uint8_t stream_count) | 300 | uint8_t stream_count) |
| 289 | { | 301 | { |
| 290 | enum engine_id eng_id = ENGINE_ID_UNKNOWN; | 302 | enum engine_id eng_id = ENGINE_ID_UNKNOWN, eng_id_req = ENGINE_ID_UNKNOWN; |
| 291 | int i; | 303 | int i; |
| 292 | int j; | 304 | int j; |
| 293 | 305 | ||
| @@ -377,8 +389,14 @@ void link_enc_cfg_link_encs_assign( · 83 unmodified lines | |||
| 377 | * assigned to that endpoint. | 389 | * assigned to that endpoint. |
| 378 | */ | 390 | */ |
| 379 | link_enc = get_link_enc_used_by_link(state, stream->link); | 391 | link_enc = get_link_enc_used_by_link(state, stream->link); |
| 380 | if (link_enc == NULL) | 392 | if (link_enc == NULL) { |
| 381 | eng_id = find_first_avail_link_enc(stream->ctx, state); | 393 | |
| 394 | if (stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && | ||
| 395 | stream->link->dpia_preferred_eng_id != ENGINE_ID_UNKNOWN) | ||
| 396 | eng_id_req = stream->link->dpia_preferred_eng_id; | ||
| 397 | |||
| 398 | eng_id = find_first_avail_link_enc(stream->ctx, state, eng_id_req); | ||
| 399 | } | ||
| 382 | else | 400 | else |
| 383 | eng_id = link_enc->preferred_engine; | 401 | eng_id = link_enc->preferred_engine; |
| 384 | 402 | ||
| @@ -402,7 +420,9 @@ void link_enc_cfg_link_encs_assign( · 17 unmodified lines | |||
| 402 | DC_LOG_DEBUG("%s: CUR %s(%d) - enc_id(%d)\n", | 420 | DC_LOG_DEBUG("%s: CUR %s(%d) - enc_id(%d)\n", |
| 403 | __func__, | 421 | __func__, |
| 404 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? "PHY" : "DPIA", | 422 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? "PHY" : "DPIA", |
| 405 | assignment.ep_id.link_id.enum_id - 1, | 423 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? |
| 424 | assignment.ep_id.link_id.enum_id : | ||
| 425 | assignment.ep_id.link_id.enum_id - 1, | ||
| 406 | assignment.eng_id); | 426 | assignment.eng_id); |
| 407 | } | 427 | } |
| 408 | for (i = 0; i < MAX_PIPES; i++) { | 428 | for (i = 0; i < MAX_PIPES; i++) { |
| @@ -413,7 +433,9 @@ void link_enc_cfg_link_encs_assign( · 4 unmodified lines | |||
| 413 | DC_LOG_DEBUG("%s: NEW %s(%d) - enc_id(%d)\n", | 433 | DC_LOG_DEBUG("%s: NEW %s(%d) - enc_id(%d)\n", |
| 414 | __func__, | 434 | __func__, |
| 415 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? "PHY" : "DPIA", | 435 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? "PHY" : "DPIA", |
| 416 | assignment.ep_id.link_id.enum_id - 1, | 436 | assignment.ep_id.ep_type == DISPLAY_ENDPOINT_PHY ? |
| 437 | assignment.ep_id.link_id.enum_id : | ||
| 438 | assignment.ep_id.link_id.enum_id - 1, | ||
| 417 | assignment.eng_id); | 439 | assignment.eng_id); |
| 418 | } | 440 | } |
| 419 | 441 | ||
| @@ -478,7 +500,6 @@ struct dc_link *link_enc_cfg_get_link_using_link_enc( · 58 unmodified lines | |||
| 478 | if (stream) | 500 | if (stream) |
| 479 | link = stream->link; | 501 | link = stream->link; |
| 480 | 502 | ||
| 481 | // dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id); | ||
| 482 | return link; | 503 | return link; |
| 483 | } | 504 | } |
| 484 | 505 | ||
| @@ -1496,6 +1496,7 @@ struct dc_link { · 1495 unmodified lines | |||
| 1496 | * object creation. | 1496 | * object creation. |
| 1497 | */ | 1497 | */ |
| 1498 | enum engine_id eng_id; | 1498 | enum engine_id eng_id; |
| 1499 | enum engine_id dpia_preferred_eng_id; | ||
| 1499 | 1500 | ||
| 1500 | bool test_pattern_enabled; | 1501 | bool test_pattern_enabled; |
| 1501 | enum dp_test_pattern current_test_pattern; | 1502 | enum dp_test_pattern current_test_pattern; |
| @@ -964,7 +964,9 @@ void dce110_edp_backlight_control( · 963 unmodified lines | |||
| 964 | return; | 964 | return; |
| 965 | } | 965 | } |
| 966 | 966 | ||
| 967 | if (link->panel_cntl) { | 967 | if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || |
| 968 | link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || | ||
| 969 | link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { | ||
| 968 | bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); | 970 | bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); |
| 969 | 971 | ||
| 970 | if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { | 972 | if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { |
| @@ -1176,12 +1178,15 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) · 205 unmodified lines | |||
| 1176 | dto_params.otg_inst = tg->inst; | 1178 | dto_params.otg_inst = tg->inst; |
| 1177 | dto_params.timing = &pipe_ctx->stream->timing; | 1179 | dto_params.timing = &pipe_ctx->stream->timing; |
| 1178 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | 1180 | dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; |
| 1179 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | 1181 | if (dccg) { |
| 1180 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); | 1182 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); |
| 1181 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); | 1183 | dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); |
| 1182 | } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->disable_symclk_se) | 1184 | dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); |
| 1185 | } | ||
| 1186 | } else if (dccg && dccg->funcs->disable_symclk_se) { | ||
| 1183 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, | 1187 | dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, |
| 1184 | link_enc->transmitter - TRANSMITTER_UNIPHY_A); | 1188 | link_enc->transmitter - TRANSMITTER_UNIPHY_A); |
| 1189 | } | ||
| 1185 | 1190 | ||
| 1186 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { | 1191 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { |
| 1187 | /* TODO: This looks like a bug to me as we are disabling HPO IO when | 1192 | /* TODO: This looks like a bug to me as we are disabling HPO IO when |
| @@ -2656,11 +2661,11 @@ void dce110_prepare_bandwidth( · 1468 unmodified lines | |||
| 2656 | struct clk_mgr *dccg = dc->clk_mgr; | 2661 | struct clk_mgr *dccg = dc->clk_mgr; |
| 2657 | 2662 | ||
| 2658 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); | 2663 | dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); |
| 2659 | 2664 | if (dccg) | |
| 2660 | dccg->funcs->update_clocks( | 2665 | dccg->funcs->update_clocks( |
| 2661 | dccg, | 2666 | dccg, |
| 2662 | context, | 2667 | context, |
| 2663 | false); | 2668 | false); |
| 2664 | } | 2669 | } |
| 2665 | 2670 | ||
| 2666 | void dce110_optimize_bandwidth( | 2671 | void dce110_optimize_bandwidth( |
| @@ -2671,10 +2676,11 @@ void dce110_optimize_bandwidth( · 4 unmodified lines | |||
| 2671 | 2676 | ||
| 2672 | dce110_set_displaymarks(dc, context); | 2677 | dce110_set_displaymarks(dc, context); |
| 2673 | 2678 | ||
| 2674 | dccg->funcs->update_clocks( | 2679 | if (dccg) |
| 2675 | dccg, | 2680 | dccg->funcs->update_clocks( |
| 2676 | context, | 2681 | dccg, |
| 2677 | true); | 2682 | context, |
| 2683 | true); | ||
| 2678 | } | 2684 | } |
| 2679 | 2685 | ||
| 2680 | static void dce110_program_front_end_for_pipe( | 2686 | static void dce110_program_front_end_for_pipe( |
| @@ -2692,8 +2692,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 2691 unmodified lines | |||
| 2692 | struct dce_hwseq *hws = dc->hwseq; | 2692 | struct dce_hwseq *hws = dc->hwseq; |
| 2693 | unsigned int k1_div = PIXEL_RATE_DIV_NA; | 2693 | unsigned int k1_div = PIXEL_RATE_DIV_NA; |
| 2694 | unsigned int k2_div = PIXEL_RATE_DIV_NA; | 2694 | unsigned int k2_div = PIXEL_RATE_DIV_NA; |
| 2695 | struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link); | ||
| 2696 | struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; | ||
| 2697 | 2695 | ||
| 2698 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { | 2696 | if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { |
| 2699 | if (dc->hwseq->funcs.setup_hpo_hw_control) | 2697 | if (dc->hwseq->funcs.setup_hpo_hw_control) |
| @@ -2713,10 +2711,8 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) · 13 unmodified lines | |||
| 2713 | dto_params.timing = &pipe_ctx->stream->timing; | 2711 | dto_params.timing = &pipe_ctx->stream->timing; |
| 2714 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); | 2712 | dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); |
| 2715 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); | 2713 | dccg->funcs->set_dtbclk_dto(dccg, &dto_params); |
| 2716 | } else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST && dccg->funcs->enable_symclk_se) | 2714 | } else { |
| 2717 | dccg->funcs->enable_symclk_se(dccg, | 2715 | } |
| 2718 | stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A); | ||
| 2719 | |||
| 2720 | if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) { | 2716 | if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) { |
| 2721 | hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div); | 2717 | hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div); |
| 2722 | 2718 | ||
| @@ -1032,6 +1032,28 @@ static const struct dce_i2c_mask i2c_masks = { · 1031 unmodified lines | |||
| 1032 | I2C_COMMON_MASK_SH_LIST_DCN30(_MASK) | 1032 | I2C_COMMON_MASK_SH_LIST_DCN30(_MASK) |
| 1033 | }; | 1033 | }; |
| 1034 | 1034 | ||
| 1035 | /* ========================================================== */ | ||
| 1036 | |||
| 1037 | /* | ||
| 1038 | * DPIA index | Preferred Encoder | Host Router | ||
| 1039 | * 0 | C | 0 | ||
| 1040 | * 1 | First Available | 0 | ||
| 1041 | * 2 | D | 1 | ||
| 1042 | * 3 | First Available | 1 | ||
| 1043 | */ | ||
| 1044 | /* ========================================================== */ | ||
| 1045 | static const enum engine_id dpia_to_preferred_enc_id_table[] = { | ||
| 1046 | ENGINE_ID_DIGC, | ||
| 1047 | ENGINE_ID_DIGC, | ||
| 1048 | ENGINE_ID_DIGD, | ||
| 1049 | ENGINE_ID_DIGD | ||
| 1050 | }; | ||
| 1051 | |||
| 1052 | static enum engine_id dcn314_get_preferred_eng_id_dpia(unsigned int dpia_index) | ||
| 1053 | { | ||
| 1054 | return dpia_to_preferred_enc_id_table[dpia_index]; | ||
| 1055 | } | ||
| 1056 | |||
| 1035 | static struct dce_i2c_hw *dcn31_i2c_hw_create( | 1057 | static struct dce_i2c_hw *dcn31_i2c_hw_create( |
| 1036 | struct dc_context *ctx, | 1058 | struct dc_context *ctx, |
| 1037 | uint32_t inst) | 1059 | uint32_t inst) |
| @@ -1785,6 +1807,7 @@ static struct resource_funcs dcn314_res_pool_funcs = { · 747 unmodified lines | |||
| 1785 | .update_bw_bounding_box = dcn314_update_bw_bounding_box, | 1807 | .update_bw_bounding_box = dcn314_update_bw_bounding_box, |
| 1786 | .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, | 1808 | .patch_unknown_plane_state = dcn20_patch_unknown_plane_state, |
| 1787 | .get_panel_config_defaults = dcn314_get_panel_config_defaults, | 1809 | .get_panel_config_defaults = dcn314_get_panel_config_defaults, |
| 1810 | .get_preferred_eng_id_dpia = dcn314_get_preferred_eng_id_dpia, | ||
| 1788 | }; | 1811 | }; |
| 1789 | 1812 | ||
| 1790 | static struct clock_source *dcn30_clock_source_create( | 1813 | static struct clock_source *dcn30_clock_source_create( |
| @@ -75,7 +75,7 @@ void mpc32_power_on_blnd_lut( · 74 unmodified lines | |||
| 75 | if (power_on) { | 75 | if (power_on) { |
| 76 | REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0); | 76 | REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0); |
| 77 | REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5); | 77 | REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5); |
| 78 | } else { | 78 | } else if (!mpc->ctx->dc->debug.disable_mem_low_power) { |
| 79 | ASSERT(false); | 79 | ASSERT(false); |
| 80 | /* TODO: change to mpc | 80 | /* TODO: change to mpc |
| 81 | * dpp_base->ctx->dc->optimized_required = true; | 81 | * dpp_base->ctx->dc->optimized_required = true; |
| @@ -65,6 +65,7 @@ struct resource_context; · 64 unmodified lines | |||
| 65 | struct clk_bw_params; | 65 | struct clk_bw_params; |
| 66 | 66 | ||
| 67 | struct resource_funcs { | 67 | struct resource_funcs { |
| 68 | enum engine_id (*get_preferred_eng_id_dpia)(unsigned int dpia_index); | ||
| 68 | void (*destroy)(struct resource_pool **pool); | 69 | void (*destroy)(struct resource_pool **pool); |
| 69 | void (*link_init)(struct dc_link *link); | 70 | void (*link_init)(struct dc_link *link); |
| 70 | struct panel_cntl*(*panel_cntl_create)( | 71 | struct panel_cntl*(*panel_cntl_create)( |
| @@ -791,6 +791,10 @@ static bool construct_dpia(struct dc_link *link, · 790 unmodified lines | |||
| 791 | /* Set dpia port index : 0 to number of dpia ports */ | 791 | /* Set dpia port index : 0 to number of dpia ports */ |
| 792 | link->ddc_hw_inst = init_params->connector_index; | 792 | link->ddc_hw_inst = init_params->connector_index; |
| 793 | 793 | ||
| 794 | // Assign Dpia preferred eng_id | ||
| 795 | if (link->dc->res_pool->funcs->get_preferred_eng_id_dpia) | ||
| 796 | link->dpia_preferred_eng_id = link->dc->res_pool->funcs->get_preferred_eng_id_dpia(link->ddc_hw_inst); | ||
| 797 | |||
| 794 | /* TODO: Create link encoder */ | 798 | /* TODO: Create link encoder */ |
| 795 | 799 | ||
| 796 | link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; | 800 | link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; |
| @@ -31,12 +31,12 @@ · 30 unmodified lines | |||
| 31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 32 | #include <linux/bitmap.h> | 32 | #include <linux/bitmap.h> |
| 33 | #include <linux/dma-fence.h> | 33 | #include <linux/dma-fence.h> |
| 34 | #include "amdgpu_irq.h" | ||
| 35 | #include "amdgpu_gfx.h" | ||
| 34 | 36 | ||
| 35 | struct pci_dev; | 37 | struct pci_dev; |
| 36 | struct amdgpu_device; | 38 | struct amdgpu_device; |
| 37 | 39 | ||
| 38 | #define KGD_MAX_QUEUES 128 | ||
| 39 | |||
| 40 | struct kfd_dev; | 40 | struct kfd_dev; |
| 41 | struct kgd_mem; | 41 | struct kgd_mem; |
| 42 | 42 | ||
| @@ -68,7 +68,7 @@ struct kfd_cu_info { · 25 unmodified lines | |||
| 68 | uint32_t wave_front_size; | 68 | uint32_t wave_front_size; |
| 69 | uint32_t max_scratch_slots_per_cu; | 69 | uint32_t max_scratch_slots_per_cu; |
| 70 | uint32_t lds_size; | 70 | uint32_t lds_size; |
| 71 | uint32_t cu_bitmap[4][4]; | 71 | uint32_t cu_bitmap[AMDGPU_MAX_GC_INSTANCES][4][4]; |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | /* For getting GPU local memory information from KGD */ | 74 | /* For getting GPU local memory information from KGD */ |
| @@ -326,8 +326,7 @@ struct kfd2kgd_calls { · 251 unmodified lines | |||
| 326 | uint32_t wait_times, | 326 | uint32_t wait_times, |
| 327 | uint32_t grace_period, | 327 | uint32_t grace_period, |
| 328 | uint32_t *reg_offset, | 328 | uint32_t *reg_offset, |
| 329 | uint32_t *reg_data, | 329 | uint32_t *reg_data); |
| 330 | uint32_t inst); | ||
| 331 | void (*get_cu_occupancy)(struct amdgpu_device *adev, int pasid, | 330 | void (*get_cu_occupancy)(struct amdgpu_device *adev, int pasid, |
| 332 | int *wave_cnt, int *max_waves_per_cu, uint32_t inst); | 331 | int *wave_cnt, int *max_waves_per_cu, uint32_t inst); |
| 333 | void (*program_trap_handler_settings)(struct amdgpu_device *adev, | 332 | void (*program_trap_handler_settings)(struct amdgpu_device *adev, |
| @@ -336,7 +336,7 @@ static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu) · 335 unmodified lines | |||
| 336 | 336 | ||
| 337 | /* Store one-time values in driver PPTable */ | 337 | /* Store one-time values in driver PPTable */ |
| 338 | if (!pptable->Init) { | 338 | if (!pptable->Init) { |
| 339 | while (retry--) { | 339 | while (--retry) { |
| 340 | ret = smu_v13_0_6_get_metrics_table(smu, NULL, true); | 340 | ret = smu_v13_0_6_get_metrics_table(smu, NULL, true); |
| 341 | if (ret) | 341 | if (ret) |
| 342 | return ret; | 342 | return ret; |
| @@ -2203,6 +2203,7 @@ static int drm_mode_create_colorspace_property(struct drm_connector *connector, · 2202 unmodified lines | |||
| 2203 | /** | 2203 | /** |
| 2204 | * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property | 2204 | * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property |
| 2205 | * @connector: connector to create the Colorspace property on. | 2205 | * @connector: connector to create the Colorspace property on. |
| 2206 | * @supported_colorspaces: bitmap of supported color spaces | ||
| 2206 | * | 2207 | * |
| 2207 | * Called by a driver the first time it's needed, must be attached to desired | 2208 | * Called by a driver the first time it's needed, must be attached to desired |
| 2208 | * HDMI connectors. | 2209 | * HDMI connectors. |
| @@ -2227,6 +2228,7 @@ EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); · 18 unmodified lines | |||
| 2227 | /** | 2228 | /** |
| 2228 | * drm_mode_create_dp_colorspace_property - create dp colorspace property | 2229 | * drm_mode_create_dp_colorspace_property - create dp colorspace property |
| 2229 | * @connector: connector to create the Colorspace property on. | 2230 | * @connector: connector to create the Colorspace property on. |
| 2231 | * @supported_colorspaces: bitmap of supported color spaces | ||
| 2230 | * | 2232 | * |
| 2231 | * Called by a driver the first time it's needed, must be attached to desired | 2233 | * Called by a driver the first time it's needed, must be attached to desired |
| 2232 | * DP connectors. | 2234 | * DP connectors. |
| @@ -56,7 +56,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec) · 55 unmodified lines | |||
| 56 | struct drm_gem_object *obj; | 56 | struct drm_gem_object *obj; |
| 57 | unsigned long index; | 57 | unsigned long index; |
| 58 | 58 | ||
| 59 | drm_exec_for_each_locked_object(exec, index, obj) { | 59 | drm_exec_for_each_locked_object_reverse(exec, index, obj) { |
| 60 | dma_resv_unlock(obj->resv); | 60 | dma_resv_unlock(obj->resv); |
| 61 | drm_gem_object_put(obj); | 61 | drm_gem_object_put(obj); |
| 62 | } | 62 | } |
| @@ -3540,6 +3540,27 @@ enum aux_ch intel_bios_dp_aux_ch(const struct intel_bios_encoder_data *devdata) · 3539 unmodified lines | |||
| 3540 | return map_aux_ch(devdata->i915, devdata->child.aux_channel); | 3540 | return map_aux_ch(devdata->i915, devdata->child.aux_channel); |
| 3541 | } | 3541 | } |
| 3542 | 3542 | ||
| 3543 | bool intel_bios_dp_has_shared_aux_ch(const struct intel_bios_encoder_data *devdata) | ||
| 3544 | { | ||
| 3545 | struct drm_i915_private *i915; | ||
| 3546 | u8 aux_channel; | ||
| 3547 | int count = 0; | ||
| 3548 | |||
| 3549 | if (!devdata || !devdata->child.aux_channel) | ||
| 3550 | return false; | ||
| 3551 | |||
| 3552 | i915 = devdata->i915; | ||
| 3553 | aux_channel = devdata->child.aux_channel; | ||
| 3554 | |||
| 3555 | list_for_each_entry(devdata, &i915->display.vbt.display_devices, node) { | ||
| 3556 | if (intel_bios_encoder_supports_dp(devdata) && | ||
| 3557 | aux_channel == devdata->child.aux_channel) | ||
| 3558 | count++; | ||
| 3559 | } | ||
| 3560 | |||
| 3561 | return count > 1; | ||
| 3562 | } | ||
| 3563 | |||
| 3543 | int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata) | 3564 | int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata) |
| 3544 | { | 3565 | { |
| 3545 | if (!devdata || devdata->i915->display.vbt.version < 196 || !devdata->child.iboost) | 3566 | if (!devdata || devdata->i915->display.vbt.version < 196 || !devdata->child.iboost) |
| @@ -273,6 +273,7 @@ enum aux_ch intel_bios_dp_aux_ch(const struct intel_bios_encoder_data *devdata); · 272 unmodified lines | |||
| 273 | int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata); | 273 | int intel_bios_dp_boost_level(const struct intel_bios_encoder_data *devdata); |
| 274 | int intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata); | 274 | int intel_bios_dp_max_lane_count(const struct intel_bios_encoder_data *devdata); |
| 275 | int intel_bios_dp_max_link_rate(const struct intel_bios_encoder_data *devdata); | 275 | int intel_bios_dp_max_link_rate(const struct intel_bios_encoder_data *devdata); |
| 276 | bool intel_bios_dp_has_shared_aux_ch(const struct intel_bios_encoder_data *devdata); | ||
| 276 | int intel_bios_hdmi_boost_level(const struct intel_bios_encoder_data *devdata); | 277 | int intel_bios_hdmi_boost_level(const struct intel_bios_encoder_data *devdata); |
| 277 | int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata); | 278 | int intel_bios_hdmi_ddc_pin(const struct intel_bios_encoder_data *devdata); |
| 278 | int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata); | 279 | int intel_bios_hdmi_level_shift(const struct intel_bios_encoder_data *devdata); |
| @@ -5512,8 +5512,13 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, · 5511 unmodified lines | |||
| 5512 | /* | 5512 | /* |
| 5513 | * VBT and straps are liars. Also check HPD as that seems | 5513 | * VBT and straps are liars. Also check HPD as that seems |
| 5514 | * to be the most reliable piece of information available. | 5514 | * to be the most reliable piece of information available. |
| 5515 | * | ||
| 5516 | * ... expect on devices that forgot to hook HPD up for eDP | ||
| 5517 | * (eg. Acer Chromebook C710), so we'll check it only if multiple | ||
| 5518 | * ports are attempting to use the same AUX CH, according to VBT. | ||
| 5515 | */ | 5519 | */ |
| 5516 | if (!intel_digital_port_connected(encoder)) { | 5520 | if (intel_bios_dp_has_shared_aux_ch(encoder->devdata) && |
| 5521 | !intel_digital_port_connected(encoder)) { | ||
| 5517 | /* | 5522 | /* |
| 5518 | * If this fails, presume the DPCD answer came | 5523 | * If this fails, presume the DPCD answer came |
| 5519 | * from some other port using the same AUX CH. | 5524 | * from some other port using the same AUX CH. |
| @@ -100,6 +100,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 99 unmodified lines | |||
| 100 | st->nents = 0; | 100 | st->nents = 0; |
| 101 | for (i = 0; i < page_count; i++) { | 101 | for (i = 0; i < page_count; i++) { |
| 102 | struct folio *folio; | 102 | struct folio *folio; |
| 103 | unsigned long nr_pages; | ||
| 103 | const unsigned int shrink[] = { | 104 | const unsigned int shrink[] = { |
| 104 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND, | 105 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND, |
| 105 | 0, | 106 | 0, |
| @@ -150,6 +151,8 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 44 unmodified lines | |||
| 150 | } | 151 | } |
| 151 | } while (1); | 152 | } while (1); |
| 152 | 153 | ||
| 154 | nr_pages = min_t(unsigned long, | ||
| 155 | folio_nr_pages(folio), page_count - i); | ||
| 153 | if (!i || | 156 | if (!i || |
| 154 | sg->length >= max_segment || | 157 | sg->length >= max_segment || |
| 155 | folio_pfn(folio) != next_pfn) { | 158 | folio_pfn(folio) != next_pfn) { |
| @@ -157,13 +160,13 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, · 1 unmodified line | |||
| 157 | sg = sg_next(sg); | 160 | sg = sg_next(sg); |
| 158 | 161 | ||
| 159 | st->nents++; | 162 | st->nents++; |
| 160 | sg_set_folio(sg, folio, folio_size(folio), 0); | 163 | sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0); |
| 161 | } else { | 164 | } else { |
| 162 | /* XXX: could overflow? */ | 165 | /* XXX: could overflow? */ |
| 163 | sg->length += folio_size(folio); | 166 | sg->length += nr_pages * PAGE_SIZE; |
| 164 | } | 167 | } |
| 165 | next_pfn = folio_pfn(folio) + folio_nr_pages(folio); | 168 | next_pfn = folio_pfn(folio) + nr_pages; |
| 166 | i += folio_nr_pages(folio) - 1; | 169 | i += nr_pages - 1; |
| 167 | 170 | ||
| 168 | /* Check that the i965g/gm workaround works. */ | 171 | /* Check that the i965g/gm workaround works. */ |
| 169 | GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL); | 172 | GEM_BUG_ON(gfp & __GFP_DMA32 && next_pfn >= 0x00100000UL); |
| @@ -558,7 +558,6 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, · 557 unmodified lines | |||
| 558 | DRIVER_CAPS(i915)->has_logical_contexts = true; | 558 | DRIVER_CAPS(i915)->has_logical_contexts = true; |
| 559 | 559 | ||
| 560 | ewma__engine_latency_init(&engine->latency); | 560 | ewma__engine_latency_init(&engine->latency); |
| 561 | seqcount_init(&engine->stats.execlists.lock); | ||
| 562 | 561 | ||
| 563 | ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); | 562 | ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); |
| 564 | 563 | ||
| @@ -3550,6 +3550,8 @@ int intel_execlists_submission_setup(struct intel_engine_cs *engine) · 3549 unmodified lines | |||
| 3550 | logical_ring_default_vfuncs(engine); | 3550 | logical_ring_default_vfuncs(engine); |
| 3551 | logical_ring_default_irqs(engine); | 3551 | logical_ring_default_irqs(engine); |
| 3552 | 3552 | ||
| 3553 | seqcount_init(&engine->stats.execlists.lock); | ||
| 3554 | |||
| 3553 | if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) | 3555 | if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) |
| 3554 | rcs_submission_override(engine); | 3556 | rcs_submission_override(engine); |
| 3555 | 3557 | ||
| @@ -511,20 +511,31 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm, · 510 unmodified lines | |||
| 511 | vm->clear_range(vm, vma_res->start, vma_res->vma_size); | 511 | vm->clear_range(vm, vma_res->start, vma_res->vma_size); |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | /* | ||
| 515 | * Reserve the top of the GuC address space for firmware images. Addresses | ||
| 516 | * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC, | ||
| 517 | * which makes for a suitable range to hold GuC/HuC firmware images if the | ||
| 518 | * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT | ||
| 519 | * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk | ||
| 520 | * of the same size anyway, which is far more than needed, to keep the logic | ||
| 521 | * in uc_fw_ggtt_offset() simple. | ||
| 522 | */ | ||
| 523 | #define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP) | ||
| 524 | |||
| 514 | static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) | 525 | static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) |
| 515 | { | 526 | { |
| 516 | u64 size; | 527 | u64 offset; |
| 517 | int ret; | 528 | int ret; |
| 518 | 529 | ||
| 519 | if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) | 530 | if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) |
| 520 | return 0; | 531 | return 0; |
| 521 | 532 | ||
| 522 | GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP); | 533 | GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE); |
| 523 | size = ggtt->vm.total - GUC_GGTT_TOP; | 534 | offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE; |
| 524 | 535 | ||
| 525 | ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size, | 536 | ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, |
| 526 | GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE, | 537 | GUC_TOP_RESERVE_SIZE, offset, |
| 527 | PIN_NOEVICT); | 538 | I915_COLOR_UNEVICTABLE, PIN_NOEVICT); |
| 528 | if (ret) | 539 | if (ret) |
| 529 | drm_dbg(&ggtt->vm.i915->drm, | 540 | drm_dbg(&ggtt->vm.i915->drm, |
| 530 | "Failed to reserve top of GGTT for GuC\n"); | 541 | "Failed to reserve top of GGTT for GuC\n"); |
| @@ -1094,6 +1094,9 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine) · 1093 unmodified lines | |||
| 1094 | I915_BO_ALLOC_PM_VOLATILE); | 1094 | I915_BO_ALLOC_PM_VOLATILE); |
| 1095 | if (IS_ERR(obj)) { | 1095 | if (IS_ERR(obj)) { |
| 1096 | obj = i915_gem_object_create_shmem(engine->i915, context_size); | 1096 | obj = i915_gem_object_create_shmem(engine->i915, context_size); |
| 1097 | if (IS_ERR(obj)) | ||
| 1098 | return ERR_CAST(obj); | ||
| 1099 | |||
| 1097 | /* | 1100 | /* |
| 1098 | * Wa_22016122933: For Media version 13.0, all Media GT shared | 1101 | * Wa_22016122933: For Media version 13.0, all Media GT shared |
| 1099 | * memory needs to be mapped as WC on CPU side and UC (PAT | 1102 | * memory needs to be mapped as WC on CPU side and UC (PAT |
| @@ -1102,8 +1105,6 @@ __lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine) · 2 unmodified lines | |||
| 1102 | if (intel_gt_needs_wa_22016122933(engine->gt)) | 1105 | if (intel_gt_needs_wa_22016122933(engine->gt)) |
| 1103 | i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); | 1106 | i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); |
| 1104 | } | 1107 | } |
| 1105 | if (IS_ERR(obj)) | ||
| 1106 | return ERR_CAST(obj); | ||
| 1107 | 1108 | ||
| 1108 | vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); | 1109 | vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); |
| 1109 | if (IS_ERR(vma)) { | 1110 | if (IS_ERR(vma)) { |
| @@ -1432,6 +1432,36 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 1431 unmodified lines | |||
| 1432 | unsigned long index; | 1432 | unsigned long index; |
| 1433 | int srcu, ret; | 1433 | int srcu, ret; |
| 1434 | 1434 | ||
| 1435 | /* | ||
| 1436 | * Ideally the busyness worker should take a gt pm wakeref because the | ||
| 1437 | * worker only needs to be active while gt is awake. However, the | ||
| 1438 | * gt_park path cancels the worker synchronously and this complicates | ||
| 1439 | * the flow if the worker is also running at the same time. The cancel | ||
| 1440 | * waits for the worker and when the worker releases the wakeref, that | ||
| 1441 | * would call gt_park and would lead to a deadlock. | ||
| 1442 | * | ||
| 1443 | * The resolution is to take the global pm wakeref if runtime pm is | ||
| 1444 | * already active. If not, we don't need to update the busyness stats as | ||
| 1445 | * the stats would already be updated when the gt was parked. | ||
| 1446 | * | ||
| 1447 | * Note: | ||
| 1448 | * - We do not requeue the worker if we cannot take a reference to runtime | ||
| 1449 | * pm since intel_guc_busyness_unpark would requeue the worker in the | ||
| 1450 | * resume path. | ||
| 1451 | * | ||
| 1452 | * - If the gt was parked longer than time taken for GT timestamp to roll | ||
| 1453 | * over, we ignore those rollovers since we don't care about tracking | ||
| 1454 | * the exact GT time. We only care about roll overs when the gt is | ||
| 1455 | * active and running workloads. | ||
| 1456 | * | ||
| 1457 | * - There is a window of time between gt_park and runtime suspend, | ||
| 1458 | * where the worker may run. This is acceptable since the worker will | ||
| 1459 | * not find any new data to update busyness. | ||
| 1460 | */ | ||
| 1461 | wakeref = intel_runtime_pm_get_if_active(>->i915->runtime_pm); | ||
| 1462 | if (!wakeref) | ||
| 1463 | return; | ||
| 1464 | |||
| 1435 | /* | 1465 | /* |
| 1436 | * Synchronize with gt reset to make sure the worker does not | 1466 | * Synchronize with gt reset to make sure the worker does not |
| 1437 | * corrupt the engine/guc stats. NB: can't actually block waiting | 1467 | * corrupt the engine/guc stats. NB: can't actually block waiting |
| @@ -1440,10 +1470,9 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 2 unmodified lines | |||
| 1440 | */ | 1470 | */ |
| 1441 | ret = intel_gt_reset_trylock(gt, &srcu); | 1471 | ret = intel_gt_reset_trylock(gt, &srcu); |
| 1442 | if (ret) | 1472 | if (ret) |
| 1443 | return; | 1473 | goto err_trylock; |
| 1444 | 1474 | ||
| 1445 | with_intel_runtime_pm(>->i915->runtime_pm, wakeref) | 1475 | __update_guc_busyness_stats(guc); |
| 1446 | __update_guc_busyness_stats(guc); | ||
| 1447 | 1476 | ||
| 1448 | /* adjust context stats for overflow */ | 1477 | /* adjust context stats for overflow */ |
| 1449 | xa_for_each(&guc->context_lookup, index, ce) | 1478 | xa_for_each(&guc->context_lookup, index, ce) |
| @@ -1452,6 +1481,9 @@ static void guc_timestamp_ping(struct work_struct *wrk) · 2 unmodified lines | |||
| 1452 | intel_gt_reset_unlock(gt, srcu); | 1481 | intel_gt_reset_unlock(gt, srcu); |
| 1453 | 1482 | ||
| 1454 | guc_enable_busyness_worker(guc); | 1483 | guc_enable_busyness_worker(guc); |
| 1484 | |||
| 1485 | err_trylock: | ||
| 1486 | intel_runtime_pm_put(>->i915->runtime_pm, wakeref); | ||
| 1455 | } | 1487 | } |
| 1456 | 1488 | ||
| 1457 | static int guc_action_enable_usage_stats(struct intel_guc *guc) | 1489 | static int guc_action_enable_usage_stats(struct intel_guc *guc) |
| @@ -334,6 +334,8 @@ static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge, · 333 unmodified lines | |||
| 334 | return; | 334 | return; |
| 335 | 335 | ||
| 336 | cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); | 336 | cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); |
| 337 | |||
| 338 | kfree(edid); | ||
| 337 | } else | 339 | } else |
| 338 | cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); | 340 | cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); |
| 339 | } | 341 | } |
| @@ -189,21 +189,12 @@ u_free(void *addr) · 188 unmodified lines | |||
| 189 | static inline void * | 189 | static inline void * |
| 190 | u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) | 190 | u_memcpya(uint64_t user, unsigned int nmemb, unsigned int size) |
| 191 | { | 191 | { |
| 192 | void *mem; | 192 | void __user *userptr = u64_to_user_ptr(user); |
| 193 | void __user *userptr = (void __force __user *)(uintptr_t)user; | 193 | size_t bytes; |
| 194 | 194 | ||
| 195 | size *= nmemb; | 195 | if (unlikely(check_mul_overflow(nmemb, size, &bytes))) |
| 196 | 196 | return ERR_PTR(-EOVERFLOW); | |
| 197 | mem = kvmalloc(size, GFP_KERNEL); | 197 | return vmemdup_user(userptr, bytes); |
| 198 | if (!mem) | ||
| 199 | return ERR_PTR(-ENOMEM); | ||
| 200 | |||
| 201 | if (copy_from_user(mem, userptr, size)) { | ||
| 202 | u_free(mem); | ||
| 203 | return ERR_PTR(-EFAULT); | ||
| 204 | } | ||
| 205 | |||
| 206 | return mem; | ||
| 207 | } | 198 | } |
| 208 | 199 | ||
| 209 | #include <nvif/object.h> | 200 | #include <nvif/object.h> |
| @@ -213,7 +213,7 @@ nouveau_exec_job_timeout(struct nouveau_job *job) · 212 unmodified lines | |||
| 213 | 213 | ||
| 214 | nouveau_sched_entity_fini(job->entity); | 214 | nouveau_sched_entity_fini(job->entity); |
| 215 | 215 | ||
| 216 | return DRM_GPU_SCHED_STAT_ENODEV; | 216 | return DRM_GPU_SCHED_STAT_NOMINAL; |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | static struct nouveau_job_ops nouveau_exec_job_ops = { | 219 | static struct nouveau_job_ops nouveau_exec_job_ops = { |
| @@ -207,7 +207,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha · 206 unmodified lines | |||
| 207 | int | 207 | int |
| 208 | nouveau_fence_emit(struct nouveau_fence *fence) | 208 | nouveau_fence_emit(struct nouveau_fence *fence) |
| 209 | { | 209 | { |
| 210 | struct nouveau_channel *chan = fence->channel; | 210 | struct nouveau_channel *chan = unrcu_pointer(fence->channel); |
| 211 | struct nouveau_fence_chan *fctx = chan->fence; | 211 | struct nouveau_fence_chan *fctx = chan->fence; |
| 212 | struct nouveau_fence_priv *priv = (void*)chan->drm->fence; | 212 | struct nouveau_fence_priv *priv = (void*)chan->drm->fence; |
| 213 | int ret; | 213 | int ret; |
| @@ -375,14 +375,20 @@ nouveau_sched_run_job(struct drm_sched_job *sched_job) · 374 unmodified lines | |||
| 375 | static enum drm_gpu_sched_stat | 375 | static enum drm_gpu_sched_stat |
| 376 | nouveau_sched_timedout_job(struct drm_sched_job *sched_job) | 376 | nouveau_sched_timedout_job(struct drm_sched_job *sched_job) |
| 377 | { | 377 | { |
| 378 | struct drm_gpu_scheduler *sched = sched_job->sched; | ||
| 378 | struct nouveau_job *job = to_nouveau_job(sched_job); | 379 | struct nouveau_job *job = to_nouveau_job(sched_job); |
| 380 | enum drm_gpu_sched_stat stat = DRM_GPU_SCHED_STAT_NOMINAL; | ||
| 379 | 381 | ||
| 380 | NV_PRINTK(warn, job->cli, "Job timed out.\n"); | 382 | drm_sched_stop(sched, sched_job); |
| 381 | 383 | ||
| 382 | if (job->ops->timeout) | 384 | if (job->ops->timeout) |
| 383 | return job->ops->timeout(job); | 385 | stat = job->ops->timeout(job); |
| 386 | else | ||
| 387 | NV_PRINTK(warn, job->cli, "Generic job timeout.\n"); | ||
| 388 | |||
| 389 | drm_sched_start(sched, true); | ||
| 384 | 390 | ||
| 385 | return DRM_GPU_SCHED_STAT_ENODEV; | 391 | return stat; |
| 386 | } | 392 | } |
| 387 | 393 | ||
| 388 | static void | 394 | static void |
| @@ -123,7 +123,7 @@ int radeon_sa_bo_new(struct radeon_sa_manager *sa_manager, · 122 unmodified lines | |||
| 123 | unsigned int size, unsigned int align) | 123 | unsigned int size, unsigned int align) |
| 124 | { | 124 | { |
| 125 | struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size, | 125 | struct drm_suballoc *sa = drm_suballoc_new(&sa_manager->base, size, |
| 126 | GFP_KERNEL, true, align); | 126 | GFP_KERNEL, false, align); |
| 127 | 127 | ||
| 128 | if (IS_ERR(sa)) { | 128 | if (IS_ERR(sa)) { |
| 129 | *sa_bo = NULL; | 129 | *sa_bo = NULL; |
| @@ -939,7 +939,7 @@ static void drm_test_mm_insert_range(struct kunit *test) · 938 unmodified lines | |||
| 939 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); | 939 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); |
| 940 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); | 940 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); |
| 941 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, | 941 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, |
| 942 | max / 2, max / 2)); | 942 | max / 2, max)); |
| 943 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, | 943 | KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, |
| 944 | max / 4 + 1, 3 * max / 4 - 1)); | 944 | max / 4 + 1, 3 * max / 4 - 1)); |
| 945 | 945 | ||
| @@ -70,10 +70,10 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); · 69 unmodified lines | |||
| 70 | #define READ_STATUS_SIZE 13 | 70 | #define READ_STATUS_SIZE 13 |
| 71 | #define MISC_VALUE_SIZE 4 | 71 | #define MISC_VALUE_SIZE 4 |
| 72 | 72 | ||
| 73 | #define CMD_TIMEOUT msecs_to_jiffies(200) | 73 | #define CMD_TIMEOUT 200 |
| 74 | #define DATA_TIMEOUT msecs_to_jiffies(1000) | 74 | #define DATA_TIMEOUT 1000 |
| 75 | #define IDLE_TIMEOUT msecs_to_jiffies(2000) | 75 | #define IDLE_TIMEOUT 2000 |
| 76 | #define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000) | 76 | #define FIRST_FRAME_TIMEOUT 2000 |
| 77 | 77 | ||
| 78 | #define MISC_REQ_GET_SET_ECO_A 0xff | 78 | #define MISC_REQ_GET_SET_ECO_A 0xff |
| 79 | #define MISC_REQ_GET_SET_ECO_B 0x35 | 79 | #define MISC_REQ_GET_SET_ECO_B 0x35 |
| @@ -389,7 +389,7 @@ static void gm12u320_fb_update_work(struct work_struct *work) · 309 unmodified lines | |||
| 389 | * switches back to showing its logo. | 389 | * switches back to showing its logo. |
| 390 | */ | 390 | */ |
| 391 | queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, | 391 | queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, |
| 392 | IDLE_TIMEOUT); | 392 | msecs_to_jiffies(IDLE_TIMEOUT)); |
| 393 | 393 | ||
| 394 | return; | 394 | return; |
| 395 | err: | 395 | err: |
| @@ -361,7 +361,6 @@ static void virtio_gpu_complete_submit(struct virtio_gpu_submit *submit) · 360 unmodified lines | |||
| 361 | submit->buf = NULL; | 361 | submit->buf = NULL; |
| 362 | submit->buflist = NULL; | 362 | submit->buflist = NULL; |
| 363 | submit->sync_file = NULL; | 363 | submit->sync_file = NULL; |
| 364 | submit->out_fence = NULL; | ||
| 365 | submit->out_fence_fd = -1; | 364 | submit->out_fence_fd = -1; |
| 366 | } | 365 | } |
| 367 | 366 | ||
| @@ -408,15 +408,10 @@ void vkms_set_composer(struct vkms_output *out, bool enabled) · 407 unmodified lines | |||
| 408 | if (enabled) | 408 | if (enabled) |
| 409 | drm_crtc_vblank_get(&out->crtc); | 409 | drm_crtc_vblank_get(&out->crtc); |
| 410 | 410 | ||
| 411 | mutex_lock(&out->enabled_lock); | 411 | spin_lock_irq(&out->lock); |
| 412 | old_enabled = out->composer_enabled; | 412 | old_enabled = out->composer_enabled; |
| 413 | out->composer_enabled = enabled; | 413 | out->composer_enabled = enabled; |
| 414 | 414 | spin_unlock_irq(&out->lock); | |
| 415 | /* the composition wasn't enabled, so unlock the lock to make sure the lock | ||
| 416 | * will be balanced even if we have a failed commit | ||
| 417 | */ | ||
| 418 | if (!out->composer_enabled) | ||
| 419 | mutex_unlock(&out->enabled_lock); | ||
| 420 | 415 | ||
| 421 | if (old_enabled) | 416 | if (old_enabled) |
| 422 | drm_crtc_vblank_put(&out->crtc); | 417 | drm_crtc_vblank_put(&out->crtc); |
| @@ -16,7 +16,7 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) · 15 unmodified lines | |||
| 16 | struct drm_crtc *crtc = &output->crtc; | 16 | struct drm_crtc *crtc = &output->crtc; |
| 17 | struct vkms_crtc_state *state; | 17 | struct vkms_crtc_state *state; |
| 18 | u64 ret_overrun; | 18 | u64 ret_overrun; |
| 19 | bool ret, fence_cookie, composer_enabled; | 19 | bool ret, fence_cookie; |
| 20 | 20 | ||
| 21 | fence_cookie = dma_fence_begin_signalling(); | 21 | fence_cookie = dma_fence_begin_signalling(); |
| 22 | 22 | ||
| @@ -25,15 +25,15 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) · 2 unmodified lines | |||
| 25 | if (ret_overrun != 1) | 25 | if (ret_overrun != 1) |
| 26 | pr_warn("%s: vblank timer overrun\n", __func__); | 26 | pr_warn("%s: vblank timer overrun\n", __func__); |
| 27 | 27 | ||
| 28 | spin_lock(&output->lock); | ||
| 28 | ret = drm_crtc_handle_vblank(crtc); | 29 | ret = drm_crtc_handle_vblank(crtc); |
| 29 | if (!ret) | 30 | if (!ret) |
| 30 | DRM_ERROR("vkms failure on handling vblank"); | 31 | DRM_ERROR("vkms failure on handling vblank"); |
| 31 | 32 | ||
| 32 | state = output->composer_state; | 33 | state = output->composer_state; |
| 33 | composer_enabled = output->composer_enabled; | 34 | spin_unlock(&output->lock); |
| 34 | mutex_unlock(&output->enabled_lock); | ||
| 35 | 35 | ||
| 36 | if (state && composer_enabled) { | 36 | if (state && output->composer_enabled) { |
| 37 | u64 frame = drm_crtc_accurate_vblank_count(crtc); | 37 | u64 frame = drm_crtc_accurate_vblank_count(crtc); |
| 38 | 38 | ||
| 39 | /* update frame_start only if a queued vkms_composer_worker() | 39 | /* update frame_start only if a queued vkms_composer_worker() |
| @@ -295,7 +295,6 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, · 255 unmodified lines | |||
| 295 | 295 | ||
| 296 | spin_lock_init(&vkms_out->lock); | 296 | spin_lock_init(&vkms_out->lock); |
| 297 | spin_lock_init(&vkms_out->composer_lock); | 297 | spin_lock_init(&vkms_out->composer_lock); |
| 298 | mutex_init(&vkms_out->enabled_lock); | ||
| 299 | 298 | ||
| 300 | vkms_out->composer_workq = alloc_ordered_workqueue("vkms_composer", 0); | 299 | vkms_out->composer_workq = alloc_ordered_workqueue("vkms_composer", 0); |
| 301 | if (!vkms_out->composer_workq) | 300 | if (!vkms_out->composer_workq) |
| @@ -108,10 +108,8 @@ struct vkms_output { · 107 unmodified lines | |||
| 108 | struct workqueue_struct *composer_workq; | 108 | struct workqueue_struct *composer_workq; |
| 109 | /* protects concurrent access to composer */ | 109 | /* protects concurrent access to composer */ |
| 110 | spinlock_t lock; | 110 | spinlock_t lock; |
| 111 | /* guarantees that if the composer is enabled, a job will be queued */ | ||
| 112 | struct mutex enabled_lock; | ||
| 113 | 111 | ||
| 114 | /* protected by @enabled_lock */ | 112 | /* protected by @lock */ |
| 115 | bool composer_enabled; | 113 | bool composer_enabled; |
| 116 | struct vkms_crtc_state *composer_state; | 114 | struct vkms_crtc_state *composer_state; |
| 117 | 115 | ||
| @@ -1910,6 +1910,10 @@ static umode_t nct6775_in_is_visible(struct kobject *kobj, · 1909 unmodified lines | |||
| 1910 | struct device *dev = kobj_to_dev(kobj); | 1910 | struct device *dev = kobj_to_dev(kobj); |
| 1911 | struct nct6775_data *data = dev_get_drvdata(dev); | 1911 | struct nct6775_data *data = dev_get_drvdata(dev); |
| 1912 | int in = index / 5; /* voltage index */ | 1912 | int in = index / 5; /* voltage index */ |
| 1913 | int nr = index % 5; /* attribute index */ | ||
| 1914 | |||
| 1915 | if (nr == 1 && data->ALARM_BITS[in] == -1) | ||
| 1916 | return 0; | ||
| 1913 | 1917 | ||
| 1914 | if (!(data->have_in & BIT(in))) | 1918 | if (!(data->have_in & BIT(in))) |
| 1915 | return 0; | 1919 | return 0; |
| @@ -72,7 +72,7 @@ config I2C_MUX · 71 unmodified lines | |||
| 72 | source "drivers/i2c/muxes/Kconfig" | 72 | source "drivers/i2c/muxes/Kconfig" |
| 73 | 73 | ||
| 74 | config I2C_ATR | 74 | config I2C_ATR |
| 75 | tristate "I2C Address Translator (ATR) support" | 75 | tristate "I2C Address Translator (ATR) support" if COMPILE_TEST |
| 76 | help | 76 | help |
| 77 | Enable support for I2C Address Translator (ATR) chips. | 77 | Enable support for I2C Address Translator (ATR) chips. |
| 78 | 78 | ||
| @@ -1384,10 +1384,10 @@ config I2C_ICY · 1383 unmodified lines | |||
| 1384 | 1384 | ||
| 1385 | config I2C_MLXCPLD | 1385 | config I2C_MLXCPLD |
| 1386 | tristate "Mellanox I2C driver" | 1386 | tristate "Mellanox I2C driver" |
| 1387 | depends on X86_64 || ARM64 || COMPILE_TEST | 1387 | depends on X86_64 || (ARM64 && ACPI) || COMPILE_TEST |
| 1388 | help | 1388 | help |
| 1389 | This exposes the Mellanox platform I2C busses to the linux I2C layer | 1389 | This exposes the Mellanox platform I2C busses to the linux I2C layer |
| 1390 | for X86 based systems. | 1390 | for X86 and ARM64/ACPI based systems. |
| 1391 | Controller is implemented as CPLD logic. | 1391 | Controller is implemented as CPLD logic. |
| 1392 | 1392 | ||
| 1393 | This driver can also be built as a module. If so, the module will be | 1393 | This driver can also be built as a module. If so, the module will be |
| @@ -698,13 +698,16 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, · 697 unmodified lines | |||
| 698 | 698 | ||
| 699 | if (time_left == 0) { | 699 | if (time_left == 0) { |
| 700 | /* | 700 | /* |
| 701 | * If timed out and bus is still busy in a multi master | 701 | * In a multi-master setup, if a timeout occurs, attempt |
| 702 | * environment, attempt recovery at here. | 702 | * recovery. But if the bus is idle, we still need to reset the |
| 703 | * i2c controller to clear the remaining interrupts. | ||
| 703 | */ | 704 | */ |
| 704 | if (bus->multi_master && | 705 | if (bus->multi_master && |
| 705 | (readl(bus->base + ASPEED_I2C_CMD_REG) & | 706 | (readl(bus->base + ASPEED_I2C_CMD_REG) & |
| 706 | ASPEED_I2CD_BUS_BUSY_STS)) | 707 | ASPEED_I2CD_BUS_BUSY_STS)) |
| 707 | aspeed_i2c_recover_bus(bus); | 708 | aspeed_i2c_recover_bus(bus); |
| 709 | else | ||
| 710 | aspeed_i2c_reset(bus); | ||
| 708 | 711 | ||
| 709 | /* | 712 | /* |
| 710 | * If timed out and the state is still pending, drop the pending | 713 | * If timed out and the state is still pending, drop the pending |
| @@ -182,6 +182,7 @@ enum cdns_i2c_slave_state { · 181 unmodified lines | |||
| 182 | * @reset: Reset control for the device | 182 | * @reset: Reset control for the device |
| 183 | * @quirks: flag for broken hold bit usage in r1p10 | 183 | * @quirks: flag for broken hold bit usage in r1p10 |
| 184 | * @ctrl_reg: Cached value of the control register. | 184 | * @ctrl_reg: Cached value of the control register. |
| 185 | * @rinfo: I2C GPIO recovery information | ||
| 185 | * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register | 186 | * @ctrl_reg_diva_divb: value of fields DIV_A and DIV_B from CR register |
| 186 | * @slave: Registered slave instance. | 187 | * @slave: Registered slave instance. |
| 187 | * @dev_mode: I2C operating role(master/slave). | 188 | * @dev_mode: I2C operating role(master/slave). |
| @@ -441,8 +441,25 @@ err_release_lock: · 440 unmodified lines | |||
| 441 | 441 | ||
| 442 | void __i2c_dw_disable(struct dw_i2c_dev *dev) | 442 | void __i2c_dw_disable(struct dw_i2c_dev *dev) |
| 443 | { | 443 | { |
| 444 | unsigned int raw_intr_stats; | ||
| 445 | unsigned int enable; | ||
| 444 | int timeout = 100; | 446 | int timeout = 100; |
| 447 | bool abort_needed; | ||
| 445 | unsigned int status; | 448 | unsigned int status; |
| 449 | int ret; | ||
| 450 | |||
| 451 | regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); | ||
| 452 | regmap_read(dev->map, DW_IC_ENABLE, &enable); | ||
| 453 | |||
| 454 | abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD; | ||
| 455 | if (abort_needed) { | ||
| 456 | regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); | ||
| 457 | ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, | ||
| 458 | !(enable & DW_IC_ENABLE_ABORT), 10, | ||
| 459 | 100); | ||
| 460 | if (ret) | ||
| 461 | dev_err(dev->dev, "timeout while trying to abort current transfer\n"); | ||
| 462 | } | ||
| 446 | 463 | ||
| 447 | do { | 464 | do { |
| 448 | __i2c_dw_disable_nowait(dev); | 465 | __i2c_dw_disable_nowait(dev); |
| @@ -98,6 +98,7 @@ · 97 unmodified lines | |||
| 98 | #define DW_IC_INTR_START_DET BIT(10) | 98 | #define DW_IC_INTR_START_DET BIT(10) |
| 99 | #define DW_IC_INTR_GEN_CALL BIT(11) | 99 | #define DW_IC_INTR_GEN_CALL BIT(11) |
| 100 | #define DW_IC_INTR_RESTART_DET BIT(12) | 100 | #define DW_IC_INTR_RESTART_DET BIT(12) |
| 101 | #define DW_IC_INTR_MST_ON_HOLD BIT(13) | ||
| 101 | 102 | ||
| 102 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ | 103 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ |
| 103 | DW_IC_INTR_TX_ABRT | \ | 104 | DW_IC_INTR_TX_ABRT | \ |
| @@ -108,6 +109,8 @@ · 4 unmodified lines | |||
| 108 | DW_IC_INTR_RX_UNDER | \ | 109 | DW_IC_INTR_RX_UNDER | \ |
| 109 | DW_IC_INTR_RD_REQ) | 110 | DW_IC_INTR_RD_REQ) |
| 110 | 111 | ||
| 112 | #define DW_IC_ENABLE_ABORT BIT(1) | ||
| 113 | |||
| 111 | #define DW_IC_STATUS_ACTIVITY BIT(0) | 114 | #define DW_IC_STATUS_ACTIVITY BIT(0) |
| 112 | #define DW_IC_STATUS_TFE BIT(2) | 115 | #define DW_IC_STATUS_TFE BIT(2) |
| 113 | #define DW_IC_STATUS_RFNE BIT(3) | 116 | #define DW_IC_STATUS_RFNE BIT(3) |
| @@ -1754,6 +1754,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) · 1753 unmodified lines | |||
| 1754 | "SMBus I801 adapter at %04lx", priv->smba); | 1754 | "SMBus I801 adapter at %04lx", priv->smba); |
| 1755 | err = i2c_add_adapter(&priv->adapter); | 1755 | err = i2c_add_adapter(&priv->adapter); |
| 1756 | if (err) { | 1756 | if (err) { |
| 1757 | platform_device_unregister(priv->tco_pdev); | ||
| 1757 | i801_acpi_remove(priv); | 1758 | i801_acpi_remove(priv); |
| 1758 | return err; | 1759 | return err; |
| 1759 | } | 1760 | } |
| @@ -694,6 +694,7 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 693 unmodified lines | |||
| 694 | { | 694 | { |
| 695 | struct i2c_msg *msgs; | 695 | struct i2c_msg *msgs; |
| 696 | int msgs_num; | 696 | int msgs_num; |
| 697 | bool do_complete = false; | ||
| 697 | 698 | ||
| 698 | msgs = bus->msgs; | 699 | msgs = bus->msgs; |
| 699 | msgs_num = bus->msgs_num; | 700 | msgs_num = bus->msgs_num; |
| @@ -722,23 +723,17 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 22 unmodified lines | |||
| 722 | msgs[1].flags & I2C_M_RD) | 723 | msgs[1].flags & I2C_M_RD) |
| 723 | msgs[1].len = info; | 724 | msgs[1].len = info; |
| 724 | } | 725 | } |
| 725 | if (completion_done(&bus->cmd_complete) == false) | 726 | do_complete = true; |
| 726 | complete(&bus->cmd_complete); | 727 | break; |
| 727 | break; | ||
| 728 | |||
| 729 | case I2C_NACK_IND: | 728 | case I2C_NACK_IND: |
| 730 | /* MASTER transmit got a NACK before tx all bytes */ | 729 | /* MASTER transmit got a NACK before tx all bytes */ |
| 731 | bus->cmd_err = -ENXIO; | 730 | bus->cmd_err = -ENXIO; |
| 732 | if (bus->master_or_slave == I2C_MASTER) | 731 | do_complete = true; |
| 733 | complete(&bus->cmd_complete); | ||
| 734 | |||
| 735 | break; | 732 | break; |
| 736 | case I2C_BUS_ERR_IND: | 733 | case I2C_BUS_ERR_IND: |
| 737 | /* Bus error */ | 734 | /* Bus error */ |
| 738 | bus->cmd_err = -EAGAIN; | 735 | bus->cmd_err = -EAGAIN; |
| 739 | if (bus->master_or_slave == I2C_MASTER) | 736 | do_complete = true; |
| 740 | complete(&bus->cmd_complete); | ||
| 741 | |||
| 742 | break; | 737 | break; |
| 743 | case I2C_WAKE_UP_IND: | 738 | case I2C_WAKE_UP_IND: |
| 744 | /* I2C wake up */ | 739 | /* I2C wake up */ |
| @@ -752,6 +747,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, · 7 unmodified lines | |||
| 752 | if (bus->slave) | 747 | if (bus->slave) |
| 753 | bus->master_or_slave = I2C_SLAVE; | 748 | bus->master_or_slave = I2C_SLAVE; |
| 754 | #endif | 749 | #endif |
| 750 | if (do_complete) | ||
| 751 | complete(&bus->cmd_complete); | ||
| 755 | } | 752 | } |
| 756 | 753 | ||
| 757 | static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) | 754 | static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) |
| @@ -710,7 +710,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) · 709 unmodified lines | |||
| 710 | * reset the IP instead of just flush fifos | 710 | * reset the IP instead of just flush fifos |
| 711 | */ | 711 | */ |
| 712 | ret = xiic_reinit(i2c); | 712 | ret = xiic_reinit(i2c); |
| 713 | if (!ret) | 713 | if (ret < 0) |
| 714 | dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); | 714 | dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); |
| 715 | 715 | ||
| 716 | if (i2c->rx_msg) { | 716 | if (i2c->rx_msg) { |
| @@ -341,7 +341,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, · 340 unmodified lines | |||
| 341 | priv->adap.lock_ops = &i2c_parent_lock_ops; | 341 | priv->adap.lock_ops = &i2c_parent_lock_ops; |
| 342 | 342 | ||
| 343 | /* Sanity check on class */ | 343 | /* Sanity check on class */ |
| 344 | if (i2c_mux_parent_classes(parent) & class) | 344 | if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) |
| 345 | dev_err(&parent->dev, | 345 | dev_err(&parent->dev, |
| 346 | "Segment %d behind mux can't share classes with ancestors\n", | 346 | "Segment %d behind mux can't share classes with ancestors\n", |
| 347 | chan_id); | 347 | chan_id); |
| @@ -243,6 +243,10 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) · 242 unmodified lines | |||
| 243 | 243 | ||
| 244 | props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); | 244 | props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); |
| 245 | props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); | 245 | props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); |
| 246 | if (!props[i].name || !props[i].value) { | ||
| 247 | err = -ENOMEM; | ||
| 248 | goto err_rollback; | ||
| 249 | } | ||
| 246 | props[i].length = 3; | 250 | props[i].length = 3; |
| 247 | 251 | ||
| 248 | of_changeset_init(&priv->chan[i].chgset); | 252 | of_changeset_init(&priv->chan[i].chgset); |
| @@ -105,8 +105,10 @@ static int i2c_mux_gpio_probe_fw(struct gpiomux *mux, · 104 unmodified lines | |||
| 105 | 105 | ||
| 106 | } else if (is_acpi_node(child)) { | 106 | } else if (is_acpi_node(child)) { |
| 107 | rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); | 107 | rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); |
| 108 | if (rc) | 108 | if (rc) { |
| 109 | fwnode_handle_put(child); | ||
| 109 | return dev_err_probe(dev, rc, "Cannot get address\n"); | 110 | return dev_err_probe(dev, rc, "Cannot get address\n"); |
| 111 | } | ||
| 110 | } | 112 | } |
| 111 | 113 | ||
| 112 | i++; | 114 | i++; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/irqdomain.h> | 12 | #include <linux/irqdomain.h> |
| 13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
| 14 | #include <linux/irqchip.h> | 14 | #include <linux/irqchip.h> |
| 15 | #include <linux/irqchip/xtensa-mx.h> | ||
| 15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
| 16 | 17 | ||
| 17 | #include <asm/mxregs.h> | 18 | #include <asm/mxregs.h> |
| @@ -214,6 +214,7 @@ struct dm_table { · 213 unmodified lines | |||
| 214 | 214 | ||
| 215 | /* a list of devices used by this table */ | 215 | /* a list of devices used by this table */ |
| 216 | struct list_head devices; | 216 | struct list_head devices; |
| 217 | struct rw_semaphore devices_lock; | ||
| 217 | 218 | ||
| 218 | /* events get handed up using this callback */ | 219 | /* events get handed up using this callback */ |
| 219 | void (*event_fn)(void *data); | 220 | void (*event_fn)(void *data); |
| @@ -1630,6 +1630,8 @@ static void retrieve_deps(struct dm_table *table, · 1629 unmodified lines | |||
| 1630 | struct dm_dev_internal *dd; | 1630 | struct dm_dev_internal *dd; |
| 1631 | struct dm_target_deps *deps; | 1631 | struct dm_target_deps *deps; |
| 1632 | 1632 | ||
| 1633 | down_read(&table->devices_lock); | ||
| 1634 | |||
| 1633 | deps = get_result_buffer(param, param_size, &len); | 1635 | deps = get_result_buffer(param, param_size, &len); |
| 1634 | 1636 | ||
| 1635 | /* | 1637 | /* |
| @@ -1644,7 +1646,7 @@ static void retrieve_deps(struct dm_table *table, · 8 unmodified lines | |||
| 1644 | needed = struct_size(deps, dev, count); | 1646 | needed = struct_size(deps, dev, count); |
| 1645 | if (len < needed) { | 1647 | if (len < needed) { |
| 1646 | param->flags |= DM_BUFFER_FULL_FLAG; | 1648 | param->flags |= DM_BUFFER_FULL_FLAG; |
| 1647 | return; | 1649 | goto out; |
| 1648 | } | 1650 | } |
| 1649 | 1651 | ||
| 1650 | /* | 1652 | /* |
| @@ -1656,6 +1658,9 @@ static void retrieve_deps(struct dm_table *table, · 5 unmodified lines | |||
| 1656 | deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev); | 1658 | deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev); |
| 1657 | 1659 | ||
| 1658 | param->data_size = param->data_start + needed; | 1660 | param->data_size = param->data_start + needed; |
| 1661 | |||
| 1662 | out: | ||
| 1663 | up_read(&table->devices_lock); | ||
| 1659 | } | 1664 | } |
| 1660 | 1665 | ||
| 1661 | static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size) | 1666 | static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size) |
| @@ -135,6 +135,7 @@ int dm_table_create(struct dm_table **result, blk_mode_t mode, · 134 unmodified lines | |||
| 135 | return -ENOMEM; | 135 | return -ENOMEM; |
| 136 | 136 | ||
| 137 | INIT_LIST_HEAD(&t->devices); | 137 | INIT_LIST_HEAD(&t->devices); |
| 138 | init_rwsem(&t->devices_lock); | ||
| 138 | 139 | ||
| 139 | if (!num_targets) | 140 | if (!num_targets) |
| 140 | num_targets = KEYS_PER_NODE; | 141 | num_targets = KEYS_PER_NODE; |
| @@ -359,16 +360,20 @@ int __ref dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode, · 218 unmodified lines | |||
| 359 | if (dev == disk_devt(t->md->disk)) | 360 | if (dev == disk_devt(t->md->disk)) |
| 360 | return -EINVAL; | 361 | return -EINVAL; |
| 361 | 362 | ||
| 363 | down_write(&t->devices_lock); | ||
| 364 | |||
| 362 | dd = find_device(&t->devices, dev); | 365 | dd = find_device(&t->devices, dev); |
| 363 | if (!dd) { | 366 | if (!dd) { |
| 364 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 367 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); |
| 365 | if (!dd) | 368 | if (!dd) { |
| 366 | return -ENOMEM; | 369 | r = -ENOMEM; |
| 370 | goto unlock_ret_r; | ||
| 371 | } | ||
| 367 | 372 | ||
| 368 | r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev); | 373 | r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev); |
| 369 | if (r) { | 374 | if (r) { |
| 370 | kfree(dd); | 375 | kfree(dd); |
| 371 | return r; | 376 | goto unlock_ret_r; |
| 372 | } | 377 | } |
| 373 | 378 | ||
| 374 | refcount_set(&dd->count, 1); | 379 | refcount_set(&dd->count, 1); |
| @@ -378,12 +383,17 @@ int __ref dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode, · 3 unmodified lines | |||
| 378 | } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { | 383 | } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { |
| 379 | r = upgrade_mode(dd, mode, t->md); | 384 | r = upgrade_mode(dd, mode, t->md); |
| 380 | if (r) | 385 | if (r) |
| 381 | return r; | 386 | goto unlock_ret_r; |
| 382 | } | 387 | } |
| 383 | refcount_inc(&dd->count); | 388 | refcount_inc(&dd->count); |
| 384 | out: | 389 | out: |
| 390 | up_write(&t->devices_lock); | ||
| 385 | *result = dd->dm_dev; | 391 | *result = dd->dm_dev; |
| 386 | return 0; | 392 | return 0; |
| 393 | |||
| 394 | unlock_ret_r: | ||
| 395 | up_write(&t->devices_lock); | ||
| 396 | return r; | ||
| 387 | } | 397 | } |
| 388 | EXPORT_SYMBOL(dm_get_device); | 398 | EXPORT_SYMBOL(dm_get_device); |
| 389 | 399 | ||
| @@ -419,9 +429,12 @@ static int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, · 29 unmodified lines | |||
| 419 | void dm_put_device(struct dm_target *ti, struct dm_dev *d) | 429 | void dm_put_device(struct dm_target *ti, struct dm_dev *d) |
| 420 | { | 430 | { |
| 421 | int found = 0; | 431 | int found = 0; |
| 422 | struct list_head *devices = &ti->table->devices; | 432 | struct dm_table *t = ti->table; |
| 433 | struct list_head *devices = &t->devices; | ||
| 423 | struct dm_dev_internal *dd; | 434 | struct dm_dev_internal *dd; |
| 424 | 435 | ||
| 436 | down_write(&t->devices_lock); | ||
| 437 | |||
| 425 | list_for_each_entry(dd, devices, list) { | 438 | list_for_each_entry(dd, devices, list) { |
| 426 | if (dd->dm_dev == d) { | 439 | if (dd->dm_dev == d) { |
| 427 | found = 1; | 440 | found = 1; |
| @@ -430,14 +443,17 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d) · 2 unmodified lines | |||
| 430 | } | 443 | } |
| 431 | if (!found) { | 444 | if (!found) { |
| 432 | DMERR("%s: device %s not in table devices list", | 445 | DMERR("%s: device %s not in table devices list", |
| 433 | dm_device_name(ti->table->md), d->name); | 446 | dm_device_name(t->md), d->name); |
| 434 | return; | 447 | goto unlock_ret; |
| 435 | } | 448 | } |
| 436 | if (refcount_dec_and_test(&dd->count)) { | 449 | if (refcount_dec_and_test(&dd->count)) { |
| 437 | dm_put_table_device(ti->table->md, d); | 450 | dm_put_table_device(t->md, d); |
| 438 | list_del(&dd->list); | 451 | list_del(&dd->list); |
| 439 | kfree(dd); | 452 | kfree(dd); |
| 440 | } | 453 | } |
| 454 | |||
| 455 | unlock_ret: | ||
| 456 | up_write(&t->devices_lock); | ||
| 441 | } | 457 | } |
| 442 | EXPORT_SYMBOL(dm_put_device); | 458 | EXPORT_SYMBOL(dm_put_device); |
| 443 | 459 | ||
| @@ -715,24 +715,6 @@ static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU) · 714 unmodified lines | |||
| 715 | rcu_read_unlock(); | 715 | rcu_read_unlock(); |
| 716 | } | 716 | } |
| 717 | 717 | ||
| 718 | static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md, | ||
| 719 | int *srcu_idx, blk_opf_t bio_opf) | ||
| 720 | { | ||
| 721 | if (bio_opf & REQ_NOWAIT) | ||
| 722 | return dm_get_live_table_fast(md); | ||
| 723 | else | ||
| 724 | return dm_get_live_table(md, srcu_idx); | ||
| 725 | } | ||
| 726 | |||
| 727 | static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx, | ||
| 728 | blk_opf_t bio_opf) | ||
| 729 | { | ||
| 730 | if (bio_opf & REQ_NOWAIT) | ||
| 731 | dm_put_live_table_fast(md); | ||
| 732 | else | ||
| 733 | dm_put_live_table(md, srcu_idx); | ||
| 734 | } | ||
| 735 | |||
| 736 | static char *_dm_claim_ptr = "I belong to device-mapper"; | 718 | static char *_dm_claim_ptr = "I belong to device-mapper"; |
| 737 | 719 | ||
| 738 | /* | 720 | /* |
| @@ -1833,9 +1815,8 @@ static void dm_submit_bio(struct bio *bio) · 1094 unmodified lines | |||
| 1833 | struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; | 1815 | struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; |
| 1834 | int srcu_idx; | 1816 | int srcu_idx; |
| 1835 | struct dm_table *map; | 1817 | struct dm_table *map; |
| 1836 | blk_opf_t bio_opf = bio->bi_opf; | ||
| 1837 | 1818 | ||
| 1838 | map = dm_get_live_table_bio(md, &srcu_idx, bio_opf); | 1819 | map = dm_get_live_table(md, &srcu_idx); |
| 1839 | 1820 | ||
| 1840 | /* If suspended, or map not yet available, queue this IO for later */ | 1821 | /* If suspended, or map not yet available, queue this IO for later */ |
| 1841 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || | 1822 | if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || |
| @@ -1851,7 +1832,7 @@ static void dm_submit_bio(struct bio *bio) · 9 unmodified lines | |||
| 1851 | 1832 | ||
| 1852 | dm_split_and_process_bio(md, map, bio); | 1833 | dm_split_and_process_bio(md, map, bio); |
| 1853 | out: | 1834 | out: |
| 1854 | dm_put_live_table_bio(md, srcu_idx, bio_opf); | 1835 | dm_put_live_table(md, srcu_idx); |
| 1855 | } | 1836 | } |
| 1856 | 1837 | ||
| 1857 | static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, | 1838 | static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, |
| @@ -798,14 +798,14 @@ void mddev_unlock(struct mddev *mddev) · 797 unmodified lines | |||
| 798 | } else | 798 | } else |
| 799 | mutex_unlock(&mddev->reconfig_mutex); | 799 | mutex_unlock(&mddev->reconfig_mutex); |
| 800 | 800 | ||
| 801 | md_wakeup_thread(mddev->thread); | ||
| 802 | wake_up(&mddev->sb_wait); | ||
| 803 | |||
| 801 | list_for_each_entry_safe(rdev, tmp, &delete, same_set) { | 804 | list_for_each_entry_safe(rdev, tmp, &delete, same_set) { |
| 802 | list_del_init(&rdev->same_set); | 805 | list_del_init(&rdev->same_set); |
| 803 | kobject_del(&rdev->kobj); | 806 | kobject_del(&rdev->kobj); |
| 804 | export_rdev(rdev, mddev); | 807 | export_rdev(rdev, mddev); |
| 805 | } | 808 | } |
| 806 | |||
| 807 | md_wakeup_thread(mddev->thread); | ||
| 808 | wake_up(&mddev->sb_wait); | ||
| 809 | } | 809 | } |
| 810 | EXPORT_SYMBOL_GPL(mddev_unlock); | 810 | EXPORT_SYMBOL_GPL(mddev_unlock); |
| 811 | 811 | ||
| @@ -2452,7 +2452,8 @@ static void export_rdev(struct md_rdev *rdev, struct mddev *mddev) · 1640 unmodified lines | |||
| 2452 | if (test_bit(AutoDetected, &rdev->flags)) | 2452 | if (test_bit(AutoDetected, &rdev->flags)) |
| 2453 | md_autodetect_dev(rdev->bdev->bd_dev); | 2453 | md_autodetect_dev(rdev->bdev->bd_dev); |
| 2454 | #endif | 2454 | #endif |
| 2455 | blkdev_put(rdev->bdev, mddev->external ? &claim_rdev : rdev); | 2455 | blkdev_put(rdev->bdev, |
| 2456 | test_bit(Holder, &rdev->flags) ? rdev : &claim_rdev); | ||
| 2456 | rdev->bdev = NULL; | 2457 | rdev->bdev = NULL; |
| 2457 | kobject_put(&rdev->kobj); | 2458 | kobject_put(&rdev->kobj); |
| 2458 | } | 2459 | } |
| @@ -3632,6 +3633,7 @@ EXPORT_SYMBOL_GPL(md_rdev_init); · 1173 unmodified lines | |||
| 3632 | static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor) | 3633 | static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor) |
| 3633 | { | 3634 | { |
| 3634 | struct md_rdev *rdev; | 3635 | struct md_rdev *rdev; |
| 3636 | struct md_rdev *holder; | ||
| 3635 | sector_t size; | 3637 | sector_t size; |
| 3636 | int err; | 3638 | int err; |
| 3637 | 3639 | ||
| @@ -3646,8 +3648,15 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe · 8 unmodified lines | |||
| 3646 | if (err) | 3648 | if (err) |
| 3647 | goto out_clear_rdev; | 3649 | goto out_clear_rdev; |
| 3648 | 3650 | ||
| 3651 | if (super_format == -2) { | ||
| 3652 | holder = &claim_rdev; | ||
| 3653 | } else { | ||
| 3654 | holder = rdev; | ||
| 3655 | set_bit(Holder, &rdev->flags); | ||
| 3656 | } | ||
| 3657 | |||
| 3649 | rdev->bdev = blkdev_get_by_dev(newdev, BLK_OPEN_READ | BLK_OPEN_WRITE, | 3658 | rdev->bdev = blkdev_get_by_dev(newdev, BLK_OPEN_READ | BLK_OPEN_WRITE, |
| 3650 | super_format == -2 ? &claim_rdev : rdev, NULL); | 3659 | holder, NULL); |
| 3651 | if (IS_ERR(rdev->bdev)) { | 3660 | if (IS_ERR(rdev->bdev)) { |
| 3652 | pr_warn("md: could not open device unknown-block(%u,%u).\n", | 3661 | pr_warn("md: could not open device unknown-block(%u,%u).\n", |
| 3653 | MAJOR(newdev), MINOR(newdev)); | 3662 | MAJOR(newdev), MINOR(newdev)); |
| @@ -3684,7 +3693,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe · 30 unmodified lines | |||
| 3684 | return rdev; | 3693 | return rdev; |
| 3685 | 3694 | ||
| 3686 | out_blkdev_put: | 3695 | out_blkdev_put: |
| 3687 | blkdev_put(rdev->bdev, super_format == -2 ? &claim_rdev : rdev); | 3696 | blkdev_put(rdev->bdev, holder); |
| 3688 | out_clear_rdev: | 3697 | out_clear_rdev: |
| 3689 | md_rdev_clear(rdev); | 3698 | md_rdev_clear(rdev); |
| 3690 | out_free_rdev: | 3699 | out_free_rdev: |
| @@ -8256,7 +8265,7 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) · 4565 unmodified lines | |||
| 8256 | spin_unlock(&all_mddevs_lock); | 8265 | spin_unlock(&all_mddevs_lock); |
| 8257 | 8266 | ||
| 8258 | if (to_put) | 8267 | if (to_put) |
| 8259 | mddev_put(mddev); | 8268 | mddev_put(to_put); |
| 8260 | return next_mddev; | 8269 | return next_mddev; |
| 8261 | 8270 | ||
| 8262 | } | 8271 | } |
| @@ -211,6 +211,9 @@ enum flag_bits { · 210 unmodified lines | |||
| 211 | * check if there is collision between raid1 | 211 | * check if there is collision between raid1 |
| 212 | * serial bios. | 212 | * serial bios. |
| 213 | */ | 213 | */ |
| 214 | Holder, /* rdev is used as holder while opening | ||
| 215 | * underlying disk exclusively. | ||
| 216 | */ | ||
| 214 | }; | 217 | }; |
| 215 | 218 | ||
| 216 | static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors, | 219 | static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors, |
| @@ -1837,12 +1837,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) · 1836 unmodified lines | |||
| 1837 | struct r1conf *conf = mddev->private; | 1837 | struct r1conf *conf = mddev->private; |
| 1838 | int err = 0; | 1838 | int err = 0; |
| 1839 | int number = rdev->raid_disk; | 1839 | int number = rdev->raid_disk; |
| 1840 | struct raid1_info *p = conf->mirrors + number; | ||
| 1840 | 1841 | ||
| 1841 | if (unlikely(number >= conf->raid_disks)) | 1842 | if (unlikely(number >= conf->raid_disks)) |
| 1842 | goto abort; | 1843 | goto abort; |
| 1843 | 1844 | ||
| 1844 | struct raid1_info *p = conf->mirrors + number; | ||
| 1845 | |||
| 1846 | if (rdev != p->rdev) | 1845 | if (rdev != p->rdev) |
| 1847 | p = conf->mirrors + conf->raid_disks + number; | 1846 | p = conf->mirrors + conf->raid_disks + number; |
| 1848 | 1847 | ||
| @@ -31,6 +31,10 @@ · 30 unmodified lines | |||
| 31 | * different type underlying the specified range of virtual addresses. | 31 | * different type underlying the specified range of virtual addresses. |
| 32 | * When the function isn't able to map a single page, it returns error. | 32 | * When the function isn't able to map a single page, it returns error. |
| 33 | * | 33 | * |
| 34 | * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used | ||
| 35 | * to be able to do that, but that could (racily) return non-refcounted | ||
| 36 | * pfns. | ||
| 37 | * | ||
| 34 | * This function takes care of grabbing mmap_lock as necessary. | 38 | * This function takes care of grabbing mmap_lock as necessary. |
| 35 | */ | 39 | */ |
| 36 | int get_vaddr_frames(unsigned long start, unsigned int nr_frames, bool write, | 40 | int get_vaddr_frames(unsigned long start, unsigned int nr_frames, bool write, |
| @@ -59,8 +63,6 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, bool write, · 22 unmodified lines | |||
| 59 | if (likely(ret > 0)) | 63 | if (likely(ret > 0)) |
| 60 | return ret; | 64 | return ret; |
| 61 | 65 | ||
| 62 | /* This used to (racily) return non-refcounted pfns. Let people know */ | ||
| 63 | WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); | ||
| 64 | vec->nr_frames = 0; | 66 | vec->nr_frames = 0; |
| 65 | return ret ? ret : -EFAULT; | 67 | return ret ? ret : -EFAULT; |
| 66 | } | 68 | } |
| @@ -691,12 +691,12 @@ static int imx219_init_cfg(struct v4l2_subdev *sd, · 690 unmodified lines | |||
| 691 | struct v4l2_mbus_framefmt *format; | 691 | struct v4l2_mbus_framefmt *format; |
| 692 | struct v4l2_rect *crop; | 692 | struct v4l2_rect *crop; |
| 693 | 693 | ||
| 694 | /* Initialize try_fmt */ | 694 | /* Initialize the format. */ |
| 695 | format = v4l2_subdev_get_pad_format(sd, state, 0); | 695 | format = v4l2_subdev_get_pad_format(sd, state, 0); |
| 696 | imx219_update_pad_format(imx219, &supported_modes[0], format, | 696 | imx219_update_pad_format(imx219, &supported_modes[0], format, |
| 697 | MEDIA_BUS_FMT_SRGGB10_1X10); | 697 | MEDIA_BUS_FMT_SRGGB10_1X10); |
| 698 | 698 | ||
| 699 | /* Initialize crop rectangle. */ | 699 | /* Initialize the crop rectangle. */ |
| 700 | crop = v4l2_subdev_get_pad_crop(sd, state, 0); | 700 | crop = v4l2_subdev_get_pad_crop(sd, state, 0); |
| 701 | crop->top = IMX219_PIXEL_ARRAY_TOP; | 701 | crop->top = IMX219_PIXEL_ARRAY_TOP; |
| 702 | crop->left = IMX219_PIXEL_ARRAY_LEFT; | 702 | crop->left = IMX219_PIXEL_ARRAY_LEFT; |
| @@ -750,6 +750,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, · 47 unmodified lines | |||
| 750 | const struct imx219_mode *mode; | 750 | const struct imx219_mode *mode; |
| 751 | int exposure_max, exposure_def, hblank; | 751 | int exposure_max, exposure_def, hblank; |
| 752 | struct v4l2_mbus_framefmt *format; | 752 | struct v4l2_mbus_framefmt *format; |
| 753 | struct v4l2_rect *crop; | ||
| 753 | 754 | ||
| 754 | mode = v4l2_find_nearest_size(supported_modes, | 755 | mode = v4l2_find_nearest_size(supported_modes, |
| 755 | ARRAY_SIZE(supported_modes), | 756 | ARRAY_SIZE(supported_modes), |
| @@ -757,10 +758,12 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, · 1 unmodified line | |||
| 757 | fmt->format.width, fmt->format.height); | 758 | fmt->format.width, fmt->format.height); |
| 758 | 759 | ||
| 759 | imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); | 760 | imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); |
| 761 | |||
| 760 | format = v4l2_subdev_get_pad_format(sd, sd_state, 0); | 762 | format = v4l2_subdev_get_pad_format(sd, sd_state, 0); |
| 763 | crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0); | ||
| 761 | 764 | ||
| 762 | if (imx219->mode == mode && format->code == fmt->format.code) | 765 | *format = fmt->format; |
| 763 | return 0; | 766 | *crop = mode->crop; |
| 764 | 767 | ||
| 765 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 768 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
| 766 | imx219->mode = mode; | 769 | imx219->mode = mode; |
| @@ -788,8 +791,6 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, · 21 unmodified lines | |||
| 788 | hblank); | 791 | hblank); |
| 789 | } | 792 | } |
| 790 | 793 | ||
| 791 | *format = fmt->format; | ||
| 792 | |||
| 793 | return 0; | 794 | return 0; |
| 794 | } | 795 | } |
| 795 | 796 | ||
| @@ -1110,7 +1110,6 @@ err_async: · 1109 unmodified lines | |||
| 1110 | 1110 | ||
| 1111 | static void max9286_v4l2_unregister(struct max9286_priv *priv) | 1111 | static void max9286_v4l2_unregister(struct max9286_priv *priv) |
| 1112 | { | 1112 | { |
| 1113 | fwnode_handle_put(priv->sd.fwnode); | ||
| 1114 | v4l2_ctrl_handler_free(&priv->ctrls); | 1113 | v4l2_ctrl_handler_free(&priv->ctrls); |
| 1115 | v4l2_async_unregister_subdev(&priv->sd); | 1114 | v4l2_async_unregister_subdev(&priv->sd); |
| 1116 | max9286_v4l2_notifier_unregister(priv); | 1115 | max9286_v4l2_notifier_unregister(priv); |
| @@ -608,7 +608,6 @@ static void rdacm21_remove(struct i2c_client *client) · 607 unmodified lines | |||
| 608 | v4l2_async_unregister_subdev(&dev->sd); | 608 | v4l2_async_unregister_subdev(&dev->sd); |
| 609 | v4l2_ctrl_handler_free(&dev->ctrls); | 609 | v4l2_ctrl_handler_free(&dev->ctrls); |
| 610 | i2c_unregister_device(dev->isp); | 610 | i2c_unregister_device(dev->isp); |
| 611 | fwnode_handle_put(dev->sd.fwnode); | ||
| 612 | } | 611 | } |
| 613 | 612 | ||
| 614 | static const struct of_device_id rdacm21_of_ids[] = { | 613 | static const struct of_device_id rdacm21_of_ids[] = { |
| @@ -68,9 +68,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, · 67 unmodified lines | |||
| 68 | sg = sglist; | 68 | sg = sglist; |
| 69 | for (line = 0; line < store_lines; line++) { | 69 | for (line = 0; line < store_lines; line++) { |
| 70 | if ((line >= (store_lines - VCR_HACK_LINES)) && | 70 | if ((line >= (store_lines - VCR_HACK_LINES)) && |
| 71 | (btv->opt_vcr_hack || | 71 | btv->opt_vcr_hack) |
| 72 | (V4L2_FIELD_HAS_BOTH(btv->field) || | ||
| 73 | btv->field == V4L2_FIELD_ALTERNATE))) | ||
| 74 | continue; | 72 | continue; |
| 75 | while (offset && offset >= sg_dma_len(sg)) { | 73 | while (offset && offset >= sg_dma_len(sg)) { |
| 76 | offset -= sg_dma_len(sg); | 74 | offset -= sg_dma_len(sg); |
| @@ -3,7 +3,10 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | config INTEL_VSC | 4 | config INTEL_VSC |
| 5 | tristate "Intel Visual Sensing Controller" | 5 | tristate "Intel Visual Sensing Controller" |
| 6 | depends on INTEL_MEI && ACPI | 6 | depends on INTEL_MEI && ACPI && VIDEO_DEV |
| 7 | select MEDIA_CONTROLLER | ||
| 8 | select VIDEO_V4L2_SUBDEV_API | ||
| 9 | select V4L2_ASYNC | ||
| 7 | help | 10 | help |
| 8 | This adds support for Intel Visual Sensing Controller (IVSC). | 11 | This adds support for Intel Visual Sensing Controller (IVSC). |
| 9 | 12 | ||
| @@ -7,7 +7,7 @@ config VIDEO_CAFE_CCIC · 6 unmodified lines | |||
| 7 | depends on V4L_PLATFORM_DRIVERS | 7 | depends on V4L_PLATFORM_DRIVERS |
| 8 | depends on PCI && I2C && VIDEO_DEV | 8 | depends on PCI && I2C && VIDEO_DEV |
| 9 | depends on COMMON_CLK | 9 | depends on COMMON_CLK |
| 10 | select VIDEO_OV7670 | 10 | select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR |
| 11 | select VIDEOBUF2_VMALLOC | 11 | select VIDEOBUF2_VMALLOC |
| 12 | select VIDEOBUF2_DMA_CONTIG | 12 | select VIDEOBUF2_DMA_CONTIG |
| 13 | select VIDEOBUF2_DMA_SG | 13 | select VIDEOBUF2_DMA_SG |
| @@ -22,7 +22,7 @@ config VIDEO_MMP_CAMERA · 8 unmodified lines | |||
| 22 | depends on I2C && VIDEO_DEV | 22 | depends on I2C && VIDEO_DEV |
| 23 | depends on ARCH_MMP || COMPILE_TEST | 23 | depends on ARCH_MMP || COMPILE_TEST |
| 24 | depends on COMMON_CLK | 24 | depends on COMMON_CLK |
| 25 | select VIDEO_OV7670 | 25 | select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR |
| 26 | select I2C_GPIO | 26 | select I2C_GPIO |
| 27 | select VIDEOBUF2_VMALLOC | 27 | select VIDEOBUF2_VMALLOC |
| 28 | select VIDEOBUF2_DMA_CONTIG | 28 | select VIDEOBUF2_DMA_CONTIG |
| @@ -1490,7 +1490,6 @@ err_cleanup: · 1489 unmodified lines | |||
| 1490 | v4l2_async_unregister_subdev(&csis->sd); | 1490 | v4l2_async_unregister_subdev(&csis->sd); |
| 1491 | err_disable_clock: | 1491 | err_disable_clock: |
| 1492 | mipi_csis_clk_disable(csis); | 1492 | mipi_csis_clk_disable(csis); |
| 1493 | fwnode_handle_put(csis->sd.fwnode); | ||
| 1494 | 1493 | ||
| 1495 | return ret; | 1494 | return ret; |
| 1496 | } | 1495 | } |
| @@ -1510,7 +1509,6 @@ static void mipi_csis_remove(struct platform_device *pdev) · 13 unmodified lines | |||
| 1510 | mipi_csis_clk_disable(csis); | 1509 | mipi_csis_clk_disable(csis); |
| 1511 | v4l2_subdev_cleanup(&csis->sd); | 1510 | v4l2_subdev_cleanup(&csis->sd); |
| 1512 | media_entity_cleanup(&csis->sd.entity); | 1511 | media_entity_cleanup(&csis->sd.entity); |
| 1513 | fwnode_handle_put(csis->sd.fwnode); | ||
| 1514 | pm_runtime_set_suspended(&pdev->dev); | 1512 | pm_runtime_set_suspended(&pdev->dev); |
| 1515 | } | 1513 | } |
| 1516 | 1514 | ||
| @@ -7,7 +7,7 @@ config VIDEO_VIA_CAMERA · 6 unmodified lines | |||
| 7 | depends on V4L_PLATFORM_DRIVERS | 7 | depends on V4L_PLATFORM_DRIVERS |
| 8 | depends on FB_VIA && VIDEO_DEV | 8 | depends on FB_VIA && VIDEO_DEV |
| 9 | select VIDEOBUF2_DMA_SG | 9 | select VIDEOBUF2_DMA_SG |
| 10 | select VIDEO_OV7670 | 10 | select VIDEO_OV7670 if VIDEO_CAMERA_SENSOR |
| 11 | help | 11 | help |
| 12 | Driver support for the integrated camera controller in VIA | 12 | Driver support for the integrated camera controller in VIA |
| 13 | Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems | 13 | Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems |
| @@ -12,8 +12,8 @@ config VIDEO_EM28XX_V4L2 · 11 unmodified lines | |||
| 12 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT | 12 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT |
| 13 | select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT | 13 | select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT | 14 | select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT |
| 15 | select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | 15 | select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR |
| 16 | select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | 16 | select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR |
| 17 | help | 17 | help |
| 18 | This is a video4linux driver for Empia 28xx based TV cards. | 18 | This is a video4linux driver for Empia 28xx based TV cards. |
| 19 | 19 | ||
| @@ -12,8 +12,8 @@ config VIDEO_GO7007 · 11 unmodified lines | |||
| 12 | select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT | 12 | select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT |
| 13 | select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT | 13 | select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT | 14 | select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT |
| 15 | select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | ||
| 16 | select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT | 15 | select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT |
| 16 | select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR | ||
| 17 | help | 17 | help |
| 18 | This is a video4linux driver for the WIS GO7007 MPEG | 18 | This is a video4linux driver for the WIS GO7007 MPEG |
| 19 | encoder chip. | 19 | encoder chip. |
| @@ -1402,6 +1402,9 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, · 1401 unmodified lines | |||
| 1402 | query_menu->id = id; | 1402 | query_menu->id = id; |
| 1403 | query_menu->index = index; | 1403 | query_menu->index = index; |
| 1404 | 1404 | ||
| 1405 | if (index >= BITS_PER_TYPE(mapping->menu_mask)) | ||
| 1406 | return -EINVAL; | ||
| 1407 | |||
| 1405 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | 1408 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); |
| 1406 | if (ret < 0) | 1409 | if (ret < 0) |
| 1407 | return -ERESTARTSYS; | 1410 | return -ERESTARTSYS; |
| @@ -1178,8 +1178,8 @@ err: · 1177 unmodified lines | |||
| 1178 | } | 1178 | } |
| 1179 | 1179 | ||
| 1180 | EXPORT_NS_GPL_DEV_PM_OPS(cs42l43_pm_ops, MFD_CS42L43) = { | 1180 | EXPORT_NS_GPL_DEV_PM_OPS(cs42l43_pm_ops, MFD_CS42L43) = { |
| 1181 | SET_SYSTEM_SLEEP_PM_OPS(cs42l43_suspend, cs42l43_resume) | 1181 | SYSTEM_SLEEP_PM_OPS(cs42l43_suspend, cs42l43_resume) |
| 1182 | SET_RUNTIME_PM_OPS(cs42l43_runtime_suspend, cs42l43_runtime_resume, NULL) | 1182 | RUNTIME_PM_OPS(cs42l43_runtime_suspend, cs42l43_runtime_resume, NULL) |
| 1183 | }; | 1183 | }; |
| 1184 | 1184 | ||
| 1185 | MODULE_DESCRIPTION("CS42L43 Core Driver"); | 1185 | MODULE_DESCRIPTION("CS42L43 Core Driver"); |
| @@ -83,63 +83,20 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr) · 82 unmodified lines | |||
| 83 | 83 | ||
| 84 | static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) | 84 | static void rts5227_init_from_cfg(struct rtsx_pcr *pcr) |
| 85 | { | 85 | { |
| 86 | struct pci_dev *pdev = pcr->pci; | ||
| 87 | int l1ss; | ||
| 88 | u32 lval; | ||
| 89 | struct rtsx_cr_option *option = &pcr->option; | 86 | struct rtsx_cr_option *option = &pcr->option; |
| 90 | 87 | ||
| 91 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 92 | if (!l1ss) | ||
| 93 | return; | ||
| 94 | |||
| 95 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 96 | |||
| 97 | if (CHK_PCI_PID(pcr, 0x522A)) { | 88 | if (CHK_PCI_PID(pcr, 0x522A)) { |
| 98 | if (0 == (lval & 0x0F)) | 89 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 99 | rtsx_pci_enable_oobs_polling(pcr); | 90 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 100 | else | ||
| 101 | rtsx_pci_disable_oobs_polling(pcr); | 91 | rtsx_pci_disable_oobs_polling(pcr); |
| 92 | else | ||
| 93 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 102 | } | 94 | } |
| 103 | 95 | ||
| 104 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 105 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 106 | else | ||
| 107 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 108 | |||
| 109 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 110 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 111 | else | ||
| 112 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 113 | |||
| 114 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 115 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 116 | else | ||
| 117 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 118 | |||
| 119 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 120 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 121 | else | ||
| 122 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 123 | |||
| 124 | if (option->ltr_en) { | 96 | if (option->ltr_en) { |
| 125 | u16 val; | 97 | if (option->ltr_enabled) |
| 126 | |||
| 127 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); | ||
| 128 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 129 | option->ltr_enabled = true; | ||
| 130 | option->ltr_active = true; | ||
| 131 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 98 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 132 | } else { | ||
| 133 | option->ltr_enabled = false; | ||
| 134 | } | ||
| 135 | } | 99 | } |
| 136 | |||
| 137 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 138 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 139 | option->force_clkreq_0 = false; | ||
| 140 | else | ||
| 141 | option->force_clkreq_0 = true; | ||
| 142 | |||
| 143 | } | 100 | } |
| 144 | 101 | ||
| 145 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | 102 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) |
| @@ -195,7 +152,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) · 49 unmodified lines | |||
| 195 | } | 152 | } |
| 196 | } | 153 | } |
| 197 | 154 | ||
| 198 | if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | 155 | if (option->force_clkreq_0) |
| 199 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, | 156 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, |
| 200 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | 157 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 201 | else | 158 | else |
| @@ -386,59 +386,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr) · 385 unmodified lines | |||
| 386 | 386 | ||
| 387 | static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) | 387 | static void rts5228_init_from_cfg(struct rtsx_pcr *pcr) |
| 388 | { | 388 | { |
| 389 | struct pci_dev *pdev = pcr->pci; | ||
| 390 | int l1ss; | ||
| 391 | u32 lval; | ||
| 392 | struct rtsx_cr_option *option = &pcr->option; | 389 | struct rtsx_cr_option *option = &pcr->option; |
| 393 | 390 | ||
| 394 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | 391 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 395 | if (!l1ss) | 392 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 396 | return; | ||
| 397 | |||
| 398 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 399 | |||
| 400 | if (0 == (lval & 0x0F)) | ||
| 401 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 402 | else | ||
| 403 | rtsx_pci_disable_oobs_polling(pcr); | 393 | rtsx_pci_disable_oobs_polling(pcr); |
| 404 | |||
| 405 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 406 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 407 | else | ||
| 408 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 409 | |||
| 410 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 411 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 412 | else | ||
| 413 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 414 | |||
| 415 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 416 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 417 | else | 394 | else |
| 418 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | 395 | rtsx_pci_enable_oobs_polling(pcr); |
| 419 | |||
| 420 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 421 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 422 | else | ||
| 423 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 424 | 396 | ||
| 425 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); | 397 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); |
| 426 | if (option->ltr_en) { | ||
| 427 | u16 val; | ||
| 428 | 398 | ||
| 429 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val); | 399 | if (option->ltr_en) { |
| 430 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | 400 | if (option->ltr_enabled) |
| 431 | option->ltr_enabled = true; | ||
| 432 | option->ltr_active = true; | ||
| 433 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 401 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 434 | } else { | ||
| 435 | option->ltr_enabled = false; | ||
| 436 | } | ||
| 437 | } | 402 | } |
| 438 | } | 403 | } |
| 439 | 404 | ||
| 440 | static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) | 405 | static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) |
| 441 | { | 406 | { |
| 407 | struct rtsx_cr_option *option = &pcr->option; | ||
| 442 | 408 | ||
| 443 | rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, | 409 | rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1, |
| 444 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); | 410 | CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); |
| @@ -469,6 +435,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr) · 24 unmodified lines | |||
| 469 | else | 435 | else |
| 470 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); | 436 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 471 | 437 | ||
| 438 | /* | ||
| 439 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 440 | * to drive low, and we forcibly request clock. | ||
| 441 | */ | ||
| 442 | if (option->force_clkreq_0) | ||
| 443 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 444 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 445 | else | ||
| 446 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 447 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 448 | |||
| 472 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); | 449 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 473 | 450 | ||
| 474 | if (pcr->rtd3_en) { | 451 | if (pcr->rtd3_en) { |
| @@ -86,64 +86,22 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) · 85 unmodified lines | |||
| 86 | 86 | ||
| 87 | static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) | 87 | static void rts5249_init_from_cfg(struct rtsx_pcr *pcr) |
| 88 | { | 88 | { |
| 89 | struct pci_dev *pdev = pcr->pci; | ||
| 90 | int l1ss; | ||
| 91 | struct rtsx_cr_option *option = &(pcr->option); | 89 | struct rtsx_cr_option *option = &(pcr->option); |
| 92 | u32 lval; | ||
| 93 | |||
| 94 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 95 | if (!l1ss) | ||
| 96 | return; | ||
| 97 | |||
| 98 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 99 | 90 | ||
| 100 | if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { | 91 | if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { |
| 101 | if (0 == (lval & 0x0F)) | 92 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN |
| 102 | rtsx_pci_enable_oobs_polling(pcr); | 93 | | PM_L1_1_EN | PM_L1_2_EN)) |
| 103 | else | ||
| 104 | rtsx_pci_disable_oobs_polling(pcr); | 94 | rtsx_pci_disable_oobs_polling(pcr); |
| 95 | else | ||
| 96 | rtsx_pci_enable_oobs_polling(pcr); | ||
| 105 | } | 97 | } |
| 106 | 98 | ||
| 107 | |||
| 108 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 109 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 110 | |||
| 111 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 112 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 113 | |||
| 114 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 115 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 116 | |||
| 117 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 118 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 119 | |||
| 120 | if (option->ltr_en) { | 99 | if (option->ltr_en) { |
| 121 | u16 val; | 100 | if (option->ltr_enabled) |
| 122 | |||
| 123 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 124 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 125 | option->ltr_enabled = true; | ||
| 126 | option->ltr_active = true; | ||
| 127 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 101 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 128 | } else { | ||
| 129 | option->ltr_enabled = false; | ||
| 130 | } | ||
| 131 | } | 102 | } |
| 132 | } | 103 | } |
| 133 | 104 | ||
| 134 | static int rts5249_init_from_hw(struct rtsx_pcr *pcr) | ||
| 135 | { | ||
| 136 | struct rtsx_cr_option *option = &(pcr->option); | ||
| 137 | |||
| 138 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 139 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 140 | option->force_clkreq_0 = false; | ||
| 141 | else | ||
| 142 | option->force_clkreq_0 = true; | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime) | 105 | static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime) |
| 148 | { | 106 | { |
| 149 | /* Set relink_time to 0 */ | 107 | /* Set relink_time to 0 */ |
| @@ -276,7 +234,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) · 126 unmodified lines | |||
| 276 | struct rtsx_cr_option *option = &(pcr->option); | 234 | struct rtsx_cr_option *option = &(pcr->option); |
| 277 | 235 | ||
| 278 | rts5249_init_from_cfg(pcr); | 236 | rts5249_init_from_cfg(pcr); |
| 279 | rts5249_init_from_hw(pcr); | ||
| 280 | 237 | ||
| 281 | rtsx_pci_init_cmd(pcr); | 238 | rtsx_pci_init_cmd(pcr); |
| 282 | 239 | ||
| @@ -327,11 +284,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) · 44 unmodified lines | |||
| 327 | } | 284 | } |
| 328 | } | 285 | } |
| 329 | 286 | ||
| 287 | |||
| 330 | /* | 288 | /* |
| 331 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | 289 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced |
| 332 | * to drive low, and we forcibly request clock. | 290 | * to drive low, and we forcibly request clock. |
| 333 | */ | 291 | */ |
| 334 | if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG) | 292 | if (option->force_clkreq_0) |
| 335 | rtsx_pci_write_register(pcr, PETXCFG, | 293 | rtsx_pci_write_register(pcr, PETXCFG, |
| 336 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | 294 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); |
| 337 | else | 295 | else |
| @@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr) · 479 unmodified lines | |||
| 480 | 480 | ||
| 481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) | 481 | static void rts5260_init_from_cfg(struct rtsx_pcr *pcr) |
| 482 | { | 482 | { |
| 483 | struct pci_dev *pdev = pcr->pci; | ||
| 484 | int l1ss; | ||
| 485 | struct rtsx_cr_option *option = &pcr->option; | 483 | struct rtsx_cr_option *option = &pcr->option; |
| 486 | u32 lval; | ||
| 487 | |||
| 488 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 489 | if (!l1ss) | ||
| 490 | return; | ||
| 491 | |||
| 492 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 493 | |||
| 494 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 495 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 496 | |||
| 497 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 498 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 499 | |||
| 500 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 501 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 502 | |||
| 503 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 504 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 505 | 484 | ||
| 506 | rts5260_pwr_saving_setting(pcr); | 485 | rts5260_pwr_saving_setting(pcr); |
| 507 | 486 | ||
| 508 | if (option->ltr_en) { | 487 | if (option->ltr_en) { |
| 509 | u16 val; | 488 | if (option->ltr_enabled) |
| 510 | |||
| 511 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 512 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 513 | option->ltr_enabled = true; | ||
| 514 | option->ltr_active = true; | ||
| 515 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 489 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 516 | } else { | ||
| 517 | option->ltr_enabled = false; | ||
| 518 | } | ||
| 519 | } | 490 | } |
| 520 | } | 491 | } |
| 521 | 492 | ||
| 522 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) | 493 | static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) |
| 523 | { | 494 | { |
| 495 | struct rtsx_cr_option *option = &pcr->option; | ||
| 524 | 496 | ||
| 525 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ | 497 | /* Set mcu_cnt to 7 to ensure data can be sampled properly */ |
| 526 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); | 498 | rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07); |
| @@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) · 12 unmodified lines | |||
| 539 | 511 | ||
| 540 | rts5260_init_hw(pcr); | 512 | rts5260_init_hw(pcr); |
| 541 | 513 | ||
| 514 | /* | ||
| 515 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 516 | * to drive low, and we forcibly request clock. | ||
| 517 | */ | ||
| 518 | if (option->force_clkreq_0) | ||
| 519 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 520 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 521 | else | ||
| 522 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 523 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 524 | |||
| 542 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); | 525 | rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); |
| 543 | 526 | ||
| 544 | return 0; | 527 | return 0; |
| @@ -454,54 +454,17 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr) · 453 unmodified lines | |||
| 454 | 454 | ||
| 455 | static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) | 455 | static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) |
| 456 | { | 456 | { |
| 457 | struct pci_dev *pdev = pcr->pci; | ||
| 458 | int l1ss; | ||
| 459 | u32 lval; | ||
| 460 | struct rtsx_cr_option *option = &pcr->option; | 457 | struct rtsx_cr_option *option = &pcr->option; |
| 461 | 458 | ||
| 462 | l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS); | ||
| 463 | if (!l1ss) | ||
| 464 | return; | ||
| 465 | |||
| 466 | pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 467 | |||
| 468 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 469 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 470 | else | ||
| 471 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 472 | |||
| 473 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 474 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 475 | else | ||
| 476 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 477 | |||
| 478 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 479 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 480 | else | ||
| 481 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 482 | |||
| 483 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 484 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 485 | else | ||
| 486 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 487 | |||
| 488 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0); | ||
| 489 | if (option->ltr_en) { | 459 | if (option->ltr_en) { |
| 490 | u16 val; | 460 | if (option->ltr_enabled) |
| 491 | |||
| 492 | pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val); | ||
| 493 | if (val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 494 | option->ltr_enabled = true; | ||
| 495 | option->ltr_active = true; | ||
| 496 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); | 461 | rtsx_set_ltr_latency(pcr, option->ltr_active_latency); |
| 497 | } else { | ||
| 498 | option->ltr_enabled = false; | ||
| 499 | } | ||
| 500 | } | 462 | } |
| 501 | } | 463 | } |
| 502 | 464 | ||
| 503 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) | 465 | static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) |
| 504 | { | 466 | { |
| 467 | struct rtsx_cr_option *option = &pcr->option; | ||
| 505 | u32 val; | 468 | u32 val; |
| 506 | 469 | ||
| 507 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, | 470 | rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, |
| @@ -547,6 +510,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) · 39 unmodified lines | |||
| 547 | else | 510 | else |
| 548 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); | 511 | rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); |
| 549 | 512 | ||
| 513 | /* | ||
| 514 | * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced | ||
| 515 | * to drive low, and we forcibly request clock. | ||
| 516 | */ | ||
| 517 | if (option->force_clkreq_0) | ||
| 518 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 519 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW); | ||
| 520 | else | ||
| 521 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 522 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 523 | |||
| 550 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); | 524 | rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); |
| 551 | 525 | ||
| 552 | if (pcr->rtd3_en) { | 526 | if (pcr->rtd3_en) { |
| @@ -1326,11 +1326,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) · 1325 unmodified lines | |||
| 1326 | return err; | 1326 | return err; |
| 1327 | } | 1327 | } |
| 1328 | 1328 | ||
| 1329 | if (pcr->aspm_mode == ASPM_MODE_REG) { | 1329 | if (pcr->aspm_mode == ASPM_MODE_REG) |
| 1330 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); | 1330 | rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); |
| 1331 | rtsx_pci_write_register(pcr, PETXCFG, | ||
| 1332 | FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); | ||
| 1333 | } | ||
| 1334 | 1331 | ||
| 1335 | /* No CD interrupt if probing driver with card inserted. | 1332 | /* No CD interrupt if probing driver with card inserted. |
| 1336 | * So we need to initialize pcr->card_exist here. | 1333 | * So we need to initialize pcr->card_exist here. |
| @@ -1345,7 +1342,9 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) · 8 unmodified lines | |||
| 1345 | 1342 | ||
| 1346 | static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | 1343 | static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) |
| 1347 | { | 1344 | { |
| 1348 | int err; | 1345 | struct rtsx_cr_option *option = &(pcr->option); |
| 1346 | int err, l1ss; | ||
| 1347 | u32 lval; | ||
| 1349 | u16 cfg_val; | 1348 | u16 cfg_val; |
| 1350 | u8 val; | 1349 | u8 val; |
| 1351 | 1350 | ||
| @@ -1430,6 +1429,48 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) · 78 unmodified lines | |||
| 1430 | pcr->aspm_enabled = true; | 1429 | pcr->aspm_enabled = true; |
| 1431 | } | 1430 | } |
| 1432 | 1431 | ||
| 1432 | l1ss = pci_find_ext_capability(pcr->pci, PCI_EXT_CAP_ID_L1SS); | ||
| 1433 | if (l1ss) { | ||
| 1434 | pci_read_config_dword(pcr->pci, l1ss + PCI_L1SS_CTL1, &lval); | ||
| 1435 | |||
| 1436 | if (lval & PCI_L1SS_CTL1_ASPM_L1_1) | ||
| 1437 | rtsx_set_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 1438 | else | ||
| 1439 | rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN); | ||
| 1440 | |||
| 1441 | if (lval & PCI_L1SS_CTL1_ASPM_L1_2) | ||
| 1442 | rtsx_set_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 1443 | else | ||
| 1444 | rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN); | ||
| 1445 | |||
| 1446 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_1) | ||
| 1447 | rtsx_set_dev_flag(pcr, PM_L1_1_EN); | ||
| 1448 | else | ||
| 1449 | rtsx_clear_dev_flag(pcr, PM_L1_1_EN); | ||
| 1450 | |||
| 1451 | if (lval & PCI_L1SS_CTL1_PCIPM_L1_2) | ||
| 1452 | rtsx_set_dev_flag(pcr, PM_L1_2_EN); | ||
| 1453 | else | ||
| 1454 | rtsx_clear_dev_flag(pcr, PM_L1_2_EN); | ||
| 1455 | |||
| 1456 | pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &cfg_val); | ||
| 1457 | if (cfg_val & PCI_EXP_DEVCTL2_LTR_EN) { | ||
| 1458 | option->ltr_enabled = true; | ||
| 1459 | option->ltr_active = true; | ||
| 1460 | } else { | ||
| 1461 | option->ltr_enabled = false; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN | ||
| 1465 | | PM_L1_1_EN | PM_L1_2_EN)) | ||
| 1466 | option->force_clkreq_0 = false; | ||
| 1467 | else | ||
| 1468 | option->force_clkreq_0 = true; | ||
| 1469 | } else { | ||
| 1470 | option->ltr_enabled = false; | ||
| 1471 | option->force_clkreq_0 = true; | ||
| 1472 | } | ||
| 1473 | |||
| 1433 | if (pcr->ops->fetch_vendor_settings) | 1474 | if (pcr->ops->fetch_vendor_settings) |
| 1434 | pcr->ops->fetch_vendor_settings(pcr); | 1475 | pcr->ops->fetch_vendor_settings(pcr); |
| 1435 | 1476 | ||
| @@ -266,6 +266,8 @@ struct sja1105_private { · 265 unmodified lines | |||
| 266 | * the switch doesn't confuse them with one another. | 266 | * the switch doesn't confuse them with one another. |
| 267 | */ | 267 | */ |
| 268 | struct mutex mgmt_lock; | 268 | struct mutex mgmt_lock; |
| 269 | /* Serializes accesses to the FDB */ | ||
| 270 | struct mutex fdb_lock; | ||
| 269 | /* PTP two-step TX timestamp ID, and its serialization lock */ | 271 | /* PTP two-step TX timestamp ID, and its serialization lock */ |
| 270 | spinlock_t ts_id_lock; | 272 | spinlock_t ts_id_lock; |
| 271 | u8 ts_id; | 273 | u8 ts_id; |
| @@ -1175,18 +1175,15 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { · 1174 unmodified lines | |||
| 1175 | 1175 | ||
| 1176 | static int | 1176 | static int |
| 1177 | sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, | 1177 | sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, |
| 1178 | struct sja1105_dyn_cmd *cmd, | 1178 | const struct sja1105_dynamic_table_ops *ops, |
| 1179 | const struct sja1105_dynamic_table_ops *ops) | 1179 | void *entry, bool check_valident, |
| 1180 | bool check_errors) | ||
| 1180 | { | 1181 | { |
| 1181 | u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; | 1182 | u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; |
| 1183 | struct sja1105_dyn_cmd cmd = {}; | ||
| 1182 | int rc; | 1184 | int rc; |
| 1183 | 1185 | ||
| 1184 | /* We don't _need_ to read the full entry, just the command area which | 1186 | /* Read back the whole entry + command structure. */ |
| 1185 | * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a | ||
| 1186 | * buffer that contains the full entry too. Additionally, our API | ||
| 1187 | * doesn't really know how many bytes into the buffer does the command | ||
| 1188 | * area really begin. So just read back the whole entry. | ||
| 1189 | */ | ||
| 1190 | rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, | 1187 | rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, |
| 1191 | ops->packed_size); | 1188 | ops->packed_size); |
| 1192 | if (rc) | 1189 | if (rc) |
| @@ -1195,11 +1192,25 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, · 2 unmodified lines | |||
| 1195 | /* Unpack the command structure, and return it to the caller in case it | 1192 | /* Unpack the command structure, and return it to the caller in case it |
| 1196 | * needs to perform further checks on it (VALIDENT). | 1193 | * needs to perform further checks on it (VALIDENT). |
| 1197 | */ | 1194 | */ |
| 1198 | memset(cmd, 0, sizeof(*cmd)); | 1195 | ops->cmd_packing(packed_buf, &cmd, UNPACK); |
| 1199 | ops->cmd_packing(packed_buf, cmd, UNPACK); | ||
| 1200 | 1196 | ||
| 1201 | /* Hardware hasn't cleared VALID => still working on it */ | 1197 | /* Hardware hasn't cleared VALID => still working on it */ |
| 1202 | return cmd->valid ? -EAGAIN : 0; | 1198 | if (cmd.valid) |
| 1199 | return -EAGAIN; | ||
| 1200 | |||
| 1201 | if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY)) | ||
| 1202 | return -ENOENT; | ||
| 1203 | |||
| 1204 | if (check_errors && cmd.errors) | ||
| 1205 | return -EINVAL; | ||
| 1206 | |||
| 1207 | /* Don't dereference possibly NULL pointer - maybe caller | ||
| 1208 | * only wanted to see whether the entry existed or not. | ||
| 1209 | */ | ||
| 1210 | if (entry) | ||
| 1211 | ops->entry_packing(packed_buf, entry, UNPACK); | ||
| 1212 | |||
| 1213 | return 0; | ||
| 1203 | } | 1214 | } |
| 1204 | 1215 | ||
| 1205 | /* Poll the dynamic config entry's control area until the hardware has | 1216 | /* Poll the dynamic config entry's control area until the hardware has |
| @@ -1208,16 +1219,19 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, · 2 unmodified lines | |||
| 1208 | */ | 1219 | */ |
| 1209 | static int | 1220 | static int |
| 1210 | sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, | 1221 | sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, |
| 1211 | struct sja1105_dyn_cmd *cmd, | 1222 | const struct sja1105_dynamic_table_ops *ops, |
| 1212 | const struct sja1105_dynamic_table_ops *ops) | 1223 | void *entry, bool check_valident, |
| 1224 | bool check_errors) | ||
| 1213 | { | 1225 | { |
| 1214 | int rc; | 1226 | int err, rc; |
| 1215 | 1227 | ||
| 1216 | return read_poll_timeout(sja1105_dynamic_config_poll_valid, | 1228 | err = read_poll_timeout(sja1105_dynamic_config_poll_valid, |
| 1217 | rc, rc != -EAGAIN, | 1229 | rc, rc != -EAGAIN, |
| 1218 | SJA1105_DYNAMIC_CONFIG_SLEEP_US, | 1230 | SJA1105_DYNAMIC_CONFIG_SLEEP_US, |
| 1219 | SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, | 1231 | SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, |
| 1220 | false, priv, cmd, ops); | 1232 | false, priv, ops, entry, check_valident, |
| 1233 | check_errors); | ||
| 1234 | return err < 0 ? err : rc; | ||
| 1221 | } | 1235 | } |
| 1222 | 1236 | ||
| 1223 | /* Provides read access to the settings through the dynamic interface | 1237 | /* Provides read access to the settings through the dynamic interface |
| @@ -1286,25 +1300,14 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, · 62 unmodified lines | |||
| 1286 | mutex_lock(&priv->dynamic_config_lock); | 1300 | mutex_lock(&priv->dynamic_config_lock); |
| 1287 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, | 1301 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, |
| 1288 | ops->packed_size); | 1302 | ops->packed_size); |
| 1289 | if (rc < 0) { | ||
| 1290 | mutex_unlock(&priv->dynamic_config_lock); | ||
| 1291 | return rc; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); | ||
| 1295 | mutex_unlock(&priv->dynamic_config_lock); | ||
| 1296 | if (rc < 0) | 1303 | if (rc < 0) |
| 1297 | return rc; | 1304 | goto out; |
| 1298 | 1305 | ||
| 1299 | if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) | 1306 | rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false); |
| 1300 | return -ENOENT; | 1307 | out: |
| 1308 | mutex_unlock(&priv->dynamic_config_lock); | ||
| 1301 | 1309 | ||
| 1302 | /* Don't dereference possibly NULL pointer - maybe caller | 1310 | return rc; |
| 1303 | * only wanted to see whether the entry existed or not. | ||
| 1304 | */ | ||
| 1305 | if (entry) | ||
| 1306 | ops->entry_packing(packed_buf, entry, UNPACK); | ||
| 1307 | return 0; | ||
| 1308 | } | 1311 | } |
| 1309 | 1312 | ||
| 1310 | int sja1105_dynamic_config_write(struct sja1105_private *priv, | 1313 | int sja1105_dynamic_config_write(struct sja1105_private *priv, |
| @@ -1356,22 +1359,14 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv, · 45 unmodified lines | |||
| 1356 | mutex_lock(&priv->dynamic_config_lock); | 1359 | mutex_lock(&priv->dynamic_config_lock); |
| 1357 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, | 1360 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, |
| 1358 | ops->packed_size); | 1361 | ops->packed_size); |
| 1359 | if (rc < 0) { | ||
| 1360 | mutex_unlock(&priv->dynamic_config_lock); | ||
| 1361 | return rc; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); | ||
| 1365 | mutex_unlock(&priv->dynamic_config_lock); | ||
| 1366 | if (rc < 0) | 1362 | if (rc < 0) |
| 1367 | return rc; | 1363 | goto out; |
| 1368 | 1364 | ||
| 1369 | cmd = (struct sja1105_dyn_cmd) {0}; | 1365 | rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true); |
| 1370 | ops->cmd_packing(packed_buf, &cmd, UNPACK); | 1366 | out: |
| 1371 | if (cmd.errors) | 1367 | mutex_unlock(&priv->dynamic_config_lock); |
| 1372 | return -EINVAL; | ||
| 1373 | 1368 | ||
| 1374 | return 0; | 1369 | return rc; |
| 1375 | } | 1370 | } |
| 1376 | 1371 | ||
| 1377 | static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) | 1372 | static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) |
| @@ -1798,6 +1798,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, · 1797 unmodified lines | |||
| 1798 | struct dsa_db db) | 1798 | struct dsa_db db) |
| 1799 | { | 1799 | { |
| 1800 | struct sja1105_private *priv = ds->priv; | 1800 | struct sja1105_private *priv = ds->priv; |
| 1801 | int rc; | ||
| 1801 | 1802 | ||
| 1802 | if (!vid) { | 1803 | if (!vid) { |
| 1803 | switch (db.type) { | 1804 | switch (db.type) { |
| @@ -1812,12 +1813,16 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, · 8 unmodified lines | |||
| 1812 | } | 1813 | } |
| 1813 | } | 1814 | } |
| 1814 | 1815 | ||
| 1815 | return priv->info->fdb_add_cmd(ds, port, addr, vid); | 1816 | mutex_lock(&priv->fdb_lock); |
| 1817 | rc = priv->info->fdb_add_cmd(ds, port, addr, vid); | ||
| 1818 | mutex_unlock(&priv->fdb_lock); | ||
| 1819 | |||
| 1820 | return rc; | ||
| 1816 | } | 1821 | } |
| 1817 | 1822 | ||
| 1818 | static int sja1105_fdb_del(struct dsa_switch *ds, int port, | 1823 | static int __sja1105_fdb_del(struct dsa_switch *ds, int port, |
| 1819 | const unsigned char *addr, u16 vid, | 1824 | const unsigned char *addr, u16 vid, |
| 1820 | struct dsa_db db) | 1825 | struct dsa_db db) |
| 1821 | { | 1826 | { |
| 1822 | struct sja1105_private *priv = ds->priv; | 1827 | struct sja1105_private *priv = ds->priv; |
| 1823 | 1828 | ||
| @@ -1837,6 +1842,20 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port, · 13 unmodified lines | |||
| 1837 | return priv->info->fdb_del_cmd(ds, port, addr, vid); | 1842 | return priv->info->fdb_del_cmd(ds, port, addr, vid); |
| 1838 | } | 1843 | } |
| 1839 | 1844 | ||
| 1845 | static int sja1105_fdb_del(struct dsa_switch *ds, int port, | ||
| 1846 | const unsigned char *addr, u16 vid, | ||
| 1847 | struct dsa_db db) | ||
| 1848 | { | ||
| 1849 | struct sja1105_private *priv = ds->priv; | ||
| 1850 | int rc; | ||
| 1851 | |||
| 1852 | mutex_lock(&priv->fdb_lock); | ||
| 1853 | rc = __sja1105_fdb_del(ds, port, addr, vid, db); | ||
| 1854 | mutex_unlock(&priv->fdb_lock); | ||
| 1855 | |||
| 1856 | return rc; | ||
| 1857 | } | ||
| 1858 | |||
| 1840 | static int sja1105_fdb_dump(struct dsa_switch *ds, int port, | 1859 | static int sja1105_fdb_dump(struct dsa_switch *ds, int port, |
| 1841 | dsa_fdb_dump_cb_t *cb, void *data) | 1860 | dsa_fdb_dump_cb_t *cb, void *data) |
| 1842 | { | 1861 | { |
| @@ -1868,13 +1887,14 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port, · 25 unmodified lines | |||
| 1868 | if (!(l2_lookup.destports & BIT(port))) | 1887 | if (!(l2_lookup.destports & BIT(port))) |
| 1869 | continue; | 1888 | continue; |
| 1870 | 1889 | ||
| 1871 | /* We need to hide the FDB entry for unknown multicast */ | ||
| 1872 | if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST && | ||
| 1873 | l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST) | ||
| 1874 | continue; | ||
| 1875 | |||
| 1876 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); | 1890 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); |
| 1877 | 1891 | ||
| 1892 | /* Hardware FDB is shared for fdb and mdb, "bridge fdb show" | ||
| 1893 | * only wants to see unicast | ||
| 1894 | */ | ||
| 1895 | if (is_multicast_ether_addr(macaddr)) | ||
| 1896 | continue; | ||
| 1897 | |||
| 1878 | /* We need to hide the dsa_8021q VLANs from the user. */ | 1898 | /* We need to hide the dsa_8021q VLANs from the user. */ |
| 1879 | if (vid_is_dsa_8021q(l2_lookup.vlanid)) | 1899 | if (vid_is_dsa_8021q(l2_lookup.vlanid)) |
| 1880 | l2_lookup.vlanid = 0; | 1900 | l2_lookup.vlanid = 0; |
| @@ -1898,6 +1918,8 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 17 unmodified lines | |||
| 1898 | }; | 1918 | }; |
| 1899 | int i; | 1919 | int i; |
| 1900 | 1920 | ||
| 1921 | mutex_lock(&priv->fdb_lock); | ||
| 1922 | |||
| 1901 | for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { | 1923 | for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { |
| 1902 | struct sja1105_l2_lookup_entry l2_lookup = {0}; | 1924 | struct sja1105_l2_lookup_entry l2_lookup = {0}; |
| 1903 | u8 macaddr[ETH_ALEN]; | 1925 | u8 macaddr[ETH_ALEN]; |
| @@ -1911,7 +1933,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 7 unmodified lines | |||
| 1911 | if (rc) { | 1933 | if (rc) { |
| 1912 | dev_err(ds->dev, "Failed to read FDB: %pe\n", | 1934 | dev_err(ds->dev, "Failed to read FDB: %pe\n", |
| 1913 | ERR_PTR(rc)); | 1935 | ERR_PTR(rc)); |
| 1914 | return; | 1936 | break; |
| 1915 | } | 1937 | } |
| 1916 | 1938 | ||
| 1917 | if (!(l2_lookup.destports & BIT(port))) | 1939 | if (!(l2_lookup.destports & BIT(port))) |
| @@ -1923,14 +1945,16 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 5 unmodified lines | |||
| 1923 | 1945 | ||
| 1924 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); | 1946 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); |
| 1925 | 1947 | ||
| 1926 | rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); | 1948 | rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); |
| 1927 | if (rc) { | 1949 | if (rc) { |
| 1928 | dev_err(ds->dev, | 1950 | dev_err(ds->dev, |
| 1929 | "Failed to delete FDB entry %pM vid %lld: %pe\n", | 1951 | "Failed to delete FDB entry %pM vid %lld: %pe\n", |
| 1930 | macaddr, l2_lookup.vlanid, ERR_PTR(rc)); | 1952 | macaddr, l2_lookup.vlanid, ERR_PTR(rc)); |
| 1931 | return; | 1953 | break; |
| 1932 | } | 1954 | } |
| 1933 | } | 1955 | } |
| 1956 | |||
| 1957 | mutex_unlock(&priv->fdb_lock); | ||
| 1934 | } | 1958 | } |
| 1935 | 1959 | ||
| 1936 | static int sja1105_mdb_add(struct dsa_switch *ds, int port, | 1960 | static int sja1105_mdb_add(struct dsa_switch *ds, int port, |
| @@ -2273,6 +2297,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, · 336 unmodified lines | |||
| 2273 | int rc, i; | 2297 | int rc, i; |
| 2274 | s64 now; | 2298 | s64 now; |
| 2275 | 2299 | ||
| 2300 | mutex_lock(&priv->fdb_lock); | ||
| 2276 | mutex_lock(&priv->mgmt_lock); | 2301 | mutex_lock(&priv->mgmt_lock); |
| 2277 | 2302 | ||
| 2278 | mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; | 2303 | mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; |
| @@ -2385,6 +2410,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, · 106 unmodified lines | |||
| 2385 | goto out; | 2410 | goto out; |
| 2386 | out: | 2411 | out: |
| 2387 | mutex_unlock(&priv->mgmt_lock); | 2412 | mutex_unlock(&priv->mgmt_lock); |
| 2413 | mutex_unlock(&priv->fdb_lock); | ||
| 2388 | 2414 | ||
| 2389 | return rc; | 2415 | return rc; |
| 2390 | } | 2416 | } |
| @@ -2954,7 +2980,9 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 563 unmodified lines | |||
| 2954 | { | 2980 | { |
| 2955 | struct sja1105_l2_lookup_entry *l2_lookup; | 2981 | struct sja1105_l2_lookup_entry *l2_lookup; |
| 2956 | struct sja1105_table *table; | 2982 | struct sja1105_table *table; |
| 2957 | int match; | 2983 | int match, rc; |
| 2984 | |||
| 2985 | mutex_lock(&priv->fdb_lock); | ||
| 2958 | 2986 | ||
| 2959 | table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; | 2987 | table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; |
| 2960 | l2_lookup = table->entries; | 2988 | l2_lookup = table->entries; |
| @@ -2967,7 +2995,8 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 6 unmodified lines | |||
| 2967 | if (match == table->entry_count) { | 2995 | if (match == table->entry_count) { |
| 2968 | NL_SET_ERR_MSG_MOD(extack, | 2996 | NL_SET_ERR_MSG_MOD(extack, |
| 2969 | "Could not find FDB entry for unknown multicast"); | 2997 | "Could not find FDB entry for unknown multicast"); |
| 2970 | return -ENOSPC; | 2998 | rc = -ENOSPC; |
| 2999 | goto out; | ||
| 2971 | } | 3000 | } |
| 2972 | 3001 | ||
| 2973 | if (flags.val & BR_MCAST_FLOOD) | 3002 | if (flags.val & BR_MCAST_FLOOD) |
| @@ -2975,10 +3004,13 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 1 unmodified line | |||
| 2975 | else | 3004 | else |
| 2976 | l2_lookup[match].destports &= ~BIT(to); | 3005 | l2_lookup[match].destports &= ~BIT(to); |
| 2977 | 3006 | ||
| 2978 | return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, | 3007 | rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, |
| 2979 | l2_lookup[match].index, | 3008 | l2_lookup[match].index, |
| 2980 | &l2_lookup[match], | 3009 | &l2_lookup[match], true); |
| 2981 | true); | 3010 | out: |
| 3011 | mutex_unlock(&priv->fdb_lock); | ||
| 3012 | |||
| 3013 | return rc; | ||
| 2982 | } | 3014 | } |
| 2983 | 3015 | ||
| 2984 | static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port, | 3016 | static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port, |
| @@ -3348,6 +3380,7 @@ static int sja1105_probe(struct spi_device *spi) · 363 unmodified lines | |||
| 3348 | mutex_init(&priv->ptp_data.lock); | 3380 | mutex_init(&priv->ptp_data.lock); |
| 3349 | mutex_init(&priv->dynamic_config_lock); | 3381 | mutex_init(&priv->dynamic_config_lock); |
| 3350 | mutex_init(&priv->mgmt_lock); | 3382 | mutex_init(&priv->mgmt_lock); |
| 3383 | mutex_init(&priv->fdb_lock); | ||
| 3351 | spin_lock_init(&priv->ts_id_lock); | 3384 | spin_lock_init(&priv->ts_id_lock); |
| 3352 | 3385 | ||
| 3353 | rc = sja1105_parse_dt(priv); | 3386 | rc = sja1105_parse_dt(priv); |
| @@ -1385,7 +1385,7 @@ static int adin1110_fdb_add(struct adin1110_port_priv *port_priv, · 1384 unmodified lines | |||
| 1385 | return -ENOMEM; | 1385 | return -ENOMEM; |
| 1386 | 1386 | ||
| 1387 | other_port = priv->ports[!port_priv->nr]; | 1387 | other_port = priv->ports[!port_priv->nr]; |
| 1388 | port_rules = adin1110_port_rules(port_priv, false, true); | 1388 | port_rules = adin1110_port_rules(other_port, false, true); |
| 1389 | eth_broadcast_addr(mask); | 1389 | eth_broadcast_addr(mask); |
| 1390 | 1390 | ||
| 1391 | return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr, | 1391 | return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr, |
| @@ -1833,6 +1833,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, · 1832 unmodified lines | |||
| 1833 | return work_done; | 1833 | return work_done; |
| 1834 | 1834 | ||
| 1835 | error: | 1835 | error: |
| 1836 | if (xdp_flags & ENA_XDP_REDIRECT) | ||
| 1837 | xdp_do_flush(); | ||
| 1838 | |||
| 1836 | adapter = netdev_priv(rx_ring->netdev); | 1839 | adapter = netdev_priv(rx_ring->netdev); |
| 1837 | 1840 | ||
| 1838 | if (rc == -ENOSPC) { | 1841 | if (rc == -ENOSPC) { |
| @@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf) · 527 unmodified lines | |||
| 528 | ASP_RX_FILTER_BLK_CTRL); | 528 | ASP_RX_FILTER_BLK_CTRL); |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | 531 | int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, |
| 532 | u32 *rule_cnt) | 532 | u32 *rule_cnt) |
| 533 | { | 533 | { |
| 534 | struct bcmasp_priv *priv = intf->parent; | 534 | struct bcmasp_priv *priv = intf->parent; |
| 535 | int j = 0, i; | 535 | int j = 0, i; |
| 536 | 536 | ||
| 537 | for (i = 0; i < NUM_NET_FILTERS; i++) { | 537 | for (i = 0; i < NUM_NET_FILTERS; i++) { |
| 538 | if (j == *rule_cnt) | ||
| 539 | return -EMSGSIZE; | ||
| 540 | |||
| 538 | if (!priv->net_filters[i].claimed || | 541 | if (!priv->net_filters[i].claimed || |
| 539 | priv->net_filters[i].port != intf->port) | 542 | priv->net_filters[i].port != intf->port) |
| 540 | continue; | 543 | continue; |
| @@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, · 7 unmodified lines | |||
| 548 | } | 551 | } |
| 549 | 552 | ||
| 550 | *rule_cnt = j; | 553 | *rule_cnt = j; |
| 554 | |||
| 555 | return 0; | ||
| 551 | } | 556 | } |
| 552 | 557 | ||
| 553 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf) | 558 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf) |
| @@ -1300,6 +1305,7 @@ static int bcmasp_probe(struct platform_device *pdev) · 746 unmodified lines | |||
| 1300 | if (!intf) { | 1305 | if (!intf) { |
| 1301 | dev_err(dev, "Cannot create eth interface %d\n", i); | 1306 | dev_err(dev, "Cannot create eth interface %d\n", i); |
| 1302 | bcmasp_remove_intfs(priv); | 1307 | bcmasp_remove_intfs(priv); |
| 1308 | of_node_put(intf_node); | ||
| 1303 | goto of_put_exit; | 1309 | goto of_put_exit; |
| 1304 | } | 1310 | } |
| 1305 | list_add_tail(&intf->list, &priv->intfs); | 1311 | list_add_tail(&intf->list, &priv->intfs); |
| @@ -577,8 +577,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf, · 576 unmodified lines | |||
| 577 | 577 | ||
| 578 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf); | 578 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf); |
| 579 | 579 | ||
| 580 | void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | 580 | int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, |
| 581 | u32 *rule_cnt); | 581 | u32 *rule_cnt); |
| 582 | 582 | ||
| 583 | void bcmasp_netfilt_suspend(struct bcmasp_intf *intf); | 583 | void bcmasp_netfilt_suspend(struct bcmasp_intf *intf); |
| 584 | 584 | ||
| @@ -335,7 +335,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, · 334 unmodified lines | |||
| 335 | err = bcmasp_flow_get(intf, cmd); | 335 | err = bcmasp_flow_get(intf, cmd); |
| 336 | break; | 336 | break; |
| 337 | case ETHTOOL_GRXCLSRLALL: | 337 | case ETHTOOL_GRXCLSRLALL: |
| 338 | bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt); | 338 | err = bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt); |
| 339 | cmd->data = NUM_NET_FILTERS; | 339 | cmd->data = NUM_NET_FILTERS; |
| 340 | break; | 340 | break; |
| 341 | default: | 341 | default: |
| @@ -2614,6 +2614,7 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) · 2613 unmodified lines | |||
| 2614 | struct rx_cmp_ext *rxcmp1; | 2614 | struct rx_cmp_ext *rxcmp1; |
| 2615 | u32 cp_cons, tmp_raw_cons; | 2615 | u32 cp_cons, tmp_raw_cons; |
| 2616 | u32 raw_cons = cpr->cp_raw_cons; | 2616 | u32 raw_cons = cpr->cp_raw_cons; |
| 2617 | bool flush_xdp = false; | ||
| 2617 | u32 rx_pkts = 0; | 2618 | u32 rx_pkts = 0; |
| 2618 | u8 event = 0; | 2619 | u8 event = 0; |
| 2619 | 2620 | ||
| @@ -2648,6 +2649,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) · 28 unmodified lines | |||
| 2648 | rx_pkts++; | 2649 | rx_pkts++; |
| 2649 | else if (rc == -EBUSY) /* partial completion */ | 2650 | else if (rc == -EBUSY) /* partial completion */ |
| 2650 | break; | 2651 | break; |
| 2652 | if (event & BNXT_REDIRECT_EVENT) | ||
| 2653 | flush_xdp = true; | ||
| 2651 | } else if (unlikely(TX_CMP_TYPE(txcmp) == | 2654 | } else if (unlikely(TX_CMP_TYPE(txcmp) == |
| 2652 | CMPL_BASE_TYPE_HWRM_DONE)) { | 2655 | CMPL_BASE_TYPE_HWRM_DONE)) { |
| 2653 | bnxt_hwrm_handler(bp, txcmp); | 2656 | bnxt_hwrm_handler(bp, txcmp); |
| @@ -2667,6 +2670,8 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) · 13 unmodified lines | |||
| 2667 | 2670 | ||
| 2668 | if (event & BNXT_AGG_EVENT) | 2671 | if (event & BNXT_AGG_EVENT) |
| 2669 | bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); | 2672 | bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); |
| 2673 | if (flush_xdp) | ||
| 2674 | xdp_do_flush(); | ||
| 2670 | 2675 | ||
| 2671 | if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { | 2676 | if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { |
| 2672 | napi_complete_done(napi, rx_pkts); | 2677 | napi_complete_done(napi, rx_pkts); |
| @@ -756,8 +756,6 @@ static void macb_mac_link_up(struct phylink_config *config, · 755 unmodified lines | |||
| 756 | if (rx_pause) | 756 | if (rx_pause) |
| 757 | ctrl |= MACB_BIT(PAE); | 757 | ctrl |= MACB_BIT(PAE); |
| 758 | 758 | ||
| 759 | macb_set_tx_clk(bp, speed); | ||
| 760 | |||
| 761 | /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down | 759 | /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down |
| 762 | * cleared the pipeline and control registers. | 760 | * cleared the pipeline and control registers. |
| 763 | */ | 761 | */ |
| @@ -777,6 +775,9 @@ static void macb_mac_link_up(struct phylink_config *config, · 13 unmodified lines | |||
| 777 | 775 | ||
| 778 | spin_unlock_irqrestore(&bp->lock, flags); | 776 | spin_unlock_irqrestore(&bp->lock, flags); |
| 779 | 777 | ||
| 778 | if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) | ||
| 779 | macb_set_tx_clk(bp, speed); | ||
| 780 | |||
| 780 | /* Enable Rx and Tx; Enable PTP unicast */ | 781 | /* Enable Rx and Tx; Enable PTP unicast */ |
| 781 | ctrl = macb_readl(bp, NCR); | 782 | ctrl = macb_readl(bp, NCR); |
| 782 | if (gem_has_ptp(bp)) | 783 | if (gem_has_ptp(bp)) |
| @@ -300,10 +300,8 @@ static void tsnep_ethtool_get_channels(struct net_device *netdev, · 299 unmodified lines | |||
| 300 | { | 300 | { |
| 301 | struct tsnep_adapter *adapter = netdev_priv(netdev); | 301 | struct tsnep_adapter *adapter = netdev_priv(netdev); |
| 302 | 302 | ||
| 303 | ch->max_rx = adapter->num_rx_queues; | 303 | ch->max_combined = adapter->num_queues; |
| 304 | ch->max_tx = adapter->num_tx_queues; | 304 | ch->combined_count = adapter->num_queues; |
| 305 | ch->rx_count = adapter->num_rx_queues; | ||
| 306 | ch->tx_count = adapter->num_tx_queues; | ||
| 307 | } | 305 | } |
| 308 | 306 | ||
| 309 | static int tsnep_ethtool_get_ts_info(struct net_device *netdev, | 307 | static int tsnep_ethtool_get_ts_info(struct net_device *netdev, |
| @@ -87,8 +87,11 @@ static irqreturn_t tsnep_irq(int irq, void *arg) · 86 unmodified lines | |||
| 87 | 87 | ||
| 88 | /* handle TX/RX queue 0 interrupt */ | 88 | /* handle TX/RX queue 0 interrupt */ |
| 89 | if ((active & adapter->queue[0].irq_mask) != 0) { | 89 | if ((active & adapter->queue[0].irq_mask) != 0) { |
| 90 | tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); | 90 | if (napi_schedule_prep(&adapter->queue[0].napi)) { |
| 91 | napi_schedule(&adapter->queue[0].napi); | 91 | tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); |
| 92 | /* schedule after masking to avoid races */ | ||
| 93 | __napi_schedule(&adapter->queue[0].napi); | ||
| 94 | } | ||
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | return IRQ_HANDLED; | 97 | return IRQ_HANDLED; |
| @@ -99,8 +102,11 @@ static irqreturn_t tsnep_irq_txrx(int irq, void *arg) · 4 unmodified lines | |||
| 99 | struct tsnep_queue *queue = arg; | 102 | struct tsnep_queue *queue = arg; |
| 100 | 103 | ||
| 101 | /* handle TX/RX queue interrupt */ | 104 | /* handle TX/RX queue interrupt */ |
| 102 | tsnep_disable_irq(queue->adapter, queue->irq_mask); | 105 | if (napi_schedule_prep(&queue->napi)) { |
| 103 | napi_schedule(&queue->napi); | 106 | tsnep_disable_irq(queue->adapter, queue->irq_mask); |
| 107 | /* schedule after masking to avoid races */ | ||
| 108 | __napi_schedule(&queue->napi); | ||
| 109 | } | ||
| 104 | 110 | ||
| 105 | return IRQ_HANDLED; | 111 | return IRQ_HANDLED; |
| 106 | } | 112 | } |
| @@ -1728,6 +1734,10 @@ static int tsnep_poll(struct napi_struct *napi, int budget) · 1621 unmodified lines | |||
| 1728 | if (queue->tx) | 1734 | if (queue->tx) |
| 1729 | complete = tsnep_tx_poll(queue->tx, budget); | 1735 | complete = tsnep_tx_poll(queue->tx, budget); |
| 1730 | 1736 | ||
| 1737 | /* handle case where we are called by netpoll with a budget of 0 */ | ||
| 1738 | if (unlikely(budget <= 0)) | ||
| 1739 | return budget; | ||
| 1740 | |||
| 1731 | if (queue->rx) { | 1741 | if (queue->rx) { |
| 1732 | done = queue->rx->xsk_pool ? | 1742 | done = queue->rx->xsk_pool ? |
| 1733 | tsnep_rx_poll_zc(queue->rx, napi, budget) : | 1743 | tsnep_rx_poll_zc(queue->rx, napi, budget) : |
| @@ -3353,6 +3353,15 @@ static void hns3_set_default_feature(struct net_device *netdev) · 3352 unmodified lines | |||
| 3353 | NETIF_F_HW_TC); | 3353 | NETIF_F_HW_TC); |
| 3354 | 3354 | ||
| 3355 | netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID; | 3355 | netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID; |
| 3356 | |||
| 3357 | /* The device_version V3 hardware can't offload the checksum for IP in | ||
| 3358 | * GRE packets, but can do it for NvGRE. So default to disable the | ||
| 3359 | * checksum and GSO offload for GRE. | ||
| 3360 | */ | ||
| 3361 | if (ae_dev->dev_version > HNAE3_DEVICE_VERSION_V2) { | ||
| 3362 | netdev->features &= ~NETIF_F_GSO_GRE; | ||
| 3363 | netdev->features &= ~NETIF_F_GSO_GRE_CSUM; | ||
| 3364 | } | ||
| 3356 | } | 3365 | } |
| 3357 | 3366 | ||
| 3358 | static int hns3_alloc_buffer(struct hns3_enet_ring *ring, | 3367 | static int hns3_alloc_buffer(struct hns3_enet_ring *ring, |
| @@ -3564,9 +3564,14 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) · 3563 unmodified lines | |||
| 3564 | static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, | 3564 | static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, |
| 3565 | u32 regclr) | 3565 | u32 regclr) |
| 3566 | { | 3566 | { |
| 3567 | #define HCLGE_IMP_RESET_DELAY 5 | ||
| 3568 | |||
| 3567 | switch (event_type) { | 3569 | switch (event_type) { |
| 3568 | case HCLGE_VECTOR0_EVENT_PTP: | 3570 | case HCLGE_VECTOR0_EVENT_PTP: |
| 3569 | case HCLGE_VECTOR0_EVENT_RST: | 3571 | case HCLGE_VECTOR0_EVENT_RST: |
| 3572 | if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) | ||
| 3573 | mdelay(HCLGE_IMP_RESET_DELAY); | ||
| 3574 | |||
| 3570 | hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); | 3575 | hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); |
| 3571 | break; | 3576 | break; |
| 3572 | case HCLGE_VECTOR0_EVENT_MBX: | 3577 | case HCLGE_VECTOR0_EVENT_MBX: |
| @@ -7348,6 +7353,12 @@ static int hclge_del_cls_flower(struct hnae3_handle *handle, · 3775 unmodified lines | |||
| 7348 | ret = hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, rule->location, | 7353 | ret = hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, rule->location, |
| 7349 | NULL, false); | 7354 | NULL, false); |
| 7350 | if (ret) { | 7355 | if (ret) { |
| 7356 | /* if tcam config fail, set rule state to TO_DEL, | ||
| 7357 | * so the rule will be deleted when periodic | ||
| 7358 | * task being scheduled. | ||
| 7359 | */ | ||
| 7360 | hclge_update_fd_list(hdev, HCLGE_FD_TO_DEL, rule->location, NULL); | ||
| 7361 | set_bit(HCLGE_STATE_FD_TBL_CHANGED, &hdev->state); | ||
| 7351 | spin_unlock_bh(&hdev->fd_rule_lock); | 7362 | spin_unlock_bh(&hdev->fd_rule_lock); |
| 7352 | return ret; | 7363 | return ret; |
| 7353 | } | 7364 | } |
| @@ -8824,7 +8835,7 @@ static void hclge_update_overflow_flags(struct hclge_vport *vport, · 1470 unmodified lines | |||
| 8824 | if (mac_type == HCLGE_MAC_ADDR_UC) { | 8835 | if (mac_type == HCLGE_MAC_ADDR_UC) { |
| 8825 | if (is_all_added) | 8836 | if (is_all_added) |
| 8826 | vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE; | 8837 | vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE; |
| 8827 | else | 8838 | else if (hclge_is_umv_space_full(vport, true)) |
| 8828 | vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE; | 8839 | vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE; |
| 8829 | } else { | 8840 | } else { |
| 8830 | if (is_all_added) | 8841 | if (is_all_added) |
| @@ -1855,7 +1855,8 @@ static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev) · 1854 unmodified lines | |||
| 1855 | unsigned long delta = round_jiffies_relative(HZ); | 1855 | unsigned long delta = round_jiffies_relative(HZ); |
| 1856 | struct hnae3_handle *handle = &hdev->nic; | 1856 | struct hnae3_handle *handle = &hdev->nic; |
| 1857 | 1857 | ||
| 1858 | if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) | 1858 | if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state) || |
| 1859 | test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state)) | ||
| 1859 | return; | 1860 | return; |
| 1860 | 1861 | ||
| 1861 | if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { | 1862 | if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { |
| @@ -456,9 +456,6 @@ int hinic_set_vlan_fliter(struct hinic_dev *nic_dev, u32 en) · 455 unmodified lines | |||
| 456 | u16 out_size = sizeof(vlan_filter); | 456 | u16 out_size = sizeof(vlan_filter); |
| 457 | int err; | 457 | int err; |
| 458 | 458 | ||
| 459 | if (!hwdev) | ||
| 460 | return -EINVAL; | ||
| 461 | |||
| 462 | vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif); | 459 | vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
| 463 | vlan_filter.enable = en; | 460 | vlan_filter.enable = en; |
| 464 | 461 | ||
| @@ -4475,9 +4475,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, · 4474 unmodified lines | |||
| 4475 | goto error_pvid; | 4475 | goto error_pvid; |
| 4476 | 4476 | ||
| 4477 | i40e_vlan_stripping_enable(vsi); | 4477 | i40e_vlan_stripping_enable(vsi); |
| 4478 | i40e_vc_reset_vf(vf, true); | 4478 | |
| 4479 | /* During reset the VF got a new VSI, so refresh a pointer. */ | ||
| 4480 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 4481 | /* Locked once because multiple functions below iterate list */ | 4479 | /* Locked once because multiple functions below iterate list */ |
| 4482 | spin_lock_bh(&vsi->mac_filter_hash_lock); | 4480 | spin_lock_bh(&vsi->mac_filter_hash_lock); |
| 4483 | 4481 | ||
| @@ -4563,6 +4561,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, · 79 unmodified lines | |||
| 4563 | */ | 4561 | */ |
| 4564 | vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); | 4562 | vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); |
| 4565 | 4563 | ||
| 4564 | i40e_vc_reset_vf(vf, true); | ||
| 4565 | /* During reset the VF got a new VSI, so refresh a pointer. */ | ||
| 4566 | vsi = pf->vsi[vf->lan_vsi_idx]; | ||
| 4567 | |||
| 4566 | ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); | 4568 | ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); |
| 4567 | if (ret) { | 4569 | if (ret) { |
| 4568 | dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); | 4570 | dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); |
| @@ -521,7 +521,7 @@ void iavf_down(struct iavf_adapter *adapter); · 520 unmodified lines | |||
| 521 | int iavf_process_config(struct iavf_adapter *adapter); | 521 | int iavf_process_config(struct iavf_adapter *adapter); |
| 522 | int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); | 522 | int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); |
| 523 | void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); | 523 | void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); |
| 524 | void iavf_schedule_request_stats(struct iavf_adapter *adapter); | 524 | void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags); |
| 525 | void iavf_schedule_finish_config(struct iavf_adapter *adapter); | 525 | void iavf_schedule_finish_config(struct iavf_adapter *adapter); |
| 526 | void iavf_reset(struct iavf_adapter *adapter); | 526 | void iavf_reset(struct iavf_adapter *adapter); |
| 527 | void iavf_set_ethtool_ops(struct net_device *netdev); | 527 | void iavf_set_ethtool_ops(struct net_device *netdev); |
| @@ -362,7 +362,7 @@ static void iavf_get_ethtool_stats(struct net_device *netdev, · 361 unmodified lines | |||
| 362 | unsigned int i; | 362 | unsigned int i; |
| 363 | 363 | ||
| 364 | /* Explicitly request stats refresh */ | 364 | /* Explicitly request stats refresh */ |
| 365 | iavf_schedule_request_stats(adapter); | 365 | iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_REQUEST_STATS); |
| 366 | 366 | ||
| 367 | iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); | 367 | iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); |
| 368 | 368 | ||
| @@ -314,15 +314,13 @@ void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags) · 313 unmodified lines | |||
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | /** | 316 | /** |
| 317 | * iavf_schedule_request_stats - Set the flags and schedule statistics request | 317 | * iavf_schedule_aq_request - Set the flags and schedule aq request |
| 318 | * @adapter: board private structure | 318 | * @adapter: board private structure |
| 319 | * | 319 | * @flags: requested aq flags |
| 320 | * Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly | ||
| 321 | * request and refresh ethtool stats | ||
| 322 | **/ | 320 | **/ |
| 323 | void iavf_schedule_request_stats(struct iavf_adapter *adapter) | 321 | void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags) |
| 324 | { | 322 | { |
| 325 | adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS; | 323 | adapter->aq_required |= flags; |
| 326 | mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); | 324 | mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); |
| 327 | } | 325 | } |
| 328 | 326 | ||
| @@ -823,7 +821,7 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, · 494 unmodified lines | |||
| 823 | list_add_tail(&f->list, &adapter->vlan_filter_list); | 821 | list_add_tail(&f->list, &adapter->vlan_filter_list); |
| 824 | f->state = IAVF_VLAN_ADD; | 822 | f->state = IAVF_VLAN_ADD; |
| 825 | adapter->num_vlan_filters++; | 823 | adapter->num_vlan_filters++; |
| 826 | adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER; | 824 | iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER); |
| 827 | } | 825 | } |
| 828 | 826 | ||
| 829 | clearout: | 827 | clearout: |
| @@ -845,7 +843,7 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, struct iavf_vlan vlan) · 15 unmodified lines | |||
| 845 | f = iavf_find_vlan(adapter, vlan); | 843 | f = iavf_find_vlan(adapter, vlan); |
| 846 | if (f) { | 844 | if (f) { |
| 847 | f->state = IAVF_VLAN_REMOVE; | 845 | f->state = IAVF_VLAN_REMOVE; |
| 848 | adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; | 846 | iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_DEL_VLAN_FILTER); |
| 849 | } | 847 | } |
| 850 | 848 | ||
| 851 | spin_unlock_bh(&adapter->mac_vlan_list_lock); | 849 | spin_unlock_bh(&adapter->mac_vlan_list_lock); |
| @@ -1421,7 +1419,8 @@ void iavf_down(struct iavf_adapter *adapter) · 569 unmodified lines | |||
| 1421 | iavf_clear_fdir_filters(adapter); | 1419 | iavf_clear_fdir_filters(adapter); |
| 1422 | iavf_clear_adv_rss_conf(adapter); | 1420 | iavf_clear_adv_rss_conf(adapter); |
| 1423 | 1421 | ||
| 1424 | if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) { | 1422 | if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) && |
| 1423 | !(test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))) { | ||
| 1425 | /* cancel any current operation */ | 1424 | /* cancel any current operation */ |
| 1426 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; | 1425 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
| 1427 | /* Schedule operations to close down the HW. Don't wait | 1426 | /* Schedule operations to close down the HW. Don't wait |
| @@ -3827,8 +3827,11 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit) · 3826 unmodified lines | |||
| 3827 | } | 3827 | } |
| 3828 | 3828 | ||
| 3829 | /* only call pci_enable_sriov() if no VFs are allocated already */ | 3829 | /* only call pci_enable_sriov() if no VFs are allocated already */ |
| 3830 | if (!old_vfs) | 3830 | if (!old_vfs) { |
| 3831 | err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); | 3831 | err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); |
| 3832 | if (err) | ||
| 3833 | goto err_out; | ||
| 3834 | } | ||
| 3832 | 3835 | ||
| 3833 | goto out; | 3836 | goto out; |
| 3834 | 3837 | ||
| @@ -868,6 +868,18 @@ static void igc_ethtool_get_stats(struct net_device *netdev, · 867 unmodified lines | |||
| 868 | spin_unlock(&adapter->stats64_lock); | 868 | spin_unlock(&adapter->stats64_lock); |
| 869 | } | 869 | } |
| 870 | 870 | ||
| 871 | static int igc_ethtool_get_previous_rx_coalesce(struct igc_adapter *adapter) | ||
| 872 | { | ||
| 873 | return (adapter->rx_itr_setting <= 3) ? | ||
| 874 | adapter->rx_itr_setting : adapter->rx_itr_setting >> 2; | ||
| 875 | } | ||
| 876 | |||
| 877 | static int igc_ethtool_get_previous_tx_coalesce(struct igc_adapter *adapter) | ||
| 878 | { | ||
| 879 | return (adapter->tx_itr_setting <= 3) ? | ||
| 880 | adapter->tx_itr_setting : adapter->tx_itr_setting >> 2; | ||
| 881 | } | ||
| 882 | |||
| 871 | static int igc_ethtool_get_coalesce(struct net_device *netdev, | 883 | static int igc_ethtool_get_coalesce(struct net_device *netdev, |
| 872 | struct ethtool_coalesce *ec, | 884 | struct ethtool_coalesce *ec, |
| 873 | struct kernel_ethtool_coalesce *kernel_coal, | 885 | struct kernel_ethtool_coalesce *kernel_coal, |
| @@ -875,17 +887,8 @@ static int igc_ethtool_get_coalesce(struct net_device *netdev, · 1 unmodified line | |||
| 875 | { | 887 | { |
| 876 | struct igc_adapter *adapter = netdev_priv(netdev); | 888 | struct igc_adapter *adapter = netdev_priv(netdev); |
| 877 | 889 | ||
| 878 | if (adapter->rx_itr_setting <= 3) | 890 | ec->rx_coalesce_usecs = igc_ethtool_get_previous_rx_coalesce(adapter); |
| 879 | ec->rx_coalesce_usecs = adapter->rx_itr_setting; | 891 | ec->tx_coalesce_usecs = igc_ethtool_get_previous_tx_coalesce(adapter); |
| 880 | else | ||
| 881 | ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; | ||
| 882 | |||
| 883 | if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS)) { | ||
| 884 | if (adapter->tx_itr_setting <= 3) | ||
| 885 | ec->tx_coalesce_usecs = adapter->tx_itr_setting; | ||
| 886 | else | ||
| 887 | ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; | ||
| 888 | } | ||
| 889 | 892 | ||
| 890 | return 0; | 893 | return 0; |
| 891 | } | 894 | } |
| @@ -910,8 +913,12 @@ static int igc_ethtool_set_coalesce(struct net_device *netdev, · 18 unmodified lines | |||
| 910 | ec->tx_coalesce_usecs == 2) | 913 | ec->tx_coalesce_usecs == 2) |
| 911 | return -EINVAL; | 914 | return -EINVAL; |
| 912 | 915 | ||
| 913 | if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) | 916 | if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && |
| 917 | ec->tx_coalesce_usecs != igc_ethtool_get_previous_tx_coalesce(adapter)) { | ||
| 918 | NL_SET_ERR_MSG_MOD(extack, | ||
| 919 | "Queue Pair mode enabled, both Rx and Tx coalescing controlled by rx-usecs"); | ||
| 914 | return -EINVAL; | 920 | return -EINVAL; |
| 921 | } | ||
| 915 | 922 | ||
| 916 | /* If ITR is disabled, disable DMAC */ | 923 | /* If ITR is disabled, disable DMAC */ |
| 917 | if (ec->rx_coalesce_usecs == 0) { | 924 | if (ec->rx_coalesce_usecs == 0) { |
| @@ -6491,7 +6491,7 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames, · 6490 unmodified lines | |||
| 6491 | struct igc_ring *ring; | 6491 | struct igc_ring *ring; |
| 6492 | int i, drops; | 6492 | int i, drops; |
| 6493 | 6493 | ||
| 6494 | if (unlikely(test_bit(__IGC_DOWN, &adapter->state))) | 6494 | if (unlikely(!netif_carrier_ok(dev))) |
| 6495 | return -ENETDOWN; | 6495 | return -ENETDOWN; |
| 6496 | 6496 | ||
| 6497 | if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) | 6497 | if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) |
| @@ -979,6 +979,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 978 unmodified lines | |||
| 979 | u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; | 979 | u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; |
| 980 | u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; | 980 | u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; |
| 981 | u32 tsync_rx_mtrl = PTP_EV_PORT << 16; | 981 | u32 tsync_rx_mtrl = PTP_EV_PORT << 16; |
| 982 | u32 aflags = adapter->flags; | ||
| 982 | bool is_l2 = false; | 983 | bool is_l2 = false; |
| 983 | u32 regval; | 984 | u32 regval; |
| 984 | 985 | ||
| @@ -996,20 +997,20 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 11 unmodified lines | |||
| 996 | case HWTSTAMP_FILTER_NONE: | 997 | case HWTSTAMP_FILTER_NONE: |
| 997 | tsync_rx_ctl = 0; | 998 | tsync_rx_ctl = 0; |
| 998 | tsync_rx_mtrl = 0; | 999 | tsync_rx_mtrl = 0; |
| 999 | adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | 1000 | aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | |
| 1000 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | 1001 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); |
| 1001 | break; | 1002 | break; |
| 1002 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | 1003 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
| 1003 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | 1004 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
| 1004 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; | 1005 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; |
| 1005 | adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | 1006 | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | |
| 1006 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | 1007 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); |
| 1007 | break; | 1008 | break; |
| 1008 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | 1009 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
| 1009 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | 1010 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
| 1010 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; | 1011 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; |
| 1011 | adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | 1012 | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | |
| 1012 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | 1013 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); |
| 1013 | break; | 1014 | break; |
| 1014 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | 1015 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
| 1015 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | 1016 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
| @@ -1023,8 +1024,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 7 unmodified lines | |||
| 1023 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; | 1024 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; |
| 1024 | is_l2 = true; | 1025 | is_l2 = true; |
| 1025 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | 1026 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
| 1026 | adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | 1027 | aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | |
| 1027 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | 1028 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); |
| 1028 | break; | 1029 | break; |
| 1029 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | 1030 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
| 1030 | case HWTSTAMP_FILTER_NTP_ALL: | 1031 | case HWTSTAMP_FILTER_NTP_ALL: |
| @@ -1035,7 +1036,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 4 unmodified lines | |||
| 1035 | if (hw->mac.type >= ixgbe_mac_X550) { | 1036 | if (hw->mac.type >= ixgbe_mac_X550) { |
| 1036 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; | 1037 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; |
| 1037 | config->rx_filter = HWTSTAMP_FILTER_ALL; | 1038 | config->rx_filter = HWTSTAMP_FILTER_ALL; |
| 1038 | adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | 1039 | aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; |
| 1039 | break; | 1040 | break; |
| 1040 | } | 1041 | } |
| 1041 | fallthrough; | 1042 | fallthrough; |
| @@ -1046,8 +1047,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 4 unmodified lines | |||
| 1046 | * Delay_Req messages and hardware does not support | 1047 | * Delay_Req messages and hardware does not support |
| 1047 | * timestamping all packets => return error | 1048 | * timestamping all packets => return error |
| 1048 | */ | 1049 | */ |
| 1049 | adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | ||
| 1050 | IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | ||
| 1051 | config->rx_filter = HWTSTAMP_FILTER_NONE; | 1050 | config->rx_filter = HWTSTAMP_FILTER_NONE; |
| 1052 | return -ERANGE; | 1051 | return -ERANGE; |
| 1053 | } | 1052 | } |
| @@ -1079,8 +1078,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 25 unmodified lines | |||
| 1079 | IXGBE_TSYNCRXCTL_TYPE_ALL | | 1078 | IXGBE_TSYNCRXCTL_TYPE_ALL | |
| 1080 | IXGBE_TSYNCRXCTL_TSIP_UT_EN; | 1079 | IXGBE_TSYNCRXCTL_TSIP_UT_EN; |
| 1081 | config->rx_filter = HWTSTAMP_FILTER_ALL; | 1080 | config->rx_filter = HWTSTAMP_FILTER_ALL; |
| 1082 | adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | 1081 | aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; |
| 1083 | adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; | 1082 | aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; |
| 1084 | is_l2 = true; | 1083 | is_l2 = true; |
| 1085 | break; | 1084 | break; |
| 1086 | default: | 1085 | default: |
| @@ -1113,6 +1112,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 26 unmodified lines | |||
| 1113 | 1112 | ||
| 1114 | IXGBE_WRITE_FLUSH(hw); | 1113 | IXGBE_WRITE_FLUSH(hw); |
| 1115 | 1114 | ||
| 1115 | /* configure adapter flags only when HW is actually configured */ | ||
| 1116 | adapter->flags = aflags; | ||
| 1117 | |||
| 1116 | /* clear TX/RX time stamp registers, just to be sure */ | 1118 | /* clear TX/RX time stamp registers, just to be sure */ |
| 1117 | ixgbe_ptp_clear_tx_timestamp(adapter); | 1119 | ixgbe_ptp_clear_tx_timestamp(adapter); |
| 1118 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); | 1120 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); |
| @@ -5586,6 +5586,11 @@ static int mvpp2_ethtool_get_rxnfc(struct net_device *dev, · 5585 unmodified lines | |||
| 5586 | break; | 5586 | break; |
| 5587 | case ETHTOOL_GRXCLSRLALL: | 5587 | case ETHTOOL_GRXCLSRLALL: |
| 5588 | for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { | 5588 | for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { |
| 5589 | if (loc == info->rule_cnt) { | ||
| 5590 | ret = -EMSGSIZE; | ||
| 5591 | break; | ||
| 5592 | } | ||
| 5593 | |||
| 5589 | if (port->rfs_rules[i]) | 5594 | if (port->rfs_rules[i]) |
| 5590 | rules[loc++] = i; | 5595 | rules[loc++] = i; |
| 5591 | } | 5596 | } |
| @@ -734,13 +734,13 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb, · 733 unmodified lines | |||
| 734 | dma_map_sg_err: | 734 | dma_map_sg_err: |
| 735 | if (si > 0) { | 735 | if (si > 0) { |
| 736 | dma_unmap_single(iq->dev, sglist[0].dma_ptr[0], | 736 | dma_unmap_single(iq->dev, sglist[0].dma_ptr[0], |
| 737 | sglist[0].len[0], DMA_TO_DEVICE); | 737 | sglist[0].len[3], DMA_TO_DEVICE); |
| 738 | sglist[0].len[0] = 0; | 738 | sglist[0].len[3] = 0; |
| 739 | } | 739 | } |
| 740 | while (si > 1) { | 740 | while (si > 1) { |
| 741 | dma_unmap_page(iq->dev, sglist[si >> 2].dma_ptr[si & 3], | 741 | dma_unmap_page(iq->dev, sglist[si >> 2].dma_ptr[si & 3], |
| 742 | sglist[si >> 2].len[si & 3], DMA_TO_DEVICE); | 742 | sglist[si >> 2].len[3 - (si & 3)], DMA_TO_DEVICE); |
| 743 | sglist[si >> 2].len[si & 3] = 0; | 743 | sglist[si >> 2].len[3 - (si & 3)] = 0; |
| 744 | si--; | 744 | si--; |
| 745 | } | 745 | } |
| 746 | tx_buffer->gather = 0; | 746 | tx_buffer->gather = 0; |
| @@ -69,12 +69,12 @@ int octep_iq_process_completions(struct octep_iq *iq, u16 budget) · 68 unmodified lines | |||
| 69 | compl_sg++; | 69 | compl_sg++; |
| 70 | 70 | ||
| 71 | dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0], | 71 | dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0], |
| 72 | tx_buffer->sglist[0].len[0], DMA_TO_DEVICE); | 72 | tx_buffer->sglist[0].len[3], DMA_TO_DEVICE); |
| 73 | 73 | ||
| 74 | i = 1; /* entry 0 is main skb, unmapped above */ | 74 | i = 1; /* entry 0 is main skb, unmapped above */ |
| 75 | while (frags--) { | 75 | while (frags--) { |
| 76 | dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], | 76 | dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], |
| 77 | tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); | 77 | tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); |
| 78 | i++; | 78 | i++; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| @@ -131,13 +131,13 @@ static void octep_iq_free_pending(struct octep_iq *iq) · 50 unmodified lines | |||
| 131 | 131 | ||
| 132 | dma_unmap_single(iq->dev, | 132 | dma_unmap_single(iq->dev, |
| 133 | tx_buffer->sglist[0].dma_ptr[0], | 133 | tx_buffer->sglist[0].dma_ptr[0], |
| 134 | tx_buffer->sglist[0].len[0], | 134 | tx_buffer->sglist[0].len[3], |
| 135 | DMA_TO_DEVICE); | 135 | DMA_TO_DEVICE); |
| 136 | 136 | ||
| 137 | i = 1; /* entry 0 is main skb, unmapped above */ | 137 | i = 1; /* entry 0 is main skb, unmapped above */ |
| 138 | while (frags--) { | 138 | while (frags--) { |
| 139 | dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], | 139 | dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], |
| 140 | tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); | 140 | tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); |
| 141 | i++; | 141 | i++; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| @@ -17,7 +17,21 @@ · 16 unmodified lines | |||
| 17 | #define TX_BUFTYPE_NET_SG 2 | 17 | #define TX_BUFTYPE_NET_SG 2 |
| 18 | #define NUM_TX_BUFTYPES 3 | 18 | #define NUM_TX_BUFTYPES 3 |
| 19 | 19 | ||
| 20 | /* Hardware format for Scatter/Gather list */ | 20 | /* Hardware format for Scatter/Gather list |
| 21 | * | ||
| 22 | * 63 48|47 32|31 16|15 0 | ||
| 23 | * ----------------------------------------- | ||
| 24 | * | Len 0 | Len 1 | Len 2 | Len 3 | | ||
| 25 | * ----------------------------------------- | ||
| 26 | * | Ptr 0 | | ||
| 27 | * ----------------------------------------- | ||
| 28 | * | Ptr 1 | | ||
| 29 | * ----------------------------------------- | ||
| 30 | * | Ptr 2 | | ||
| 31 | * ----------------------------------------- | ||
| 32 | * | Ptr 3 | | ||
| 33 | * ----------------------------------------- | ||
| 34 | */ | ||
| 21 | struct octep_tx_sglist_desc { | 35 | struct octep_tx_sglist_desc { |
| 22 | u16 len[4]; | 36 | u16 len[4]; |
| 23 | dma_addr_t dma_ptr[4]; | 37 | dma_addr_t dma_ptr[4]; |
| @@ -107,12 +107,13 @@ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura) · 106 unmodified lines | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | #define NPA_MAX_BURST 16 | 109 | #define NPA_MAX_BURST 16 |
| 110 | void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | 110 | int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) |
| 111 | { | 111 | { |
| 112 | struct otx2_nic *pfvf = dev; | 112 | struct otx2_nic *pfvf = dev; |
| 113 | int cnt = cq->pool_ptrs; | ||
| 113 | u64 ptrs[NPA_MAX_BURST]; | 114 | u64 ptrs[NPA_MAX_BURST]; |
| 114 | int num_ptrs = 1; | ||
| 115 | dma_addr_t bufptr; | 115 | dma_addr_t bufptr; |
| 116 | int num_ptrs = 1; | ||
| 116 | 117 | ||
| 117 | /* Refill pool with new buffers */ | 118 | /* Refill pool with new buffers */ |
| 118 | while (cq->pool_ptrs) { | 119 | while (cq->pool_ptrs) { |
| @@ -131,6 +132,7 @@ void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) · 12 unmodified lines | |||
| 131 | num_ptrs = 1; | 132 | num_ptrs = 1; |
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 135 | return cnt - cq->pool_ptrs; | ||
| 134 | } | 136 | } |
| 135 | 137 | ||
| 136 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx) | 138 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx) |
| @@ -24,7 +24,7 @@ static inline int mtu_to_dwrr_weight(struct otx2_nic *pfvf, int mtu) · 23 unmodified lines | |||
| 24 | return weight; | 24 | return weight; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | 27 | int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); |
| 28 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx); | 28 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx); |
| 29 | int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); | 29 | int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); |
| 30 | int cn10k_lmtst_init(struct otx2_nic *pfvf); | 30 | int cn10k_lmtst_init(struct otx2_nic *pfvf); |
| @@ -574,20 +574,8 @@ int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, · 573 unmodified lines | |||
| 574 | int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, | 574 | int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, |
| 575 | dma_addr_t *dma) | 575 | dma_addr_t *dma) |
| 576 | { | 576 | { |
| 577 | if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) { | 577 | if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) |
| 578 | struct refill_work *work; | ||
| 579 | struct delayed_work *dwork; | ||
| 580 | |||
| 581 | work = &pfvf->refill_wrk[cq->cq_idx]; | ||
| 582 | dwork = &work->pool_refill_work; | ||
| 583 | /* Schedule a task if no other task is running */ | ||
| 584 | if (!cq->refill_task_sched) { | ||
| 585 | cq->refill_task_sched = true; | ||
| 586 | schedule_delayed_work(dwork, | ||
| 587 | msecs_to_jiffies(100)); | ||
| 588 | } | ||
| 589 | return -ENOMEM; | 578 | return -ENOMEM; |
| 590 | } | ||
| 591 | return 0; | 579 | return 0; |
| 592 | } | 580 | } |
| 593 | 581 | ||
| @@ -1082,39 +1070,20 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx) · 488 unmodified lines | |||
| 1082 | static void otx2_pool_refill_task(struct work_struct *work) | 1070 | static void otx2_pool_refill_task(struct work_struct *work) |
| 1083 | { | 1071 | { |
| 1084 | struct otx2_cq_queue *cq; | 1072 | struct otx2_cq_queue *cq; |
| 1085 | struct otx2_pool *rbpool; | ||
| 1086 | struct refill_work *wrk; | 1073 | struct refill_work *wrk; |
| 1087 | int qidx, free_ptrs = 0; | ||
| 1088 | struct otx2_nic *pfvf; | 1074 | struct otx2_nic *pfvf; |
| 1089 | dma_addr_t bufptr; | 1075 | int qidx; |
| 1090 | 1076 | ||
| 1091 | wrk = container_of(work, struct refill_work, pool_refill_work.work); | 1077 | wrk = container_of(work, struct refill_work, pool_refill_work.work); |
| 1092 | pfvf = wrk->pf; | 1078 | pfvf = wrk->pf; |
| 1093 | qidx = wrk - pfvf->refill_wrk; | 1079 | qidx = wrk - pfvf->refill_wrk; |
| 1094 | cq = &pfvf->qset.cq[qidx]; | 1080 | cq = &pfvf->qset.cq[qidx]; |
| 1095 | rbpool = cq->rbpool; | ||
| 1096 | free_ptrs = cq->pool_ptrs; | ||
| 1097 | 1081 | ||
| 1098 | while (cq->pool_ptrs) { | ||
| 1099 | if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) { | ||
| 1100 | /* Schedule a WQ if we fails to free atleast half of the | ||
| 1101 | * pointers else enable napi for this RQ. | ||
| 1102 | */ | ||
| 1103 | if (!((free_ptrs - cq->pool_ptrs) > free_ptrs / 2)) { | ||
| 1104 | struct delayed_work *dwork; | ||
| 1105 | |||
| 1106 | dwork = &wrk->pool_refill_work; | ||
| 1107 | schedule_delayed_work(dwork, | ||
| 1108 | msecs_to_jiffies(100)); | ||
| 1109 | } else { | ||
| 1110 | cq->refill_task_sched = false; | ||
| 1111 | } | ||
| 1112 | return; | ||
| 1113 | } | ||
| 1114 | pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM); | ||
| 1115 | cq->pool_ptrs--; | ||
| 1116 | } | ||
| 1117 | cq->refill_task_sched = false; | 1082 | cq->refill_task_sched = false; |
| 1083 | |||
| 1084 | local_bh_disable(); | ||
| 1085 | napi_schedule(wrk->napi); | ||
| 1086 | local_bh_enable(); | ||
| 1118 | } | 1087 | } |
| 1119 | 1088 | ||
| 1120 | int otx2_config_nix_queues(struct otx2_nic *pfvf) | 1089 | int otx2_config_nix_queues(struct otx2_nic *pfvf) |
| @@ -302,6 +302,7 @@ struct flr_work { · 301 unmodified lines | |||
| 302 | struct refill_work { | 302 | struct refill_work { |
| 303 | struct delayed_work pool_refill_work; | 303 | struct delayed_work pool_refill_work; |
| 304 | struct otx2_nic *pf; | 304 | struct otx2_nic *pf; |
| 305 | struct napi_struct *napi; | ||
| 305 | }; | 306 | }; |
| 306 | 307 | ||
| 307 | /* PTPv2 originTimestamp structure */ | 308 | /* PTPv2 originTimestamp structure */ |
| @@ -370,7 +371,7 @@ struct dev_hw_ops { · 62 unmodified lines | |||
| 370 | int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura); | 371 | int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura); |
| 371 | void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq, | 372 | void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq, |
| 372 | int size, int qidx); | 373 | int size, int qidx); |
| 373 | void (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); | 374 | int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); |
| 374 | void (*aura_freeptr)(void *dev, int aura, u64 buf); | 375 | void (*aura_freeptr)(void *dev, int aura, u64 buf); |
| 375 | }; | 376 | }; |
| 376 | 377 | ||
| @@ -1943,6 +1943,10 @@ int otx2_stop(struct net_device *netdev) · 1942 unmodified lines | |||
| 1943 | 1943 | ||
| 1944 | netif_tx_disable(netdev); | 1944 | netif_tx_disable(netdev); |
| 1945 | 1945 | ||
| 1946 | for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++) | ||
| 1947 | cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work); | ||
| 1948 | devm_kfree(pf->dev, pf->refill_wrk); | ||
| 1949 | |||
| 1946 | otx2_free_hw_resources(pf); | 1950 | otx2_free_hw_resources(pf); |
| 1947 | otx2_free_cints(pf, pf->hw.cint_cnt); | 1951 | otx2_free_cints(pf, pf->hw.cint_cnt); |
| 1948 | otx2_disable_napi(pf); | 1952 | otx2_disable_napi(pf); |
| @@ -1950,9 +1954,6 @@ int otx2_stop(struct net_device *netdev) · 1 unmodified line | |||
| 1950 | for (qidx = 0; qidx < netdev->num_tx_queues; qidx++) | 1954 | for (qidx = 0; qidx < netdev->num_tx_queues; qidx++) |
| 1951 | netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx)); | 1955 | netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx)); |
| 1952 | 1956 | ||
| 1953 | for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++) | ||
| 1954 | cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work); | ||
| 1955 | devm_kfree(pf->dev, pf->refill_wrk); | ||
| 1956 | 1957 | ||
| 1957 | kfree(qset->sq); | 1958 | kfree(qset->sq); |
| 1958 | kfree(qset->cq); | 1959 | kfree(qset->cq); |
| @@ -29,7 +29,8 @@ · 28 unmodified lines | |||
| 29 | static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, | 29 | static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, |
| 30 | struct bpf_prog *prog, | 30 | struct bpf_prog *prog, |
| 31 | struct nix_cqe_rx_s *cqe, | 31 | struct nix_cqe_rx_s *cqe, |
| 32 | struct otx2_cq_queue *cq); | 32 | struct otx2_cq_queue *cq, |
| 33 | bool *need_xdp_flush); | ||
| 33 | 34 | ||
| 34 | static int otx2_nix_cq_op_status(struct otx2_nic *pfvf, | 35 | static int otx2_nix_cq_op_status(struct otx2_nic *pfvf, |
| 35 | struct otx2_cq_queue *cq) | 36 | struct otx2_cq_queue *cq) |
| @@ -337,7 +338,7 @@ static bool otx2_check_rcv_errors(struct otx2_nic *pfvf, · 301 unmodified lines | |||
| 337 | static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, | 338 | static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, |
| 338 | struct napi_struct *napi, | 339 | struct napi_struct *napi, |
| 339 | struct otx2_cq_queue *cq, | 340 | struct otx2_cq_queue *cq, |
| 340 | struct nix_cqe_rx_s *cqe) | 341 | struct nix_cqe_rx_s *cqe, bool *need_xdp_flush) |
| 341 | { | 342 | { |
| 342 | struct nix_rx_parse_s *parse = &cqe->parse; | 343 | struct nix_rx_parse_s *parse = &cqe->parse; |
| 343 | struct nix_rx_sg_s *sg = &cqe->sg; | 344 | struct nix_rx_sg_s *sg = &cqe->sg; |
| @@ -353,7 +354,7 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, · 9 unmodified lines | |||
| 353 | } | 354 | } |
| 354 | 355 | ||
| 355 | if (pfvf->xdp_prog) | 356 | if (pfvf->xdp_prog) |
| 356 | if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq)) | 357 | if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq, need_xdp_flush)) |
| 357 | return; | 358 | return; |
| 358 | 359 | ||
| 359 | skb = napi_get_frags(napi); | 360 | skb = napi_get_frags(napi); |
| @@ -388,6 +389,7 @@ static int otx2_rx_napi_handler(struct otx2_nic *pfvf, · 28 unmodified lines | |||
| 388 | struct napi_struct *napi, | 389 | struct napi_struct *napi, |
| 389 | struct otx2_cq_queue *cq, int budget) | 390 | struct otx2_cq_queue *cq, int budget) |
| 390 | { | 391 | { |
| 392 | bool need_xdp_flush = false; | ||
| 391 | struct nix_cqe_rx_s *cqe; | 393 | struct nix_cqe_rx_s *cqe; |
| 392 | int processed_cqe = 0; | 394 | int processed_cqe = 0; |
| 393 | 395 | ||
| @@ -409,13 +411,15 @@ process_cqe: · 15 unmodified lines | |||
| 409 | cq->cq_head++; | 411 | cq->cq_head++; |
| 410 | cq->cq_head &= (cq->cqe_cnt - 1); | 412 | cq->cq_head &= (cq->cqe_cnt - 1); |
| 411 | 413 | ||
| 412 | otx2_rcv_pkt_handler(pfvf, napi, cq, cqe); | 414 | otx2_rcv_pkt_handler(pfvf, napi, cq, cqe, &need_xdp_flush); |
| 413 | 415 | ||
| 414 | cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; | 416 | cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; |
| 415 | cqe->sg.seg_addr = 0x00; | 417 | cqe->sg.seg_addr = 0x00; |
| 416 | processed_cqe++; | 418 | processed_cqe++; |
| 417 | cq->pend_cqe--; | 419 | cq->pend_cqe--; |
| 418 | } | 420 | } |
| 421 | if (need_xdp_flush) | ||
| 422 | xdp_do_flush(); | ||
| 419 | 423 | ||
| 420 | /* Free CQEs to HW */ | 424 | /* Free CQEs to HW */ |
| 421 | otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, | 425 | otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, |
| @@ -424,9 +428,10 @@ process_cqe: · 2 unmodified lines | |||
| 424 | return processed_cqe; | 428 | return processed_cqe; |
| 425 | } | 429 | } |
| 426 | 430 | ||
| 427 | void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | 431 | int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) |
| 428 | { | 432 | { |
| 429 | struct otx2_nic *pfvf = dev; | 433 | struct otx2_nic *pfvf = dev; |
| 434 | int cnt = cq->pool_ptrs; | ||
| 430 | dma_addr_t bufptr; | 435 | dma_addr_t bufptr; |
| 431 | 436 | ||
| 432 | while (cq->pool_ptrs) { | 437 | while (cq->pool_ptrs) { |
| @@ -435,6 +440,8 @@ void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) · 2 unmodified lines | |||
| 435 | otx2_aura_freeptr(pfvf, cq->cq_idx, bufptr + OTX2_HEAD_ROOM); | 440 | otx2_aura_freeptr(pfvf, cq->cq_idx, bufptr + OTX2_HEAD_ROOM); |
| 436 | cq->pool_ptrs--; | 441 | cq->pool_ptrs--; |
| 437 | } | 442 | } |
| 443 | |||
| 444 | return cnt - cq->pool_ptrs; | ||
| 438 | } | 445 | } |
| 439 | 446 | ||
| 440 | static int otx2_tx_napi_handler(struct otx2_nic *pfvf, | 447 | static int otx2_tx_napi_handler(struct otx2_nic *pfvf, |
| @@ -521,6 +528,7 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 80 unmodified lines | |||
| 521 | struct otx2_cq_queue *cq; | 528 | struct otx2_cq_queue *cq; |
| 522 | struct otx2_qset *qset; | 529 | struct otx2_qset *qset; |
| 523 | struct otx2_nic *pfvf; | 530 | struct otx2_nic *pfvf; |
| 531 | int filled_cnt = -1; | ||
| 524 | 532 | ||
| 525 | cq_poll = container_of(napi, struct otx2_cq_poll, napi); | 533 | cq_poll = container_of(napi, struct otx2_cq_poll, napi); |
| 526 | pfvf = (struct otx2_nic *)cq_poll->dev; | 534 | pfvf = (struct otx2_nic *)cq_poll->dev; |
| @@ -541,7 +549,7 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 14 unmodified lines | |||
| 541 | } | 549 | } |
| 542 | 550 | ||
| 543 | if (rx_cq && rx_cq->pool_ptrs) | 551 | if (rx_cq && rx_cq->pool_ptrs) |
| 544 | pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq); | 552 | filled_cnt = pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq); |
| 545 | /* Clear the IRQ */ | 553 | /* Clear the IRQ */ |
| 546 | otx2_write64(pfvf, NIX_LF_CINTX_INT(cq_poll->cint_idx), BIT_ULL(0)); | 554 | otx2_write64(pfvf, NIX_LF_CINTX_INT(cq_poll->cint_idx), BIT_ULL(0)); |
| 547 | 555 | ||
| @@ -561,9 +569,25 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 13 unmodified lines | |||
| 561 | otx2_config_irq_coalescing(pfvf, i); | 569 | otx2_config_irq_coalescing(pfvf, i); |
| 562 | } | 570 | } |
| 563 | 571 | ||
| 564 | /* Re-enable interrupts */ | 572 | if (unlikely(!filled_cnt)) { |
| 565 | otx2_write64(pfvf, NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), | 573 | struct refill_work *work; |
| 566 | BIT_ULL(0)); | 574 | struct delayed_work *dwork; |
| 575 | |||
| 576 | work = &pfvf->refill_wrk[cq->cq_idx]; | ||
| 577 | dwork = &work->pool_refill_work; | ||
| 578 | /* Schedule a task if no other task is running */ | ||
| 579 | if (!cq->refill_task_sched) { | ||
| 580 | work->napi = napi; | ||
| 581 | cq->refill_task_sched = true; | ||
| 582 | schedule_delayed_work(dwork, | ||
| 583 | msecs_to_jiffies(100)); | ||
| 584 | } | ||
| 585 | } else { | ||
| 586 | /* Re-enable interrupts */ | ||
| 587 | otx2_write64(pfvf, | ||
| 588 | NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), | ||
| 589 | BIT_ULL(0)); | ||
| 590 | } | ||
| 567 | } | 591 | } |
| 568 | return workdone; | 592 | return workdone; |
| 569 | } | 593 | } |
| @@ -1334,7 +1358,8 @@ bool otx2_xdp_sq_append_pkt(struct otx2_nic *pfvf, u64 iova, int len, u16 qidx) · 764 unmodified lines | |||
| 1334 | static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, | 1358 | static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, |
| 1335 | struct bpf_prog *prog, | 1359 | struct bpf_prog *prog, |
| 1336 | struct nix_cqe_rx_s *cqe, | 1360 | struct nix_cqe_rx_s *cqe, |
| 1337 | struct otx2_cq_queue *cq) | 1361 | struct otx2_cq_queue *cq, |
| 1362 | bool *need_xdp_flush) | ||
| 1338 | { | 1363 | { |
| 1339 | unsigned char *hard_start, *data; | 1364 | unsigned char *hard_start, *data; |
| 1340 | int qidx = cq->cq_idx; | 1365 | int qidx = cq->cq_idx; |
| @@ -1371,8 +1396,10 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, · 30 unmodified lines | |||
| 1371 | 1396 | ||
| 1372 | otx2_dma_unmap_page(pfvf, iova, pfvf->rbsize, | 1397 | otx2_dma_unmap_page(pfvf, iova, pfvf->rbsize, |
| 1373 | DMA_FROM_DEVICE); | 1398 | DMA_FROM_DEVICE); |
| 1374 | if (!err) | 1399 | if (!err) { |
| 1400 | *need_xdp_flush = true; | ||
| 1375 | return true; | 1401 | return true; |
| 1402 | } | ||
| 1376 | put_page(page); | 1403 | put_page(page); |
| 1377 | break; | 1404 | break; |
| 1378 | default: | 1405 | default: |
| @@ -170,6 +170,6 @@ void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, · 169 unmodified lines | |||
| 170 | int size, int qidx); | 170 | int size, int qidx); |
| 171 | void otx2_sqe_flush(void *dev, struct otx2_snd_queue *sq, | 171 | void otx2_sqe_flush(void *dev, struct otx2_snd_queue *sq, |
| 172 | int size, int qidx); | 172 | int size, int qidx); |
| 173 | void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | 173 | int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); |
| 174 | void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | 174 | int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); |
| 175 | #endif /* OTX2_TXRX_H */ | 175 | #endif /* OTX2_TXRX_H */ |
| @@ -2005,11 +2005,11 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, · 2004 unmodified lines | |||
| 2005 | u8 *data, *new_data; | 2005 | u8 *data, *new_data; |
| 2006 | struct mtk_rx_dma_v2 *rxd, trxd; | 2006 | struct mtk_rx_dma_v2 *rxd, trxd; |
| 2007 | int done = 0, bytes = 0; | 2007 | int done = 0, bytes = 0; |
| 2008 | dma_addr_t dma_addr = DMA_MAPPING_ERROR; | ||
| 2008 | 2009 | ||
| 2009 | while (done < budget) { | 2010 | while (done < budget) { |
| 2010 | unsigned int pktlen, *rxdcsum; | 2011 | unsigned int pktlen, *rxdcsum; |
| 2011 | struct net_device *netdev; | 2012 | struct net_device *netdev; |
| 2012 | dma_addr_t dma_addr; | ||
| 2013 | u32 hash, reason; | 2013 | u32 hash, reason; |
| 2014 | int mac = 0; | 2014 | int mac = 0; |
| 2015 | 2015 | ||
| @@ -2186,7 +2186,8 @@ release_desc: · 170 unmodified lines | |||
| 2186 | else | 2186 | else |
| 2187 | rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); | 2187 | rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); |
| 2188 | 2188 | ||
| 2189 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) | 2189 | if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && |
| 2190 | likely(dma_addr != DMA_MAPPING_ERROR)) | ||
| 2190 | rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); | 2191 | rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); |
| 2191 | 2192 | ||
| 2192 | ring->calc_idx = idx; | 2193 | ring->calc_idx = idx; |
| @@ -2994,6 +2995,9 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev, · 801 unmodified lines | |||
| 2994 | int i; | 2995 | int i; |
| 2995 | 2996 | ||
| 2996 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { | 2997 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { |
| 2998 | if (cnt == cmd->rule_cnt) | ||
| 2999 | return -EMSGSIZE; | ||
| 3000 | |||
| 2997 | if (mac->hwlro_ip[i]) { | 3001 | if (mac->hwlro_ip[i]) { |
| 2998 | rule_locs[cnt] = i; | 3002 | rule_locs[cnt] = i; |
| 2999 | cnt++; | 3003 | cnt++; |
| @@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, · 213 unmodified lines | |||
| 214 | dsa_port = mtk_flow_get_dsa_port(&dev); | 214 | dsa_port = mtk_flow_get_dsa_port(&dev); |
| 215 | 215 | ||
| 216 | if (dev == eth->netdev[0]) | 216 | if (dev == eth->netdev[0]) |
| 217 | pse_port = 1; | 217 | pse_port = PSE_GDM1_PORT; |
| 218 | else if (dev == eth->netdev[1]) | 218 | else if (dev == eth->netdev[1]) |
| 219 | pse_port = 2; | 219 | pse_port = PSE_GDM2_PORT; |
| 220 | else if (dev == eth->netdev[2]) | ||
| 221 | pse_port = PSE_GDM3_PORT; | ||
| 220 | else | 222 | else |
| 221 | return -EOPNOTSUPP; | 223 | return -EOPNOTSUPP; |
| 222 | 224 | ||
| @@ -1021,18 +1021,32 @@ static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri, · 1020 unmodified lines | |||
| 1021 | list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) { | 1021 | list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) { |
| 1022 | newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL); | 1022 | newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL); |
| 1023 | if (!newckf) | 1023 | if (!newckf) |
| 1024 | return ERR_PTR(-ENOMEM); | 1024 | goto err; |
| 1025 | list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields); | 1025 | list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields); |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| 1028 | list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) { | 1028 | list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) { |
| 1029 | newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL); | 1029 | newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL); |
| 1030 | if (!newcaf) | 1030 | if (!newcaf) |
| 1031 | return ERR_PTR(-ENOMEM); | 1031 | goto err; |
| 1032 | list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields); | 1032 | list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields); |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| 1035 | return duprule; | 1035 | return duprule; |
| 1036 | |||
| 1037 | err: | ||
| 1038 | list_for_each_entry_safe(ckf, newckf, &duprule->data.keyfields, ctrl.list) { | ||
| 1039 | list_del(&ckf->ctrl.list); | ||
| 1040 | kfree(ckf); | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | list_for_each_entry_safe(caf, newcaf, &duprule->data.actionfields, ctrl.list) { | ||
| 1044 | list_del(&caf->ctrl.list); | ||
| 1045 | kfree(caf); | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | kfree(duprule); | ||
| 1049 | return ERR_PTR(-ENOMEM); | ||
| 1036 | } | 1050 | } |
| 1037 | 1051 | ||
| 1038 | static void vcap_apply_width(u8 *dst, int width, int bytes) | 1052 | static void vcap_apply_width(u8 *dst, int width, int bytes) |
| @@ -243,10 +243,9 @@ static void vcap_test_api_init(struct vcap_admin *admin) · 242 unmodified lines | |||
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | /* Helper function to create a rule of a specific size */ | 245 | /* Helper function to create a rule of a specific size */ |
| 246 | static struct vcap_rule * | 246 | static void test_vcap_xn_rule_creator(struct kunit *test, int cid, |
| 247 | test_vcap_xn_rule_creator(struct kunit *test, int cid, enum vcap_user user, | 247 | enum vcap_user user, u16 priority, |
| 248 | u16 priority, | 248 | int id, int size, int expected_addr) |
| 249 | int id, int size, int expected_addr) | ||
| 250 | { | 249 | { |
| 251 | struct vcap_rule *rule; | 250 | struct vcap_rule *rule; |
| 252 | struct vcap_rule_internal *ri; | 251 | struct vcap_rule_internal *ri; |
| @@ -311,7 +310,7 @@ test_vcap_xn_rule_creator(struct kunit *test, int cid, enum vcap_user user, · 58 unmodified lines | |||
| 311 | ret = vcap_add_rule(rule); | 310 | ret = vcap_add_rule(rule); |
| 312 | KUNIT_EXPECT_EQ(test, 0, ret); | 311 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 313 | KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); | 312 | KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); |
| 314 | return rule; | 313 | vcap_free_rule(rule); |
| 315 | } | 314 | } |
| 316 | 315 | ||
| 317 | /* Prepare testing rule deletion */ | 316 | /* Prepare testing rule deletion */ |
| @@ -995,6 +994,16 @@ static void vcap_api_encode_rule_actionset_test(struct kunit *test) · 677 unmodified lines | |||
| 995 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[11]); | 994 | KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[11]); |
| 996 | } | 995 | } |
| 997 | 996 | ||
| 997 | static void vcap_free_ckf(struct vcap_rule *rule) | ||
| 998 | { | ||
| 999 | struct vcap_client_keyfield *ckf, *next_ckf; | ||
| 1000 | |||
| 1001 | list_for_each_entry_safe(ckf, next_ckf, &rule->keyfields, ctrl.list) { | ||
| 1002 | list_del(&ckf->ctrl.list); | ||
| 1003 | kfree(ckf); | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 998 | static void vcap_api_rule_add_keyvalue_test(struct kunit *test) | 1007 | static void vcap_api_rule_add_keyvalue_test(struct kunit *test) |
| 999 | { | 1008 | { |
| 1000 | struct vcap_admin admin = { | 1009 | struct vcap_admin admin = { |
| @@ -1027,6 +1036,7 @@ static void vcap_api_rule_add_keyvalue_test(struct kunit *test) · 26 unmodified lines | |||
| 1027 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); | 1036 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
| 1028 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); | 1037 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); |
| 1029 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); | 1038 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); |
| 1039 | vcap_free_ckf(rule); | ||
| 1030 | 1040 | ||
| 1031 | INIT_LIST_HEAD(&rule->keyfields); | 1041 | INIT_LIST_HEAD(&rule->keyfields); |
| 1032 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); | 1042 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); |
| @@ -1039,6 +1049,7 @@ static void vcap_api_rule_add_keyvalue_test(struct kunit *test) · 6 unmodified lines | |||
| 1039 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); | 1049 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
| 1040 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.value); | 1050 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.value); |
| 1041 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); | 1051 | KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); |
| 1052 | vcap_free_ckf(rule); | ||
| 1042 | 1053 | ||
| 1043 | INIT_LIST_HEAD(&rule->keyfields); | 1054 | INIT_LIST_HEAD(&rule->keyfields); |
| 1044 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, | 1055 | ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, |
| @@ -1052,6 +1063,7 @@ static void vcap_api_rule_add_keyvalue_test(struct kunit *test) · 7 unmodified lines | |||
| 1052 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); | 1063 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); |
| 1053 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); | 1064 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); |
| 1054 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.mask); | 1065 | KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.mask); |
| 1066 | vcap_free_ckf(rule); | ||
| 1055 | 1067 | ||
| 1056 | INIT_LIST_HEAD(&rule->keyfields); | 1068 | INIT_LIST_HEAD(&rule->keyfields); |
| 1057 | ret = vcap_rule_add_key_u32(rule, VCAP_KF_TYPE, 0x98765432, 0xff00ffab); | 1069 | ret = vcap_rule_add_key_u32(rule, VCAP_KF_TYPE, 0x98765432, 0xff00ffab); |
| @@ -1064,6 +1076,7 @@ static void vcap_api_rule_add_keyvalue_test(struct kunit *test) · 6 unmodified lines | |||
| 1064 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, kf->ctrl.type); | 1076 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, kf->ctrl.type); |
| 1065 | KUNIT_EXPECT_EQ(test, 0x98765432, kf->data.u32.value); | 1077 | KUNIT_EXPECT_EQ(test, 0x98765432, kf->data.u32.value); |
| 1066 | KUNIT_EXPECT_EQ(test, 0xff00ffab, kf->data.u32.mask); | 1078 | KUNIT_EXPECT_EQ(test, 0xff00ffab, kf->data.u32.mask); |
| 1079 | vcap_free_ckf(rule); | ||
| 1067 | 1080 | ||
| 1068 | INIT_LIST_HEAD(&rule->keyfields); | 1081 | INIT_LIST_HEAD(&rule->keyfields); |
| 1069 | ret = vcap_rule_add_key_u128(rule, VCAP_KF_L3_IP6_SIP, &dip); | 1082 | ret = vcap_rule_add_key_u128(rule, VCAP_KF_L3_IP6_SIP, &dip); |
| @@ -1078,6 +1091,18 @@ static void vcap_api_rule_add_keyvalue_test(struct kunit *test) · 8 unmodified lines | |||
| 1078 | KUNIT_EXPECT_EQ(test, dip.value[idx], kf->data.u128.value[idx]); | 1091 | KUNIT_EXPECT_EQ(test, dip.value[idx], kf->data.u128.value[idx]); |
| 1079 | for (idx = 0; idx < ARRAY_SIZE(dip.mask); ++idx) | 1092 | for (idx = 0; idx < ARRAY_SIZE(dip.mask); ++idx) |
| 1080 | KUNIT_EXPECT_EQ(test, dip.mask[idx], kf->data.u128.mask[idx]); | 1093 | KUNIT_EXPECT_EQ(test, dip.mask[idx], kf->data.u128.mask[idx]); |
| 1094 | vcap_free_ckf(rule); | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | static void vcap_free_caf(struct vcap_rule *rule) | ||
| 1098 | { | ||
| 1099 | struct vcap_client_actionfield *caf, *next_caf; | ||
| 1100 | |||
| 1101 | list_for_each_entry_safe(caf, next_caf, | ||
| 1102 | &rule->actionfields, ctrl.list) { | ||
| 1103 | list_del(&caf->ctrl.list); | ||
| 1104 | kfree(caf); | ||
| 1105 | } | ||
| 1081 | } | 1106 | } |
| 1082 | 1107 | ||
| 1083 | static void vcap_api_rule_add_actionvalue_test(struct kunit *test) | 1108 | static void vcap_api_rule_add_actionvalue_test(struct kunit *test) |
| @@ -1105,6 +1130,7 @@ static void vcap_api_rule_add_actionvalue_test(struct kunit *test) · 21 unmodified lines | |||
| 1105 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); | 1130 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
| 1106 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); | 1131 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
| 1107 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); | 1132 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); |
| 1133 | vcap_free_caf(rule); | ||
| 1108 | 1134 | ||
| 1109 | INIT_LIST_HEAD(&rule->actionfields); | 1135 | INIT_LIST_HEAD(&rule->actionfields); |
| 1110 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_1); | 1136 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_1); |
| @@ -1116,6 +1142,7 @@ static void vcap_api_rule_add_actionvalue_test(struct kunit *test) · 5 unmodified lines | |||
| 1116 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); | 1142 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
| 1117 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); | 1143 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
| 1118 | KUNIT_EXPECT_EQ(test, 0x1, af->data.u1.value); | 1144 | KUNIT_EXPECT_EQ(test, 0x1, af->data.u1.value); |
| 1145 | vcap_free_caf(rule); | ||
| 1119 | 1146 | ||
| 1120 | INIT_LIST_HEAD(&rule->actionfields); | 1147 | INIT_LIST_HEAD(&rule->actionfields); |
| 1121 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_ANY); | 1148 | ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_ANY); |
| @@ -1127,6 +1154,7 @@ static void vcap_api_rule_add_actionvalue_test(struct kunit *test) · 5 unmodified lines | |||
| 1127 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); | 1154 | KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); |
| 1128 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); | 1155 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); |
| 1129 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); | 1156 | KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); |
| 1157 | vcap_free_caf(rule); | ||
| 1130 | 1158 | ||
| 1131 | INIT_LIST_HEAD(&rule->actionfields); | 1159 | INIT_LIST_HEAD(&rule->actionfields); |
| 1132 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_TYPE, 0x98765432); | 1160 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_TYPE, 0x98765432); |
| @@ -1138,6 +1166,7 @@ static void vcap_api_rule_add_actionvalue_test(struct kunit *test) · 5 unmodified lines | |||
| 1138 | KUNIT_EXPECT_EQ(test, VCAP_AF_TYPE, af->ctrl.action); | 1166 | KUNIT_EXPECT_EQ(test, VCAP_AF_TYPE, af->ctrl.action); |
| 1139 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); | 1167 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); |
| 1140 | KUNIT_EXPECT_EQ(test, 0x98765432, af->data.u32.value); | 1168 | KUNIT_EXPECT_EQ(test, 0x98765432, af->data.u32.value); |
| 1169 | vcap_free_caf(rule); | ||
| 1141 | 1170 | ||
| 1142 | INIT_LIST_HEAD(&rule->actionfields); | 1171 | INIT_LIST_HEAD(&rule->actionfields); |
| 1143 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_MASK_MODE, 0xaabbccdd); | 1172 | ret = vcap_rule_add_action_u32(rule, VCAP_AF_MASK_MODE, 0xaabbccdd); |
| @@ -1149,6 +1178,7 @@ static void vcap_api_rule_add_actionvalue_test(struct kunit *test) · 5 unmodified lines | |||
| 1149 | KUNIT_EXPECT_EQ(test, VCAP_AF_MASK_MODE, af->ctrl.action); | 1178 | KUNIT_EXPECT_EQ(test, VCAP_AF_MASK_MODE, af->ctrl.action); |
| 1150 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); | 1179 | KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); |
| 1151 | KUNIT_EXPECT_EQ(test, 0xaabbccdd, af->data.u32.value); | 1180 | KUNIT_EXPECT_EQ(test, 0xaabbccdd, af->data.u32.value); |
| 1181 | vcap_free_caf(rule); | ||
| 1152 | } | 1182 | } |
| 1153 | 1183 | ||
| 1154 | static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) | 1184 | static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) |
| @@ -1408,6 +1438,10 @@ static void vcap_api_encode_rule_test(struct kunit *test) · 253 unmodified lines | |||
| 1408 | ret = list_empty(&is2_admin.rules); | 1438 | ret = list_empty(&is2_admin.rules); |
| 1409 | KUNIT_EXPECT_EQ(test, false, ret); | 1439 | KUNIT_EXPECT_EQ(test, false, ret); |
| 1410 | KUNIT_EXPECT_EQ(test, 0, ret); | 1440 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 1441 | |||
| 1442 | vcap_enable_lookups(&test_vctrl, &test_netdev, 0, 0, | ||
| 1443 | rule->cookie, false); | ||
| 1444 | |||
| 1411 | vcap_free_rule(rule); | 1445 | vcap_free_rule(rule); |
| 1412 | 1446 | ||
| 1413 | /* Check that the rule has been freed: tricky to access since this | 1447 | /* Check that the rule has been freed: tricky to access since this |
| @@ -1418,6 +1452,8 @@ static void vcap_api_encode_rule_test(struct kunit *test) · 4 unmodified lines | |||
| 1418 | KUNIT_EXPECT_EQ(test, true, ret); | 1452 | KUNIT_EXPECT_EQ(test, true, ret); |
| 1419 | ret = list_empty(&rule->actionfields); | 1453 | ret = list_empty(&rule->actionfields); |
| 1420 | KUNIT_EXPECT_EQ(test, true, ret); | 1454 | KUNIT_EXPECT_EQ(test, true, ret); |
| 1455 | |||
| 1456 | vcap_del_rule(&test_vctrl, &test_netdev, id); | ||
| 1421 | } | 1457 | } |
| 1422 | 1458 | ||
| 1423 | static void vcap_api_set_rule_counter_test(struct kunit *test) | 1459 | static void vcap_api_set_rule_counter_test(struct kunit *test) |
| @@ -1561,6 +1597,11 @@ static void vcap_api_rule_insert_in_order_test(struct kunit *test) · 137 unmodified lines | |||
| 1561 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); | 1597 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); |
| 1562 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); | 1598 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); |
| 1563 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); | 1599 | test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); |
| 1600 | |||
| 1601 | vcap_del_rule(&test_vctrl, &test_netdev, 200); | ||
| 1602 | vcap_del_rule(&test_vctrl, &test_netdev, 300); | ||
| 1603 | vcap_del_rule(&test_vctrl, &test_netdev, 400); | ||
| 1604 | vcap_del_rule(&test_vctrl, &test_netdev, 500); | ||
| 1564 | } | 1605 | } |
| 1565 | 1606 | ||
| 1566 | static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) | 1607 | static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) |
| @@ -1619,6 +1660,11 @@ static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) · 52 unmodified lines | |||
| 1619 | ++idx; | 1660 | ++idx; |
| 1620 | } | 1661 | } |
| 1621 | KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); | 1662 | KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); |
| 1663 | |||
| 1664 | vcap_del_rule(&test_vctrl, &test_netdev, 500); | ||
| 1665 | vcap_del_rule(&test_vctrl, &test_netdev, 400); | ||
| 1666 | vcap_del_rule(&test_vctrl, &test_netdev, 300); | ||
| 1667 | vcap_del_rule(&test_vctrl, &test_netdev, 200); | ||
| 1622 | } | 1668 | } |
| 1623 | 1669 | ||
| 1624 | static void vcap_api_rule_remove_at_end_test(struct kunit *test) | 1670 | static void vcap_api_rule_remove_at_end_test(struct kunit *test) |
| @@ -1819,6 +1865,9 @@ static void vcap_api_rule_remove_in_front_test(struct kunit *test) · 194 unmodified lines | |||
| 1819 | KUNIT_EXPECT_EQ(test, 786, test_init_start); | 1865 | KUNIT_EXPECT_EQ(test, 786, test_init_start); |
| 1820 | KUNIT_EXPECT_EQ(test, 8, test_init_count); | 1866 | KUNIT_EXPECT_EQ(test, 8, test_init_count); |
| 1821 | KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); | 1867 | KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); |
| 1868 | |||
| 1869 | vcap_del_rule(&test_vctrl, &test_netdev, 200); | ||
| 1870 | vcap_del_rule(&test_vctrl, &test_netdev, 300); | ||
| 1822 | } | 1871 | } |
| 1823 | 1872 | ||
| 1824 | static struct kunit_case vcap_api_rule_remove_test_cases[] = { | 1873 | static struct kunit_case vcap_api_rule_remove_test_cases[] = { |
| @@ -187,6 +187,7 @@ typedef void (*ionic_desc_cb)(struct ionic_queue *q, · 186 unmodified lines | |||
| 187 | struct ionic_desc_info *desc_info, | 187 | struct ionic_desc_info *desc_info, |
| 188 | struct ionic_cq_info *cq_info, void *cb_arg); | 188 | struct ionic_cq_info *cq_info, void *cb_arg); |
| 189 | 189 | ||
| 190 | #define IONIC_MAX_BUF_LEN ((u16)-1) | ||
| 190 | #define IONIC_PAGE_SIZE PAGE_SIZE | 191 | #define IONIC_PAGE_SIZE PAGE_SIZE |
| 191 | #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) | 192 | #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) |
| 192 | #define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\ | 193 | #define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\ |
| @@ -207,7 +207,8 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q, · 206 unmodified lines | |||
| 207 | return NULL; | 207 | return NULL; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); | 210 | frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, |
| 211 | IONIC_PAGE_SIZE - buf_info->page_offset)); | ||
| 211 | len -= frag_len; | 212 | len -= frag_len; |
| 212 | 213 | ||
| 213 | dma_sync_single_for_cpu(dev, | 214 | dma_sync_single_for_cpu(dev, |
| @@ -452,7 +453,8 @@ void ionic_rx_fill(struct ionic_queue *q) · 238 unmodified lines | |||
| 452 | 453 | ||
| 453 | /* fill main descriptor - buf[0] */ | 454 | /* fill main descriptor - buf[0] */ |
| 454 | desc->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); | 455 | desc->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); |
| 455 | frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); | 456 | frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, |
| 457 | IONIC_PAGE_SIZE - buf_info->page_offset)); | ||
| 456 | desc->len = cpu_to_le16(frag_len); | 458 | desc->len = cpu_to_le16(frag_len); |
| 457 | remain_len -= frag_len; | 459 | remain_len -= frag_len; |
| 458 | buf_info++; | 460 | buf_info++; |
| @@ -471,7 +473,9 @@ void ionic_rx_fill(struct ionic_queue *q) · 12 unmodified lines | |||
| 471 | } | 473 | } |
| 472 | 474 | ||
| 473 | sg_elem->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); | 475 | sg_elem->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); |
| 474 | frag_len = min_t(u16, remain_len, IONIC_PAGE_SIZE - buf_info->page_offset); | 476 | frag_len = min_t(u16, remain_len, min_t(u32, IONIC_MAX_BUF_LEN, |
| 477 | IONIC_PAGE_SIZE - | ||
| 478 | buf_info->page_offset)); | ||
| 475 | sg_elem->len = cpu_to_le16(frag_len); | 479 | sg_elem->len = cpu_to_le16(frag_len); |
| 476 | remain_len -= frag_len; | 480 | remain_len -= frag_len; |
| 477 | buf_info++; | 481 | buf_info++; |
| @@ -799,6 +799,7 @@ static int rswitch_poll(struct napi_struct *napi, int budget) · 798 unmodified lines | |||
| 799 | struct net_device *ndev = napi->dev; | 799 | struct net_device *ndev = napi->dev; |
| 800 | struct rswitch_private *priv; | 800 | struct rswitch_private *priv; |
| 801 | struct rswitch_device *rdev; | 801 | struct rswitch_device *rdev; |
| 802 | unsigned long flags; | ||
| 802 | int quota = budget; | 803 | int quota = budget; |
| 803 | 804 | ||
| 804 | rdev = netdev_priv(ndev); | 805 | rdev = netdev_priv(ndev); |
| @@ -816,10 +817,12 @@ retry: · 11 unmodified lines | |||
| 816 | 817 | ||
| 817 | netif_wake_subqueue(ndev, 0); | 818 | netif_wake_subqueue(ndev, 0); |
| 818 | 819 | ||
| 819 | napi_complete(napi); | 820 | if (napi_complete_done(napi, budget - quota)) { |
| 820 | 821 | spin_lock_irqsave(&priv->lock, flags); | |
| 821 | rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); | 822 | rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); |
| 822 | rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); | 823 | rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); |
| 824 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 825 | } | ||
| 823 | 826 | ||
| 824 | out: | 827 | out: |
| 825 | return budget - quota; | 828 | return budget - quota; |
| @@ -835,8 +838,10 @@ static void rswitch_queue_interrupt(struct net_device *ndev) · 9 unmodified lines | |||
| 835 | struct rswitch_device *rdev = netdev_priv(ndev); | 838 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 836 | 839 | ||
| 837 | if (napi_schedule_prep(&rdev->napi)) { | 840 | if (napi_schedule_prep(&rdev->napi)) { |
| 841 | spin_lock(&rdev->priv->lock); | ||
| 838 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); | 842 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); |
| 839 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); | 843 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); |
| 844 | spin_unlock(&rdev->priv->lock); | ||
| 840 | __napi_schedule(&rdev->napi); | 845 | __napi_schedule(&rdev->napi); |
| 841 | } | 846 | } |
| 842 | } | 847 | } |
| @@ -1440,14 +1445,17 @@ static void rswitch_ether_port_deinit_all(struct rswitch_private *priv) · 597 unmodified lines | |||
| 1440 | static int rswitch_open(struct net_device *ndev) | 1445 | static int rswitch_open(struct net_device *ndev) |
| 1441 | { | 1446 | { |
| 1442 | struct rswitch_device *rdev = netdev_priv(ndev); | 1447 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 1448 | unsigned long flags; | ||
| 1443 | 1449 | ||
| 1444 | phy_start(ndev->phydev); | 1450 | phy_start(ndev->phydev); |
| 1445 | 1451 | ||
| 1446 | napi_enable(&rdev->napi); | 1452 | napi_enable(&rdev->napi); |
| 1447 | netif_start_queue(ndev); | 1453 | netif_start_queue(ndev); |
| 1448 | 1454 | ||
| 1455 | spin_lock_irqsave(&rdev->priv->lock, flags); | ||
| 1449 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true); | 1456 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true); |
| 1450 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true); | 1457 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true); |
| 1458 | spin_unlock_irqrestore(&rdev->priv->lock, flags); | ||
| 1451 | 1459 | ||
| 1452 | if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS)) | 1460 | if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS)) |
| 1453 | iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE); | 1461 | iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE); |
| @@ -1461,6 +1469,7 @@ static int rswitch_stop(struct net_device *ndev) · 7 unmodified lines | |||
| 1461 | { | 1469 | { |
| 1462 | struct rswitch_device *rdev = netdev_priv(ndev); | 1470 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 1463 | struct rswitch_gwca_ts_info *ts_info, *ts_info2; | 1471 | struct rswitch_gwca_ts_info *ts_info, *ts_info2; |
| 1472 | unsigned long flags; | ||
| 1464 | 1473 | ||
| 1465 | netif_tx_stop_all_queues(ndev); | 1474 | netif_tx_stop_all_queues(ndev); |
| 1466 | bitmap_clear(rdev->priv->opened_ports, rdev->port, 1); | 1475 | bitmap_clear(rdev->priv->opened_ports, rdev->port, 1); |
| @@ -1476,8 +1485,10 @@ static int rswitch_stop(struct net_device *ndev) · 9 unmodified lines | |||
| 1476 | kfree(ts_info); | 1485 | kfree(ts_info); |
| 1477 | } | 1486 | } |
| 1478 | 1487 | ||
| 1488 | spin_lock_irqsave(&rdev->priv->lock, flags); | ||
| 1479 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); | 1489 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); |
| 1480 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); | 1490 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); |
| 1491 | spin_unlock_irqrestore(&rdev->priv->lock, flags); | ||
| 1481 | 1492 | ||
| 1482 | phy_stop(ndev->phydev); | 1493 | phy_stop(ndev->phydev); |
| 1483 | napi_disable(&rdev->napi); | 1494 | napi_disable(&rdev->napi); |
| @@ -1887,6 +1898,7 @@ static int renesas_eth_sw_probe(struct platform_device *pdev) · 403 unmodified lines | |||
| 1887 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 1898 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 1888 | if (!priv) | 1899 | if (!priv) |
| 1889 | return -ENOMEM; | 1900 | return -ENOMEM; |
| 1901 | spin_lock_init(&priv->lock); | ||
| 1890 | 1902 | ||
| 1891 | attr = soc_device_match(rswitch_soc_no_speed_change); | 1903 | attr = soc_device_match(rswitch_soc_no_speed_change); |
| 1892 | if (attr) | 1904 | if (attr) |
| @@ -1011,6 +1011,8 @@ struct rswitch_private { · 1010 unmodified lines | |||
| 1011 | struct rswitch_etha etha[RSWITCH_NUM_PORTS]; | 1011 | struct rswitch_etha etha[RSWITCH_NUM_PORTS]; |
| 1012 | struct rswitch_mfwd mfwd; | 1012 | struct rswitch_mfwd mfwd; |
| 1013 | 1013 | ||
| 1014 | spinlock_t lock; /* lock interrupt registers' control */ | ||
| 1015 | |||
| 1014 | bool etha_no_runtime_change; | 1016 | bool etha_no_runtime_change; |
| 1015 | bool gwca_halt; | 1017 | bool gwca_halt; |
| 1016 | }; | 1018 | }; |
| @@ -136,6 +136,8 @@ static struct efx_tc_mac_pedit_action *efx_tc_flower_get_mac(struct efx_nic *efx · 135 unmodified lines | |||
| 136 | if (old) { | 136 | if (old) { |
| 137 | /* don't need our new entry */ | 137 | /* don't need our new entry */ |
| 138 | kfree(ped); | 138 | kfree(ped); |
| 139 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 140 | return ERR_CAST(old); | ||
| 139 | if (!refcount_inc_not_zero(&old->ref)) | 141 | if (!refcount_inc_not_zero(&old->ref)) |
| 140 | return ERR_PTR(-EAGAIN); | 142 | return ERR_PTR(-EAGAIN); |
| 141 | /* existing entry found, ref taken */ | 143 | /* existing entry found, ref taken */ |
| @@ -602,6 +604,8 @@ static int efx_tc_flower_record_encap_match(struct efx_nic *efx, · 460 unmodified lines | |||
| 602 | kfree(encap); | 604 | kfree(encap); |
| 603 | if (pseudo) /* don't need our new pseudo either */ | 605 | if (pseudo) /* don't need our new pseudo either */ |
| 604 | efx_tc_flower_release_encap_match(efx, pseudo); | 606 | efx_tc_flower_release_encap_match(efx, pseudo); |
| 607 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 608 | return PTR_ERR(old); | ||
| 605 | /* check old and new em_types are compatible */ | 609 | /* check old and new em_types are compatible */ |
| 606 | switch (old->type) { | 610 | switch (old->type) { |
| 607 | case EFX_TC_EM_DIRECT: | 611 | case EFX_TC_EM_DIRECT: |
| @@ -700,6 +704,8 @@ static struct efx_tc_recirc_id *efx_tc_get_recirc_id(struct efx_nic *efx, · 92 unmodified lines | |||
| 700 | if (old) { | 704 | if (old) { |
| 701 | /* don't need our new entry */ | 705 | /* don't need our new entry */ |
| 702 | kfree(rid); | 706 | kfree(rid); |
| 707 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 708 | return ERR_CAST(old); | ||
| 703 | if (!refcount_inc_not_zero(&old->ref)) | 709 | if (!refcount_inc_not_zero(&old->ref)) |
| 704 | return ERR_PTR(-EAGAIN); | 710 | return ERR_PTR(-EAGAIN); |
| 705 | /* existing entry found */ | 711 | /* existing entry found */ |
| @@ -1482,7 +1488,10 @@ static int efx_tc_flower_replace_foreign(struct efx_nic *efx, · 776 unmodified lines | |||
| 1482 | old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht, | 1488 | old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht, |
| 1483 | &rule->linkage, | 1489 | &rule->linkage, |
| 1484 | efx_tc_match_action_ht_params); | 1490 | efx_tc_match_action_ht_params); |
| 1485 | if (old) { | 1491 | if (IS_ERR(old)) { |
| 1492 | rc = PTR_ERR(old); | ||
| 1493 | goto release; | ||
| 1494 | } else if (old) { | ||
| 1486 | netif_dbg(efx, drv, efx->net_dev, | 1495 | netif_dbg(efx, drv, efx->net_dev, |
| 1487 | "Ignoring already-offloaded rule (cookie %lx)\n", | 1496 | "Ignoring already-offloaded rule (cookie %lx)\n", |
| 1488 | tc->cookie); | 1497 | tc->cookie); |
| @@ -1697,7 +1706,10 @@ static int efx_tc_flower_replace_lhs(struct efx_nic *efx, · 208 unmodified lines | |||
| 1697 | old = rhashtable_lookup_get_insert_fast(&efx->tc->lhs_rule_ht, | 1706 | old = rhashtable_lookup_get_insert_fast(&efx->tc->lhs_rule_ht, |
| 1698 | &rule->linkage, | 1707 | &rule->linkage, |
| 1699 | efx_tc_lhs_rule_ht_params); | 1708 | efx_tc_lhs_rule_ht_params); |
| 1700 | if (old) { | 1709 | if (IS_ERR(old)) { |
| 1710 | rc = PTR_ERR(old); | ||
| 1711 | goto release; | ||
| 1712 | } else if (old) { | ||
| 1701 | netif_dbg(efx, drv, efx->net_dev, | 1713 | netif_dbg(efx, drv, efx->net_dev, |
| 1702 | "Already offloaded rule (cookie %lx)\n", tc->cookie); | 1714 | "Already offloaded rule (cookie %lx)\n", tc->cookie); |
| 1703 | rc = -EEXIST; | 1715 | rc = -EEXIST; |
| @@ -1858,7 +1870,10 @@ static int efx_tc_flower_replace(struct efx_nic *efx, · 154 unmodified lines | |||
| 1858 | old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht, | 1870 | old = rhashtable_lookup_get_insert_fast(&efx->tc->match_action_ht, |
| 1859 | &rule->linkage, | 1871 | &rule->linkage, |
| 1860 | efx_tc_match_action_ht_params); | 1872 | efx_tc_match_action_ht_params); |
| 1861 | if (old) { | 1873 | if (IS_ERR(old)) { |
| 1874 | rc = PTR_ERR(old); | ||
| 1875 | goto release; | ||
| 1876 | } else if (old) { | ||
| 1862 | netif_dbg(efx, drv, efx->net_dev, | 1877 | netif_dbg(efx, drv, efx->net_dev, |
| 1863 | "Already offloaded rule (cookie %lx)\n", tc->cookie); | 1878 | "Already offloaded rule (cookie %lx)\n", tc->cookie); |
| 1864 | NL_SET_ERR_MSG_MOD(extack, "Rule already offloaded"); | 1879 | NL_SET_ERR_MSG_MOD(extack, "Rule already offloaded"); |
| @@ -298,7 +298,10 @@ static int efx_tc_ct_replace(struct efx_tc_ct_zone *ct_zone, · 297 unmodified lines | |||
| 298 | old = rhashtable_lookup_get_insert_fast(&efx->tc->ct_ht, | 298 | old = rhashtable_lookup_get_insert_fast(&efx->tc->ct_ht, |
| 299 | &conn->linkage, | 299 | &conn->linkage, |
| 300 | efx_tc_ct_ht_params); | 300 | efx_tc_ct_ht_params); |
| 301 | if (old) { | 301 | if (IS_ERR(old)) { |
| 302 | rc = PTR_ERR(old); | ||
| 303 | goto release; | ||
| 304 | } else if (old) { | ||
| 302 | netif_dbg(efx, drv, efx->net_dev, | 305 | netif_dbg(efx, drv, efx->net_dev, |
| 303 | "Already offloaded conntrack (cookie %lx)\n", tc->cookie); | 306 | "Already offloaded conntrack (cookie %lx)\n", tc->cookie); |
| 304 | rc = -EEXIST; | 307 | rc = -EEXIST; |
| @@ -482,6 +485,8 @@ struct efx_tc_ct_zone *efx_tc_ct_register_zone(struct efx_nic *efx, u16 zone, · 177 unmodified lines | |||
| 482 | if (old) { | 485 | if (old) { |
| 483 | /* don't need our new entry */ | 486 | /* don't need our new entry */ |
| 484 | kfree(ct_zone); | 487 | kfree(ct_zone); |
| 488 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 489 | return ERR_CAST(old); | ||
| 485 | if (!refcount_inc_not_zero(&old->ref)) | 490 | if (!refcount_inc_not_zero(&old->ref)) |
| 486 | return ERR_PTR(-EAGAIN); | 491 | return ERR_PTR(-EAGAIN); |
| 487 | /* existing entry found */ | 492 | /* existing entry found */ |
| @@ -236,6 +236,8 @@ struct efx_tc_counter_index *efx_tc_flower_get_counter_index( · 235 unmodified lines | |||
| 236 | if (old) { | 236 | if (old) { |
| 237 | /* don't need our new entry */ | 237 | /* don't need our new entry */ |
| 238 | kfree(ctr); | 238 | kfree(ctr); |
| 239 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 240 | return ERR_CAST(old); | ||
| 239 | if (!refcount_inc_not_zero(&old->ref)) | 241 | if (!refcount_inc_not_zero(&old->ref)) |
| 240 | return ERR_PTR(-EAGAIN); | 242 | return ERR_PTR(-EAGAIN); |
| 241 | /* existing entry found */ | 243 | /* existing entry found */ |
| @@ -132,6 +132,8 @@ static int efx_bind_neigh(struct efx_nic *efx, · 131 unmodified lines | |||
| 132 | /* don't need our new entry */ | 132 | /* don't need our new entry */ |
| 133 | put_net_track(neigh->net, &neigh->ns_tracker); | 133 | put_net_track(neigh->net, &neigh->ns_tracker); |
| 134 | kfree(neigh); | 134 | kfree(neigh); |
| 135 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 136 | return PTR_ERR(old); | ||
| 135 | if (!refcount_inc_not_zero(&old->ref)) | 137 | if (!refcount_inc_not_zero(&old->ref)) |
| 136 | return -EAGAIN; | 138 | return -EAGAIN; |
| 137 | /* existing entry found, ref taken */ | 139 | /* existing entry found, ref taken */ |
| @@ -640,6 +642,8 @@ struct efx_tc_encap_action *efx_tc_flower_create_encap_md( · 502 unmodified lines | |||
| 640 | if (old) { | 642 | if (old) { |
| 641 | /* don't need our new entry */ | 643 | /* don't need our new entry */ |
| 642 | kfree(encap); | 644 | kfree(encap); |
| 645 | if (IS_ERR(old)) /* oh dear, it's actually an error */ | ||
| 646 | return ERR_CAST(old); | ||
| 643 | if (!refcount_inc_not_zero(&old->ref)) | 647 | if (!refcount_inc_not_zero(&old->ref)) |
| 644 | return ERR_PTR(-EAGAIN); | 648 | return ERR_PTR(-EAGAIN); |
| 645 | /* existing entry found, ref taken */ | 649 | /* existing entry found, ref taken */ |
| @@ -70,7 +70,7 @@ struct stmmac_txq_stats { · 69 unmodified lines | |||
| 70 | u64 tx_tso_frames; | 70 | u64 tx_tso_frames; |
| 71 | u64 tx_tso_nfrags; | 71 | u64 tx_tso_nfrags; |
| 72 | struct u64_stats_sync syncp; | 72 | struct u64_stats_sync syncp; |
| 73 | }; | 73 | } ____cacheline_aligned_in_smp; |
| 74 | 74 | ||
| 75 | struct stmmac_rxq_stats { | 75 | struct stmmac_rxq_stats { |
| 76 | u64 rx_bytes; | 76 | u64 rx_bytes; |
| @@ -79,7 +79,7 @@ struct stmmac_rxq_stats { · 2 unmodified lines | |||
| 79 | u64 rx_normal_irq_n; | 79 | u64 rx_normal_irq_n; |
| 80 | u64 napi_poll; | 80 | u64 napi_poll; |
| 81 | struct u64_stats_sync syncp; | 81 | struct u64_stats_sync syncp; |
| 82 | }; | 82 | } ____cacheline_aligned_in_smp; |
| 83 | 83 | ||
| 84 | /* Extra statistic and debug information exposed by ethtool */ | 84 | /* Extra statistic and debug information exposed by ethtool */ |
| 85 | struct stmmac_extra_stats { | 85 | struct stmmac_extra_stats { |
| @@ -202,6 +202,9 @@ struct stmmac_extra_stats { · 116 unmodified lines | |||
| 202 | unsigned long mtl_est_hlbf; | 202 | unsigned long mtl_est_hlbf; |
| 203 | unsigned long mtl_est_btre; | 203 | unsigned long mtl_est_btre; |
| 204 | unsigned long mtl_est_btrlm; | 204 | unsigned long mtl_est_btrlm; |
| 205 | /* per queue statistics */ | ||
| 206 | struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES]; | ||
| 207 | struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES]; | ||
| 205 | unsigned long rx_dropped; | 208 | unsigned long rx_dropped; |
| 206 | unsigned long rx_errors; | 209 | unsigned long rx_errors; |
| 207 | unsigned long tx_dropped; | 210 | unsigned long tx_dropped; |
| @@ -441,8 +441,8 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 440 unmodified lines | |||
| 441 | struct stmmac_extra_stats *x, u32 chan, | 441 | struct stmmac_extra_stats *x, u32 chan, |
| 442 | u32 dir) | 442 | u32 dir) |
| 443 | { | 443 | { |
| 444 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; | 444 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 445 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; | 445 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; |
| 446 | int ret = 0; | 446 | int ret = 0; |
| 447 | u32 v; | 447 | u32 v; |
| 448 | 448 | ||
| @@ -455,9 +455,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 6 unmodified lines | |||
| 455 | 455 | ||
| 456 | if (v & EMAC_TX_INT) { | 456 | if (v & EMAC_TX_INT) { |
| 457 | ret |= handle_tx; | 457 | ret |= handle_tx; |
| 458 | u64_stats_update_begin(&tx_q->txq_stats.syncp); | 458 | u64_stats_update_begin(&txq_stats->syncp); |
| 459 | tx_q->txq_stats.tx_normal_irq_n++; | 459 | txq_stats->tx_normal_irq_n++; |
| 460 | u64_stats_update_end(&tx_q->txq_stats.syncp); | 460 | u64_stats_update_end(&txq_stats->syncp); |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | if (v & EMAC_TX_DMA_STOP_INT) | 463 | if (v & EMAC_TX_DMA_STOP_INT) |
| @@ -479,9 +479,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv, · 15 unmodified lines | |||
| 479 | 479 | ||
| 480 | if (v & EMAC_RX_INT) { | 480 | if (v & EMAC_RX_INT) { |
| 481 | ret |= handle_rx; | 481 | ret |= handle_rx; |
| 482 | u64_stats_update_begin(&rx_q->rxq_stats.syncp); | 482 | u64_stats_update_begin(&rxq_stats->syncp); |
| 483 | rx_q->rxq_stats.rx_normal_irq_n++; | 483 | rxq_stats->rx_normal_irq_n++; |
| 484 | u64_stats_update_end(&rx_q->rxq_stats.syncp); | 484 | u64_stats_update_end(&rxq_stats->syncp); |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | if (v & EMAC_RX_BUF_UA_INT) | 487 | if (v & EMAC_RX_BUF_UA_INT) |
| @@ -171,8 +171,8 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 170 unmodified lines | |||
| 171 | const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; | 171 | const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs; |
| 172 | u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); | 172 | u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan)); |
| 173 | u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); | 173 | u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan)); |
| 174 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; | 174 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 175 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; | 175 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; |
| 176 | int ret = 0; | 176 | int ret = 0; |
| 177 | 177 | ||
| 178 | if (dir == DMA_DIR_RX) | 178 | if (dir == DMA_DIR_RX) |
| @@ -201,15 +201,15 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 22 unmodified lines | |||
| 201 | } | 201 | } |
| 202 | /* TX/RX NORMAL interrupts */ | 202 | /* TX/RX NORMAL interrupts */ |
| 203 | if (likely(intr_status & DMA_CHAN_STATUS_RI)) { | 203 | if (likely(intr_status & DMA_CHAN_STATUS_RI)) { |
| 204 | u64_stats_update_begin(&rx_q->rxq_stats.syncp); | 204 | u64_stats_update_begin(&rxq_stats->syncp); |
| 205 | rx_q->rxq_stats.rx_normal_irq_n++; | 205 | rxq_stats->rx_normal_irq_n++; |
| 206 | u64_stats_update_end(&rx_q->rxq_stats.syncp); | 206 | u64_stats_update_end(&rxq_stats->syncp); |
| 207 | ret |= handle_rx; | 207 | ret |= handle_rx; |
| 208 | } | 208 | } |
| 209 | if (likely(intr_status & DMA_CHAN_STATUS_TI)) { | 209 | if (likely(intr_status & DMA_CHAN_STATUS_TI)) { |
| 210 | u64_stats_update_begin(&tx_q->txq_stats.syncp); | 210 | u64_stats_update_begin(&txq_stats->syncp); |
| 211 | tx_q->txq_stats.tx_normal_irq_n++; | 211 | txq_stats->tx_normal_irq_n++; |
| 212 | u64_stats_update_end(&tx_q->txq_stats.syncp); | 212 | u64_stats_update_end(&txq_stats->syncp); |
| 213 | ret |= handle_tx; | 213 | ret |= handle_tx; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| @@ -162,8 +162,8 @@ static void show_rx_process_state(unsigned int status) · 161 unmodified lines | |||
| 162 | int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, | 162 | int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, |
| 163 | struct stmmac_extra_stats *x, u32 chan, u32 dir) | 163 | struct stmmac_extra_stats *x, u32 chan, u32 dir) |
| 164 | { | 164 | { |
| 165 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; | 165 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 166 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; | 166 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; |
| 167 | int ret = 0; | 167 | int ret = 0; |
| 168 | /* read the status register (CSR5) */ | 168 | /* read the status register (CSR5) */ |
| 169 | u32 intr_status = readl(ioaddr + DMA_STATUS); | 169 | u32 intr_status = readl(ioaddr + DMA_STATUS); |
| @@ -215,16 +215,16 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr, · 45 unmodified lines | |||
| 215 | u32 value = readl(ioaddr + DMA_INTR_ENA); | 215 | u32 value = readl(ioaddr + DMA_INTR_ENA); |
| 216 | /* to schedule NAPI on real RIE event. */ | 216 | /* to schedule NAPI on real RIE event. */ |
| 217 | if (likely(value & DMA_INTR_ENA_RIE)) { | 217 | if (likely(value & DMA_INTR_ENA_RIE)) { |
| 218 | u64_stats_update_begin(&rx_q->rxq_stats.syncp); | 218 | u64_stats_update_begin(&rxq_stats->syncp); |
| 219 | rx_q->rxq_stats.rx_normal_irq_n++; | 219 | rxq_stats->rx_normal_irq_n++; |
| 220 | u64_stats_update_end(&rx_q->rxq_stats.syncp); | 220 | u64_stats_update_end(&rxq_stats->syncp); |
| 221 | ret |= handle_rx; | 221 | ret |= handle_rx; |
| 222 | } | 222 | } |
| 223 | } | 223 | } |
| 224 | if (likely(intr_status & DMA_STATUS_TI)) { | 224 | if (likely(intr_status & DMA_STATUS_TI)) { |
| 225 | u64_stats_update_begin(&tx_q->txq_stats.syncp); | 225 | u64_stats_update_begin(&txq_stats->syncp); |
| 226 | tx_q->txq_stats.tx_normal_irq_n++; | 226 | txq_stats->tx_normal_irq_n++; |
| 227 | u64_stats_update_end(&tx_q->txq_stats.syncp); | 227 | u64_stats_update_end(&txq_stats->syncp); |
| 228 | ret |= handle_tx; | 228 | ret |= handle_tx; |
| 229 | } | 229 | } |
| 230 | if (unlikely(intr_status & DMA_STATUS_ERI)) | 230 | if (unlikely(intr_status & DMA_STATUS_ERI)) |
| @@ -337,8 +337,8 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, · 336 unmodified lines | |||
| 337 | struct stmmac_extra_stats *x, u32 chan, | 337 | struct stmmac_extra_stats *x, u32 chan, |
| 338 | u32 dir) | 338 | u32 dir) |
| 339 | { | 339 | { |
| 340 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; | 340 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 341 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; | 341 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[chan]; |
| 342 | u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); | 342 | u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); |
| 343 | u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | 343 | u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); |
| 344 | int ret = 0; | 344 | int ret = 0; |
| @@ -367,15 +367,15 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, · 22 unmodified lines | |||
| 367 | /* TX/RX NORMAL interrupts */ | 367 | /* TX/RX NORMAL interrupts */ |
| 368 | if (likely(intr_status & XGMAC_NIS)) { | 368 | if (likely(intr_status & XGMAC_NIS)) { |
| 369 | if (likely(intr_status & XGMAC_RI)) { | 369 | if (likely(intr_status & XGMAC_RI)) { |
| 370 | u64_stats_update_begin(&rx_q->rxq_stats.syncp); | 370 | u64_stats_update_begin(&rxq_stats->syncp); |
| 371 | rx_q->rxq_stats.rx_normal_irq_n++; | 371 | rxq_stats->rx_normal_irq_n++; |
| 372 | u64_stats_update_end(&rx_q->rxq_stats.syncp); | 372 | u64_stats_update_end(&rxq_stats->syncp); |
| 373 | ret |= handle_rx; | 373 | ret |= handle_rx; |
| 374 | } | 374 | } |
| 375 | if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { | 375 | if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { |
| 376 | u64_stats_update_begin(&tx_q->txq_stats.syncp); | 376 | u64_stats_update_begin(&txq_stats->syncp); |
| 377 | tx_q->txq_stats.tx_normal_irq_n++; | 377 | txq_stats->tx_normal_irq_n++; |
| 378 | u64_stats_update_end(&tx_q->txq_stats.syncp); | 378 | u64_stats_update_end(&txq_stats->syncp); |
| 379 | ret |= handle_tx; | 379 | ret |= handle_tx; |
| 380 | } | 380 | } |
| 381 | } | 381 | } |
| @@ -78,7 +78,6 @@ struct stmmac_tx_queue { · 77 unmodified lines | |||
| 78 | dma_addr_t dma_tx_phy; | 78 | dma_addr_t dma_tx_phy; |
| 79 | dma_addr_t tx_tail_addr; | 79 | dma_addr_t tx_tail_addr; |
| 80 | u32 mss; | 80 | u32 mss; |
| 81 | struct stmmac_txq_stats txq_stats; | ||
| 82 | }; | 81 | }; |
| 83 | 82 | ||
| 84 | struct stmmac_rx_buffer { | 83 | struct stmmac_rx_buffer { |
| @@ -123,7 +122,6 @@ struct stmmac_rx_queue { · 38 unmodified lines | |||
| 123 | unsigned int len; | 122 | unsigned int len; |
| 124 | unsigned int error; | 123 | unsigned int error; |
| 125 | } state; | 124 | } state; |
| 126 | struct stmmac_rxq_stats rxq_stats; | ||
| 127 | }; | 125 | }; |
| 128 | 126 | ||
| 129 | struct stmmac_channel { | 127 | struct stmmac_channel { |
| @@ -548,14 +548,14 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) · 547 unmodified lines | |||
| 548 | 548 | ||
| 549 | pos = data; | 549 | pos = data; |
| 550 | for (q = 0; q < tx_cnt; q++) { | 550 | for (q = 0; q < tx_cnt; q++) { |
| 551 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[q]; | 551 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; |
| 552 | struct stmmac_txq_stats snapshot; | 552 | struct stmmac_txq_stats snapshot; |
| 553 | 553 | ||
| 554 | data = pos; | 554 | data = pos; |
| 555 | do { | 555 | do { |
| 556 | start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp); | 556 | start = u64_stats_fetch_begin(&txq_stats->syncp); |
| 557 | snapshot = tx_q->txq_stats; | 557 | snapshot = *txq_stats; |
| 558 | } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start)); | 558 | } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); |
| 559 | 559 | ||
| 560 | p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); | 560 | p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n); |
| 561 | for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { | 561 | for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { |
| @@ -566,14 +566,14 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) · 4 unmodified lines | |||
| 566 | 566 | ||
| 567 | pos = data; | 567 | pos = data; |
| 568 | for (q = 0; q < rx_cnt; q++) { | 568 | for (q = 0; q < rx_cnt; q++) { |
| 569 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[q]; | 569 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; |
| 570 | struct stmmac_rxq_stats snapshot; | 570 | struct stmmac_rxq_stats snapshot; |
| 571 | 571 | ||
| 572 | data = pos; | 572 | data = pos; |
| 573 | do { | 573 | do { |
| 574 | start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp); | 574 | start = u64_stats_fetch_begin(&rxq_stats->syncp); |
| 575 | snapshot = rx_q->rxq_stats; | 575 | snapshot = *rxq_stats; |
| 576 | } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start)); | 576 | } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); |
| 577 | 577 | ||
| 578 | p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); | 578 | p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n); |
| 579 | for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { | 579 | for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { |
| @@ -637,14 +637,14 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, · 57 unmodified lines | |||
| 637 | 637 | ||
| 638 | pos = j; | 638 | pos = j; |
| 639 | for (i = 0; i < rx_queues_count; i++) { | 639 | for (i = 0; i < rx_queues_count; i++) { |
| 640 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[i]; | 640 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[i]; |
| 641 | struct stmmac_rxq_stats snapshot; | 641 | struct stmmac_rxq_stats snapshot; |
| 642 | 642 | ||
| 643 | j = pos; | 643 | j = pos; |
| 644 | do { | 644 | do { |
| 645 | start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp); | 645 | start = u64_stats_fetch_begin(&rxq_stats->syncp); |
| 646 | snapshot = rx_q->rxq_stats; | 646 | snapshot = *rxq_stats; |
| 647 | } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start)); | 647 | } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); |
| 648 | 648 | ||
| 649 | data[j++] += snapshot.rx_pkt_n; | 649 | data[j++] += snapshot.rx_pkt_n; |
| 650 | data[j++] += snapshot.rx_normal_irq_n; | 650 | data[j++] += snapshot.rx_normal_irq_n; |
| @@ -654,14 +654,14 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, · 3 unmodified lines | |||
| 654 | 654 | ||
| 655 | pos = j; | 655 | pos = j; |
| 656 | for (i = 0; i < tx_queues_count; i++) { | 656 | for (i = 0; i < tx_queues_count; i++) { |
| 657 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[i]; | 657 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[i]; |
| 658 | struct stmmac_txq_stats snapshot; | 658 | struct stmmac_txq_stats snapshot; |
| 659 | 659 | ||
| 660 | j = pos; | 660 | j = pos; |
| 661 | do { | 661 | do { |
| 662 | start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp); | 662 | start = u64_stats_fetch_begin(&txq_stats->syncp); |
| 663 | snapshot = tx_q->txq_stats; | 663 | snapshot = *txq_stats; |
| 664 | } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start)); | 664 | } while (u64_stats_fetch_retry(&txq_stats->syncp, start)); |
| 665 | 665 | ||
| 666 | data[j++] += snapshot.tx_pkt_n; | 666 | data[j++] += snapshot.tx_pkt_n; |
| 667 | data[j++] += snapshot.tx_normal_irq_n; | 667 | data[j++] += snapshot.tx_normal_irq_n; |
| @@ -2426,6 +2426,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 2425 unmodified lines | |||
| 2426 | { | 2426 | { |
| 2427 | struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); | 2427 | struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); |
| 2428 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 2428 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 2429 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; | ||
| 2429 | struct xsk_buff_pool *pool = tx_q->xsk_pool; | 2430 | struct xsk_buff_pool *pool = tx_q->xsk_pool; |
| 2430 | unsigned int entry = tx_q->cur_tx; | 2431 | unsigned int entry = tx_q->cur_tx; |
| 2431 | struct dma_desc *tx_desc = NULL; | 2432 | struct dma_desc *tx_desc = NULL; |
| @@ -2505,9 +2506,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 73 unmodified lines | |||
| 2505 | tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); | 2506 | tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); |
| 2506 | entry = tx_q->cur_tx; | 2507 | entry = tx_q->cur_tx; |
| 2507 | } | 2508 | } |
| 2508 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 2509 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 2509 | tx_q->txq_stats.tx_set_ic_bit += tx_set_ic_bit; | 2510 | txq_stats->tx_set_ic_bit += tx_set_ic_bit; |
| 2510 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 2511 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 2511 | 2512 | ||
| 2512 | if (tx_desc) { | 2513 | if (tx_desc) { |
| 2513 | stmmac_flush_tx_descriptors(priv, queue); | 2514 | stmmac_flush_tx_descriptors(priv, queue); |
| @@ -2547,6 +2548,7 @@ static void stmmac_bump_dma_threshold(struct stmmac_priv *priv, u32 chan) · 33 unmodified lines | |||
| 2547 | static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) | 2548 | static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) |
| 2548 | { | 2549 | { |
| 2549 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 2550 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 2551 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; | ||
| 2550 | unsigned int bytes_compl = 0, pkts_compl = 0; | 2552 | unsigned int bytes_compl = 0, pkts_compl = 0; |
| 2551 | unsigned int entry, xmits = 0, count = 0; | 2553 | unsigned int entry, xmits = 0, count = 0; |
| 2552 | u32 tx_packets = 0, tx_errors = 0; | 2554 | u32 tx_packets = 0, tx_errors = 0; |
| @@ -2704,15 +2706,13 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) · 151 unmodified lines | |||
| 2704 | 2706 | ||
| 2705 | /* We still have pending packets, let's call for a new scheduling */ | 2707 | /* We still have pending packets, let's call for a new scheduling */ |
| 2706 | if (tx_q->dirty_tx != tx_q->cur_tx) | 2708 | if (tx_q->dirty_tx != tx_q->cur_tx) |
| 2707 | hrtimer_start(&tx_q->txtimer, | 2709 | stmmac_tx_timer_arm(priv, queue); |
| 2708 | STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), | ||
| 2709 | HRTIMER_MODE_REL); | ||
| 2710 | 2710 | ||
| 2711 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 2711 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 2712 | tx_q->txq_stats.tx_packets += tx_packets; | 2712 | txq_stats->tx_packets += tx_packets; |
| 2713 | tx_q->txq_stats.tx_pkt_n += tx_packets; | 2713 | txq_stats->tx_pkt_n += tx_packets; |
| 2714 | tx_q->txq_stats.tx_clean++; | 2714 | txq_stats->tx_clean++; |
| 2715 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 2715 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 2716 | 2716 | ||
| 2717 | priv->xstats.tx_errors += tx_errors; | 2717 | priv->xstats.tx_errors += tx_errors; |
| 2718 | 2718 | ||
| @@ -2995,9 +2995,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) · 276 unmodified lines | |||
| 2995 | static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) | 2995 | static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) |
| 2996 | { | 2996 | { |
| 2997 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 2997 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 2998 | u32 tx_coal_timer = priv->tx_coal_timer[queue]; | ||
| 2999 | |||
| 3000 | if (!tx_coal_timer) | ||
| 3001 | return; | ||
| 2998 | 3002 | ||
| 2999 | hrtimer_start(&tx_q->txtimer, | 3003 | hrtimer_start(&tx_q->txtimer, |
| 3000 | STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), | 3004 | STMMAC_COAL_TIMER(tx_coal_timer), |
| 3001 | HRTIMER_MODE_REL); | 3005 | HRTIMER_MODE_REL); |
| 3002 | } | 3006 | } |
| 3003 | 3007 | ||
| @@ -4112,6 +4116,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 1108 unmodified lines | |||
| 4112 | int nfrags = skb_shinfo(skb)->nr_frags; | 4116 | int nfrags = skb_shinfo(skb)->nr_frags; |
| 4113 | u32 queue = skb_get_queue_mapping(skb); | 4117 | u32 queue = skb_get_queue_mapping(skb); |
| 4114 | unsigned int first_entry, tx_packets; | 4118 | unsigned int first_entry, tx_packets; |
| 4119 | struct stmmac_txq_stats *txq_stats; | ||
| 4115 | int tmp_pay_len = 0, first_tx; | 4120 | int tmp_pay_len = 0, first_tx; |
| 4116 | struct stmmac_tx_queue *tx_q; | 4121 | struct stmmac_tx_queue *tx_q; |
| 4117 | bool has_vlan, set_ic; | 4122 | bool has_vlan, set_ic; |
| @@ -4122,6 +4127,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 4 unmodified lines | |||
| 4122 | int i; | 4127 | int i; |
| 4123 | 4128 | ||
| 4124 | tx_q = &priv->dma_conf.tx_queue[queue]; | 4129 | tx_q = &priv->dma_conf.tx_queue[queue]; |
| 4130 | txq_stats = &priv->xstats.txq_stats[queue]; | ||
| 4125 | first_tx = tx_q->cur_tx; | 4131 | first_tx = tx_q->cur_tx; |
| 4126 | 4132 | ||
| 4127 | /* Compute header lengths */ | 4133 | /* Compute header lengths */ |
| @@ -4280,13 +4286,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 152 unmodified lines | |||
| 4280 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); | 4286 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); |
| 4281 | } | 4287 | } |
| 4282 | 4288 | ||
| 4283 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 4289 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 4284 | tx_q->txq_stats.tx_bytes += skb->len; | 4290 | txq_stats->tx_bytes += skb->len; |
| 4285 | tx_q->txq_stats.tx_tso_frames++; | 4291 | txq_stats->tx_tso_frames++; |
| 4286 | tx_q->txq_stats.tx_tso_nfrags += nfrags; | 4292 | txq_stats->tx_tso_nfrags += nfrags; |
| 4287 | if (set_ic) | 4293 | if (set_ic) |
| 4288 | tx_q->txq_stats.tx_set_ic_bit++; | 4294 | txq_stats->tx_set_ic_bit++; |
| 4289 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 4295 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 4290 | 4296 | ||
| 4291 | if (priv->sarc_type) | 4297 | if (priv->sarc_type) |
| 4292 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); | 4298 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); |
| @@ -4357,6 +4363,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 64 unmodified lines | |||
| 4357 | u32 queue = skb_get_queue_mapping(skb); | 4363 | u32 queue = skb_get_queue_mapping(skb); |
| 4358 | int nfrags = skb_shinfo(skb)->nr_frags; | 4364 | int nfrags = skb_shinfo(skb)->nr_frags; |
| 4359 | int gso = skb_shinfo(skb)->gso_type; | 4365 | int gso = skb_shinfo(skb)->gso_type; |
| 4366 | struct stmmac_txq_stats *txq_stats; | ||
| 4360 | struct dma_edesc *tbs_desc = NULL; | 4367 | struct dma_edesc *tbs_desc = NULL; |
| 4361 | struct dma_desc *desc, *first; | 4368 | struct dma_desc *desc, *first; |
| 4362 | struct stmmac_tx_queue *tx_q; | 4369 | struct stmmac_tx_queue *tx_q; |
| @@ -4366,6 +4373,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 3 unmodified lines | |||
| 4366 | dma_addr_t des; | 4373 | dma_addr_t des; |
| 4367 | 4374 | ||
| 4368 | tx_q = &priv->dma_conf.tx_queue[queue]; | 4375 | tx_q = &priv->dma_conf.tx_queue[queue]; |
| 4376 | txq_stats = &priv->xstats.txq_stats[queue]; | ||
| 4369 | first_tx = tx_q->cur_tx; | 4377 | first_tx = tx_q->cur_tx; |
| 4370 | 4378 | ||
| 4371 | if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en) | 4379 | if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en) |
| @@ -4517,11 +4525,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 145 unmodified lines | |||
| 4517 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); | 4525 | netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); |
| 4518 | } | 4526 | } |
| 4519 | 4527 | ||
| 4520 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 4528 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 4521 | tx_q->txq_stats.tx_bytes += skb->len; | 4529 | txq_stats->tx_bytes += skb->len; |
| 4522 | if (set_ic) | 4530 | if (set_ic) |
| 4523 | tx_q->txq_stats.tx_set_ic_bit++; | 4531 | txq_stats->tx_set_ic_bit++; |
| 4524 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 4532 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 4525 | 4533 | ||
| 4526 | if (priv->sarc_type) | 4534 | if (priv->sarc_type) |
| 4527 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); | 4535 | stmmac_set_desc_sarc(priv, first, priv->sarc_type); |
| @@ -4728,6 +4736,7 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, · 200 unmodified lines | |||
| 4728 | static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, | 4736 | static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, |
| 4729 | struct xdp_frame *xdpf, bool dma_map) | 4737 | struct xdp_frame *xdpf, bool dma_map) |
| 4730 | { | 4738 | { |
| 4739 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; | ||
| 4731 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 4740 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 4732 | unsigned int entry = tx_q->cur_tx; | 4741 | unsigned int entry = tx_q->cur_tx; |
| 4733 | struct dma_desc *tx_desc; | 4742 | struct dma_desc *tx_desc; |
| @@ -4787,9 +4796,9 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, · 53 unmodified lines | |||
| 4787 | unsigned long flags; | 4796 | unsigned long flags; |
| 4788 | tx_q->tx_count_frames = 0; | 4797 | tx_q->tx_count_frames = 0; |
| 4789 | stmmac_set_tx_ic(priv, tx_desc); | 4798 | stmmac_set_tx_ic(priv, tx_desc); |
| 4790 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 4799 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 4791 | tx_q->txq_stats.tx_set_ic_bit++; | 4800 | txq_stats->tx_set_ic_bit++; |
| 4792 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 4801 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 4793 | } | 4802 | } |
| 4794 | 4803 | ||
| 4795 | stmmac_enable_dma_transmission(priv, priv->ioaddr); | 4804 | stmmac_enable_dma_transmission(priv, priv->ioaddr); |
| @@ -4934,7 +4943,7 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, · 138 unmodified lines | |||
| 4934 | struct dma_desc *p, struct dma_desc *np, | 4943 | struct dma_desc *p, struct dma_desc *np, |
| 4935 | struct xdp_buff *xdp) | 4944 | struct xdp_buff *xdp) |
| 4936 | { | 4945 | { |
| 4937 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; | 4946 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[queue]; |
| 4938 | struct stmmac_channel *ch = &priv->channel[queue]; | 4947 | struct stmmac_channel *ch = &priv->channel[queue]; |
| 4939 | unsigned int len = xdp->data_end - xdp->data; | 4948 | unsigned int len = xdp->data_end - xdp->data; |
| 4940 | enum pkt_hash_types hash_type; | 4949 | enum pkt_hash_types hash_type; |
| @@ -4964,10 +4973,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue, · 23 unmodified lines | |||
| 4964 | skb_record_rx_queue(skb, queue); | 4973 | skb_record_rx_queue(skb, queue); |
| 4965 | napi_gro_receive(&ch->rxtx_napi, skb); | 4974 | napi_gro_receive(&ch->rxtx_napi, skb); |
| 4966 | 4975 | ||
| 4967 | flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); | 4976 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); |
| 4968 | rx_q->rxq_stats.rx_pkt_n++; | 4977 | rxq_stats->rx_pkt_n++; |
| 4969 | rx_q->rxq_stats.rx_bytes += len; | 4978 | rxq_stats->rx_bytes += len; |
| 4970 | u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); | 4979 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); |
| 4971 | } | 4980 | } |
| 4972 | 4981 | ||
| 4973 | static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) | 4982 | static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) |
| @@ -5040,6 +5049,7 @@ static struct stmmac_xdp_buff *xsk_buff_to_stmmac_ctx(struct xdp_buff *xdp) · 66 unmodified lines | |||
| 5040 | 5049 | ||
| 5041 | static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) | 5050 | static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) |
| 5042 | { | 5051 | { |
| 5052 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[queue]; | ||
| 5043 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; | 5053 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; |
| 5044 | unsigned int count = 0, error = 0, len = 0; | 5054 | unsigned int count = 0, error = 0, len = 0; |
| 5045 | int dirty = stmmac_rx_dirty(priv, queue); | 5055 | int dirty = stmmac_rx_dirty(priv, queue); |
| @@ -5203,9 +5213,9 @@ read_again: · 157 unmodified lines | |||
| 5203 | 5213 | ||
| 5204 | stmmac_finalize_xdp_rx(priv, xdp_status); | 5214 | stmmac_finalize_xdp_rx(priv, xdp_status); |
| 5205 | 5215 | ||
| 5206 | flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); | 5216 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); |
| 5207 | rx_q->rxq_stats.rx_pkt_n += count; | 5217 | rxq_stats->rx_pkt_n += count; |
| 5208 | u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); | 5218 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); |
| 5209 | 5219 | ||
| 5210 | priv->xstats.rx_dropped += rx_dropped; | 5220 | priv->xstats.rx_dropped += rx_dropped; |
| 5211 | priv->xstats.rx_errors += rx_errors; | 5221 | priv->xstats.rx_errors += rx_errors; |
| @@ -5233,6 +5243,7 @@ read_again: · 21 unmodified lines | |||
| 5233 | static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | 5243 | static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) |
| 5234 | { | 5244 | { |
| 5235 | u32 rx_errors = 0, rx_dropped = 0, rx_bytes = 0, rx_packets = 0; | 5245 | u32 rx_errors = 0, rx_dropped = 0, rx_bytes = 0, rx_packets = 0; |
| 5246 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[queue]; | ||
| 5236 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; | 5247 | struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; |
| 5237 | struct stmmac_channel *ch = &priv->channel[queue]; | 5248 | struct stmmac_channel *ch = &priv->channel[queue]; |
| 5238 | unsigned int count = 0, error = 0, len = 0; | 5249 | unsigned int count = 0, error = 0, len = 0; |
| @@ -5494,11 +5505,11 @@ drain_data: · 255 unmodified lines | |||
| 5494 | 5505 | ||
| 5495 | stmmac_rx_refill(priv, queue); | 5506 | stmmac_rx_refill(priv, queue); |
| 5496 | 5507 | ||
| 5497 | flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); | 5508 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); |
| 5498 | rx_q->rxq_stats.rx_packets += rx_packets; | 5509 | rxq_stats->rx_packets += rx_packets; |
| 5499 | rx_q->rxq_stats.rx_bytes += rx_bytes; | 5510 | rxq_stats->rx_bytes += rx_bytes; |
| 5500 | rx_q->rxq_stats.rx_pkt_n += count; | 5511 | rxq_stats->rx_pkt_n += count; |
| 5501 | u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); | 5512 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); |
| 5502 | 5513 | ||
| 5503 | priv->xstats.rx_dropped += rx_dropped; | 5514 | priv->xstats.rx_dropped += rx_dropped; |
| 5504 | priv->xstats.rx_errors += rx_errors; | 5515 | priv->xstats.rx_errors += rx_errors; |
| @@ -5511,15 +5522,15 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget) · 6 unmodified lines | |||
| 5511 | struct stmmac_channel *ch = | 5522 | struct stmmac_channel *ch = |
| 5512 | container_of(napi, struct stmmac_channel, rx_napi); | 5523 | container_of(napi, struct stmmac_channel, rx_napi); |
| 5513 | struct stmmac_priv *priv = ch->priv_data; | 5524 | struct stmmac_priv *priv = ch->priv_data; |
| 5514 | struct stmmac_rx_queue *rx_q; | 5525 | struct stmmac_rxq_stats *rxq_stats; |
| 5515 | u32 chan = ch->index; | 5526 | u32 chan = ch->index; |
| 5516 | unsigned long flags; | 5527 | unsigned long flags; |
| 5517 | int work_done; | 5528 | int work_done; |
| 5518 | 5529 | ||
| 5519 | rx_q = &priv->dma_conf.rx_queue[chan]; | 5530 | rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 5520 | flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); | 5531 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); |
| 5521 | rx_q->rxq_stats.napi_poll++; | 5532 | rxq_stats->napi_poll++; |
| 5522 | u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); | 5533 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); |
| 5523 | 5534 | ||
| 5524 | work_done = stmmac_rx(priv, budget, chan); | 5535 | work_done = stmmac_rx(priv, budget, chan); |
| 5525 | if (work_done < budget && napi_complete_done(napi, work_done)) { | 5536 | if (work_done < budget && napi_complete_done(napi, work_done)) { |
| @@ -5538,15 +5549,15 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget) · 12 unmodified lines | |||
| 5538 | struct stmmac_channel *ch = | 5549 | struct stmmac_channel *ch = |
| 5539 | container_of(napi, struct stmmac_channel, tx_napi); | 5550 | container_of(napi, struct stmmac_channel, tx_napi); |
| 5540 | struct stmmac_priv *priv = ch->priv_data; | 5551 | struct stmmac_priv *priv = ch->priv_data; |
| 5541 | struct stmmac_tx_queue *tx_q; | 5552 | struct stmmac_txq_stats *txq_stats; |
| 5542 | u32 chan = ch->index; | 5553 | u32 chan = ch->index; |
| 5543 | unsigned long flags; | 5554 | unsigned long flags; |
| 5544 | int work_done; | 5555 | int work_done; |
| 5545 | 5556 | ||
| 5546 | tx_q = &priv->dma_conf.tx_queue[chan]; | 5557 | txq_stats = &priv->xstats.txq_stats[chan]; |
| 5547 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 5558 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 5548 | tx_q->txq_stats.napi_poll++; | 5559 | txq_stats->napi_poll++; |
| 5549 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 5560 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 5550 | 5561 | ||
| 5551 | work_done = stmmac_tx_clean(priv, budget, chan); | 5562 | work_done = stmmac_tx_clean(priv, budget, chan); |
| 5552 | work_done = min(work_done, budget); | 5563 | work_done = min(work_done, budget); |
| @@ -5568,20 +5579,20 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget) · 15 unmodified lines | |||
| 5568 | container_of(napi, struct stmmac_channel, rxtx_napi); | 5579 | container_of(napi, struct stmmac_channel, rxtx_napi); |
| 5569 | struct stmmac_priv *priv = ch->priv_data; | 5580 | struct stmmac_priv *priv = ch->priv_data; |
| 5570 | int rx_done, tx_done, rxtx_done; | 5581 | int rx_done, tx_done, rxtx_done; |
| 5571 | struct stmmac_rx_queue *rx_q; | 5582 | struct stmmac_rxq_stats *rxq_stats; |
| 5572 | struct stmmac_tx_queue *tx_q; | 5583 | struct stmmac_txq_stats *txq_stats; |
| 5573 | u32 chan = ch->index; | 5584 | u32 chan = ch->index; |
| 5574 | unsigned long flags; | 5585 | unsigned long flags; |
| 5575 | 5586 | ||
| 5576 | rx_q = &priv->dma_conf.rx_queue[chan]; | 5587 | rxq_stats = &priv->xstats.rxq_stats[chan]; |
| 5577 | flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp); | 5588 | flags = u64_stats_update_begin_irqsave(&rxq_stats->syncp); |
| 5578 | rx_q->rxq_stats.napi_poll++; | 5589 | rxq_stats->napi_poll++; |
| 5579 | u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags); | 5590 | u64_stats_update_end_irqrestore(&rxq_stats->syncp, flags); |
| 5580 | 5591 | ||
| 5581 | tx_q = &priv->dma_conf.tx_queue[chan]; | 5592 | txq_stats = &priv->xstats.txq_stats[chan]; |
| 5582 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); | 5593 | flags = u64_stats_update_begin_irqsave(&txq_stats->syncp); |
| 5583 | tx_q->txq_stats.napi_poll++; | 5594 | txq_stats->napi_poll++; |
| 5584 | u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags); | 5595 | u64_stats_update_end_irqrestore(&txq_stats->syncp, flags); |
| 5585 | 5596 | ||
| 5586 | tx_done = stmmac_tx_clean(priv, budget, chan); | 5597 | tx_done = stmmac_tx_clean(priv, budget, chan); |
| 5587 | tx_done = min(tx_done, budget); | 5598 | tx_done = min(tx_done, budget); |
| @@ -6924,7 +6935,7 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 · 1336 unmodified lines | |||
| 6924 | int q; | 6935 | int q; |
| 6925 | 6936 | ||
| 6926 | for (q = 0; q < tx_cnt; q++) { | 6937 | for (q = 0; q < tx_cnt; q++) { |
| 6927 | struct stmmac_txq_stats *txq_stats = &priv->dma_conf.tx_queue[q].txq_stats; | 6938 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q]; |
| 6928 | u64 tx_packets; | 6939 | u64 tx_packets; |
| 6929 | u64 tx_bytes; | 6940 | u64 tx_bytes; |
| 6930 | 6941 | ||
| @@ -6939,7 +6950,7 @@ static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 · 8 unmodified lines | |||
| 6939 | } | 6950 | } |
| 6940 | 6951 | ||
| 6941 | for (q = 0; q < rx_cnt; q++) { | 6952 | for (q = 0; q < rx_cnt; q++) { |
| 6942 | struct stmmac_rxq_stats *rxq_stats = &priv->dma_conf.rx_queue[q].rxq_stats; | 6953 | struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q]; |
| 6943 | u64 rx_packets; | 6954 | u64 rx_packets; |
| 6944 | u64 rx_bytes; | 6955 | u64 rx_bytes; |
| 6945 | 6956 | ||
| @@ -7340,9 +7351,9 @@ int stmmac_dvr_probe(struct device *device, · 394 unmodified lines | |||
| 7340 | priv->dev = ndev; | 7351 | priv->dev = ndev; |
| 7341 | 7352 | ||
| 7342 | for (i = 0; i < MTL_MAX_RX_QUEUES; i++) | 7353 | for (i = 0; i < MTL_MAX_RX_QUEUES; i++) |
| 7343 | u64_stats_init(&priv->dma_conf.rx_queue[i].rxq_stats.syncp); | 7354 | u64_stats_init(&priv->xstats.rxq_stats[i].syncp); |
| 7344 | for (i = 0; i < MTL_MAX_TX_QUEUES; i++) | 7355 | for (i = 0; i < MTL_MAX_TX_QUEUES; i++) |
| 7345 | u64_stats_init(&priv->dma_conf.tx_queue[i].txq_stats.syncp); | 7356 | u64_stats_init(&priv->xstats.txq_stats[i].syncp); |
| 7346 | 7357 | ||
| 7347 | stmmac_set_ethtool_ops(ndev); | 7358 | stmmac_set_ethtool_ops(ndev); |
| 7348 | priv->pause = pause; | 7359 | priv->pause = pause; |
| @@ -199,6 +199,7 @@ config TI_ICSSG_PRUETH · 198 unmodified lines | |||
| 199 | 199 | ||
| 200 | config TI_ICSS_IEP | 200 | config TI_ICSS_IEP |
| 201 | tristate "TI PRU ICSS IEP driver" | 201 | tristate "TI PRU ICSS IEP driver" |
| 202 | depends on PTP_1588_CLOCK_OPTIONAL | ||
| 202 | depends on TI_PRUSS | 203 | depends on TI_PRUSS |
| 203 | default TI_PRUSS | 204 | default TI_PRUSS |
| 204 | help | 205 | help |
| @@ -2115,7 +2115,12 @@ static const struct ethtool_ops team_ethtool_ops = { · 2114 unmodified lines | |||
| 2115 | static void team_setup_by_port(struct net_device *dev, | 2115 | static void team_setup_by_port(struct net_device *dev, |
| 2116 | struct net_device *port_dev) | 2116 | struct net_device *port_dev) |
| 2117 | { | 2117 | { |
| 2118 | dev->header_ops = port_dev->header_ops; | 2118 | struct team *team = netdev_priv(dev); |
| 2119 | |||
| 2120 | if (port_dev->type == ARPHRD_ETHER) | ||
| 2121 | dev->header_ops = team->header_ops_cache; | ||
| 2122 | else | ||
| 2123 | dev->header_ops = port_dev->header_ops; | ||
| 2119 | dev->type = port_dev->type; | 2124 | dev->type = port_dev->type; |
| 2120 | dev->hard_header_len = port_dev->hard_header_len; | 2125 | dev->hard_header_len = port_dev->hard_header_len; |
| 2121 | dev->needed_headroom = port_dev->needed_headroom; | 2126 | dev->needed_headroom = port_dev->needed_headroom; |
| @@ -2162,8 +2167,11 @@ static int team_dev_type_check_change(struct net_device *dev, · 40 unmodified lines | |||
| 2162 | 2167 | ||
| 2163 | static void team_setup(struct net_device *dev) | 2168 | static void team_setup(struct net_device *dev) |
| 2164 | { | 2169 | { |
| 2170 | struct team *team = netdev_priv(dev); | ||
| 2171 | |||
| 2165 | ether_setup(dev); | 2172 | ether_setup(dev); |
| 2166 | dev->max_mtu = ETH_MAX_MTU; | 2173 | dev->max_mtu = ETH_MAX_MTU; |
| 2174 | team->header_ops_cache = dev->header_ops; | ||
| 2167 | 2175 | ||
| 2168 | dev->netdev_ops = &team_netdev_ops; | 2176 | dev->netdev_ops = &team_netdev_ops; |
| 2169 | dev->ethtool_ops = &team_ethtool_ops; | 2177 | dev->ethtool_ops = &team_ethtool_ops; |
| @@ -1049,12 +1049,11 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb, · 1048 unmodified lines | |||
| 1049 | *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, | 1049 | *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, |
| 1050 | ip_hdr(skb)->daddr, 0, | 1050 | ip_hdr(skb)->daddr, 0, |
| 1051 | ip_hdr(skb)->protocol, 0); | 1051 | ip_hdr(skb)->protocol, 0); |
| 1052 | } else if (skb_is_gso_v6(skb)) { | 1052 | } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { |
| 1053 | tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); | 1053 | tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); |
| 1054 | *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 1054 | *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
| 1055 | &ipv6_hdr(skb)->daddr, 0, | 1055 | &ipv6_hdr(skb)->daddr, 0, |
| 1056 | IPPROTO_TCP, 0); | 1056 | IPPROTO_TCP, 0); |
| 1057 | return false; | ||
| 1058 | } else if (protocol == htons(ETH_P_IPV6)) { | 1057 | } else if (protocol == htons(ETH_P_IPV6)) { |
| 1059 | tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; | 1058 | tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; |
| 1060 | *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 1059 | *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
| @@ -2636,6 +2636,9 @@ static int r8152_poll(struct napi_struct *napi, int budget) · 2635 unmodified lines | |||
| 2636 | struct r8152 *tp = container_of(napi, struct r8152, napi); | 2636 | struct r8152 *tp = container_of(napi, struct r8152, napi); |
| 2637 | int work_done; | 2637 | int work_done; |
| 2638 | 2638 | ||
| 2639 | if (!budget) | ||
| 2640 | return 0; | ||
| 2641 | |||
| 2639 | work_done = rx_bottom(tp, budget); | 2642 | work_done = rx_bottom(tp, budget); |
| 2640 | 2643 | ||
| 2641 | if (work_done < budget) { | 2644 | if (work_done < budget) { |
| @@ -1446,6 +1446,8 @@ static int veth_open(struct net_device *dev) · 1445 unmodified lines | |||
| 1446 | netif_carrier_on(peer); | 1446 | netif_carrier_on(peer); |
| 1447 | } | 1447 | } |
| 1448 | 1448 | ||
| 1449 | veth_set_xdp_features(dev); | ||
| 1450 | |||
| 1449 | return 0; | 1451 | return 0; |
| 1450 | } | 1452 | } |
| 1451 | 1453 | ||
| @@ -4331,6 +4331,10 @@ static size_t vxlan_get_size(const struct net_device *dev) · 4330 unmodified lines | |||
| 4331 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_TX */ | 4331 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_TX */ |
| 4332 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */ | 4332 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */ |
| 4333 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LOCALBYPASS */ | 4333 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_LOCALBYPASS */ |
| 4334 | nla_total_size(0) + /* IFLA_VXLAN_GBP */ | ||
| 4335 | nla_total_size(0) + /* IFLA_VXLAN_GPE */ | ||
| 4336 | nla_total_size(0) + /* IFLA_VXLAN_REMCSUM_NOPARTIAL */ | ||
| 4337 | nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_VNIFILTER */ | ||
| 4334 | 0; | 4338 | 0; |
| 4335 | } | 4339 | } |
| 4336 | 4340 | ||
| @@ -2245,25 +2245,8 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 2244 unmodified lines | |||
| 2245 | else | 2245 | else |
| 2246 | ctrl->ctrl_config = NVME_CC_CSS_NVM; | 2246 | ctrl->ctrl_config = NVME_CC_CSS_NVM; |
| 2247 | 2247 | ||
| 2248 | if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { | 2248 | if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) |
| 2249 | u32 crto; | 2249 | ctrl->ctrl_config |= NVME_CC_CRIME; |
| 2250 | |||
| 2251 | ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); | ||
| 2252 | if (ret) { | ||
| 2253 | dev_err(ctrl->device, "Reading CRTO failed (%d)\n", | ||
| 2254 | ret); | ||
| 2255 | return ret; | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | if (ctrl->cap & NVME_CAP_CRMS_CRIMS) { | ||
| 2259 | ctrl->ctrl_config |= NVME_CC_CRIME; | ||
| 2260 | timeout = NVME_CRTO_CRIMT(crto); | ||
| 2261 | } else { | ||
| 2262 | timeout = NVME_CRTO_CRWMT(crto); | ||
| 2263 | } | ||
| 2264 | } else { | ||
| 2265 | timeout = NVME_CAP_TIMEOUT(ctrl->cap); | ||
| 2266 | } | ||
| 2267 | 2250 | ||
| 2268 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; | 2251 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; |
| 2269 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; | 2252 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; |
| @@ -2277,6 +2260,39 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 7 unmodified lines | |||
| 2277 | if (ret) | 2260 | if (ret) |
| 2278 | return ret; | 2261 | return ret; |
| 2279 | 2262 | ||
| 2263 | /* CAP value may change after initial CC write */ | ||
| 2264 | ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap); | ||
| 2265 | if (ret) | ||
| 2266 | return ret; | ||
| 2267 | |||
| 2268 | timeout = NVME_CAP_TIMEOUT(ctrl->cap); | ||
| 2269 | if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { | ||
| 2270 | u32 crto, ready_timeout; | ||
| 2271 | |||
| 2272 | ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); | ||
| 2273 | if (ret) { | ||
| 2274 | dev_err(ctrl->device, "Reading CRTO failed (%d)\n", | ||
| 2275 | ret); | ||
| 2276 | return ret; | ||
| 2277 | } | ||
| 2278 | |||
| 2279 | /* | ||
| 2280 | * CRTO should always be greater or equal to CAP.TO, but some | ||
| 2281 | * devices are known to get this wrong. Use the larger of the | ||
| 2282 | * two values. | ||
| 2283 | */ | ||
| 2284 | if (ctrl->ctrl_config & NVME_CC_CRIME) | ||
| 2285 | ready_timeout = NVME_CRTO_CRIMT(crto); | ||
| 2286 | else | ||
| 2287 | ready_timeout = NVME_CRTO_CRWMT(crto); | ||
| 2288 | |||
| 2289 | if (ready_timeout < timeout) | ||
| 2290 | dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", | ||
| 2291 | crto, ctrl->cap); | ||
| 2292 | else | ||
| 2293 | timeout = ready_timeout; | ||
| 2294 | } | ||
| 2295 | |||
| 2280 | ctrl->ctrl_config |= NVME_CC_ENABLE; | 2296 | ctrl->ctrl_config |= NVME_CC_ENABLE; |
| 2281 | ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); | 2297 | ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); |
| 2282 | if (ret) | 2298 | if (ret) |
| @@ -1924,7 +1924,7 @@ char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req) · 1923 unmodified lines | |||
| 1924 | struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req); | 1924 | struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req); |
| 1925 | struct request *rq = op->rq; | 1925 | struct request *rq = op->rq; |
| 1926 | 1926 | ||
| 1927 | if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio) | 1927 | if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq || !rq->bio) |
| 1928 | return NULL; | 1928 | return NULL; |
| 1929 | return blkcg_get_fc_appid(rq->bio); | 1929 | return blkcg_get_fc_appid(rq->bio); |
| 1930 | } | 1930 | } |
| @@ -187,7 +187,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data, · 186 unmodified lines | |||
| 187 | return 0; | 187 | return 0; |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | static const struct hwmon_channel_info *nvme_hwmon_info[] = { | 190 | static const struct hwmon_channel_info *const nvme_hwmon_info[] = { |
| 191 | HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), | 191 | HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), |
| 192 | HWMON_CHANNEL_INFO(temp, | 192 | HWMON_CHANNEL_INFO(temp, |
| 193 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN | | 193 | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MIN | |
| @@ -2916,9 +2916,6 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, · 2915 unmodified lines | |||
| 2916 | struct nvme_dev *dev; | 2916 | struct nvme_dev *dev; |
| 2917 | int ret = -ENOMEM; | 2917 | int ret = -ENOMEM; |
| 2918 | 2918 | ||
| 2919 | if (node == NUMA_NO_NODE) | ||
| 2920 | set_dev_node(&pdev->dev, first_memory_node); | ||
| 2921 | |||
| 2922 | dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); | 2919 | dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); |
| 2923 | if (!dev) | 2920 | if (!dev) |
| 2924 | return ERR_PTR(-ENOMEM); | 2921 | return ERR_PTR(-ENOMEM); |
| @@ -348,7 +348,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd) · 347 unmodified lines | |||
| 348 | while (length) { | 348 | while (length) { |
| 349 | u32 iov_len = min_t(u32, length, sg->length - sg_offset); | 349 | u32 iov_len = min_t(u32, length, sg->length - sg_offset); |
| 350 | 350 | ||
| 351 | bvec_set_page(iov, sg_page(sg), sg->length, | 351 | bvec_set_page(iov, sg_page(sg), iov_len, |
| 352 | sg->offset + sg_offset); | 352 | sg->offset + sg_offset); |
| 353 | 353 | ||
| 354 | length -= iov_len; | 354 | length -= iov_len; |
| @@ -214,7 +214,7 @@ struct ioa_registers { · 213 unmodified lines | |||
| 214 | struct ioc { | 214 | struct ioc { |
| 215 | struct ioa_registers __iomem *ioc_regs; /* I/O MMU base address */ | 215 | struct ioa_registers __iomem *ioc_regs; /* I/O MMU base address */ |
| 216 | u8 *res_map; /* resource map, bit == pdir entry */ | 216 | u8 *res_map; /* resource map, bit == pdir entry */ |
| 217 | u64 *pdir_base; /* physical base address */ | 217 | __le64 *pdir_base; /* physical base address */ |
| 218 | u32 pdir_size; /* bytes, function of IOV Space size */ | 218 | u32 pdir_size; /* bytes, function of IOV Space size */ |
| 219 | u32 res_hint; /* next available IOVP - | 219 | u32 res_hint; /* next available IOVP - |
| 220 | circular search */ | 220 | circular search */ |
| @@ -339,7 +339,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) · 118 unmodified lines | |||
| 339 | BUG_ON(pages_needed == 0); | 339 | BUG_ON(pages_needed == 0); |
| 340 | BUG_ON((pages_needed * IOVP_SIZE) > DMA_CHUNK_SIZE); | 340 | BUG_ON((pages_needed * IOVP_SIZE) > DMA_CHUNK_SIZE); |
| 341 | 341 | ||
| 342 | DBG_RES("%s() size: %d pages_needed %d\n", | 342 | DBG_RES("%s() size: %zu pages_needed %d\n", |
| 343 | __func__, size, pages_needed); | 343 | __func__, size, pages_needed); |
| 344 | 344 | ||
| 345 | /* | 345 | /* |
| @@ -427,7 +427,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) · 81 unmodified lines | |||
| 427 | BUG_ON((pages_mapped * IOVP_SIZE) > DMA_CHUNK_SIZE); | 427 | BUG_ON((pages_mapped * IOVP_SIZE) > DMA_CHUNK_SIZE); |
| 428 | BUG_ON(pages_mapped > BITS_PER_LONG); | 428 | BUG_ON(pages_mapped > BITS_PER_LONG); |
| 429 | 429 | ||
| 430 | DBG_RES("%s(): res_idx: %d pages_mapped %d\n", | 430 | DBG_RES("%s(): res_idx: %d pages_mapped %lu\n", |
| 431 | __func__, res_idx, pages_mapped); | 431 | __func__, res_idx, pages_mapped); |
| 432 | 432 | ||
| 433 | #ifdef CCIO_COLLECT_STATS | 433 | #ifdef CCIO_COLLECT_STATS |
| @@ -543,7 +543,7 @@ static u32 hint_lookup[] = { · 109 unmodified lines | |||
| 543 | * index are bits 12:19 of the value returned by LCI. | 543 | * index are bits 12:19 of the value returned by LCI. |
| 544 | */ | 544 | */ |
| 545 | static void | 545 | static void |
| 546 | ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, | 546 | ccio_io_pdir_entry(__le64 *pdir_ptr, space_t sid, unsigned long vba, |
| 547 | unsigned long hints) | 547 | unsigned long hints) |
| 548 | { | 548 | { |
| 549 | register unsigned long pa; | 549 | register unsigned long pa; |
| @@ -719,7 +719,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, · 169 unmodified lines | |||
| 719 | unsigned long flags; | 719 | unsigned long flags; |
| 720 | dma_addr_t iovp; | 720 | dma_addr_t iovp; |
| 721 | dma_addr_t offset; | 721 | dma_addr_t offset; |
| 722 | u64 *pdir_start; | 722 | __le64 *pdir_start; |
| 723 | unsigned long hint = hint_lookup[(int)direction]; | 723 | unsigned long hint = hint_lookup[(int)direction]; |
| 724 | 724 | ||
| 725 | BUG_ON(!dev); | 725 | BUG_ON(!dev); |
| @@ -746,8 +746,8 @@ ccio_map_single(struct device *dev, void *addr, size_t size, · 20 unmodified lines | |||
| 746 | 746 | ||
| 747 | pdir_start = &(ioc->pdir_base[idx]); | 747 | pdir_start = &(ioc->pdir_base[idx]); |
| 748 | 748 | ||
| 749 | DBG_RUN("%s() 0x%p -> 0x%lx size: %0x%x\n", | 749 | DBG_RUN("%s() %px -> %#lx size: %zu\n", |
| 750 | __func__, addr, (long)iovp | offset, size); | 750 | __func__, addr, (long)(iovp | offset), size); |
| 751 | 751 | ||
| 752 | /* If not cacheline aligned, force SAFE_DMA on the whole mess */ | 752 | /* If not cacheline aligned, force SAFE_DMA on the whole mess */ |
| 753 | if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES)) | 753 | if((size % L1_CACHE_BYTES) || ((unsigned long)addr % L1_CACHE_BYTES)) |
| @@ -805,7 +805,7 @@ ccio_unmap_page(struct device *dev, dma_addr_t iova, size_t size, · 51 unmodified lines | |||
| 805 | return; | 805 | return; |
| 806 | } | 806 | } |
| 807 | 807 | ||
| 808 | DBG_RUN("%s() iovp 0x%lx/%x\n", | 808 | DBG_RUN("%s() iovp %#lx/%zx\n", |
| 809 | __func__, (long)iova, size); | 809 | __func__, (long)iova, size); |
| 810 | 810 | ||
| 811 | iova ^= offset; /* clear offset bits */ | 811 | iova ^= offset; /* clear offset bits */ |
| @@ -1283,7 +1283,7 @@ ccio_ioc_init(struct ioc *ioc) · 471 unmodified lines | |||
| 1283 | iova_space_size>>20, | 1283 | iova_space_size>>20, |
| 1284 | iov_order + PAGE_SHIFT); | 1284 | iov_order + PAGE_SHIFT); |
| 1285 | 1285 | ||
| 1286 | ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL, | 1286 | ioc->pdir_base = (__le64 *)__get_free_pages(GFP_KERNEL, |
| 1287 | get_order(ioc->pdir_size)); | 1287 | get_order(ioc->pdir_size)); |
| 1288 | if(NULL == ioc->pdir_base) { | 1288 | if(NULL == ioc->pdir_base) { |
| 1289 | panic("%s() could not allocate I/O Page Table\n", __func__); | 1289 | panic("%s() could not allocate I/O Page Table\n", __func__); |
| @@ -14,13 +14,13 @@ · 13 unmodified lines | |||
| 14 | static inline unsigned int | 14 | static inline unsigned int |
| 15 | iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, | 15 | iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, |
| 16 | unsigned long hint, | 16 | unsigned long hint, |
| 17 | void (*iommu_io_pdir_entry)(u64 *, space_t, unsigned long, | 17 | void (*iommu_io_pdir_entry)(__le64 *, space_t, unsigned long, |
| 18 | unsigned long)) | 18 | unsigned long)) |
| 19 | { | 19 | { |
| 20 | struct scatterlist *dma_sg = startsg; /* pointer to current DMA */ | 20 | struct scatterlist *dma_sg = startsg; /* pointer to current DMA */ |
| 21 | unsigned int n_mappings = 0; | 21 | unsigned int n_mappings = 0; |
| 22 | unsigned long dma_offset = 0, dma_len = 0; | 22 | unsigned long dma_offset = 0, dma_len = 0; |
| 23 | u64 *pdirp = NULL; | 23 | __le64 *pdirp = NULL; |
| 24 | 24 | ||
| 25 | /* Horrible hack. For efficiency's sake, dma_sg starts one | 25 | /* Horrible hack. For efficiency's sake, dma_sg starts one |
| 26 | * entry below the true start (it is immediately incremented | 26 | * entry below the true start (it is immediately incremented |
| @@ -31,8 +31,8 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, · 4 unmodified lines | |||
| 31 | unsigned long vaddr; | 31 | unsigned long vaddr; |
| 32 | long size; | 32 | long size; |
| 33 | 33 | ||
| 34 | DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents, | 34 | DBG_RUN_SG(" %d : %08lx %p/%05x\n", nents, |
| 35 | (unsigned long)sg_dma_address(startsg), cnt, | 35 | (unsigned long)sg_dma_address(startsg), |
| 36 | sg_virt(startsg), startsg->length | 36 | sg_virt(startsg), startsg->length |
| 37 | ); | 37 | ); |
| 38 | 38 | ||
| @@ -202,9 +202,9 @@ static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 va · 201 unmodified lines | |||
| 202 | 202 | ||
| 203 | static DEFINE_SPINLOCK(iosapic_lock); | 203 | static DEFINE_SPINLOCK(iosapic_lock); |
| 204 | 204 | ||
| 205 | static inline void iosapic_eoi(void __iomem *addr, unsigned int data) | 205 | static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data) |
| 206 | { | 206 | { |
| 207 | __raw_writel(data, addr); | 207 | __raw_writel((__force u32)data, addr); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | /* | 210 | /* |
| @@ -118,8 +118,8 @@ struct iosapic_irt { · 117 unmodified lines | |||
| 118 | struct vector_info { | 118 | struct vector_info { |
| 119 | struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ | 119 | struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ |
| 120 | struct irt_entry *irte; /* IRT entry */ | 120 | struct irt_entry *irte; /* IRT entry */ |
| 121 | u32 __iomem *eoi_addr; /* precalculate EOI reg address */ | 121 | __le32 __iomem *eoi_addr; /* precalculate EOI reg address */ |
| 122 | u32 eoi_data; /* IA64: ? PA: swapped txn_data */ | 122 | __le32 eoi_data; /* IA64: ? PA: swapped txn_data */ |
| 123 | int txn_irq; /* virtual IRQ number for processor */ | 123 | int txn_irq; /* virtual IRQ number for processor */ |
| 124 | ulong txn_addr; /* IA64: id_eid PA: partial HPA */ | 124 | ulong txn_addr; /* IA64: id_eid PA: partial HPA */ |
| 125 | u32 txn_data; /* CPU interrupt bit */ | 125 | u32 txn_data; /* CPU interrupt bit */ |
| @@ -46,8 +46,6 @@ · 45 unmodified lines | |||
| 46 | #include <linux/module.h> | 46 | #include <linux/module.h> |
| 47 | 47 | ||
| 48 | #include <asm/ropes.h> | 48 | #include <asm/ropes.h> |
| 49 | #include <asm/mckinley.h> /* for proc_mckinley_root */ | ||
| 50 | #include <asm/runway.h> /* for proc_runway_root */ | ||
| 51 | #include <asm/page.h> /* for PAGE0 */ | 49 | #include <asm/page.h> /* for PAGE0 */ |
| 52 | #include <asm/pdc.h> /* for PDC_MODEL_* */ | 50 | #include <asm/pdc.h> /* for PDC_MODEL_* */ |
| 53 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ | 51 | #include <asm/pdcpat.h> /* for is_pdc_pat() */ |
| @@ -122,7 +120,7 @@ MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART"); · 68 unmodified lines | |||
| 122 | #endif | 120 | #endif |
| 123 | 121 | ||
| 124 | static struct proc_dir_entry *proc_runway_root __ro_after_init; | 122 | static struct proc_dir_entry *proc_runway_root __ro_after_init; |
| 125 | struct proc_dir_entry *proc_mckinley_root __ro_after_init; | 123 | static struct proc_dir_entry *proc_mckinley_root __ro_after_init; |
| 126 | 124 | ||
| 127 | /************************************ | 125 | /************************************ |
| 128 | ** SBA register read and write support | 126 | ** SBA register read and write support |
| @@ -204,7 +202,7 @@ static void · 75 unmodified lines | |||
| 204 | sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide) | 202 | sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide) |
| 205 | { | 203 | { |
| 206 | /* start printing from lowest pde in rval */ | 204 | /* start printing from lowest pde in rval */ |
| 207 | u64 *ptr = &(ioc->pdir_base[pide & (~0U * BITS_PER_LONG)]); | 205 | __le64 *ptr = &(ioc->pdir_base[pide & (~0U * BITS_PER_LONG)]); |
| 208 | unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]); | 206 | unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]); |
| 209 | uint rcnt; | 207 | uint rcnt; |
| 210 | 208 | ||
| @@ -571,7 +569,7 @@ typedef unsigned long space_t; · 360 unmodified lines | |||
| 571 | */ | 569 | */ |
| 572 | 570 | ||
| 573 | static void | 571 | static void |
| 574 | sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba, | 572 | sba_io_pdir_entry(__le64 *pdir_ptr, space_t sid, unsigned long vba, |
| 575 | unsigned long hint) | 573 | unsigned long hint) |
| 576 | { | 574 | { |
| 577 | u64 pa; /* physical address */ | 575 | u64 pa; /* physical address */ |
| @@ -615,7 +613,7 @@ static void · 37 unmodified lines | |||
| 615 | sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) | 613 | sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) |
| 616 | { | 614 | { |
| 617 | u32 iovp = (u32) SBA_IOVP(ioc,iova); | 615 | u32 iovp = (u32) SBA_IOVP(ioc,iova); |
| 618 | u64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)]; | 616 | __le64 *pdir_ptr = &ioc->pdir_base[PDIR_INDEX(iovp)]; |
| 619 | 617 | ||
| 620 | #ifdef ASSERT_PDIR_SANITY | 618 | #ifdef ASSERT_PDIR_SANITY |
| 621 | /* Assert first pdir entry is set. | 619 | /* Assert first pdir entry is set. |
| @@ -716,7 +714,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, · 94 unmodified lines | |||
| 716 | unsigned long flags; | 714 | unsigned long flags; |
| 717 | dma_addr_t iovp; | 715 | dma_addr_t iovp; |
| 718 | dma_addr_t offset; | 716 | dma_addr_t offset; |
| 719 | u64 *pdir_start; | 717 | __le64 *pdir_start; |
| 720 | int pide; | 718 | int pide; |
| 721 | 719 | ||
| 722 | ioc = GET_IOC(dev); | 720 | ioc = GET_IOC(dev); |
| @@ -1434,7 +1432,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) · 711 unmodified lines | |||
| 1434 | 1432 | ||
| 1435 | ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64); | 1433 | ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64); |
| 1436 | 1434 | ||
| 1437 | DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n", | 1435 | DBG_INIT("%s() hpa %px mem %ldMB IOV %dMB (%d bits)\n", |
| 1438 | __func__, | 1436 | __func__, |
| 1439 | ioc->ioc_hpa, | 1437 | ioc->ioc_hpa, |
| 1440 | (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT), | 1438 | (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT), |
| @@ -1471,7 +1469,7 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) · 30 unmodified lines | |||
| 1471 | ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1); | 1469 | ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1); |
| 1472 | #endif | 1470 | #endif |
| 1473 | 1471 | ||
| 1474 | DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n", | 1472 | DBG_INIT("%s() IOV base %#lx mask %#0lx\n", |
| 1475 | __func__, ioc->ibase, ioc->imask); | 1473 | __func__, ioc->ibase, ioc->imask); |
| 1476 | 1474 | ||
| 1477 | /* | 1475 | /* |
| @@ -1583,7 +1581,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, · 105 unmodified lines | |||
| 1583 | 1581 | ||
| 1584 | if (!IS_PLUTO(sba_dev->dev)) { | 1582 | if (!IS_PLUTO(sba_dev->dev)) { |
| 1585 | ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); | 1583 | ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL); |
| 1586 | DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->", | 1584 | DBG_INIT("%s() hpa %px ioc_ctl 0x%Lx ->", |
| 1587 | __func__, sba_dev->sba_hpa, ioc_ctl); | 1585 | __func__, sba_dev->sba_hpa, ioc_ctl); |
| 1588 | ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE); | 1586 | ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE); |
| 1589 | ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC; | 1587 | ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC; |
| @@ -1668,14 +1666,14 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, · 78 unmodified lines | |||
| 1668 | /* flush out the last writes */ | 1666 | /* flush out the last writes */ |
| 1669 | READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); | 1667 | READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); |
| 1670 | 1668 | ||
| 1671 | DBG_INIT(" ioc[%d] ROPE_CFG 0x%Lx ROPE_DBG 0x%Lx\n", | 1669 | DBG_INIT(" ioc[%d] ROPE_CFG %#lx ROPE_DBG %lx\n", |
| 1672 | i, | 1670 | i, |
| 1673 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x40), | 1671 | (unsigned long) READ_REG(sba_dev->ioc[i].ioc_hpa + 0x40), |
| 1674 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x50) | 1672 | (unsigned long) READ_REG(sba_dev->ioc[i].ioc_hpa + 0x50) |
| 1675 | ); | 1673 | ); |
| 1676 | DBG_INIT(" STATUS_CONTROL 0x%Lx FLUSH_CTRL 0x%Lx\n", | 1674 | DBG_INIT(" STATUS_CONTROL %#lx FLUSH_CTRL %#lx\n", |
| 1677 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x108), | 1675 | (unsigned long) READ_REG(sba_dev->ioc[i].ioc_hpa + 0x108), |
| 1678 | READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400) | 1676 | (unsigned long) READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400) |
| 1679 | ); | 1677 | ); |
| 1680 | 1678 | ||
| 1681 | if (IS_PLUTO(sba_dev->dev)) { | 1679 | if (IS_PLUTO(sba_dev->dev)) { |
| @@ -1739,7 +1737,7 @@ sba_common_init(struct sba_device *sba_dev) · 57 unmodified lines | |||
| 1739 | #ifdef ASSERT_PDIR_SANITY | 1737 | #ifdef ASSERT_PDIR_SANITY |
| 1740 | /* Mark first bit busy - ie no IOVA 0 */ | 1738 | /* Mark first bit busy - ie no IOVA 0 */ |
| 1741 | sba_dev->ioc[i].res_map[0] = 0x80; | 1739 | sba_dev->ioc[i].res_map[0] = 0x80; |
| 1742 | sba_dev->ioc[i].pdir_base[0] = 0xeeffc0addbba0080ULL; | 1740 | sba_dev->ioc[i].pdir_base[0] = (__force __le64) 0xeeffc0addbba0080ULL; |
| 1743 | #endif | 1741 | #endif |
| 1744 | 1742 | ||
| 1745 | /* Third (and last) part of PIRANHA BUG */ | 1743 | /* Third (and last) part of PIRANHA BUG */ |
| @@ -1899,9 +1897,7 @@ static int __init sba_driver_callback(struct parisc_device *dev) · 153 unmodified lines | |||
| 1899 | int i; | 1897 | int i; |
| 1900 | char *version; | 1898 | char *version; |
| 1901 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); | 1899 | void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); |
| 1902 | #ifdef CONFIG_PROC_FS | 1900 | struct proc_dir_entry *root __maybe_unused; |
| 1903 | struct proc_dir_entry *root; | ||
| 1904 | #endif | ||
| 1905 | 1901 | ||
| 1906 | sba_dump_ranges(sba_addr); | 1902 | sba_dump_ranges(sba_addr); |
| 1907 | 1903 | ||
| @@ -1967,7 +1963,6 @@ static int __init sba_driver_callback(struct parisc_device *dev) · 59 unmodified lines | |||
| 1967 | 1963 | ||
| 1968 | hppa_dma_ops = &sba_ops; | 1964 | hppa_dma_ops = &sba_ops; |
| 1969 | 1965 | ||
| 1970 | #ifdef CONFIG_PROC_FS | ||
| 1971 | switch (dev->id.hversion) { | 1966 | switch (dev->id.hversion) { |
| 1972 | case PLUTO_MCKINLEY_PORT: | 1967 | case PLUTO_MCKINLEY_PORT: |
| 1973 | if (!proc_mckinley_root) | 1968 | if (!proc_mckinley_root) |
| @@ -1985,7 +1980,6 @@ static int __init sba_driver_callback(struct parisc_device *dev) · 11 unmodified lines | |||
| 1985 | 1980 | ||
| 1986 | proc_create_single("sba_iommu", 0, root, sba_proc_info); | 1981 | proc_create_single("sba_iommu", 0, root, sba_proc_info); |
| 1987 | proc_create_single("sba_iommu-bitmap", 0, root, sba_proc_bitmap_info); | 1982 | proc_create_single("sba_iommu-bitmap", 0, root, sba_proc_bitmap_info); |
| 1988 | #endif | ||
| 1989 | return 0; | 1983 | return 0; |
| 1990 | } | 1984 | } |
| 1991 | 1985 | ||
| @@ -229,6 +229,7 @@ int pcie_aer_is_native(struct pci_dev *dev) · 228 unmodified lines | |||
| 229 | 229 | ||
| 230 | return pcie_ports_native || host->native_aer; | 230 | return pcie_ports_native || host->native_aer; |
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL_NS_GPL(pcie_aer_is_native, CXL); | ||
| 232 | 233 | ||
| 233 | static int pci_enable_pcie_error_reporting(struct pci_dev *dev) | 234 | static int pci_enable_pcie_error_reporting(struct pci_dev *dev) |
| 234 | { | 235 | { |
| @@ -29,10 +29,8 @@ extern bool pcie_ports_dpc_native; · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #ifdef CONFIG_PCIEAER | 30 | #ifdef CONFIG_PCIEAER |
| 31 | int pcie_aer_init(void); | 31 | int pcie_aer_init(void); |
| 32 | int pcie_aer_is_native(struct pci_dev *dev); | ||
| 33 | #else | 32 | #else |
| 34 | static inline int pcie_aer_init(void) { return 0; } | 33 | static inline int pcie_aer_init(void) { return 0; } |
| 35 | static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; } | ||
| 36 | #endif | 34 | #endif |
| 37 | 35 | ||
| 38 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | 36 | #ifdef CONFIG_HOTPLUG_PCI_PCIE |
| @@ -60,6 +60,7 @@ config MLXBF_BOOTCTL · 59 unmodified lines | |||
| 60 | tristate "Mellanox BlueField Firmware Boot Control driver" | 60 | tristate "Mellanox BlueField Firmware Boot Control driver" |
| 61 | depends on ARM64 | 61 | depends on ARM64 |
| 62 | depends on ACPI | 62 | depends on ACPI |
| 63 | depends on NET | ||
| 63 | help | 64 | help |
| 64 | The Mellanox BlueField firmware implements functionality to | 65 | The Mellanox BlueField firmware implements functionality to |
| 65 | request swapping the primary and alternate eMMC boot partition, | 66 | request swapping the primary and alternate eMMC boot partition, |
| @@ -80,8 +81,8 @@ config MLXBF_PMC · 14 unmodified lines | |||
| 80 | 81 | ||
| 81 | config NVSW_SN2201 | 82 | config NVSW_SN2201 |
| 82 | tristate "Nvidia SN2201 platform driver support" | 83 | tristate "Nvidia SN2201 platform driver support" |
| 83 | depends on HWMON | 84 | depends on HWMON && I2C |
| 84 | depends on I2C | 85 | depends on ACPI || COMPILE_TEST |
| 85 | select REGMAP_I2C | 86 | select REGMAP_I2C |
| 86 | help | 87 | help |
| 87 | This driver provides support for the Nvidia SN2201 platform. | 88 | This driver provides support for the Nvidia SN2201 platform. |
| @@ -191,6 +191,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_smgen_events[] = { · 190 unmodified lines | |||
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { | 193 | static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { |
| 194 | { 0x0, "DISABLE" }, | ||
| 194 | { 0xa0, "TPIO_DATA_BEAT" }, | 195 | { 0xa0, "TPIO_DATA_BEAT" }, |
| 195 | { 0xa1, "TDMA_DATA_BEAT" }, | 196 | { 0xa1, "TDMA_DATA_BEAT" }, |
| 196 | { 0xa2, "MAP_DATA_BEAT" }, | 197 | { 0xa2, "MAP_DATA_BEAT" }, |
| @@ -214,6 +215,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { · 17 unmodified lines | |||
| 214 | }; | 215 | }; |
| 215 | 216 | ||
| 216 | static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { | 217 | static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { |
| 218 | { 0x0, "DISABLE" }, | ||
| 217 | { 0xa0, "TPIO_DATA_BEAT" }, | 219 | { 0xa0, "TPIO_DATA_BEAT" }, |
| 218 | { 0xa1, "TDMA_DATA_BEAT" }, | 220 | { 0xa1, "TDMA_DATA_BEAT" }, |
| 219 | { 0xa2, "MAP_DATA_BEAT" }, | 221 | { 0xa2, "MAP_DATA_BEAT" }, |
| @@ -246,6 +248,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { · 26 unmodified lines | |||
| 246 | }; | 248 | }; |
| 247 | 249 | ||
| 248 | static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { | 250 | static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { |
| 251 | { 0x0, "DISABLE" }, | ||
| 249 | { 0x100, "ECC_SINGLE_ERROR_CNT" }, | 252 | { 0x100, "ECC_SINGLE_ERROR_CNT" }, |
| 250 | { 0x104, "ECC_DOUBLE_ERROR_CNT" }, | 253 | { 0x104, "ECC_DOUBLE_ERROR_CNT" }, |
| 251 | { 0x114, "SERR_INJ" }, | 254 | { 0x114, "SERR_INJ" }, |
| @@ -258,6 +261,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { · 6 unmodified lines | |||
| 258 | }; | 261 | }; |
| 259 | 262 | ||
| 260 | static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { | 263 | static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { |
| 264 | { 0x0, "DISABLE" }, | ||
| 261 | { 0xc0, "RXREQ_MSS" }, | 265 | { 0xc0, "RXREQ_MSS" }, |
| 262 | { 0xc1, "RXDAT_MSS" }, | 266 | { 0xc1, "RXDAT_MSS" }, |
| 263 | { 0xc2, "TXRSP_MSS" }, | 267 | { 0xc2, "TXRSP_MSS" }, |
| @@ -265,6 +269,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { · 1 unmodified line | |||
| 265 | }; | 269 | }; |
| 266 | 270 | ||
| 267 | static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { | 271 | static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { |
| 272 | { 0x0, "DISABLE" }, | ||
| 268 | { 0x45, "HNF_REQUESTS" }, | 273 | { 0x45, "HNF_REQUESTS" }, |
| 269 | { 0x46, "HNF_REJECTS" }, | 274 | { 0x46, "HNF_REJECTS" }, |
| 270 | { 0x47, "ALL_BUSY" }, | 275 | { 0x47, "ALL_BUSY" }, |
| @@ -323,6 +328,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { · 52 unmodified lines | |||
| 323 | }; | 328 | }; |
| 324 | 329 | ||
| 325 | static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = { | 330 | static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = { |
| 331 | { 0x0, "DISABLE" }, | ||
| 326 | { 0x12, "CDN_REQ" }, | 332 | { 0x12, "CDN_REQ" }, |
| 327 | { 0x13, "DDN_REQ" }, | 333 | { 0x13, "DDN_REQ" }, |
| 328 | { 0x14, "NDN_REQ" }, | 334 | { 0x14, "NDN_REQ" }, |
| @@ -892,7 +898,7 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3, · 563 unmodified lines | |||
| 892 | uint64_t *result) | 898 | uint64_t *result) |
| 893 | { | 899 | { |
| 894 | uint32_t perfcfg_offset, perfval_offset; | 900 | uint32_t perfcfg_offset, perfval_offset; |
| 895 | uint64_t perfmon_cfg, perfevt, perfctl; | 901 | uint64_t perfmon_cfg, perfevt; |
| 896 | 902 | ||
| 897 | if (cnt_num >= pmc->block[blk_num].counters) | 903 | if (cnt_num >= pmc->block[blk_num].counters) |
| 898 | return -EINVAL; | 904 | return -EINVAL; |
| @@ -904,25 +910,6 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3, · 5 unmodified lines | |||
| 904 | perfval_offset = perfcfg_offset + | 910 | perfval_offset = perfcfg_offset + |
| 905 | pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE; | 911 | pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE; |
| 906 | 912 | ||
| 907 | /* Set counter in "read" mode */ | ||
| 908 | perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, | ||
| 909 | MLXBF_PMC_PERFCTL); | ||
| 910 | perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1); | ||
| 911 | perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); | ||
| 912 | |||
| 913 | if (mlxbf_pmc_write(pmc->block[blk_num].mmio_base + perfcfg_offset, | ||
| 914 | MLXBF_PMC_WRITE_REG_64, perfmon_cfg)) | ||
| 915 | return -EFAULT; | ||
| 916 | |||
| 917 | /* Check if the counter is enabled */ | ||
| 918 | |||
| 919 | if (mlxbf_pmc_read(pmc->block[blk_num].mmio_base + perfval_offset, | ||
| 920 | MLXBF_PMC_READ_REG_64, &perfctl)) | ||
| 921 | return -EFAULT; | ||
| 922 | |||
| 923 | if (!FIELD_GET(MLXBF_PMC_PERFCTL_EN0, perfctl)) | ||
| 924 | return -EINVAL; | ||
| 925 | |||
| 926 | /* Set counter in "read" mode */ | 913 | /* Set counter in "read" mode */ |
| 927 | perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, | 914 | perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, |
| 928 | MLXBF_PMC_PERFEVT); | 915 | MLXBF_PMC_PERFEVT); |
| @@ -1008,7 +995,7 @@ static ssize_t mlxbf_pmc_counter_show(struct device *dev, · 79 unmodified lines | |||
| 1008 | } else | 995 | } else |
| 1009 | return -EINVAL; | 996 | return -EINVAL; |
| 1010 | 997 | ||
| 1011 | return sprintf(buf, "0x%llx\n", value); | 998 | return sysfs_emit(buf, "0x%llx\n", value); |
| 1012 | } | 999 | } |
| 1013 | 1000 | ||
| 1014 | /* Store function for "counter" sysfs files */ | 1001 | /* Store function for "counter" sysfs files */ |
| @@ -1078,13 +1065,13 @@ static ssize_t mlxbf_pmc_event_show(struct device *dev, · 63 unmodified lines | |||
| 1078 | 1065 | ||
| 1079 | err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num); | 1066 | err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num); |
| 1080 | if (err) | 1067 | if (err) |
| 1081 | return sprintf(buf, "No event being monitored\n"); | 1068 | return sysfs_emit(buf, "No event being monitored\n"); |
| 1082 | 1069 | ||
| 1083 | evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num); | 1070 | evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num); |
| 1084 | if (!evt_name) | 1071 | if (!evt_name) |
| 1085 | return -EINVAL; | 1072 | return -EINVAL; |
| 1086 | 1073 | ||
| 1087 | return sprintf(buf, "0x%llx: %s\n", evt_num, evt_name); | 1074 | return sysfs_emit(buf, "0x%llx: %s\n", evt_num, evt_name); |
| 1088 | } | 1075 | } |
| 1089 | 1076 | ||
| 1090 | /* Store function for "event" sysfs files */ | 1077 | /* Store function for "event" sysfs files */ |
| @@ -1139,9 +1126,9 @@ static ssize_t mlxbf_pmc_event_list_show(struct device *dev, · 48 unmodified lines | |||
| 1139 | return -EINVAL; | 1126 | return -EINVAL; |
| 1140 | 1127 | ||
| 1141 | for (i = 0, buf[0] = '\0'; i < size; ++i) { | 1128 | for (i = 0, buf[0] = '\0'; i < size; ++i) { |
| 1142 | len += sprintf(e_info, "0x%x: %s\n", events[i].evt_num, | 1129 | len += snprintf(e_info, sizeof(e_info), "0x%x: %s\n", |
| 1143 | events[i].evt_name); | 1130 | events[i].evt_num, events[i].evt_name); |
| 1144 | if (len > PAGE_SIZE) | 1131 | if (len >= PAGE_SIZE) |
| 1145 | break; | 1132 | break; |
| 1146 | strcat(buf, e_info); | 1133 | strcat(buf, e_info); |
| 1147 | ret = len; | 1134 | ret = len; |
| @@ -1168,7 +1155,7 @@ static ssize_t mlxbf_pmc_enable_show(struct device *dev, · 20 unmodified lines | |||
| 1168 | 1155 | ||
| 1169 | value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); | 1156 | value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); |
| 1170 | 1157 | ||
| 1171 | return sprintf(buf, "%d\n", value); | 1158 | return sysfs_emit(buf, "%d\n", value); |
| 1172 | } | 1159 | } |
| 1173 | 1160 | ||
| 1174 | /* Store function for "enable" sysfs files - only for l3cache */ | 1161 | /* Store function for "enable" sysfs files - only for l3cache */ |
| @@ -59,6 +59,7 @@ struct mlxbf_tmfifo; · 58 unmodified lines | |||
| 59 | * @vq: pointer to the virtio virtqueue | 59 | * @vq: pointer to the virtio virtqueue |
| 60 | * @desc: current descriptor of the pending packet | 60 | * @desc: current descriptor of the pending packet |
| 61 | * @desc_head: head descriptor of the pending packet | 61 | * @desc_head: head descriptor of the pending packet |
| 62 | * @drop_desc: dummy desc for packet dropping | ||
| 62 | * @cur_len: processed length of the current descriptor | 63 | * @cur_len: processed length of the current descriptor |
| 63 | * @rem_len: remaining length of the pending packet | 64 | * @rem_len: remaining length of the pending packet |
| 64 | * @pkt_len: total length of the pending packet | 65 | * @pkt_len: total length of the pending packet |
| @@ -75,6 +76,7 @@ struct mlxbf_tmfifo_vring { · 10 unmodified lines | |||
| 75 | struct virtqueue *vq; | 76 | struct virtqueue *vq; |
| 76 | struct vring_desc *desc; | 77 | struct vring_desc *desc; |
| 77 | struct vring_desc *desc_head; | 78 | struct vring_desc *desc_head; |
| 79 | struct vring_desc drop_desc; | ||
| 78 | int cur_len; | 80 | int cur_len; |
| 79 | int rem_len; | 81 | int rem_len; |
| 80 | u32 pkt_len; | 82 | u32 pkt_len; |
| @@ -86,6 +88,14 @@ struct mlxbf_tmfifo_vring { · 5 unmodified lines | |||
| 86 | struct mlxbf_tmfifo *fifo; | 88 | struct mlxbf_tmfifo *fifo; |
| 87 | }; | 89 | }; |
| 88 | 90 | ||
| 91 | /* Check whether vring is in drop mode. */ | ||
| 92 | #define IS_VRING_DROP(_r) ({ \ | ||
| 93 | typeof(_r) (r) = (_r); \ | ||
| 94 | (r->desc_head == &r->drop_desc ? true : false); }) | ||
| 95 | |||
| 96 | /* A stub length to drop maximum length packet. */ | ||
| 97 | #define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0) | ||
| 98 | |||
| 89 | /* Interrupt types. */ | 99 | /* Interrupt types. */ |
| 90 | enum { | 100 | enum { |
| 91 | MLXBF_TM_RX_LWM_IRQ, | 101 | MLXBF_TM_RX_LWM_IRQ, |
| @@ -214,7 +224,7 @@ static u8 mlxbf_tmfifo_net_default_mac[ETH_ALEN] = { · 122 unmodified lines | |||
| 214 | static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr"; | 224 | static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr"; |
| 215 | 225 | ||
| 216 | /* Maximum L2 header length. */ | 226 | /* Maximum L2 header length. */ |
| 217 | #define MLXBF_TMFIFO_NET_L2_OVERHEAD 36 | 227 | #define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN) |
| 218 | 228 | ||
| 219 | /* Supported virtio-net features. */ | 229 | /* Supported virtio-net features. */ |
| 220 | #define MLXBF_TMFIFO_NET_FEATURES \ | 230 | #define MLXBF_TMFIFO_NET_FEATURES \ |
| @@ -262,6 +272,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo, · 41 unmodified lines | |||
| 262 | vring->align = SMP_CACHE_BYTES; | 272 | vring->align = SMP_CACHE_BYTES; |
| 263 | vring->index = i; | 273 | vring->index = i; |
| 264 | vring->vdev_id = tm_vdev->vdev.id.device; | 274 | vring->vdev_id = tm_vdev->vdev.id.device; |
| 275 | vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; | ||
| 265 | dev = &tm_vdev->vdev.dev; | 276 | dev = &tm_vdev->vdev.dev; |
| 266 | 277 | ||
| 267 | size = vring_size(vring->num, vring->align); | 278 | size = vring_size(vring->num, vring->align); |
| @@ -367,7 +378,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring, · 99 unmodified lines | |||
| 367 | return len; | 378 | return len; |
| 368 | } | 379 | } |
| 369 | 380 | ||
| 370 | static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring) | 381 | static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring) |
| 371 | { | 382 | { |
| 372 | struct vring_desc *desc_head; | 383 | struct vring_desc *desc_head; |
| 373 | u32 len = 0; | 384 | u32 len = 0; |
| @@ -596,19 +607,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring, · 222 unmodified lines | |||
| 596 | 607 | ||
| 597 | if (vring->cur_len + sizeof(u64) <= len) { | 608 | if (vring->cur_len + sizeof(u64) <= len) { |
| 598 | /* The whole word. */ | 609 | /* The whole word. */ |
| 599 | if (is_rx) | 610 | if (!IS_VRING_DROP(vring)) { |
| 600 | memcpy(addr + vring->cur_len, &data, sizeof(u64)); | 611 | if (is_rx) |
| 601 | else | 612 | memcpy(addr + vring->cur_len, &data, |
| 602 | memcpy(&data, addr + vring->cur_len, sizeof(u64)); | 613 | sizeof(u64)); |
| 614 | else | ||
| 615 | memcpy(&data, addr + vring->cur_len, | ||
| 616 | sizeof(u64)); | ||
| 617 | } | ||
| 603 | vring->cur_len += sizeof(u64); | 618 | vring->cur_len += sizeof(u64); |
| 604 | } else { | 619 | } else { |
| 605 | /* Leftover bytes. */ | 620 | /* Leftover bytes. */ |
| 606 | if (is_rx) | 621 | if (!IS_VRING_DROP(vring)) { |
| 607 | memcpy(addr + vring->cur_len, &data, | 622 | if (is_rx) |
| 608 | len - vring->cur_len); | 623 | memcpy(addr + vring->cur_len, &data, |
| 609 | else | 624 | len - vring->cur_len); |
| 610 | memcpy(&data, addr + vring->cur_len, | 625 | else |
| 611 | len - vring->cur_len); | 626 | memcpy(&data, addr + vring->cur_len, |
| 627 | len - vring->cur_len); | ||
| 628 | } | ||
| 612 | vring->cur_len = len; | 629 | vring->cur_len = len; |
| 613 | } | 630 | } |
| 614 | 631 | ||
| @@ -625,13 +642,14 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring, · 10 unmodified lines | |||
| 625 | * flag is set. | 642 | * flag is set. |
| 626 | */ | 643 | */ |
| 627 | static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, | 644 | static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, |
| 628 | struct vring_desc *desc, | 645 | struct vring_desc **desc, |
| 629 | bool is_rx, bool *vring_change) | 646 | bool is_rx, bool *vring_change) |
| 630 | { | 647 | { |
| 631 | struct mlxbf_tmfifo *fifo = vring->fifo; | 648 | struct mlxbf_tmfifo *fifo = vring->fifo; |
| 632 | struct virtio_net_config *config; | 649 | struct virtio_net_config *config; |
| 633 | struct mlxbf_tmfifo_msg_hdr hdr; | 650 | struct mlxbf_tmfifo_msg_hdr hdr; |
| 634 | int vdev_id, hdr_len; | 651 | int vdev_id, hdr_len; |
| 652 | bool drop_rx = false; | ||
| 635 | 653 | ||
| 636 | /* Read/Write packet header. */ | 654 | /* Read/Write packet header. */ |
| 637 | if (is_rx) { | 655 | if (is_rx) { |
| @@ -651,8 +669,8 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, · 13 unmodified lines | |||
| 651 | if (ntohs(hdr.len) > | 669 | if (ntohs(hdr.len) > |
| 652 | __virtio16_to_cpu(virtio_legacy_is_little_endian(), | 670 | __virtio16_to_cpu(virtio_legacy_is_little_endian(), |
| 653 | config->mtu) + | 671 | config->mtu) + |
| 654 | MLXBF_TMFIFO_NET_L2_OVERHEAD) | 672 | MLXBF_TMFIFO_NET_L2_OVERHEAD) |
| 655 | return; | 673 | drop_rx = true; |
| 656 | } else { | 674 | } else { |
| 657 | vdev_id = VIRTIO_ID_CONSOLE; | 675 | vdev_id = VIRTIO_ID_CONSOLE; |
| 658 | hdr_len = 0; | 676 | hdr_len = 0; |
| @@ -667,16 +685,25 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, · 8 unmodified lines | |||
| 667 | 685 | ||
| 668 | if (!tm_dev2) | 686 | if (!tm_dev2) |
| 669 | return; | 687 | return; |
| 670 | vring->desc = desc; | 688 | vring->desc = *desc; |
| 671 | vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX]; | 689 | vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX]; |
| 672 | *vring_change = true; | 690 | *vring_change = true; |
| 673 | } | 691 | } |
| 692 | |||
| 693 | if (drop_rx && !IS_VRING_DROP(vring)) { | ||
| 694 | if (vring->desc_head) | ||
| 695 | mlxbf_tmfifo_release_pkt(vring); | ||
| 696 | *desc = &vring->drop_desc; | ||
| 697 | vring->desc_head = *desc; | ||
| 698 | vring->desc = *desc; | ||
| 699 | } | ||
| 700 | |||
| 674 | vring->pkt_len = ntohs(hdr.len) + hdr_len; | 701 | vring->pkt_len = ntohs(hdr.len) + hdr_len; |
| 675 | } else { | 702 | } else { |
| 676 | /* Network virtio has an extra header. */ | 703 | /* Network virtio has an extra header. */ |
| 677 | hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ? | 704 | hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ? |
| 678 | sizeof(struct virtio_net_hdr) : 0; | 705 | sizeof(struct virtio_net_hdr) : 0; |
| 679 | vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc); | 706 | vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc); |
| 680 | hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? | 707 | hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? |
| 681 | VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; | 708 | VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; |
| 682 | hdr.len = htons(vring->pkt_len - hdr_len); | 709 | hdr.len = htons(vring->pkt_len - hdr_len); |
| @@ -709,15 +736,23 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring, · 26 unmodified lines | |||
| 709 | /* Get the descriptor of the next packet. */ | 736 | /* Get the descriptor of the next packet. */ |
| 710 | if (!vring->desc) { | 737 | if (!vring->desc) { |
| 711 | desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx); | 738 | desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx); |
| 712 | if (!desc) | 739 | if (!desc) { |
| 713 | return false; | 740 | /* Drop next Rx packet to avoid stuck. */ |
| 741 | if (is_rx) { | ||
| 742 | desc = &vring->drop_desc; | ||
| 743 | vring->desc_head = desc; | ||
| 744 | vring->desc = desc; | ||
| 745 | } else { | ||
| 746 | return false; | ||
| 747 | } | ||
| 748 | } | ||
| 714 | } else { | 749 | } else { |
| 715 | desc = vring->desc; | 750 | desc = vring->desc; |
| 716 | } | 751 | } |
| 717 | 752 | ||
| 718 | /* Beginning of a packet. Start to Rx/Tx packet header. */ | 753 | /* Beginning of a packet. Start to Rx/Tx packet header. */ |
| 719 | if (vring->pkt_len == 0) { | 754 | if (vring->pkt_len == 0) { |
| 720 | mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change); | 755 | mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change); |
| 721 | (*avail)--; | 756 | (*avail)--; |
| 722 | 757 | ||
| 723 | /* Return if new packet is for another ring. */ | 758 | /* Return if new packet is for another ring. */ |
| @@ -743,17 +778,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring, · 19 unmodified lines | |||
| 743 | vring->rem_len -= len; | 778 | vring->rem_len -= len; |
| 744 | 779 | ||
| 745 | /* Get the next desc on the chain. */ | 780 | /* Get the next desc on the chain. */ |
| 746 | if (vring->rem_len > 0 && | 781 | if (!IS_VRING_DROP(vring) && vring->rem_len > 0 && |
| 747 | (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) { | 782 | (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) { |
| 748 | idx = virtio16_to_cpu(vdev, desc->next); | 783 | idx = virtio16_to_cpu(vdev, desc->next); |
| 749 | desc = &vr->desc[idx]; | 784 | desc = &vr->desc[idx]; |
| 750 | goto mlxbf_tmfifo_desc_done; | 785 | goto mlxbf_tmfifo_desc_done; |
| 751 | } | 786 | } |
| 752 | 787 | ||
| 753 | /* Done and release the pending packet. */ | 788 | /* Done and release the packet. */ |
| 754 | mlxbf_tmfifo_release_pending_pkt(vring); | ||
| 755 | desc = NULL; | 789 | desc = NULL; |
| 756 | fifo->vring[is_rx] = NULL; | 790 | fifo->vring[is_rx] = NULL; |
| 791 | if (!IS_VRING_DROP(vring)) { | ||
| 792 | mlxbf_tmfifo_release_pkt(vring); | ||
| 793 | } else { | ||
| 794 | vring->pkt_len = 0; | ||
| 795 | vring->desc_head = NULL; | ||
| 796 | vring->desc = NULL; | ||
| 797 | return false; | ||
| 798 | } | ||
| 757 | 799 | ||
| 758 | /* | 800 | /* |
| 759 | * Make sure the load/store are in order before | 801 | * Make sure the load/store are in order before |
| @@ -933,7 +975,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev) · 173 unmodified lines | |||
| 933 | 975 | ||
| 934 | /* Release the pending packet. */ | 976 | /* Release the pending packet. */ |
| 935 | if (vring->desc) | 977 | if (vring->desc) |
| 936 | mlxbf_tmfifo_release_pending_pkt(vring); | 978 | mlxbf_tmfifo_release_pkt(vring); |
| 937 | vq = vring->vq; | 979 | vq = vring->vq; |
| 938 | if (vq) { | 980 | if (vq) { |
| 939 | vring->vq = NULL; | 981 | vring->vq = NULL; |
| @@ -478,6 +478,15 @@ static const struct dmi_system_id asus_quirks[] = { · 477 unmodified lines | |||
| 478 | }, | 478 | }, |
| 479 | .driver_data = &quirk_asus_tablet_mode, | 479 | .driver_data = &quirk_asus_tablet_mode, |
| 480 | }, | 480 | }, |
| 481 | { | ||
| 482 | .callback = dmi_matched, | ||
| 483 | .ident = "ASUS ROG FLOW X16", | ||
| 484 | .matches = { | ||
| 485 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 486 | DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"), | ||
| 487 | }, | ||
| 488 | .driver_data = &quirk_asus_tablet_mode, | ||
| 489 | }, | ||
| 481 | { | 490 | { |
| 482 | .callback = dmi_matched, | 491 | .callback = dmi_matched, |
| 483 | .ident = "ASUS VivoBook E410MA", | 492 | .ident = "ASUS VivoBook E410MA", |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
| 22 | #include <linux/iopoll.h> | ||
| 22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 24 | 25 | ||
| @@ -231,19 +232,15 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset) · 206 unmodified lines | |||
| 231 | /* Wait till scu status is busy */ | 232 | /* Wait till scu status is busy */ |
| 232 | static inline int busy_loop(struct intel_scu_ipc_dev *scu) | 233 | static inline int busy_loop(struct intel_scu_ipc_dev *scu) |
| 233 | { | 234 | { |
| 234 | unsigned long end = jiffies + IPC_TIMEOUT; | 235 | u8 status; |
| 235 | 236 | int err; | |
| 236 | do { | ||
| 237 | u32 status; | ||
| 238 | |||
| 239 | status = ipc_read_status(scu); | ||
| 240 | if (!(status & IPC_STATUS_BUSY)) | ||
| 241 | return (status & IPC_STATUS_ERR) ? -EIO : 0; | ||
| 242 | 237 | ||
| 243 | usleep_range(50, 100); | 238 | err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY), |
| 244 | } while (time_before(jiffies, end)); | 239 | 100, jiffies_to_usecs(IPC_TIMEOUT)); |
| 240 | if (err) | ||
| 241 | return err; | ||
| 245 | 242 | ||
| 246 | return -ETIMEDOUT; | 243 | return (status & IPC_STATUS_ERR) ? -EIO : 0; |
| 247 | } | 244 | } |
| 248 | 245 | ||
| 249 | /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ | 246 | /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ |
| @@ -251,10 +248,12 @@ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) · 1 unmodified line | |||
| 251 | { | 248 | { |
| 252 | int status; | 249 | int status; |
| 253 | 250 | ||
| 254 | if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) | 251 | wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT); |
| 255 | return -ETIMEDOUT; | ||
| 256 | 252 | ||
| 257 | status = ipc_read_status(scu); | 253 | status = ipc_read_status(scu); |
| 254 | if (status & IPC_STATUS_BUSY) | ||
| 255 | return -ETIMEDOUT; | ||
| 256 | |||
| 258 | if (status & IPC_STATUS_ERR) | 257 | if (status & IPC_STATUS_ERR) |
| 259 | return -EIO; | 258 | return -EIO; |
| 260 | 259 | ||
| @@ -266,6 +265,24 @@ static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu) · 5 unmodified lines | |||
| 266 | return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); | 265 | return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); |
| 267 | } | 266 | } |
| 268 | 267 | ||
| 268 | static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu) | ||
| 269 | { | ||
| 270 | u8 status; | ||
| 271 | |||
| 272 | if (!scu) | ||
| 273 | scu = ipcdev; | ||
| 274 | if (!scu) | ||
| 275 | return ERR_PTR(-ENODEV); | ||
| 276 | |||
| 277 | status = ipc_read_status(scu); | ||
| 278 | if (status & IPC_STATUS_BUSY) { | ||
| 279 | dev_dbg(&scu->dev, "device is busy\n"); | ||
| 280 | return ERR_PTR(-EBUSY); | ||
| 281 | } | ||
| 282 | |||
| 283 | return scu; | ||
| 284 | } | ||
| 285 | |||
| 269 | /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ | 286 | /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ |
| 270 | static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, | 287 | static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, |
| 271 | u32 count, u32 op, u32 id) | 288 | u32 count, u32 op, u32 id) |
| @@ -279,11 +296,10 @@ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, · 7 unmodified lines | |||
| 279 | memset(cbuf, 0, sizeof(cbuf)); | 296 | memset(cbuf, 0, sizeof(cbuf)); |
| 280 | 297 | ||
| 281 | mutex_lock(&ipclock); | 298 | mutex_lock(&ipclock); |
| 282 | if (!scu) | 299 | scu = intel_scu_ipc_get(scu); |
| 283 | scu = ipcdev; | 300 | if (IS_ERR(scu)) { |
| 284 | if (!scu) { | ||
| 285 | mutex_unlock(&ipclock); | 301 | mutex_unlock(&ipclock); |
| 286 | return -ENODEV; | 302 | return PTR_ERR(scu); |
| 287 | } | 303 | } |
| 288 | 304 | ||
| 289 | for (nc = 0; nc < count; nc++, offset += 2) { | 305 | for (nc = 0; nc < count; nc++, offset += 2) { |
| @@ -438,13 +454,12 @@ int intel_scu_ipc_dev_simple_command(struct intel_scu_ipc_dev *scu, int cmd, · 148 unmodified lines | |||
| 438 | int err; | 454 | int err; |
| 439 | 455 | ||
| 440 | mutex_lock(&ipclock); | 456 | mutex_lock(&ipclock); |
| 441 | if (!scu) | 457 | scu = intel_scu_ipc_get(scu); |
| 442 | scu = ipcdev; | 458 | if (IS_ERR(scu)) { |
| 443 | if (!scu) { | ||
| 444 | mutex_unlock(&ipclock); | 459 | mutex_unlock(&ipclock); |
| 445 | return -ENODEV; | 460 | return PTR_ERR(scu); |
| 446 | } | 461 | } |
| 447 | scu = ipcdev; | 462 | |
| 448 | cmdval = sub << 12 | cmd; | 463 | cmdval = sub << 12 | cmd; |
| 449 | ipc_command(scu, cmdval); | 464 | ipc_command(scu, cmdval); |
| 450 | err = intel_scu_ipc_check_status(scu); | 465 | err = intel_scu_ipc_check_status(scu); |
| @@ -484,11 +499,10 @@ int intel_scu_ipc_dev_command_with_size(struct intel_scu_ipc_dev *scu, int cmd, · 33 unmodified lines | |||
| 484 | return -EINVAL; | 499 | return -EINVAL; |
| 485 | 500 | ||
| 486 | mutex_lock(&ipclock); | 501 | mutex_lock(&ipclock); |
| 487 | if (!scu) | 502 | scu = intel_scu_ipc_get(scu); |
| 488 | scu = ipcdev; | 503 | if (IS_ERR(scu)) { |
| 489 | if (!scu) { | ||
| 490 | mutex_unlock(&ipclock); | 504 | mutex_unlock(&ipclock); |
| 491 | return -ENODEV; | 505 | return PTR_ERR(scu); |
| 492 | } | 506 | } |
| 493 | 507 | ||
| 494 | memcpy(inbuf, in, inlen); | 508 | memcpy(inbuf, in, inlen); |
| @@ -4116,9 +4116,11 @@ static void hotkey_resume(void) · 4115 unmodified lines | |||
| 4116 | { | 4116 | { |
| 4117 | tpacpi_disable_brightness_delay(); | 4117 | tpacpi_disable_brightness_delay(); |
| 4118 | 4118 | ||
| 4119 | mutex_lock(&hotkey_mutex); | ||
| 4119 | if (hotkey_status_set(true) < 0 || | 4120 | if (hotkey_status_set(true) < 0 || |
| 4120 | hotkey_mask_set(hotkey_acpi_mask) < 0) | 4121 | hotkey_mask_set(hotkey_acpi_mask) < 0) |
| 4121 | pr_err("error while attempting to reset the event firmware interface\n"); | 4122 | pr_err("error while attempting to reset the event firmware interface\n"); |
| 4123 | mutex_unlock(&hotkey_mutex); | ||
| 4122 | 4124 | ||
| 4123 | tpacpi_send_radiosw_update(); | 4125 | tpacpi_send_radiosw_update(); |
| 4124 | tpacpi_input_send_tabletsw(); | 4126 | tpacpi_input_send_tabletsw(); |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -300,7 +300,7 @@ config NVMEM_REBOOT_MODE · 299 unmodified lines | |||
| 300 | 300 | ||
| 301 | config POWER_MLXBF | 301 | config POWER_MLXBF |
| 302 | tristate "Mellanox BlueField power handling driver" | 302 | tristate "Mellanox BlueField power handling driver" |
| 303 | depends on (GPIO_MLXBF2 && ACPI) | 303 | depends on (GPIO_MLXBF2 || GPIO_MLXBF3) && ACPI |
| 304 | help | 304 | help |
| 305 | This driver supports reset or low power mode handling for Mellanox BlueField. | 305 | This driver supports reset or low power mode handling for Mellanox BlueField. |
| 306 | 306 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only or BSD-3-Clause | 1 | // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause |
| 2 | 2 | ||
| 3 | /* | 3 | /* |
| 4 | * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. | 4 | * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. |
| @@ -121,7 +121,7 @@ static int vexpress_reset_probe(struct platform_device *pdev) · 120 unmodified lines | |||
| 121 | return PTR_ERR(regmap); | 121 | return PTR_ERR(regmap); |
| 122 | dev_set_drvdata(&pdev->dev, regmap); | 122 | dev_set_drvdata(&pdev->dev, regmap); |
| 123 | 123 | ||
| 124 | switch ((enum vexpress_reset_func)match->data) { | 124 | switch ((uintptr_t)match->data) { |
| 125 | case FUNC_SHUTDOWN: | 125 | case FUNC_SHUTDOWN: |
| 126 | vexpress_power_off_device = &pdev->dev; | 126 | vexpress_power_off_device = &pdev->dev; |
| 127 | pm_power_off = vexpress_power_off; | 127 | pm_power_off = vexpress_power_off; |
| @@ -769,6 +769,7 @@ config BATTERY_RT5033 · 768 unmodified lines | |||
| 769 | config CHARGER_RT5033 | 769 | config CHARGER_RT5033 |
| 770 | tristate "RT5033 battery charger support" | 770 | tristate "RT5033 battery charger support" |
| 771 | depends on MFD_RT5033 | 771 | depends on MFD_RT5033 |
| 772 | depends on EXTCON || !EXTCON | ||
| 772 | help | 773 | help |
| 773 | This adds support for battery charger in Richtek RT5033 PMIC. | 774 | This adds support for battery charger in Richtek RT5033 PMIC. |
| 774 | The device supports pre-charge mode, fast charge mode and | 775 | The device supports pre-charge mode, fast charge mode and |
| @@ -115,7 +115,6 @@ struct ab8500_btemp { · 114 unmodified lines | |||
| 115 | static enum power_supply_property ab8500_btemp_props[] = { | 115 | static enum power_supply_property ab8500_btemp_props[] = { |
| 116 | POWER_SUPPLY_PROP_PRESENT, | 116 | POWER_SUPPLY_PROP_PRESENT, |
| 117 | POWER_SUPPLY_PROP_ONLINE, | 117 | POWER_SUPPLY_PROP_ONLINE, |
| 118 | POWER_SUPPLY_PROP_TECHNOLOGY, | ||
| 119 | POWER_SUPPLY_PROP_TEMP, | 118 | POWER_SUPPLY_PROP_TEMP, |
| 120 | }; | 119 | }; |
| 121 | 120 | ||
| @@ -532,12 +531,6 @@ static int ab8500_btemp_get_property(struct power_supply *psy, · 410 unmodified lines | |||
| 532 | else | 531 | else |
| 533 | val->intval = 1; | 532 | val->intval = 1; |
| 534 | break; | 533 | break; |
| 535 | case POWER_SUPPLY_PROP_TECHNOLOGY: | ||
| 536 | if (di->bm->bi) | ||
| 537 | val->intval = di->bm->bi->technology; | ||
| 538 | else | ||
| 539 | val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; | ||
| 540 | break; | ||
| 541 | case POWER_SUPPLY_PROP_TEMP: | 534 | case POWER_SUPPLY_PROP_TEMP: |
| 542 | val->intval = ab8500_btemp_get_temp(di); | 535 | val->intval = ab8500_btemp_get_temp(di); |
| 543 | break; | 536 | break; |
| @@ -662,7 +655,7 @@ static char *supply_interface[] = { · 118 unmodified lines | |||
| 662 | 655 | ||
| 663 | static const struct power_supply_desc ab8500_btemp_desc = { | 656 | static const struct power_supply_desc ab8500_btemp_desc = { |
| 664 | .name = "ab8500_btemp", | 657 | .name = "ab8500_btemp", |
| 665 | .type = POWER_SUPPLY_TYPE_BATTERY, | 658 | .type = POWER_SUPPLY_TYPE_UNKNOWN, |
| 666 | .properties = ab8500_btemp_props, | 659 | .properties = ab8500_btemp_props, |
| 667 | .num_properties = ARRAY_SIZE(ab8500_btemp_props), | 660 | .num_properties = ARRAY_SIZE(ab8500_btemp_props), |
| 668 | .get_property = ab8500_btemp_get_property, | 661 | .get_property = ab8500_btemp_get_property, |
| @@ -1720,7 +1720,7 @@ static char *supply_interface[] = { · 1719 unmodified lines | |||
| 1720 | 1720 | ||
| 1721 | static const struct power_supply_desc ab8500_chargalg_desc = { | 1721 | static const struct power_supply_desc ab8500_chargalg_desc = { |
| 1722 | .name = "ab8500_chargalg", | 1722 | .name = "ab8500_chargalg", |
| 1723 | .type = POWER_SUPPLY_TYPE_BATTERY, | 1723 | .type = POWER_SUPPLY_TYPE_UNKNOWN, |
| 1724 | .properties = ab8500_chargalg_props, | 1724 | .properties = ab8500_chargalg_props, |
| 1725 | .num_properties = ARRAY_SIZE(ab8500_chargalg_props), | 1725 | .num_properties = ARRAY_SIZE(ab8500_chargalg_props), |
| 1726 | .get_property = ab8500_chargalg_get_property, | 1726 | .get_property = ab8500_chargalg_get_property, |
| @@ -324,7 +324,7 @@ static int mt6370_chg_toggle_cfo(struct mt6370_priv *priv) · 323 unmodified lines | |||
| 324 | 324 | ||
| 325 | if (fl_strobe) { | 325 | if (fl_strobe) { |
| 326 | dev_err(priv->dev, "Flash led is still in strobe mode\n"); | 326 | dev_err(priv->dev, "Flash led is still in strobe mode\n"); |
| 327 | return ret; | 327 | return -EINVAL; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | /* cfo off */ | 330 | /* cfo off */ |
| @@ -482,6 +482,13 @@ int power_supply_uevent(const struct device *dev, struct kobj_uevent_env *env) · 481 unmodified lines | |||
| 482 | if (ret) | 482 | if (ret) |
| 483 | return ret; | 483 | return ret; |
| 484 | 484 | ||
| 485 | /* | ||
| 486 | * Kernel generates KOBJ_REMOVE uevent in device removal path, after | ||
| 487 | * resources have been freed. Exit early to avoid use-after-free. | ||
| 488 | */ | ||
| 489 | if (psy->removing) | ||
| 490 | return 0; | ||
| 491 | |||
| 485 | prop_buf = (char *)get_zeroed_page(GFP_KERNEL); | 492 | prop_buf = (char *)get_zeroed_page(GFP_KERNEL); |
| 486 | if (!prop_buf) | 493 | if (!prop_buf) |
| 487 | return -ENOMEM; | 494 | return -ENOMEM; |
| @@ -1045,6 +1045,13 @@ static void rk817_charging_monitor(struct work_struct *work) · 1044 unmodified lines | |||
| 1045 | queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); | 1045 | queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); |
| 1046 | } | 1046 | } |
| 1047 | 1047 | ||
| 1048 | static void rk817_cleanup_node(void *data) | ||
| 1049 | { | ||
| 1050 | struct device_node *node = data; | ||
| 1051 | |||
| 1052 | of_node_put(node); | ||
| 1053 | } | ||
| 1054 | |||
| 1048 | static int rk817_charger_probe(struct platform_device *pdev) | 1055 | static int rk817_charger_probe(struct platform_device *pdev) |
| 1049 | { | 1056 | { |
| 1050 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | 1057 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); |
| @@ -1061,11 +1068,13 @@ static int rk817_charger_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 1061 | if (!node) | 1068 | if (!node) |
| 1062 | return -ENODEV; | 1069 | return -ENODEV; |
| 1063 | 1070 | ||
| 1071 | ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); | ||
| 1072 | if (ret) | ||
| 1073 | return ret; | ||
| 1074 | |||
| 1064 | charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); | 1075 | charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); |
| 1065 | if (!charger) { | 1076 | if (!charger) |
| 1066 | of_node_put(node); | ||
| 1067 | return -ENOMEM; | 1077 | return -ENOMEM; |
| 1068 | } | ||
| 1069 | 1078 | ||
| 1070 | charger->rk808 = rk808; | 1079 | charger->rk808 = rk808; |
| 1071 | 1080 | ||
| @@ -1211,3 +1220,4 @@ MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC"); · 139 unmodified lines | |||
| 1211 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); | 1220 | MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); |
| 1212 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); | 1221 | MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); |
| 1213 | MODULE_LICENSE("GPL"); | 1222 | MODULE_LICENSE("GPL"); |
| 1223 | MODULE_ALIAS("platform:rk817-charger"); | ||
| @@ -598,8 +598,8 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) · 597 unmodified lines | |||
| 598 | 598 | ||
| 599 | reinit_completion(&data->aicl_done); | 599 | reinit_completion(&data->aicl_done); |
| 600 | ret = wait_for_completion_timeout(&data->aicl_done, msecs_to_jiffies(3500)); | 600 | ret = wait_for_completion_timeout(&data->aicl_done, msecs_to_jiffies(3500)); |
| 601 | if (ret) | 601 | if (ret == 0) |
| 602 | return ret; | 602 | return -ETIMEDOUT; |
| 603 | 603 | ||
| 604 | ret = rt9467_get_value_from_ranges(data, F_IAICR, RT9467_RANGE_IAICR, &aicr_get); | 604 | ret = rt9467_get_value_from_ranges(data, F_IAICR, RT9467_RANGE_IAICR, &aicr_get); |
| 605 | if (ret) { | 605 | if (ret) { |
| @@ -384,7 +384,8 @@ static int ucs1002_get_property(struct power_supply *psy, · 383 unmodified lines | |||
| 384 | case POWER_SUPPLY_PROP_USB_TYPE: | 384 | case POWER_SUPPLY_PROP_USB_TYPE: |
| 385 | return ucs1002_get_usb_type(info, val); | 385 | return ucs1002_get_usb_type(info, val); |
| 386 | case POWER_SUPPLY_PROP_HEALTH: | 386 | case POWER_SUPPLY_PROP_HEALTH: |
| 387 | return val->intval = info->health; | 387 | val->intval = info->health; |
| 388 | return 0; | ||
| 388 | case POWER_SUPPLY_PROP_PRESENT: | 389 | case POWER_SUPPLY_PROP_PRESENT: |
| 389 | val->intval = info->present; | 390 | val->intval = info->present; |
| 390 | return 0; | 391 | return 0; |
| @@ -197,7 +197,7 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev, · 196 unmodified lines | |||
| 197 | sel += rdev->desc->linear_ranges[i].min_sel; | 197 | sel += rdev->desc->linear_ranges[i].min_sel; |
| 198 | 198 | ||
| 199 | range = rdev->desc->linear_range_selectors_bitfield[i]; | 199 | range = rdev->desc->linear_range_selectors_bitfield[i]; |
| 200 | range <<= ffs(rdev->desc->vsel_mask) - 1; | 200 | range <<= ffs(rdev->desc->vsel_range_mask) - 1; |
| 201 | 201 | ||
| 202 | if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) { | 202 | if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) { |
| 203 | ret = regmap_update_bits(rdev->regmap, | 203 | ret = regmap_update_bits(rdev->regmap, |
| @@ -724,6 +724,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session, · 723 unmodified lines | |||
| 724 | return -EEXIST; | 724 | return -EEXIST; |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | err = -EINVAL; | ||
| 728 | if (!sk_is_tcp(sock->sk)) | ||
| 729 | goto free_socket; | ||
| 730 | |||
| 727 | err = iscsi_conn_bind(cls_session, cls_conn, is_leading); | 731 | err = iscsi_conn_bind(cls_session, cls_conn, is_leading); |
| 728 | if (err) | 732 | if (err) |
| 729 | goto free_socket; | 733 | goto free_socket; |
| @@ -6073,7 +6073,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) · 6072 unmodified lines | |||
| 6073 | phba->hba_debugfs_root, | 6073 | phba->hba_debugfs_root, |
| 6074 | phba, | 6074 | phba, |
| 6075 | &lpfc_debugfs_op_multixripools); | 6075 | &lpfc_debugfs_op_multixripools); |
| 6076 | if (!phba->debug_multixri_pools) { | 6076 | if (IS_ERR(phba->debug_multixri_pools)) { |
| 6077 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6077 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6078 | "0527 Cannot create debugfs multixripools\n"); | 6078 | "0527 Cannot create debugfs multixripools\n"); |
| 6079 | goto debug_failed; | 6079 | goto debug_failed; |
| @@ -6085,7 +6085,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) · 5 unmodified lines | |||
| 6085 | debugfs_create_file(name, S_IFREG | 0644, | 6085 | debugfs_create_file(name, S_IFREG | 0644, |
| 6086 | phba->hba_debugfs_root, | 6086 | phba->hba_debugfs_root, |
| 6087 | phba, &lpfc_cgn_buffer_op); | 6087 | phba, &lpfc_cgn_buffer_op); |
| 6088 | if (!phba->debug_cgn_buffer) { | 6088 | if (IS_ERR(phba->debug_cgn_buffer)) { |
| 6089 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6089 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6090 | "6527 Cannot create debugfs " | 6090 | "6527 Cannot create debugfs " |
| 6091 | "cgn_buffer\n"); | 6091 | "cgn_buffer\n"); |
| @@ -6098,7 +6098,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) · 6 unmodified lines | |||
| 6098 | debugfs_create_file(name, S_IFREG | 0644, | 6098 | debugfs_create_file(name, S_IFREG | 0644, |
| 6099 | phba->hba_debugfs_root, | 6099 | phba->hba_debugfs_root, |
| 6100 | phba, &lpfc_rx_monitor_op); | 6100 | phba, &lpfc_rx_monitor_op); |
| 6101 | if (!phba->debug_rx_monitor) { | 6101 | if (IS_ERR(phba->debug_rx_monitor)) { |
| 6102 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6102 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6103 | "6528 Cannot create debugfs " | 6103 | "6528 Cannot create debugfs " |
| 6104 | "rx_monitor\n"); | 6104 | "rx_monitor\n"); |
| @@ -6111,7 +6111,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) · 6 unmodified lines | |||
| 6111 | debugfs_create_file(name, 0644, | 6111 | debugfs_create_file(name, 0644, |
| 6112 | phba->hba_debugfs_root, | 6112 | phba->hba_debugfs_root, |
| 6113 | phba, &lpfc_debugfs_ras_log); | 6113 | phba, &lpfc_debugfs_ras_log); |
| 6114 | if (!phba->debug_ras_log) { | 6114 | if (IS_ERR(phba->debug_ras_log)) { |
| 6115 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6115 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6116 | "6148 Cannot create debugfs" | 6116 | "6148 Cannot create debugfs" |
| 6117 | " ras_log\n"); | 6117 | " ras_log\n"); |
| @@ -6132,7 +6132,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) · 14 unmodified lines | |||
| 6132 | debugfs_create_file(name, S_IFREG | 0644, | 6132 | debugfs_create_file(name, S_IFREG | 0644, |
| 6133 | phba->hba_debugfs_root, | 6133 | phba->hba_debugfs_root, |
| 6134 | phba, &lpfc_debugfs_op_lockstat); | 6134 | phba, &lpfc_debugfs_op_lockstat); |
| 6135 | if (!phba->debug_lockstat) { | 6135 | if (IS_ERR(phba->debug_lockstat)) { |
| 6136 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6136 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6137 | "4610 Can't create debugfs lockstat\n"); | 6137 | "4610 Can't create debugfs lockstat\n"); |
| 6138 | goto debug_failed; | 6138 | goto debug_failed; |
| @@ -6358,7 +6358,7 @@ nvmeio_off: · 219 unmodified lines | |||
| 6358 | debugfs_create_file(name, 0644, | 6358 | debugfs_create_file(name, 0644, |
| 6359 | vport->vport_debugfs_root, | 6359 | vport->vport_debugfs_root, |
| 6360 | vport, &lpfc_debugfs_op_scsistat); | 6360 | vport, &lpfc_debugfs_op_scsistat); |
| 6361 | if (!vport->debug_scsistat) { | 6361 | if (IS_ERR(vport->debug_scsistat)) { |
| 6362 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6362 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6363 | "4611 Cannot create debugfs scsistat\n"); | 6363 | "4611 Cannot create debugfs scsistat\n"); |
| 6364 | goto debug_failed; | 6364 | goto debug_failed; |
| @@ -6369,7 +6369,7 @@ nvmeio_off: · 4 unmodified lines | |||
| 6369 | debugfs_create_file(name, 0644, | 6369 | debugfs_create_file(name, 0644, |
| 6370 | vport->vport_debugfs_root, | 6370 | vport->vport_debugfs_root, |
| 6371 | vport, &lpfc_debugfs_op_ioktime); | 6371 | vport, &lpfc_debugfs_op_ioktime); |
| 6372 | if (!vport->debug_ioktime) { | 6372 | if (IS_ERR(vport->debug_ioktime)) { |
| 6373 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, | 6373 | lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, |
| 6374 | "0815 Cannot create debugfs ioktime\n"); | 6374 | "0815 Cannot create debugfs ioktime\n"); |
| 6375 | goto debug_failed; | 6375 | goto debug_failed; |
| @@ -199,11 +199,12 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) · 198 unmodified lines | |||
| 199 | /* Only 1 thread can drop the initial node reference. If | 199 | /* Only 1 thread can drop the initial node reference. If |
| 200 | * another thread has set NLP_DROPPED, this thread is done. | 200 | * another thread has set NLP_DROPPED, this thread is done. |
| 201 | */ | 201 | */ |
| 202 | if (!(ndlp->nlp_flag & NLP_DROPPED)) { | 202 | if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD) && |
| 203 | !(ndlp->nlp_flag & NLP_DROPPED)) { | ||
| 203 | ndlp->nlp_flag |= NLP_DROPPED; | 204 | ndlp->nlp_flag |= NLP_DROPPED; |
| 204 | spin_unlock_irqrestore(&ndlp->lock, iflags); | 205 | spin_unlock_irqrestore(&ndlp->lock, iflags); |
| 205 | lpfc_nlp_put(ndlp); | 206 | lpfc_nlp_put(ndlp); |
| 206 | spin_lock_irqsave(&ndlp->lock, iflags); | 207 | return; |
| 207 | } | 208 | } |
| 208 | 209 | ||
| 209 | spin_unlock_irqrestore(&ndlp->lock, iflags); | 210 | spin_unlock_irqrestore(&ndlp->lock, iflags); |
| @@ -228,8 +228,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) · 227 unmodified lines | |||
| 228 | spin_unlock_irq(&ndlp->lock); | 228 | spin_unlock_irq(&ndlp->lock); |
| 229 | 229 | ||
| 230 | /* On a devloss timeout event, one more put is executed provided the | 230 | /* On a devloss timeout event, one more put is executed provided the |
| 231 | * NVME and SCSI rport unregister requests are complete. If the vport | 231 | * NVME and SCSI rport unregister requests are complete. |
| 232 | * is unloading, this extra put is executed by lpfc_drop_node. | ||
| 233 | */ | 232 | */ |
| 234 | if (!(ndlp->fc4_xpt_flags & fc4_xpt_flags)) | 233 | if (!(ndlp->fc4_xpt_flags & fc4_xpt_flags)) |
| 235 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); | 234 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
| @@ -2567,11 +2566,7 @@ lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) · 2331 unmodified lines | |||
| 2567 | * nvme_transport perspective. Loss of an rport just means IO cannot | 2566 | * nvme_transport perspective. Loss of an rport just means IO cannot |
| 2568 | * be sent and recovery is completely up to the initator. | 2567 | * be sent and recovery is completely up to the initator. |
| 2569 | * For now, the driver just unbinds the DID and port_role so that | 2568 | * For now, the driver just unbinds the DID and port_role so that |
| 2570 | * no further IO can be issued. Changes are planned for later. | 2569 | * no further IO can be issued. |
| 2571 | * | ||
| 2572 | * Notes - the ndlp reference count is not decremented here since | ||
| 2573 | * since there is no nvme_transport api for devloss. Node ref count | ||
| 2574 | * is only adjusted in driver unload. | ||
| 2575 | */ | 2570 | */ |
| 2576 | void | 2571 | void |
| 2577 | lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 2572 | lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
| @@ -2646,6 +2641,21 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) · 68 unmodified lines | |||
| 2646 | "6167 NVME unregister failed %d " | 2641 | "6167 NVME unregister failed %d " |
| 2647 | "port_state x%x\n", | 2642 | "port_state x%x\n", |
| 2648 | ret, remoteport->port_state); | 2643 | ret, remoteport->port_state); |
| 2644 | |||
| 2645 | if (vport->load_flag & FC_UNLOADING) { | ||
| 2646 | /* Only 1 thread can drop the initial node | ||
| 2647 | * reference. Check if another thread has set | ||
| 2648 | * NLP_DROPPED. | ||
| 2649 | */ | ||
| 2650 | spin_lock_irq(&ndlp->lock); | ||
| 2651 | if (!(ndlp->nlp_flag & NLP_DROPPED)) { | ||
| 2652 | ndlp->nlp_flag |= NLP_DROPPED; | ||
| 2653 | spin_unlock_irq(&ndlp->lock); | ||
| 2654 | lpfc_nlp_put(ndlp); | ||
| 2655 | return; | ||
| 2656 | } | ||
| 2657 | spin_unlock_irq(&ndlp->lock); | ||
| 2658 | } | ||
| 2649 | } | 2659 | } |
| 2650 | } | 2660 | } |
| 2651 | return; | 2661 | return; |
| @@ -2332,7 +2332,7 @@ struct megasas_instance { · 2331 unmodified lines | |||
| 2332 | u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ | 2332 | u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ |
| 2333 | bool use_seqnum_jbod_fp; /* Added for PD sequence */ | 2333 | bool use_seqnum_jbod_fp; /* Added for PD sequence */ |
| 2334 | bool smp_affinity_enable; | 2334 | bool smp_affinity_enable; |
| 2335 | spinlock_t crashdump_lock; | 2335 | struct mutex crashdump_lock; |
| 2336 | 2336 | ||
| 2337 | struct megasas_register_set __iomem *reg_set; | 2337 | struct megasas_register_set __iomem *reg_set; |
| 2338 | u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; | 2338 | u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; |
| @@ -3271,14 +3271,13 @@ fw_crash_buffer_store(struct device *cdev, · 3270 unmodified lines | |||
| 3271 | struct megasas_instance *instance = | 3271 | struct megasas_instance *instance = |
| 3272 | (struct megasas_instance *) shost->hostdata; | 3272 | (struct megasas_instance *) shost->hostdata; |
| 3273 | int val = 0; | 3273 | int val = 0; |
| 3274 | unsigned long flags; | ||
| 3275 | 3274 | ||
| 3276 | if (kstrtoint(buf, 0, &val) != 0) | 3275 | if (kstrtoint(buf, 0, &val) != 0) |
| 3277 | return -EINVAL; | 3276 | return -EINVAL; |
| 3278 | 3277 | ||
| 3279 | spin_lock_irqsave(&instance->crashdump_lock, flags); | 3278 | mutex_lock(&instance->crashdump_lock); |
| 3280 | instance->fw_crash_buffer_offset = val; | 3279 | instance->fw_crash_buffer_offset = val; |
| 3281 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); | 3280 | mutex_unlock(&instance->crashdump_lock); |
| 3282 | return strlen(buf); | 3281 | return strlen(buf); |
| 3283 | } | 3282 | } |
| 3284 | 3283 | ||
| @@ -3293,24 +3292,23 @@ fw_crash_buffer_show(struct device *cdev, · 8 unmodified lines | |||
| 3293 | unsigned long dmachunk = CRASH_DMA_BUF_SIZE; | 3292 | unsigned long dmachunk = CRASH_DMA_BUF_SIZE; |
| 3294 | unsigned long chunk_left_bytes; | 3293 | unsigned long chunk_left_bytes; |
| 3295 | unsigned long src_addr; | 3294 | unsigned long src_addr; |
| 3296 | unsigned long flags; | ||
| 3297 | u32 buff_offset; | 3295 | u32 buff_offset; |
| 3298 | 3296 | ||
| 3299 | spin_lock_irqsave(&instance->crashdump_lock, flags); | 3297 | mutex_lock(&instance->crashdump_lock); |
| 3300 | buff_offset = instance->fw_crash_buffer_offset; | 3298 | buff_offset = instance->fw_crash_buffer_offset; |
| 3301 | if (!instance->crash_dump_buf || | 3299 | if (!instance->crash_dump_buf || |
| 3302 | !((instance->fw_crash_state == AVAILABLE) || | 3300 | !((instance->fw_crash_state == AVAILABLE) || |
| 3303 | (instance->fw_crash_state == COPYING))) { | 3301 | (instance->fw_crash_state == COPYING))) { |
| 3304 | dev_err(&instance->pdev->dev, | 3302 | dev_err(&instance->pdev->dev, |
| 3305 | "Firmware crash dump is not available\n"); | 3303 | "Firmware crash dump is not available\n"); |
| 3306 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); | 3304 | mutex_unlock(&instance->crashdump_lock); |
| 3307 | return -EINVAL; | 3305 | return -EINVAL; |
| 3308 | } | 3306 | } |
| 3309 | 3307 | ||
| 3310 | if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { | 3308 | if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { |
| 3311 | dev_err(&instance->pdev->dev, | 3309 | dev_err(&instance->pdev->dev, |
| 3312 | "Firmware crash dump offset is out of range\n"); | 3310 | "Firmware crash dump offset is out of range\n"); |
| 3313 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); | 3311 | mutex_unlock(&instance->crashdump_lock); |
| 3314 | return 0; | 3312 | return 0; |
| 3315 | } | 3313 | } |
| 3316 | 3314 | ||
| @@ -3322,7 +3320,7 @@ fw_crash_buffer_show(struct device *cdev, · 5 unmodified lines | |||
| 3322 | src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + | 3320 | src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + |
| 3323 | (buff_offset % dmachunk); | 3321 | (buff_offset % dmachunk); |
| 3324 | memcpy(buf, (void *)src_addr, size); | 3322 | memcpy(buf, (void *)src_addr, size); |
| 3325 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); | 3323 | mutex_unlock(&instance->crashdump_lock); |
| 3326 | 3324 | ||
| 3327 | return size; | 3325 | return size; |
| 3328 | } | 3326 | } |
| @@ -3347,7 +3345,6 @@ fw_crash_state_store(struct device *cdev, · 18 unmodified lines | |||
| 3347 | struct megasas_instance *instance = | 3345 | struct megasas_instance *instance = |
| 3348 | (struct megasas_instance *) shost->hostdata; | 3346 | (struct megasas_instance *) shost->hostdata; |
| 3349 | int val = 0; | 3347 | int val = 0; |
| 3350 | unsigned long flags; | ||
| 3351 | 3348 | ||
| 3352 | if (kstrtoint(buf, 0, &val) != 0) | 3349 | if (kstrtoint(buf, 0, &val) != 0) |
| 3353 | return -EINVAL; | 3350 | return -EINVAL; |
| @@ -3361,9 +3358,9 @@ fw_crash_state_store(struct device *cdev, · 7 unmodified lines | |||
| 3361 | instance->fw_crash_state = val; | 3358 | instance->fw_crash_state = val; |
| 3362 | 3359 | ||
| 3363 | if ((val == COPIED) || (val == COPY_ERROR)) { | 3360 | if ((val == COPIED) || (val == COPY_ERROR)) { |
| 3364 | spin_lock_irqsave(&instance->crashdump_lock, flags); | 3361 | mutex_lock(&instance->crashdump_lock); |
| 3365 | megasas_free_host_crash_buffer(instance); | 3362 | megasas_free_host_crash_buffer(instance); |
| 3366 | spin_unlock_irqrestore(&instance->crashdump_lock, flags); | 3363 | mutex_unlock(&instance->crashdump_lock); |
| 3367 | if (val == COPY_ERROR) | 3364 | if (val == COPY_ERROR) |
| 3368 | dev_info(&instance->pdev->dev, "application failed to " | 3365 | dev_info(&instance->pdev->dev, "application failed to " |
| 3369 | "copy Firmware crash dump\n"); | 3366 | "copy Firmware crash dump\n"); |
| @@ -7422,7 +7419,7 @@ static inline void megasas_init_ctrl_params(struct megasas_instance *instance) · 4052 unmodified lines | |||
| 7422 | init_waitqueue_head(&instance->int_cmd_wait_q); | 7419 | init_waitqueue_head(&instance->int_cmd_wait_q); |
| 7423 | init_waitqueue_head(&instance->abort_cmd_wait_q); | 7420 | init_waitqueue_head(&instance->abort_cmd_wait_q); |
| 7424 | 7421 | ||
| 7425 | spin_lock_init(&instance->crashdump_lock); | 7422 | mutex_init(&instance->crashdump_lock); |
| 7426 | spin_lock_init(&instance->mfi_pool_lock); | 7423 | spin_lock_init(&instance->mfi_pool_lock); |
| 7427 | spin_lock_init(&instance->hba_lock); | 7424 | spin_lock_init(&instance->hba_lock); |
| 7428 | spin_lock_init(&instance->stream_lock); | 7425 | spin_lock_init(&instance->stream_lock); |
| @@ -4180,7 +4180,7 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) · 4179 unmodified lines | |||
| 4180 | payload.sas_identify.dev_type = SAS_END_DEVICE; | 4180 | payload.sas_identify.dev_type = SAS_END_DEVICE; |
| 4181 | payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; | 4181 | payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; |
| 4182 | memcpy(payload.sas_identify.sas_addr, | 4182 | memcpy(payload.sas_identify.sas_addr, |
| 4183 | pm8001_ha->sas_addr, SAS_ADDR_SIZE); | 4183 | &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); |
| 4184 | payload.sas_identify.phy_id = phy_id; | 4184 | payload.sas_identify.phy_id = phy_id; |
| 4185 | 4185 | ||
| 4186 | return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, | 4186 | return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, |
| @@ -273,7 +273,6 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) · 272 unmodified lines | |||
| 273 | return ret; | 273 | return ret; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha); | ||
| 277 | static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha); | 276 | static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha); |
| 278 | 277 | ||
| 279 | /** | 278 | /** |
| @@ -294,13 +293,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, · 14 unmodified lines | |||
| 294 | pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n", | 293 | pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n", |
| 295 | pm8001_ha->chip->n_phy); | 294 | pm8001_ha->chip->n_phy); |
| 296 | 295 | ||
| 297 | /* Setup Interrupt */ | ||
| 298 | rc = pm8001_setup_irq(pm8001_ha); | ||
| 299 | if (rc) { | ||
| 300 | pm8001_dbg(pm8001_ha, FAIL, | ||
| 301 | "pm8001_setup_irq failed [ret: %d]\n", rc); | ||
| 302 | goto err_out; | ||
| 303 | } | ||
| 304 | /* Request Interrupt */ | 296 | /* Request Interrupt */ |
| 305 | rc = pm8001_request_irq(pm8001_ha); | 297 | rc = pm8001_request_irq(pm8001_ha); |
| 306 | if (rc) | 298 | if (rc) |
| @@ -1031,47 +1023,38 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) · 724 unmodified lines | |||
| 1031 | } | 1023 | } |
| 1032 | #endif | 1024 | #endif |
| 1033 | 1025 | ||
| 1034 | static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha) | ||
| 1035 | { | ||
| 1036 | struct pci_dev *pdev; | ||
| 1037 | |||
| 1038 | pdev = pm8001_ha->pdev; | ||
| 1039 | |||
| 1040 | #ifdef PM8001_USE_MSIX | ||
| 1041 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) | ||
| 1042 | return pm8001_setup_msix(pm8001_ha); | ||
| 1043 | pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); | ||
| 1044 | #endif | ||
| 1045 | return 0; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | /** | 1026 | /** |
| 1049 | * pm8001_request_irq - register interrupt | 1027 | * pm8001_request_irq - register interrupt |
| 1050 | * @pm8001_ha: our ha struct. | 1028 | * @pm8001_ha: our ha struct. |
| 1051 | */ | 1029 | */ |
| 1052 | static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) | 1030 | static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) |
| 1053 | { | 1031 | { |
| 1054 | struct pci_dev *pdev; | 1032 | struct pci_dev *pdev = pm8001_ha->pdev; |
| 1033 | #ifdef PM8001_USE_MSIX | ||
| 1055 | int rc; | 1034 | int rc; |
| 1056 | 1035 | ||
| 1057 | pdev = pm8001_ha->pdev; | 1036 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { |
| 1037 | rc = pm8001_setup_msix(pm8001_ha); | ||
| 1038 | if (rc) { | ||
| 1039 | pm8001_dbg(pm8001_ha, FAIL, | ||
| 1040 | "pm8001_setup_irq failed [ret: %d]\n", rc); | ||
| 1041 | return rc; | ||
| 1042 | } | ||
| 1058 | 1043 | ||
| 1059 | #ifdef PM8001_USE_MSIX | 1044 | if (pdev->msix_cap && pci_msi_enabled()) |
| 1060 | if (pdev->msix_cap && pci_msi_enabled()) | 1045 | return pm8001_request_msix(pm8001_ha); |
| 1061 | return pm8001_request_msix(pm8001_ha); | ||
| 1062 | else { | ||
| 1063 | pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); | ||
| 1064 | goto intx; | ||
| 1065 | } | 1046 | } |
| 1047 | |||
| 1048 | pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); | ||
| 1066 | #endif | 1049 | #endif |
| 1067 | 1050 | ||
| 1068 | intx: | ||
| 1069 | /* initialize the INT-X interrupt */ | 1051 | /* initialize the INT-X interrupt */ |
| 1070 | pm8001_ha->irq_vector[0].irq_id = 0; | 1052 | pm8001_ha->irq_vector[0].irq_id = 0; |
| 1071 | pm8001_ha->irq_vector[0].drv_inst = pm8001_ha; | 1053 | pm8001_ha->irq_vector[0].drv_inst = pm8001_ha; |
| 1072 | rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED, | 1054 | |
| 1073 | pm8001_ha->name, SHOST_TO_SAS_HA(pm8001_ha->shost)); | 1055 | return request_irq(pdev->irq, pm8001_interrupt_handler_intx, |
| 1074 | return rc; | 1056 | IRQF_SHARED, pm8001_ha->name, |
| 1057 | SHOST_TO_SAS_HA(pm8001_ha->shost)); | ||
| 1075 | } | 1058 | } |
| 1076 | 1059 | ||
| 1077 | /** | 1060 | /** |
| @@ -3671,10 +3671,12 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, · 3670 unmodified lines | |||
| 3671 | (struct set_ctrl_cfg_resp *)(piomb + 4); | 3671 | (struct set_ctrl_cfg_resp *)(piomb + 4); |
| 3672 | u32 status = le32_to_cpu(pPayload->status); | 3672 | u32 status = le32_to_cpu(pPayload->status); |
| 3673 | u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); | 3673 | u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); |
| 3674 | u32 tag = le32_to_cpu(pPayload->tag); | ||
| 3674 | 3675 | ||
| 3675 | pm8001_dbg(pm8001_ha, MSG, | 3676 | pm8001_dbg(pm8001_ha, MSG, |
| 3676 | "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", | 3677 | "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", |
| 3677 | status, err_qlfr_pgcd); | 3678 | status, err_qlfr_pgcd); |
| 3679 | pm8001_tag_free(pm8001_ha, tag); | ||
| 3678 | 3680 | ||
| 3679 | return 0; | 3681 | return 0; |
| 3680 | } | 3682 | } |
| @@ -4671,7 +4673,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) · 990 unmodified lines | |||
| 4671 | payload.sas_identify.dev_type = SAS_END_DEVICE; | 4673 | payload.sas_identify.dev_type = SAS_END_DEVICE; |
| 4672 | payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; | 4674 | payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; |
| 4673 | memcpy(payload.sas_identify.sas_addr, | 4675 | memcpy(payload.sas_identify.sas_addr, |
| 4674 | &pm8001_ha->sas_addr, SAS_ADDR_SIZE); | 4676 | &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); |
| 4675 | payload.sas_identify.phy_id = phy_id; | 4677 | payload.sas_identify.phy_id = phy_id; |
| 4676 | 4678 | ||
| 4677 | return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, | 4679 | return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, |
| @@ -307,9 +307,9 @@ static int ppa_out(ppa_struct *dev, char *buffer, int len) · 306 unmodified lines | |||
| 307 | case PPA_EPP_8: | 307 | case PPA_EPP_8: |
| 308 | epp_reset(ppb); | 308 | epp_reset(ppb); |
| 309 | w_ctr(ppb, 0x4); | 309 | w_ctr(ppb, 0x4); |
| 310 | if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x01)) | 310 | if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x03)) |
| 311 | outsl(ppb + 4, buffer, len >> 2); | 311 | outsl(ppb + 4, buffer, len >> 2); |
| 312 | else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x03)) | 312 | else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x01)) |
| 313 | outsw(ppb + 4, buffer, len >> 1); | 313 | outsw(ppb + 4, buffer, len >> 1); |
| 314 | else | 314 | else |
| 315 | outsb(ppb + 4, buffer, len); | 315 | outsb(ppb + 4, buffer, len); |
| @@ -1904,6 +1904,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) · 1903 unmodified lines | |||
| 1904 | goto drop_rdata_kref; | 1904 | goto drop_rdata_kref; |
| 1905 | } | 1905 | } |
| 1906 | 1906 | ||
| 1907 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
| 1907 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || | 1908 | if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || |
| 1908 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || | 1909 | test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || |
| 1909 | test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { | 1910 | test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { |
| @@ -1911,17 +1912,20 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) · 1 unmodified line | |||
| 1911 | "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", | 1912 | "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", |
| 1912 | io_req->xid, io_req->sc_cmd); | 1913 | io_req->xid, io_req->sc_cmd); |
| 1913 | rc = 1; | 1914 | rc = 1; |
| 1915 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
| 1914 | goto drop_rdata_kref; | 1916 | goto drop_rdata_kref; |
| 1915 | } | 1917 | } |
| 1916 | 1918 | ||
| 1919 | /* Set the command type to abort */ | ||
| 1920 | io_req->cmd_type = QEDF_ABTS; | ||
| 1921 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
| 1922 | |||
| 1917 | kref_get(&io_req->refcount); | 1923 | kref_get(&io_req->refcount); |
| 1918 | 1924 | ||
| 1919 | xid = io_req->xid; | 1925 | xid = io_req->xid; |
| 1920 | qedf->control_requests++; | 1926 | qedf->control_requests++; |
| 1921 | qedf->packet_aborts++; | 1927 | qedf->packet_aborts++; |
| 1922 | 1928 | ||
| 1923 | /* Set the command type to abort */ | ||
| 1924 | io_req->cmd_type = QEDF_ABTS; | ||
| 1925 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; | 1929 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; |
| 1926 | 1930 | ||
| 1927 | set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); | 1931 | set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); |
| @@ -2210,7 +2214,9 @@ process_els: · 282 unmodified lines | |||
| 2210 | refcount, fcport, fcport->rdata->ids.port_id); | 2214 | refcount, fcport, fcport->rdata->ids.port_id); |
| 2211 | 2215 | ||
| 2212 | /* Cleanup cmds re-use the same TID as the original I/O */ | 2216 | /* Cleanup cmds re-use the same TID as the original I/O */ |
| 2217 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
| 2213 | io_req->cmd_type = QEDF_CLEANUP; | 2218 | io_req->cmd_type = QEDF_CLEANUP; |
| 2219 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
| 2214 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; | 2220 | io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; |
| 2215 | 2221 | ||
| 2216 | init_completion(&io_req->cleanup_done); | 2222 | init_completion(&io_req->cleanup_done); |
| @@ -2805,6 +2805,8 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) · 2804 unmodified lines | |||
| 2805 | struct qedf_ioreq *io_req; | 2805 | struct qedf_ioreq *io_req; |
| 2806 | struct qedf_rport *fcport; | 2806 | struct qedf_rport *fcport; |
| 2807 | u32 comp_type; | 2807 | u32 comp_type; |
| 2808 | u8 io_comp_type; | ||
| 2809 | unsigned long flags; | ||
| 2808 | 2810 | ||
| 2809 | comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & | 2811 | comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & |
| 2810 | FCOE_CQE_CQE_TYPE_MASK; | 2812 | FCOE_CQE_CQE_TYPE_MASK; |
| @@ -2838,11 +2840,14 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe) · 27 unmodified lines | |||
| 2838 | return; | 2840 | return; |
| 2839 | } | 2841 | } |
| 2840 | 2842 | ||
| 2843 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
| 2844 | io_comp_type = io_req->cmd_type; | ||
| 2845 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
| 2841 | 2846 | ||
| 2842 | switch (comp_type) { | 2847 | switch (comp_type) { |
| 2843 | case FCOE_GOOD_COMPLETION_CQE_TYPE: | 2848 | case FCOE_GOOD_COMPLETION_CQE_TYPE: |
| 2844 | atomic_inc(&fcport->free_sqes); | 2849 | atomic_inc(&fcport->free_sqes); |
| 2845 | switch (io_req->cmd_type) { | 2850 | switch (io_comp_type) { |
| 2846 | case QEDF_SCSI_CMD: | 2851 | case QEDF_SCSI_CMD: |
| 2847 | qedf_scsi_completion(qedf, cqe, io_req); | 2852 | qedf_scsi_completion(qedf, cqe, io_req); |
| 2848 | break; | 2853 | break; |
| @@ -116,7 +116,7 @@ qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) · 115 unmodified lines | |||
| 116 | 116 | ||
| 117 | sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); | 117 | sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); |
| 118 | fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); | 118 | fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); |
| 119 | if (!fp->dfs_rport_dir) | 119 | if (IS_ERR(fp->dfs_rport_dir)) |
| 120 | return; | 120 | return; |
| 121 | if (NVME_TARGET(vha->hw, fp)) | 121 | if (NVME_TARGET(vha->hw, fp)) |
| 122 | debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, | 122 | debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, |
| @@ -708,14 +708,14 @@ create_nodes: · 585 unmodified lines | |||
| 708 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { | 708 | if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { |
| 709 | ha->tgt.dfs_naqp = debugfs_create_file("naqp", | 709 | ha->tgt.dfs_naqp = debugfs_create_file("naqp", |
| 710 | 0400, ha->dfs_dir, vha, &dfs_naqp_ops); | 710 | 0400, ha->dfs_dir, vha, &dfs_naqp_ops); |
| 711 | if (!ha->tgt.dfs_naqp) { | 711 | if (IS_ERR(ha->tgt.dfs_naqp)) { |
| 712 | ql_log(ql_log_warn, vha, 0xd011, | 712 | ql_log(ql_log_warn, vha, 0xd011, |
| 713 | "Unable to create debugFS naqp node.\n"); | 713 | "Unable to create debugFS naqp node.\n"); |
| 714 | goto out; | 714 | goto out; |
| 715 | } | 715 | } |
| 716 | } | 716 | } |
| 717 | vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); | 717 | vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); |
| 718 | if (!vha->dfs_rport_root) { | 718 | if (IS_ERR(vha->dfs_rport_root)) { |
| 719 | ql_log(ql_log_warn, vha, 0xd012, | 719 | ql_log(ql_log_warn, vha, 0xd012, |
| 720 | "Unable to create debugFS rports node.\n"); | 720 | "Unable to create debugFS rports node.\n"); |
| 721 | goto out; | 721 | goto out; |
| @@ -577,7 +577,7 @@ fcport_is_bigger(fc_port_t *fcport) · 576 unmodified lines | |||
| 577 | static inline struct qla_qpair * | 577 | static inline struct qla_qpair * |
| 578 | qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair) | 578 | qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair) |
| 579 | { | 579 | { |
| 580 | int cpuid = smp_processor_id(); | 580 | int cpuid = raw_smp_processor_id(); |
| 581 | 581 | ||
| 582 | if (qpair->cpuid != cpuid && | 582 | if (qpair->cpuid != cpuid && |
| 583 | ha->qp_cpu_map[cpuid]) { | 583 | ha->qp_cpu_map[cpuid]) { |
| @@ -3965,7 +3965,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, · 3964 unmodified lines | |||
| 3965 | if (!ha->flags.fw_started) | 3965 | if (!ha->flags.fw_started) |
| 3966 | return; | 3966 | return; |
| 3967 | 3967 | ||
| 3968 | if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { | 3968 | if (rsp->qpair->cpuid != raw_smp_processor_id() || !rsp->qpair->rcv_intr) { |
| 3969 | rsp->qpair->rcv_intr = 1; | 3969 | rsp->qpair->rcv_intr = 1; |
| 3970 | 3970 | ||
| 3971 | if (!rsp->qpair->cpu_mapped) | 3971 | if (!rsp->qpair->cpu_mapped) |
| @@ -4468,7 +4468,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id) · 496 unmodified lines | |||
| 4468 | } | 4468 | } |
| 4469 | ha = qpair->hw; | 4469 | ha = qpair->hw; |
| 4470 | 4470 | ||
| 4471 | queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); | 4471 | queue_work(ha->wq, &qpair->q_work); |
| 4472 | 4472 | ||
| 4473 | return IRQ_HANDLED; | 4473 | return IRQ_HANDLED; |
| 4474 | } | 4474 | } |
| @@ -4494,7 +4494,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) · 19 unmodified lines | |||
| 4494 | wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); | 4494 | wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); |
| 4495 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4495 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 4496 | 4496 | ||
| 4497 | queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); | 4497 | queue_work(ha->wq, &qpair->q_work); |
| 4498 | 4498 | ||
| 4499 | return IRQ_HANDLED; | 4499 | return IRQ_HANDLED; |
| 4500 | } | 4500 | } |
| @@ -399,14 +399,14 @@ static int qla_nvme_xmt_ls_rsp(struct nvme_fc_local_port *lport, · 398 unmodified lines | |||
| 399 | nvme->u.nvme.dl = 0; | 399 | nvme->u.nvme.dl = 0; |
| 400 | nvme->u.nvme.timeout_sec = 0; | 400 | nvme->u.nvme.timeout_sec = 0; |
| 401 | nvme->u.nvme.cmd_dma = fd_resp->rspdma; | 401 | nvme->u.nvme.cmd_dma = fd_resp->rspdma; |
| 402 | nvme->u.nvme.cmd_len = fd_resp->rsplen; | 402 | nvme->u.nvme.cmd_len = cpu_to_le32(fd_resp->rsplen); |
| 403 | nvme->u.nvme.rsp_len = 0; | 403 | nvme->u.nvme.rsp_len = 0; |
| 404 | nvme->u.nvme.rsp_dma = 0; | 404 | nvme->u.nvme.rsp_dma = 0; |
| 405 | nvme->u.nvme.exchange_address = uctx->exchange_address; | 405 | nvme->u.nvme.exchange_address = uctx->exchange_address; |
| 406 | nvme->u.nvme.nport_handle = uctx->nport_handle; | 406 | nvme->u.nvme.nport_handle = uctx->nport_handle; |
| 407 | nvme->u.nvme.ox_id = uctx->ox_id; | 407 | nvme->u.nvme.ox_id = uctx->ox_id; |
| 408 | dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, | 408 | dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, |
| 409 | le32_to_cpu(fd_resp->rsplen), DMA_TO_DEVICE); | 409 | fd_resp->rsplen, DMA_TO_DEVICE); |
| 410 | 410 | ||
| 411 | ql_dbg(ql_dbg_unsol, vha, 0x2122, | 411 | ql_dbg(ql_dbg_unsol, vha, 0x2122, |
| 412 | "Unsol lsreq portid=%06x %8phC exchange_address 0x%x ox_id 0x%x hdl 0x%x\n", | 412 | "Unsol lsreq portid=%06x %8phC exchange_address 0x%x ox_id 0x%x hdl 0x%x\n", |
| @@ -504,13 +504,13 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, · 91 unmodified lines | |||
| 504 | nvme->u.nvme.desc = fd; | 504 | nvme->u.nvme.desc = fd; |
| 505 | nvme->u.nvme.dir = 0; | 505 | nvme->u.nvme.dir = 0; |
| 506 | nvme->u.nvme.dl = 0; | 506 | nvme->u.nvme.dl = 0; |
| 507 | nvme->u.nvme.cmd_len = fd->rqstlen; | 507 | nvme->u.nvme.cmd_len = cpu_to_le32(fd->rqstlen); |
| 508 | nvme->u.nvme.rsp_len = fd->rsplen; | 508 | nvme->u.nvme.rsp_len = cpu_to_le32(fd->rsplen); |
| 509 | nvme->u.nvme.rsp_dma = fd->rspdma; | 509 | nvme->u.nvme.rsp_dma = fd->rspdma; |
| 510 | nvme->u.nvme.timeout_sec = fd->timeout; | 510 | nvme->u.nvme.timeout_sec = fd->timeout; |
| 511 | nvme->u.nvme.cmd_dma = fd->rqstdma; | 511 | nvme->u.nvme.cmd_dma = fd->rqstdma; |
| 512 | dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, | 512 | dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, |
| 513 | le32_to_cpu(fd->rqstlen), DMA_TO_DEVICE); | 513 | fd->rqstlen, DMA_TO_DEVICE); |
| 514 | 514 | ||
| 515 | rval = qla2x00_start_sp(sp); | 515 | rval = qla2x00_start_sp(sp); |
| 516 | if (rval != QLA_SUCCESS) { | 516 | if (rval != QLA_SUCCESS) { |
| @@ -4425,8 +4425,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, · 4424 unmodified lines | |||
| 4425 | queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); | 4425 | queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); |
| 4426 | } else if (ha->msix_count) { | 4426 | } else if (ha->msix_count) { |
| 4427 | if (cmd->atio.u.isp24.fcp_cmnd.rddata) | 4427 | if (cmd->atio.u.isp24.fcp_cmnd.rddata) |
| 4428 | queue_work_on(smp_processor_id(), qla_tgt_wq, | 4428 | queue_work(qla_tgt_wq, &cmd->work); |
| 4429 | &cmd->work); | ||
| 4430 | else | 4429 | else |
| 4431 | queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, | 4430 | queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, |
| 4432 | &cmd->work); | 4431 | &cmd->work); |
| @@ -310,7 +310,7 @@ static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) · 309 unmodified lines | |||
| 310 | cmd->trc_flags |= TRC_CMD_DONE; | 310 | cmd->trc_flags |= TRC_CMD_DONE; |
| 311 | 311 | ||
| 312 | INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); | 312 | INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); |
| 313 | queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); | 313 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | /* | 316 | /* |
| @@ -547,7 +547,7 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) · 230 unmodified lines | |||
| 547 | cmd->trc_flags |= TRC_DATA_IN; | 547 | cmd->trc_flags |= TRC_DATA_IN; |
| 548 | cmd->cmd_in_wq = 1; | 548 | cmd->cmd_in_wq = 1; |
| 549 | INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); | 549 | INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); |
| 550 | queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); | 550 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); |
| 551 | } | 551 | } |
| 552 | 552 | ||
| 553 | static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) | 553 | static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) |
| @@ -613,6 +613,17 @@ void scsi_cdl_check(struct scsi_device *sdev) · 612 unmodified lines | |||
| 613 | bool cdl_supported; | 613 | bool cdl_supported; |
| 614 | unsigned char *buf; | 614 | unsigned char *buf; |
| 615 | 615 | ||
| 616 | /* | ||
| 617 | * Support for CDL was defined in SPC-5. Ignore devices reporting an | ||
| 618 | * lower SPC version. This also avoids problems with old drives choking | ||
| 619 | * on MAINTENANCE_IN / MI_REPORT_SUPPORTED_OPERATION_CODES with a | ||
| 620 | * service action specified, as done in scsi_cdl_check_cmd(). | ||
| 621 | */ | ||
| 622 | if (sdev->scsi_level < SCSI_SPC_5) { | ||
| 623 | sdev->cdl_supported = 0; | ||
| 624 | return; | ||
| 625 | } | ||
| 626 | |||
| 616 | buf = kmalloc(SCSI_CDL_CHECK_BUF_LEN, GFP_KERNEL); | 627 | buf = kmalloc(SCSI_CDL_CHECK_BUF_LEN, GFP_KERNEL); |
| 617 | if (!buf) { | 628 | if (!buf) { |
| 618 | sdev->cdl_supported = 0; | 629 | sdev->cdl_supported = 0; |
| @@ -822,7 +822,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, · 821 unmodified lines | |||
| 822 | * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so | 822 | * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so |
| 823 | * non-zero LUNs can be scanned. | 823 | * non-zero LUNs can be scanned. |
| 824 | */ | 824 | */ |
| 825 | sdev->scsi_level = inq_result[2] & 0x07; | 825 | sdev->scsi_level = inq_result[2] & 0x0f; |
| 826 | if (sdev->scsi_level >= 2 || | 826 | if (sdev->scsi_level >= 2 || |
| 827 | (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) | 827 | (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) |
| 828 | sdev->scsi_level++; | 828 | sdev->scsi_level++; |
| @@ -1619,12 +1619,24 @@ int scsi_add_device(struct Scsi_Host *host, uint channel, · 790 unmodified lines | |||
| 1619 | } | 1619 | } |
| 1620 | EXPORT_SYMBOL(scsi_add_device); | 1620 | EXPORT_SYMBOL(scsi_add_device); |
| 1621 | 1621 | ||
| 1622 | void scsi_rescan_device(struct scsi_device *sdev) | 1622 | int scsi_rescan_device(struct scsi_device *sdev) |
| 1623 | { | 1623 | { |
| 1624 | struct device *dev = &sdev->sdev_gendev; | 1624 | struct device *dev = &sdev->sdev_gendev; |
| 1625 | int ret = 0; | ||
| 1625 | 1626 | ||
| 1626 | device_lock(dev); | 1627 | device_lock(dev); |
| 1627 | 1628 | ||
| 1629 | /* | ||
| 1630 | * Bail out if the device is not running. Otherwise, the rescan may | ||
| 1631 | * block waiting for commands to be executed, with us holding the | ||
| 1632 | * device lock. This can result in a potential deadlock in the power | ||
| 1633 | * management core code when system resume is on-going. | ||
| 1634 | */ | ||
| 1635 | if (sdev->sdev_state != SDEV_RUNNING) { | ||
| 1636 | ret = -EWOULDBLOCK; | ||
| 1637 | goto unlock; | ||
| 1638 | } | ||
| 1639 | |||
| 1628 | scsi_attach_vpd(sdev); | 1640 | scsi_attach_vpd(sdev); |
| 1629 | scsi_cdl_check(sdev); | 1641 | scsi_cdl_check(sdev); |
| 1630 | 1642 | ||
| @@ -1638,7 +1650,11 @@ void scsi_rescan_device(struct scsi_device *sdev) · 7 unmodified lines | |||
| 1638 | drv->rescan(dev); | 1650 | drv->rescan(dev); |
| 1639 | module_put(dev->driver->owner); | 1651 | module_put(dev->driver->owner); |
| 1640 | } | 1652 | } |
| 1653 | |||
| 1654 | unlock: | ||
| 1641 | device_unlock(dev); | 1655 | device_unlock(dev); |
| 1656 | |||
| 1657 | return ret; | ||
| 1642 | } | 1658 | } |
| 1643 | EXPORT_SYMBOL(scsi_rescan_device); | 1659 | EXPORT_SYMBOL(scsi_rescan_device); |
| 1644 | 1660 | ||
| @@ -201,18 +201,32 @@ cache_type_store(struct device *dev, struct device_attribute *attr, · 200 unmodified lines | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static ssize_t | 203 | static ssize_t |
| 204 | manage_start_stop_show(struct device *dev, struct device_attribute *attr, | 204 | manage_start_stop_show(struct device *dev, |
| 205 | char *buf) | 205 | struct device_attribute *attr, char *buf) |
| 206 | { | 206 | { |
| 207 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 207 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 208 | struct scsi_device *sdp = sdkp->device; | 208 | struct scsi_device *sdp = sdkp->device; |
| 209 | 209 | ||
| 210 | return sprintf(buf, "%u\n", sdp->manage_start_stop); | 210 | return sysfs_emit(buf, "%u\n", |
| 211 | sdp->manage_system_start_stop && | ||
| 212 | sdp->manage_runtime_start_stop); | ||
| 211 | } | 213 | } |
| 214 | static DEVICE_ATTR_RO(manage_start_stop); | ||
| 212 | 215 | ||
| 213 | static ssize_t | 216 | static ssize_t |
| 214 | manage_start_stop_store(struct device *dev, struct device_attribute *attr, | 217 | manage_system_start_stop_show(struct device *dev, |
| 215 | const char *buf, size_t count) | 218 | struct device_attribute *attr, char *buf) |
| 219 | { | ||
| 220 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 221 | struct scsi_device *sdp = sdkp->device; | ||
| 222 | |||
| 223 | return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop); | ||
| 224 | } | ||
| 225 | |||
| 226 | static ssize_t | ||
| 227 | manage_system_start_stop_store(struct device *dev, | ||
| 228 | struct device_attribute *attr, | ||
| 229 | const char *buf, size_t count) | ||
| 216 | { | 230 | { |
| 217 | struct scsi_disk *sdkp = to_scsi_disk(dev); | 231 | struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 218 | struct scsi_device *sdp = sdkp->device; | 232 | struct scsi_device *sdp = sdkp->device; |
| @@ -224,11 +238,42 @@ manage_start_stop_store(struct device *dev, struct device_attribute *attr, · 5 unmodified lines | |||
| 224 | if (kstrtobool(buf, &v)) | 238 | if (kstrtobool(buf, &v)) |
| 225 | return -EINVAL; | 239 | return -EINVAL; |
| 226 | 240 | ||
| 227 | sdp->manage_start_stop = v; | 241 | sdp->manage_system_start_stop = v; |
| 228 | 242 | ||
| 229 | return count; | 243 | return count; |
| 230 | } | 244 | } |
| 231 | static DEVICE_ATTR_RW(manage_start_stop); | 245 | static DEVICE_ATTR_RW(manage_system_start_stop); |
| 246 | |||
| 247 | static ssize_t | ||
| 248 | manage_runtime_start_stop_show(struct device *dev, | ||
| 249 | struct device_attribute *attr, char *buf) | ||
| 250 | { | ||
| 251 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 252 | struct scsi_device *sdp = sdkp->device; | ||
| 253 | |||
| 254 | return sysfs_emit(buf, "%u\n", sdp->manage_runtime_start_stop); | ||
| 255 | } | ||
| 256 | |||
| 257 | static ssize_t | ||
| 258 | manage_runtime_start_stop_store(struct device *dev, | ||
| 259 | struct device_attribute *attr, | ||
| 260 | const char *buf, size_t count) | ||
| 261 | { | ||
| 262 | struct scsi_disk *sdkp = to_scsi_disk(dev); | ||
| 263 | struct scsi_device *sdp = sdkp->device; | ||
| 264 | bool v; | ||
| 265 | |||
| 266 | if (!capable(CAP_SYS_ADMIN)) | ||
| 267 | return -EACCES; | ||
| 268 | |||
| 269 | if (kstrtobool(buf, &v)) | ||
| 270 | return -EINVAL; | ||
| 271 | |||
| 272 | sdp->manage_runtime_start_stop = v; | ||
| 273 | |||
| 274 | return count; | ||
| 275 | } | ||
| 276 | static DEVICE_ATTR_RW(manage_runtime_start_stop); | ||
| 232 | 277 | ||
| 233 | static ssize_t | 278 | static ssize_t |
| 234 | allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) | 279 | allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) |
| @@ -560,6 +605,8 @@ static struct attribute *sd_disk_attrs[] = { · 325 unmodified lines | |||
| 560 | &dev_attr_FUA.attr, | 605 | &dev_attr_FUA.attr, |
| 561 | &dev_attr_allow_restart.attr, | 606 | &dev_attr_allow_restart.attr, |
| 562 | &dev_attr_manage_start_stop.attr, | 607 | &dev_attr_manage_start_stop.attr, |
| 608 | &dev_attr_manage_system_start_stop.attr, | ||
| 609 | &dev_attr_manage_runtime_start_stop.attr, | ||
| 563 | &dev_attr_protection_type.attr, | 610 | &dev_attr_protection_type.attr, |
| 564 | &dev_attr_protection_mode.attr, | 611 | &dev_attr_protection_mode.attr, |
| 565 | &dev_attr_app_tag_own.attr, | 612 | &dev_attr_app_tag_own.attr, |
| @@ -3694,7 +3741,8 @@ static int sd_remove(struct device *dev) · 3128 unmodified lines | |||
| 3694 | 3741 | ||
| 3695 | device_del(&sdkp->disk_dev); | 3742 | device_del(&sdkp->disk_dev); |
| 3696 | del_gendisk(sdkp->disk); | 3743 | del_gendisk(sdkp->disk); |
| 3697 | sd_shutdown(dev); | 3744 | if (!sdkp->suspended) |
| 3745 | sd_shutdown(dev); | ||
| 3698 | 3746 | ||
| 3699 | put_disk(sdkp->disk); | 3747 | put_disk(sdkp->disk); |
| 3700 | return 0; | 3748 | return 0; |
| @@ -3771,13 +3819,20 @@ static void sd_shutdown(struct device *dev) · 70 unmodified lines | |||
| 3771 | sd_sync_cache(sdkp, NULL); | 3819 | sd_sync_cache(sdkp, NULL); |
| 3772 | } | 3820 | } |
| 3773 | 3821 | ||
| 3774 | if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { | 3822 | if (system_state != SYSTEM_RESTART && |
| 3823 | sdkp->device->manage_system_start_stop) { | ||
| 3775 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); | 3824 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); |
| 3776 | sd_start_stop_device(sdkp, 0); | 3825 | sd_start_stop_device(sdkp, 0); |
| 3777 | } | 3826 | } |
| 3778 | } | 3827 | } |
| 3779 | 3828 | ||
| 3780 | static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) | 3829 | static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) |
| 3830 | { | ||
| 3831 | return (sdev->manage_system_start_stop && !runtime) || | ||
| 3832 | (sdev->manage_runtime_start_stop && runtime); | ||
| 3833 | } | ||
| 3834 | |||
| 3835 | static int sd_suspend_common(struct device *dev, bool runtime) | ||
| 3781 | { | 3836 | { |
| 3782 | struct scsi_disk *sdkp = dev_get_drvdata(dev); | 3837 | struct scsi_disk *sdkp = dev_get_drvdata(dev); |
| 3783 | struct scsi_sense_hdr sshdr; | 3838 | struct scsi_sense_hdr sshdr; |
| @@ -3809,15 +3864,18 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) · 25 unmodified lines | |||
| 3809 | } | 3864 | } |
| 3810 | } | 3865 | } |
| 3811 | 3866 | ||
| 3812 | if (sdkp->device->manage_start_stop) { | 3867 | if (sd_do_start_stop(sdkp->device, runtime)) { |
| 3813 | if (!sdkp->device->silence_suspend) | 3868 | if (!sdkp->device->silence_suspend) |
| 3814 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); | 3869 | sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); |
| 3815 | /* an error is not worth aborting a system sleep */ | 3870 | /* an error is not worth aborting a system sleep */ |
| 3816 | ret = sd_start_stop_device(sdkp, 0); | 3871 | ret = sd_start_stop_device(sdkp, 0); |
| 3817 | if (ignore_stop_errors) | 3872 | if (!runtime) |
| 3818 | ret = 0; | 3873 | ret = 0; |
| 3819 | } | 3874 | } |
| 3820 | 3875 | ||
| 3876 | if (!ret) | ||
| 3877 | sdkp->suspended = true; | ||
| 3878 | |||
| 3821 | return ret; | 3879 | return ret; |
| 3822 | } | 3880 | } |
| 3823 | 3881 | ||
| @@ -3826,15 +3884,15 @@ static int sd_suspend_system(struct device *dev) · 2 unmodified lines | |||
| 3826 | if (pm_runtime_suspended(dev)) | 3884 | if (pm_runtime_suspended(dev)) |
| 3827 | return 0; | 3885 | return 0; |
| 3828 | 3886 | ||
| 3829 | return sd_suspend_common(dev, true); | 3887 | return sd_suspend_common(dev, false); |
| 3830 | } | 3888 | } |
| 3831 | 3889 | ||
| 3832 | static int sd_suspend_runtime(struct device *dev) | 3890 | static int sd_suspend_runtime(struct device *dev) |
| 3833 | { | 3891 | { |
| 3834 | return sd_suspend_common(dev, false); | 3892 | return sd_suspend_common(dev, true); |
| 3835 | } | 3893 | } |
| 3836 | 3894 | ||
| 3837 | static int sd_resume(struct device *dev) | 3895 | static int sd_resume(struct device *dev, bool runtime) |
| 3838 | { | 3896 | { |
| 3839 | struct scsi_disk *sdkp = dev_get_drvdata(dev); | 3897 | struct scsi_disk *sdkp = dev_get_drvdata(dev); |
| 3840 | int ret = 0; | 3898 | int ret = 0; |
| @@ -3842,16 +3900,21 @@ static int sd_resume(struct device *dev) · 1 unmodified line | |||
| 3842 | if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ | 3900 | if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ |
| 3843 | return 0; | 3901 | return 0; |
| 3844 | 3902 | ||
| 3845 | if (!sdkp->device->manage_start_stop) | 3903 | if (!sd_do_start_stop(sdkp->device, runtime)) { |
| 3904 | sdkp->suspended = false; | ||
| 3846 | return 0; | 3905 | return 0; |
| 3906 | } | ||
| 3847 | 3907 | ||
| 3848 | if (!sdkp->device->no_start_on_resume) { | 3908 | if (!sdkp->device->no_start_on_resume) { |
| 3849 | sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); | 3909 | sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); |
| 3850 | ret = sd_start_stop_device(sdkp, 1); | 3910 | ret = sd_start_stop_device(sdkp, 1); |
| 3851 | } | 3911 | } |
| 3852 | 3912 | ||
| 3853 | if (!ret) | 3913 | if (!ret) { |
| 3854 | opal_unlock_from_suspend(sdkp->opal_dev); | 3914 | opal_unlock_from_suspend(sdkp->opal_dev); |
| 3915 | sdkp->suspended = false; | ||
| 3916 | } | ||
| 3917 | |||
| 3855 | return ret; | 3918 | return ret; |
| 3856 | } | 3919 | } |
| 3857 | 3920 | ||
| @@ -3860,7 +3923,7 @@ static int sd_resume_system(struct device *dev) · 2 unmodified lines | |||
| 3860 | if (pm_runtime_suspended(dev)) | 3923 | if (pm_runtime_suspended(dev)) |
| 3861 | return 0; | 3924 | return 0; |
| 3862 | 3925 | ||
| 3863 | return sd_resume(dev); | 3926 | return sd_resume(dev, false); |
| 3864 | } | 3927 | } |
| 3865 | 3928 | ||
| 3866 | static int sd_resume_runtime(struct device *dev) | 3929 | static int sd_resume_runtime(struct device *dev) |
| @@ -3887,7 +3950,7 @@ static int sd_resume_runtime(struct device *dev) · 20 unmodified lines | |||
| 3887 | "Failed to clear sense data\n"); | 3950 | "Failed to clear sense data\n"); |
| 3888 | } | 3951 | } |
| 3889 | 3952 | ||
| 3890 | return sd_resume(dev); | 3953 | return sd_resume(dev, true); |
| 3891 | } | 3954 | } |
| 3892 | 3955 | ||
| 3893 | static const struct dev_pm_ops sd_pm_ops = { | 3956 | static const struct dev_pm_ops sd_pm_ops = { |
| @@ -131,6 +131,7 @@ struct scsi_disk { · 130 unmodified lines | |||
| 131 | u8 provisioning_mode; | 131 | u8 provisioning_mode; |
| 132 | u8 zeroing_mode; | 132 | u8 zeroing_mode; |
| 133 | u8 nr_actuators; /* Number of actuators */ | 133 | u8 nr_actuators; /* Number of actuators */ |
| 134 | bool suspended; /* Disk is suspended (stopped) */ | ||
| 134 | unsigned ATO : 1; /* state of disk ATO bit */ | 135 | unsigned ATO : 1; /* state of disk ATO bit */ |
| 135 | unsigned cache_override : 1; /* temp override of WCE,RCD */ | 136 | unsigned cache_override : 1; /* temp override of WCE,RCD */ |
| 136 | unsigned WCE : 1; /* state of disk WCE bit */ | 137 | unsigned WCE : 1; /* state of disk WCE bit */ |
| @@ -100,6 +100,7 @@ static void __init imx8mm_soc_uid(void) · 99 unmodified lines | |||
| 100 | { | 100 | { |
| 101 | void __iomem *ocotp_base; | 101 | void __iomem *ocotp_base; |
| 102 | struct device_node *np; | 102 | struct device_node *np; |
| 103 | struct clk *clk; | ||
| 103 | u32 offset = of_machine_is_compatible("fsl,imx8mp") ? | 104 | u32 offset = of_machine_is_compatible("fsl,imx8mp") ? |
| 104 | IMX8MP_OCOTP_UID_OFFSET : 0; | 105 | IMX8MP_OCOTP_UID_OFFSET : 0; |
| 105 | 106 | ||
| @@ -109,11 +110,20 @@ static void __init imx8mm_soc_uid(void) · 3 unmodified lines | |||
| 109 | 110 | ||
| 110 | ocotp_base = of_iomap(np, 0); | 111 | ocotp_base = of_iomap(np, 0); |
| 111 | WARN_ON(!ocotp_base); | 112 | WARN_ON(!ocotp_base); |
| 113 | clk = of_clk_get_by_name(np, NULL); | ||
| 114 | if (IS_ERR(clk)) { | ||
| 115 | WARN_ON(IS_ERR(clk)); | ||
| 116 | return; | ||
| 117 | } | ||
| 118 | |||
| 119 | clk_prepare_enable(clk); | ||
| 112 | 120 | ||
| 113 | soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); | 121 | soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); |
| 114 | soc_uid <<= 32; | 122 | soc_uid <<= 32; |
| 115 | soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); | 123 | soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); |
| 116 | 124 | ||
| 125 | clk_disable_unprepare(clk); | ||
| 126 | clk_put(clk); | ||
| 117 | iounmap(ocotp_base); | 127 | iounmap(ocotp_base); |
| 118 | of_node_put(np); | 128 | of_node_put(np); |
| 119 | } | 129 | } |
| @@ -20,6 +20,7 @@ config LOONGSON2_GUTS · 19 unmodified lines | |||
| 20 | config LOONGSON2_PM | 20 | config LOONGSON2_PM |
| 21 | bool "Loongson-2 SoC Power Management Controller Driver" | 21 | bool "Loongson-2 SoC Power Management Controller Driver" |
| 22 | depends on LOONGARCH && OF | 22 | depends on LOONGARCH && OF |
| 23 | depends on INPUT=y | ||
| 23 | help | 24 | help |
| 24 | The Loongson-2's power management controller was ACPI, supports ACPI | 25 | The Loongson-2's power management controller was ACPI, supports ACPI |
| 25 | S2Idle (Suspend To Idle), ACPI S3 (Suspend To RAM), ACPI S4 (Suspend To | 26 | S2Idle (Suspend To Idle), ACPI S3 (Suspend To RAM), ACPI S4 (Suspend To |
| @@ -70,7 +70,7 @@ static const struct loongson2_soc_die_attr *loongson2_soc_die_match( · 69 unmodified lines | |||
| 70 | if (matches->svr == (svr & matches->mask)) | 70 | if (matches->svr == (svr & matches->mask)) |
| 71 | return matches; | 71 | return matches; |
| 72 | matches++; | 72 | matches++; |
| 73 | }; | 73 | } |
| 74 | 74 | ||
| 75 | return NULL; | 75 | return NULL; |
| 76 | } | 76 | } |
| @@ -94,7 +94,6 @@ static int loongson2_guts_probe(struct platform_device *pdev) · 17 unmodified lines | |||
| 94 | { | 94 | { |
| 95 | struct device_node *root, *np = pdev->dev.of_node; | 95 | struct device_node *root, *np = pdev->dev.of_node; |
| 96 | struct device *dev = &pdev->dev; | 96 | struct device *dev = &pdev->dev; |
| 97 | struct resource *res; | ||
| 98 | const struct loongson2_soc_die_attr *soc_die; | 97 | const struct loongson2_soc_die_attr *soc_die; |
| 99 | const char *machine; | 98 | const char *machine; |
| 100 | u32 svr; | 99 | u32 svr; |
| @@ -106,8 +105,7 @@ static int loongson2_guts_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 106 | 105 | ||
| 107 | guts->little_endian = of_property_read_bool(np, "little-endian"); | 106 | guts->little_endian = of_property_read_bool(np, "little-endian"); |
| 108 | 107 | ||
| 109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 108 | guts->regs = devm_platform_ioremap_resource(pdev, 0); |
| 110 | guts->regs = ioremap(res->start, res->end - res->start + 1); | ||
| 111 | if (IS_ERR(guts->regs)) | 109 | if (IS_ERR(guts->regs)) |
| 112 | return PTR_ERR(guts->regs); | 110 | return PTR_ERR(guts->regs); |
| 113 | 111 | ||
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/input.h> | 11 | #include <linux/input.h> |
| 12 | #include <linux/suspend.h> | 12 | #include <linux/suspend.h> |
| 13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 14 | #include <linux/of_platform.h> | ||
| 14 | #include <linux/pm_wakeirq.h> | 15 | #include <linux/pm_wakeirq.h> |
| 15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 16 | #include <asm/bootinfo.h> | 17 | #include <asm/bootinfo.h> |
| @@ -192,12 +193,16 @@ static int loongson2_pm_probe(struct platform_device *pdev) · 175 unmodified lines | |||
| 192 | if (loongson_sysconf.suspend_addr) | 193 | if (loongson_sysconf.suspend_addr) |
| 193 | suspend_set_ops(&loongson2_suspend_ops); | 194 | suspend_set_ops(&loongson2_suspend_ops); |
| 194 | 195 | ||
| 196 | /* Populate children */ | ||
| 197 | retval = devm_of_platform_populate(dev); | ||
| 198 | if (retval) | ||
| 199 | dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n"); | ||
| 200 | |||
| 195 | return 0; | 201 | return 0; |
| 196 | } | 202 | } |
| 197 | 203 | ||
| 198 | static const struct of_device_id loongson2_pm_match[] = { | 204 | static const struct of_device_id loongson2_pm_match[] = { |
| 199 | { .compatible = "loongson,ls2k0500-pmc", }, | 205 | { .compatible = "loongson,ls2k0500-pmc", }, |
| 200 | { .compatible = "loongson,ls2k1000-pmc", }, | ||
| 201 | {}, | 206 | {}, |
| 202 | }; | 207 | }; |
| 203 | 208 | ||
| @@ -256,7 +256,6 @@ static int cs42l43_spi_probe(struct platform_device *pdev) · 255 unmodified lines | |||
| 256 | 256 | ||
| 257 | ret = devm_spi_register_controller(priv->dev, priv->ctlr); | 257 | ret = devm_spi_register_controller(priv->dev, priv->ctlr); |
| 258 | if (ret) { | 258 | if (ret) { |
| 259 | pm_runtime_disable(priv->dev); | ||
| 260 | dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret); | 259 | dev_err(priv->dev, "Failed to register SPI controller: %d\n", ret); |
| 261 | } | 260 | } |
| 262 | 261 | ||
| @@ -194,7 +194,7 @@ static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op · 193 unmodified lines | |||
| 194 | return ret; | 194 | return ret; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | return write_len; | 197 | return 0; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) | 200 | static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) |
| @@ -662,7 +662,7 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, · 661 unmodified lines | |||
| 662 | if (spi_imx->count >= 512) | 662 | if (spi_imx->count >= 512) |
| 663 | ctrl |= 0xFFF << MX51_ECSPI_CTRL_BL_OFFSET; | 663 | ctrl |= 0xFFF << MX51_ECSPI_CTRL_BL_OFFSET; |
| 664 | else | 664 | else |
| 665 | ctrl |= (spi_imx->count*8 - 1) | 665 | ctrl |= (spi_imx->count * spi_imx->bits_per_word - 1) |
| 666 | << MX51_ECSPI_CTRL_BL_OFFSET; | 666 | << MX51_ECSPI_CTRL_BL_OFFSET; |
| 667 | } | 667 | } |
| 668 | 668 | ||
| @@ -72,6 +72,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { · 71 unmodified lines | |||
| 72 | { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, | 72 | { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, |
| 73 | { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, | 73 | { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, |
| 74 | { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, | 74 | { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, |
| 75 | { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, | ||
| 75 | { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, | 76 | { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, |
| 76 | { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, | 77 | { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, |
| 77 | { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, | 78 | { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, |
| @@ -1084,6 +1084,13 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f) · 1083 unmodified lines | |||
| 1084 | fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, | 1084 | fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, |
| 1085 | base + FSPI_AHBCR); | 1085 | base + FSPI_AHBCR); |
| 1086 | 1086 | ||
| 1087 | /* Reset the FLSHxCR1 registers. */ | ||
| 1088 | reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); | ||
| 1089 | fspi_writel(f, reg, base + FSPI_FLSHA1CR1); | ||
| 1090 | fspi_writel(f, reg, base + FSPI_FLSHA2CR1); | ||
| 1091 | fspi_writel(f, reg, base + FSPI_FLSHB1CR1); | ||
| 1092 | fspi_writel(f, reg, base + FSPI_FLSHB2CR1); | ||
| 1093 | |||
| 1087 | /* AHB Read - Set lut sequence ID for all CS. */ | 1094 | /* AHB Read - Set lut sequence ID for all CS. */ |
| 1088 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); | 1095 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); |
| 1089 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); | 1096 | fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); |
| @@ -277,6 +277,7 @@ struct stm32_spi_cfg { · 276 unmodified lines | |||
| 277 | * @fifo_size: size of the embedded fifo in bytes | 277 | * @fifo_size: size of the embedded fifo in bytes |
| 278 | * @cur_midi: master inter-data idleness in ns | 278 | * @cur_midi: master inter-data idleness in ns |
| 279 | * @cur_speed: speed configured in Hz | 279 | * @cur_speed: speed configured in Hz |
| 280 | * @cur_half_period: time of a half bit in us | ||
| 280 | * @cur_bpw: number of bits in a single SPI data frame | 281 | * @cur_bpw: number of bits in a single SPI data frame |
| 281 | * @cur_fthlv: fifo threshold level (data frames in a single data packet) | 282 | * @cur_fthlv: fifo threshold level (data frames in a single data packet) |
| 282 | * @cur_comm: SPI communication mode | 283 | * @cur_comm: SPI communication mode |
| @@ -304,6 +305,7 @@ struct stm32_spi { · 21 unmodified lines | |||
| 304 | 305 | ||
| 305 | unsigned int cur_midi; | 306 | unsigned int cur_midi; |
| 306 | unsigned int cur_speed; | 307 | unsigned int cur_speed; |
| 308 | unsigned int cur_half_period; | ||
| 307 | unsigned int cur_bpw; | 309 | unsigned int cur_bpw; |
| 308 | unsigned int cur_fthlv; | 310 | unsigned int cur_fthlv; |
| 309 | unsigned int cur_comm; | 311 | unsigned int cur_comm; |
| @@ -468,6 +470,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz, · 158 unmodified lines | |||
| 468 | 470 | ||
| 469 | spi->cur_speed = spi->clk_rate / (1 << mbrdiv); | 471 | spi->cur_speed = spi->clk_rate / (1 << mbrdiv); |
| 470 | 472 | ||
| 473 | spi->cur_half_period = DIV_ROUND_CLOSEST(USEC_PER_SEC, 2 * spi->cur_speed); | ||
| 474 | |||
| 471 | return mbrdiv - 1; | 475 | return mbrdiv - 1; |
| 472 | } | 476 | } |
| 473 | 477 | ||
| @@ -709,6 +713,10 @@ static void stm32h7_spi_disable(struct stm32_spi *spi) · 235 unmodified lines | |||
| 709 | return; | 713 | return; |
| 710 | } | 714 | } |
| 711 | 715 | ||
| 716 | /* Add a delay to make sure that transmission is ended. */ | ||
| 717 | if (spi->cur_half_period) | ||
| 718 | udelay(spi->cur_half_period); | ||
| 719 | |||
| 712 | if (spi->cur_usedma && spi->dma_tx) | 720 | if (spi->cur_usedma && spi->dma_tx) |
| 713 | dmaengine_terminate_async(spi->dma_tx); | 721 | dmaengine_terminate_async(spi->dma_tx); |
| 714 | if (spi->cur_usedma && spi->dma_rx) | 722 | if (spi->cur_usedma && spi->dma_rx) |
| @@ -1340,9 +1340,9 @@ static int zynqmp_qspi_probe(struct platform_device *pdev) · 1339 unmodified lines | |||
| 1340 | return 0; | 1340 | return 0; |
| 1341 | 1341 | ||
| 1342 | clk_dis_all: | 1342 | clk_dis_all: |
| 1343 | pm_runtime_put_sync(&pdev->dev); | ||
| 1344 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1345 | pm_runtime_disable(&pdev->dev); | 1343 | pm_runtime_disable(&pdev->dev); |
| 1344 | pm_runtime_put_noidle(&pdev->dev); | ||
| 1345 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1346 | clk_disable_unprepare(xqspi->refclk); | 1346 | clk_disable_unprepare(xqspi->refclk); |
| 1347 | clk_dis_pclk: | 1347 | clk_dis_pclk: |
| 1348 | clk_disable_unprepare(xqspi->pclk); | 1348 | clk_disable_unprepare(xqspi->pclk); |
| @@ -1366,11 +1366,15 @@ static void zynqmp_qspi_remove(struct platform_device *pdev) · 17 unmodified lines | |||
| 1366 | { | 1366 | { |
| 1367 | struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev); | 1367 | struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev); |
| 1368 | 1368 | ||
| 1369 | pm_runtime_get_sync(&pdev->dev); | ||
| 1370 | |||
| 1369 | zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0); | 1371 | zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0); |
| 1372 | |||
| 1373 | pm_runtime_disable(&pdev->dev); | ||
| 1374 | pm_runtime_put_noidle(&pdev->dev); | ||
| 1375 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1370 | clk_disable_unprepare(xqspi->refclk); | 1376 | clk_disable_unprepare(xqspi->refclk); |
| 1371 | clk_disable_unprepare(xqspi->pclk); | 1377 | clk_disable_unprepare(xqspi->pclk); |
| 1372 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1373 | pm_runtime_disable(&pdev->dev); | ||
| 1374 | } | 1378 | } |
| 1375 | 1379 | ||
| 1376 | MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match); | 1380 | MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match); |
| @@ -1392,16 +1392,16 @@ static ssize_t target_wwn_vendor_id_store(struct config_item *item, · 1391 unmodified lines | |||
| 1392 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ | 1392 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ |
| 1393 | unsigned char buf[INQUIRY_VENDOR_LEN + 2]; | 1393 | unsigned char buf[INQUIRY_VENDOR_LEN + 2]; |
| 1394 | char *stripped = NULL; | 1394 | char *stripped = NULL; |
| 1395 | size_t len; | 1395 | ssize_t len; |
| 1396 | ssize_t ret; | 1396 | ssize_t ret; |
| 1397 | 1397 | ||
| 1398 | len = strlcpy(buf, page, sizeof(buf)); | 1398 | len = strscpy(buf, page, sizeof(buf)); |
| 1399 | if (len < sizeof(buf)) { | 1399 | if (len > 0) { |
| 1400 | /* Strip any newline added from userspace. */ | 1400 | /* Strip any newline added from userspace. */ |
| 1401 | stripped = strstrip(buf); | 1401 | stripped = strstrip(buf); |
| 1402 | len = strlen(stripped); | 1402 | len = strlen(stripped); |
| 1403 | } | 1403 | } |
| 1404 | if (len > INQUIRY_VENDOR_LEN) { | 1404 | if (len < 0 || len > INQUIRY_VENDOR_LEN) { |
| 1405 | pr_err("Emulated T10 Vendor Identification exceeds" | 1405 | pr_err("Emulated T10 Vendor Identification exceeds" |
| 1406 | " INQUIRY_VENDOR_LEN: " __stringify(INQUIRY_VENDOR_LEN) | 1406 | " INQUIRY_VENDOR_LEN: " __stringify(INQUIRY_VENDOR_LEN) |
| 1407 | "\n"); | 1407 | "\n"); |
| @@ -1448,16 +1448,16 @@ static ssize_t target_wwn_product_id_store(struct config_item *item, · 40 unmodified lines | |||
| 1448 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ | 1448 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ |
| 1449 | unsigned char buf[INQUIRY_MODEL_LEN + 2]; | 1449 | unsigned char buf[INQUIRY_MODEL_LEN + 2]; |
| 1450 | char *stripped = NULL; | 1450 | char *stripped = NULL; |
| 1451 | size_t len; | 1451 | ssize_t len; |
| 1452 | ssize_t ret; | 1452 | ssize_t ret; |
| 1453 | 1453 | ||
| 1454 | len = strlcpy(buf, page, sizeof(buf)); | 1454 | len = strscpy(buf, page, sizeof(buf)); |
| 1455 | if (len < sizeof(buf)) { | 1455 | if (len > 0) { |
| 1456 | /* Strip any newline added from userspace. */ | 1456 | /* Strip any newline added from userspace. */ |
| 1457 | stripped = strstrip(buf); | 1457 | stripped = strstrip(buf); |
| 1458 | len = strlen(stripped); | 1458 | len = strlen(stripped); |
| 1459 | } | 1459 | } |
| 1460 | if (len > INQUIRY_MODEL_LEN) { | 1460 | if (len < 0 || len > INQUIRY_MODEL_LEN) { |
| 1461 | pr_err("Emulated T10 Vendor exceeds INQUIRY_MODEL_LEN: " | 1461 | pr_err("Emulated T10 Vendor exceeds INQUIRY_MODEL_LEN: " |
| 1462 | __stringify(INQUIRY_MODEL_LEN) | 1462 | __stringify(INQUIRY_MODEL_LEN) |
| 1463 | "\n"); | 1463 | "\n"); |
| @@ -1504,16 +1504,16 @@ static ssize_t target_wwn_revision_store(struct config_item *item, · 40 unmodified lines | |||
| 1504 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ | 1504 | /* +2 to allow for a trailing (stripped) '\n' and null-terminator */ |
| 1505 | unsigned char buf[INQUIRY_REVISION_LEN + 2]; | 1505 | unsigned char buf[INQUIRY_REVISION_LEN + 2]; |
| 1506 | char *stripped = NULL; | 1506 | char *stripped = NULL; |
| 1507 | size_t len; | 1507 | ssize_t len; |
| 1508 | ssize_t ret; | 1508 | ssize_t ret; |
| 1509 | 1509 | ||
| 1510 | len = strlcpy(buf, page, sizeof(buf)); | 1510 | len = strscpy(buf, page, sizeof(buf)); |
| 1511 | if (len < sizeof(buf)) { | 1511 | if (len > 0) { |
| 1512 | /* Strip any newline added from userspace. */ | 1512 | /* Strip any newline added from userspace. */ |
| 1513 | stripped = strstrip(buf); | 1513 | stripped = strstrip(buf); |
| 1514 | len = strlen(stripped); | 1514 | len = strlen(stripped); |
| 1515 | } | 1515 | } |
| 1516 | if (len > INQUIRY_REVISION_LEN) { | 1516 | if (len < 0 || len > INQUIRY_REVISION_LEN) { |
| 1517 | pr_err("Emulated T10 Revision exceeds INQUIRY_REVISION_LEN: " | 1517 | pr_err("Emulated T10 Revision exceeds INQUIRY_REVISION_LEN: " |
| 1518 | __stringify(INQUIRY_REVISION_LEN) | 1518 | __stringify(INQUIRY_REVISION_LEN) |
| 1519 | "\n"); | 1519 | "\n"); |
| @@ -264,6 +264,7 @@ void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt) · 263 unmodified lines | |||
| 264 | percpu_ref_put(&cmd_cnt->refcnt); | 264 | percpu_ref_put(&cmd_cnt->refcnt); |
| 265 | 265 | ||
| 266 | percpu_ref_exit(&cmd_cnt->refcnt); | 266 | percpu_ref_exit(&cmd_cnt->refcnt); |
| 267 | kfree(cmd_cnt); | ||
| 267 | } | 268 | } |
| 268 | EXPORT_SYMBOL_GPL(target_free_cmd_counter); | 269 | EXPORT_SYMBOL_GPL(target_free_cmd_counter); |
| 269 | 270 | ||
| @@ -238,8 +238,6 @@ int optee_notif_send(struct optee *optee, u_int key); · 237 unmodified lines | |||
| 238 | u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, | 238 | u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, |
| 239 | struct tee_param *param); | 239 | struct tee_param *param); |
| 240 | 240 | ||
| 241 | int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len); | ||
| 242 | int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len); | ||
| 243 | void optee_supp_init(struct optee_supp *supp); | 241 | void optee_supp_init(struct optee_supp *supp); |
| 244 | void optee_supp_uninit(struct optee_supp *supp); | 242 | void optee_supp_uninit(struct optee_supp *supp); |
| 245 | void optee_supp_release(struct optee_supp *supp); | 243 | void optee_supp_release(struct optee_supp *supp); |
| @@ -47,8 +47,6 @@ struct tee_device { · 46 unmodified lines | |||
| 47 | struct tee_shm_pool *pool; | 47 | struct tee_shm_pool *pool; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | int tee_shm_init(void); | ||
| 51 | |||
| 52 | int tee_shm_get_fd(struct tee_shm *shm); | 50 | int tee_shm_get_fd(struct tee_shm *shm); |
| 53 | 51 | ||
| 54 | bool tee_device_get(struct tee_device *teedev); | 52 | bool tee_device_get(struct tee_device *teedev); |
| @@ -348,12 +348,14 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip_id) · 347 unmodified lines | |||
| 348 | struct thermal_trip trip; | 348 | struct thermal_trip trip; |
| 349 | 349 | ||
| 350 | /* Ignore disabled trip points */ | 350 | /* Ignore disabled trip points */ |
| 351 | if (test_bit(trip_id, &tz->trips_disabled) || | 351 | if (test_bit(trip_id, &tz->trips_disabled)) |
| 352 | trip.temperature == THERMAL_TEMP_INVALID) | ||
| 353 | return; | 352 | return; |
| 354 | 353 | ||
| 355 | __thermal_zone_get_trip(tz, trip_id, &trip); | 354 | __thermal_zone_get_trip(tz, trip_id, &trip); |
| 356 | 355 | ||
| 356 | if (trip.temperature == THERMAL_TEMP_INVALID) | ||
| 357 | return; | ||
| 358 | |||
| 357 | if (tz->last_temperature != THERMAL_TEMP_INVALID) { | 359 | if (tz->last_temperature != THERMAL_TEMP_INVALID) { |
| 358 | if (tz->last_temperature < trip.temperature && | 360 | if (tz->last_temperature < trip.temperature && |
| 359 | tz->temperature >= trip.temperature) | 361 | tz->temperature >= trip.temperature) |
| @@ -37,8 +37,10 @@ static int of_find_trip_id(struct device_node *np, struct device_node *trip) · 36 unmodified lines | |||
| 37 | */ | 37 | */ |
| 38 | for_each_child_of_node(trips, t) { | 38 | for_each_child_of_node(trips, t) { |
| 39 | 39 | ||
| 40 | if (t == trip) | 40 | if (t == trip) { |
| 41 | of_node_put(t); | ||
| 41 | goto out; | 42 | goto out; |
| 43 | } | ||
| 42 | i++; | 44 | i++; |
| 43 | } | 45 | } |
| 44 | 46 | ||
| @@ -401,8 +403,10 @@ static int thermal_of_for_each_cooling_maps(struct thermal_zone_device *tz, · 356 unmodified lines | |||
| 401 | 403 | ||
| 402 | for_each_child_of_node(cm_np, child) { | 404 | for_each_child_of_node(cm_np, child) { |
| 403 | ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action); | 405 | ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action); |
| 404 | if (ret) | 406 | if (ret) { |
| 407 | of_node_put(child); | ||
| 405 | break; | 408 | break; |
| 409 | } | ||
| 406 | } | 410 | } |
| 407 | 411 | ||
| 408 | of_node_put(cm_np); | 412 | of_node_put(cm_np); |
| @@ -185,9 +185,6 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, · 184 unmodified lines | |||
| 185 | if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) | 185 | if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip_id) != 1) |
| 186 | return -EINVAL; | 186 | return -EINVAL; |
| 187 | 187 | ||
| 188 | if (kstrtoint(buf, 10, &trip.hysteresis)) | ||
| 189 | return -EINVAL; | ||
| 190 | |||
| 191 | mutex_lock(&tz->lock); | 188 | mutex_lock(&tz->lock); |
| 192 | 189 | ||
| 193 | if (!device_is_registered(dev)) { | 190 | if (!device_is_registered(dev)) { |
| @@ -198,7 +195,11 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, · 4 unmodified lines | |||
| 198 | ret = __thermal_zone_get_trip(tz, trip_id, &trip); | 195 | ret = __thermal_zone_get_trip(tz, trip_id, &trip); |
| 199 | if (ret) | 196 | if (ret) |
| 200 | goto unlock; | 197 | goto unlock; |
| 201 | 198 | ||
| 199 | ret = kstrtoint(buf, 10, &trip.hysteresis); | ||
| 200 | if (ret) | ||
| 201 | goto unlock; | ||
| 202 | |||
| 202 | ret = thermal_zone_set_trip(tz, trip_id, &trip); | 203 | ret = thermal_zone_set_trip(tz, trip_id, &trip); |
| 203 | unlock: | 204 | unlock: |
| 204 | mutex_unlock(&tz->lock); | 205 | mutex_unlock(&tz->lock); |
| @@ -110,7 +110,8 @@ static inline int __ti_thermal_get_temp(struct thermal_zone_device *tz, int *tem · 109 unmodified lines | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static int __ti_thermal_get_trend(struct thermal_zone_device *tz, | 112 | static int __ti_thermal_get_trend(struct thermal_zone_device *tz, |
| 113 | struct thermal_trip *trip, enum thermal_trend *trend) | 113 | const struct thermal_trip *trip, |
| 114 | enum thermal_trend *trend) | ||
| 114 | { | 115 | { |
| 115 | struct ti_thermal_data *data = thermal_zone_device_priv(tz); | 116 | struct ti_thermal_data *data = thermal_zone_device_priv(tz); |
| 116 | struct ti_bandgap *bgp; | 117 | struct ti_bandgap *bgp; |
| @@ -3097,10 +3097,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3096 unmodified lines | |||
| 3097 | gsm->has_devices = false; | 3097 | gsm->has_devices = false; |
| 3098 | } | 3098 | } |
| 3099 | for (i = NUM_DLCI - 1; i >= 0; i--) | 3099 | for (i = NUM_DLCI - 1; i >= 0; i--) |
| 3100 | if (gsm->dlci[i]) { | 3100 | if (gsm->dlci[i]) |
| 3101 | gsm_dlci_release(gsm->dlci[i]); | 3101 | gsm_dlci_release(gsm->dlci[i]); |
| 3102 | gsm->dlci[i] = NULL; | ||
| 3103 | } | ||
| 3104 | mutex_unlock(&gsm->mutex); | 3102 | mutex_unlock(&gsm->mutex); |
| 3105 | /* Now wipe the queues */ | 3103 | /* Now wipe the queues */ |
| 3106 | tty_ldisc_flush(gsm->tty); | 3104 | tty_ldisc_flush(gsm->tty); |
| @@ -1936,7 +1936,10 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) · 1935 unmodified lines | |||
| 1936 | skip_rx = true; | 1936 | skip_rx = true; |
| 1937 | 1937 | ||
| 1938 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { | 1938 | if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { |
| 1939 | if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) | 1939 | struct irq_data *d; |
| 1940 | |||
| 1941 | d = irq_get_irq_data(port->irq); | ||
| 1942 | if (d && irqd_is_wakeup_set(d)) | ||
| 1940 | pm_wakeup_event(tport->tty->dev, 0); | 1943 | pm_wakeup_event(tport->tty->dev, 0); |
| 1941 | if (!up->dma || handle_rx_dma(up, iir)) | 1944 | if (!up->dma || handle_rx_dma(up, iir)) |
| 1942 | status = serial8250_rx_chars(up, status); | 1945 | status = serial8250_rx_chars(up, status); |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
| 24 | #include <linux/sched/clock.h> | 24 | #include <linux/sched/clock.h> |
| 25 | #include <linux/iopoll.h> | ||
| 25 | #include <scsi/scsi_cmnd.h> | 26 | #include <scsi/scsi_cmnd.h> |
| 26 | #include <scsi/scsi_dbg.h> | 27 | #include <scsi/scsi_dbg.h> |
| 27 | #include <scsi/scsi_driver.h> | 28 | #include <scsi/scsi_driver.h> |
| @@ -2299,7 +2300,11 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) · 2271 unmodified lines | |||
| 2299 | */ | 2300 | */ |
| 2300 | static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) | 2301 | static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) |
| 2301 | { | 2302 | { |
| 2302 | return ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY; | 2303 | u32 val; |
| 2304 | int ret = read_poll_timeout(ufshcd_readl, val, val & UIC_COMMAND_READY, | ||
| 2305 | 500, UIC_CMD_TIMEOUT * 1000, false, hba, | ||
| 2306 | REG_CONTROLLER_STATUS); | ||
| 2307 | return ret == 0 ? true : false; | ||
| 2303 | } | 2308 | } |
| 2304 | 2309 | ||
| 2305 | /** | 2310 | /** |
| @@ -2392,7 +2397,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, · 86 unmodified lines | |||
| 2392 | bool completion) | 2397 | bool completion) |
| 2393 | { | 2398 | { |
| 2394 | lockdep_assert_held(&hba->uic_cmd_mutex); | 2399 | lockdep_assert_held(&hba->uic_cmd_mutex); |
| 2395 | lockdep_assert_held(hba->host->host_lock); | ||
| 2396 | 2400 | ||
| 2397 | if (!ufshcd_ready_for_uic_cmd(hba)) { | 2401 | if (!ufshcd_ready_for_uic_cmd(hba)) { |
| 2398 | dev_err(hba->dev, | 2402 | dev_err(hba->dev, |
| @@ -2419,7 +2423,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, · 20 unmodified lines | |||
| 2419 | int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) | 2423 | int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) |
| 2420 | { | 2424 | { |
| 2421 | int ret; | 2425 | int ret; |
| 2422 | unsigned long flags; | ||
| 2423 | 2426 | ||
| 2424 | if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD) | 2427 | if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD) |
| 2425 | return 0; | 2428 | return 0; |
| @@ -2428,9 +2431,7 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) · 2 unmodified lines | |||
| 2428 | mutex_lock(&hba->uic_cmd_mutex); | 2431 | mutex_lock(&hba->uic_cmd_mutex); |
| 2429 | ufshcd_add_delay_before_dme_cmd(hba); | 2432 | ufshcd_add_delay_before_dme_cmd(hba); |
| 2430 | 2433 | ||
| 2431 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 2432 | ret = __ufshcd_send_uic_cmd(hba, uic_cmd, true); | 2434 | ret = __ufshcd_send_uic_cmd(hba, uic_cmd, true); |
| 2433 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 2434 | if (!ret) | 2435 | if (!ret) |
| 2435 | ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); | 2436 | ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); |
| 2436 | 2437 | ||
| @@ -4133,8 +4134,8 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) · 1696 unmodified lines | |||
| 4133 | wmb(); | 4134 | wmb(); |
| 4134 | reenable_intr = true; | 4135 | reenable_intr = true; |
| 4135 | } | 4136 | } |
| 4136 | ret = __ufshcd_send_uic_cmd(hba, cmd, false); | ||
| 4137 | spin_unlock_irqrestore(hba->host->host_lock, flags); | 4137 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 4138 | ret = __ufshcd_send_uic_cmd(hba, cmd, false); | ||
| 4138 | if (ret) { | 4139 | if (ret) { |
| 4139 | dev_err(hba->dev, | 4140 | dev_err(hba->dev, |
| 4140 | "pwr ctrl cmd 0x%x with mode 0x%x uic error %d\n", | 4141 | "pwr ctrl cmd 0x%x with mode 0x%x uic error %d\n", |
| @@ -84,6 +84,9 @@ void ucsi_debugfs_register(struct ucsi *ucsi) · 83 unmodified lines | |||
| 84 | 84 | ||
| 85 | void ucsi_debugfs_unregister(struct ucsi *ucsi) | 85 | void ucsi_debugfs_unregister(struct ucsi *ucsi) |
| 86 | { | 86 | { |
| 87 | if (IS_ERR_OR_NULL(ucsi) || !ucsi->debugfs) | ||
| 88 | return; | ||
| 89 | |||
| 87 | debugfs_remove_recursive(ucsi->debugfs->dentry); | 90 | debugfs_remove_recursive(ucsi->debugfs->dentry); |
| 88 | kfree(ucsi->debugfs); | 91 | kfree(ucsi->debugfs); |
| 89 | } | 92 | } |
| @@ -233,7 +233,8 @@ int parent_create_sysfs_files(struct mdev_parent *parent) · 232 unmodified lines | |||
| 233 | out_err: | 233 | out_err: |
| 234 | while (--i >= 0) | 234 | while (--i >= 0) |
| 235 | mdev_type_remove(parent->types[i]); | 235 | mdev_type_remove(parent->types[i]); |
| 236 | return 0; | 236 | kset_unregister(parent->mdev_types_kset); |
| 237 | return ret; | ||
| 237 | } | 238 | } |
| 238 | 239 | ||
| 239 | static ssize_t remove_store(struct device *dev, struct device_attribute *attr, | 240 | static ssize_t remove_store(struct device *dev, struct device_attribute *attr, |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | config PDS_VFIO_PCI | 4 | config PDS_VFIO_PCI |
| 5 | tristate "VFIO support for PDS PCI devices" | 5 | tristate "VFIO support for PDS PCI devices" |
| 6 | depends on PDS_CORE | 6 | depends on PDS_CORE && PCI_IOV |
| 7 | select VFIO_PCI_CORE | 7 | select VFIO_PCI_CORE |
| 8 | help | 8 | help |
| 9 | This provides generic PCI support for PDS devices using the VFIO | 9 | This provides generic PCI support for PDS devices using the VFIO |
| @@ -162,7 +162,7 @@ static int pds_vfio_init_device(struct vfio_device *vdev) · 161 unmodified lines | |||
| 162 | pci_id = PCI_DEVID(pdev->bus->number, pdev->devfn); | 162 | pci_id = PCI_DEVID(pdev->bus->number, pdev->devfn); |
| 163 | dev_dbg(&pdev->dev, | 163 | dev_dbg(&pdev->dev, |
| 164 | "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n", | 164 | "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n", |
| 165 | __func__, pci_dev_id(pdev->physfn), pci_id, vf_id, | 165 | __func__, pci_dev_id(pci_physfn(pdev)), pci_id, vf_id, |
| 166 | pci_domain_nr(pdev->bus), pds_vfio); | 166 | pci_domain_nr(pdev->bus), pds_vfio); |
| 167 | 167 | ||
| 168 | return 0; | 168 | return 0; |
| @@ -73,6 +73,7 @@ config DUMMY_CONSOLE_ROWS · 72 unmodified lines | |||
| 73 | config FRAMEBUFFER_CONSOLE | 73 | config FRAMEBUFFER_CONSOLE |
| 74 | bool "Framebuffer Console support" | 74 | bool "Framebuffer Console support" |
| 75 | depends on FB_CORE && !UML | 75 | depends on FB_CORE && !UML |
| 76 | default DRM_FBDEV_EMULATION | ||
| 76 | select VT_HW_CONSOLE_BINDING | 77 | select VT_HW_CONSOLE_BINDING |
| 77 | select CRC32 | 78 | select CRC32 |
| 78 | select FONT_SUPPORT | 79 | select FONT_SUPPORT |
| @@ -1762,7 +1762,7 @@ config FB_COBALT · 1761 unmodified lines | |||
| 1762 | 1762 | ||
| 1763 | config FB_SH7760 | 1763 | config FB_SH7760 |
| 1764 | bool "SH7760/SH7763/SH7720/SH7721 LCDC support" | 1764 | bool "SH7760/SH7763/SH7720/SH7721 LCDC support" |
| 1765 | depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ | 1765 | depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ |
| 1766 | || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) | 1766 | || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) |
| 1767 | select FB_IOMEM_HELPERS | 1767 | select FB_IOMEM_HELPERS |
| 1768 | help | 1768 | help |
| @@ -28,7 +28,7 @@ config FIRMWARE_EDID · 27 unmodified lines | |||
| 28 | config FB_DEVICE | 28 | config FB_DEVICE |
| 29 | bool "Provide legacy /dev/fb* device" | 29 | bool "Provide legacy /dev/fb* device" |
| 30 | depends on FB_CORE | 30 | depends on FB_CORE |
| 31 | default y | 31 | default FB |
| 32 | help | 32 | help |
| 33 | Say Y here if you want the legacy /dev/fb* device file and | 33 | Say Y here if you want the legacy /dev/fb* device file and |
| 34 | interfaces within sysfs anc procfs. It is only required if you | 34 | interfaces within sysfs anc procfs. It is only required if you |
| @@ -551,7 +551,7 @@ static struct i2c_driver ds2482_driver = { · 550 unmodified lines | |||
| 551 | .driver = { | 551 | .driver = { |
| 552 | .name = "ds2482", | 552 | .name = "ds2482", |
| 553 | }, | 553 | }, |
| 554 | .probe_new = ds2482_probe, | 554 | .probe = ds2482_probe, |
| 555 | .remove = ds2482_remove, | 555 | .remove = ds2482_remove, |
| 556 | .id_table = ds2482_id, | 556 | .id_table = ds2482_id, |
| 557 | }; | 557 | }; |
| @@ -1704,7 +1704,7 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) · 1703 unmodified lines | |||
| 1704 | generic_handle_irq(irq); | 1704 | generic_handle_irq(irq); |
| 1705 | } | 1705 | } |
| 1706 | 1706 | ||
| 1707 | static int __xen_evtchn_do_upcall(void) | 1707 | int xen_evtchn_do_upcall(void) |
| 1708 | { | 1708 | { |
| 1709 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); | 1709 | struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); |
| 1710 | int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE; | 1710 | int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE; |
| @@ -1735,24 +1735,7 @@ static int __xen_evtchn_do_upcall(void) · 24 unmodified lines | |||
| 1735 | 1735 | ||
| 1736 | return ret; | 1736 | return ret; |
| 1737 | } | 1737 | } |
| 1738 | 1738 | EXPORT_SYMBOL_GPL(xen_evtchn_do_upcall); | |
| 1739 | void xen_evtchn_do_upcall(struct pt_regs *regs) | ||
| 1740 | { | ||
| 1741 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 1742 | |||
| 1743 | irq_enter(); | ||
| 1744 | |||
| 1745 | __xen_evtchn_do_upcall(); | ||
| 1746 | |||
| 1747 | irq_exit(); | ||
| 1748 | set_irq_regs(old_regs); | ||
| 1749 | } | ||
| 1750 | |||
| 1751 | int xen_hvm_evtchn_do_upcall(void) | ||
| 1752 | { | ||
| 1753 | return __xen_evtchn_do_upcall(); | ||
| 1754 | } | ||
| 1755 | EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall); | ||
| 1756 | 1739 | ||
| 1757 | /* Rebind a new event channel to an existing irq. */ | 1740 | /* Rebind a new event channel to an existing irq. */ |
| 1758 | void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) | 1741 | void rebind_evtchn_irq(evtchn_port_t evtchn, int irq) |
| @@ -64,7 +64,7 @@ static uint64_t get_callback_via(struct pci_dev *pdev) · 63 unmodified lines | |||
| 64 | 64 | ||
| 65 | static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id) | 65 | static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id) |
| 66 | { | 66 | { |
| 67 | return xen_hvm_evtchn_do_upcall(); | 67 | return xen_evtchn_do_upcall(); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | static int xen_allocate_irq(struct pci_dev *pdev) | 70 | static int xen_allocate_irq(struct pci_dev *pdev) |
| @@ -80,7 +80,7 @@ struct aio_ring { · 79 unmodified lines | |||
| 80 | struct kioctx_table { | 80 | struct kioctx_table { |
| 81 | struct rcu_head rcu; | 81 | struct rcu_head rcu; |
| 82 | unsigned nr; | 82 | unsigned nr; |
| 83 | struct kioctx __rcu *table[]; | 83 | struct kioctx __rcu *table[] __counted_by(nr); |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | struct kioctx_cpu { | 86 | struct kioctx_cpu { |
| @@ -345,10 +345,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) · 344 unmodified lines | |||
| 345 | /* there's now no turning back... the old userspace image is dead, | 345 | /* there's now no turning back... the old userspace image is dead, |
| 346 | * defunct, deceased, etc. | 346 | * defunct, deceased, etc. |
| 347 | */ | 347 | */ |
| 348 | SET_PERSONALITY(exec_params.hdr); | ||
| 348 | if (elf_check_fdpic(&exec_params.hdr)) | 349 | if (elf_check_fdpic(&exec_params.hdr)) |
| 349 | set_personality(PER_LINUX_FDPIC); | 350 | current->personality |= PER_LINUX_FDPIC; |
| 350 | else | ||
| 351 | set_personality(PER_LINUX); | ||
| 352 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) | 351 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) |
| 353 | current->personality |= READ_IMPLIES_EXEC; | 352 | current->personality |= READ_IMPLIES_EXEC; |
| 354 | 353 | ||
| @@ -31,7 +31,7 @@ config BTRFS_FS · 30 unmodified lines | |||
| 31 | continue to be mountable and usable by newer kernels. | 31 | continue to be mountable and usable by newer kernels. |
| 32 | 32 | ||
| 33 | For more information, please see the web pages at | 33 | For more information, please see the web pages at |
| 34 | http://btrfs.wiki.kernel.org. | 34 | https://btrfs.readthedocs.io |
| 35 | 35 | ||
| 36 | To compile this file system support as a module, choose M here. The | 36 | To compile this file system support as a module, choose M here. The |
| 37 | module will be called btrfs. | 37 | module will be called btrfs. |
| @@ -3028,8 +3028,16 @@ static int update_block_group_item(struct btrfs_trans_handle *trans, · 3027 unmodified lines | |||
| 3028 | btrfs_mark_buffer_dirty(leaf); | 3028 | btrfs_mark_buffer_dirty(leaf); |
| 3029 | fail: | 3029 | fail: |
| 3030 | btrfs_release_path(path); | 3030 | btrfs_release_path(path); |
| 3031 | /* We didn't update the block group item, need to revert @commit_used. */ | 3031 | /* |
| 3032 | if (ret < 0) { | 3032 | * We didn't update the block group item, need to revert commit_used |
| 3033 | * unless the block group item didn't exist yet - this is to prevent a | ||
| 3034 | * race with a concurrent insertion of the block group item, with | ||
| 3035 | * insert_block_group_item(), that happened just after we attempted to | ||
| 3036 | * update. In that case we would reset commit_used to 0 just after the | ||
| 3037 | * insertion set it to a value greater than 0 - if the block group later | ||
| 3038 | * becomes with 0 used bytes, we would incorrectly skip its update. | ||
| 3039 | */ | ||
| 3040 | if (ret < 0 && ret != -ENOENT) { | ||
| 3033 | spin_lock(&cache->lock); | 3041 | spin_lock(&cache->lock); |
| 3034 | cache->commit_used = old_commit_used; | 3042 | cache->commit_used = old_commit_used; |
| 3035 | spin_unlock(&cache->lock); | 3043 | spin_unlock(&cache->lock); |
| @@ -412,6 +412,7 @@ static void finish_one_item(struct btrfs_delayed_root *delayed_root) · 411 unmodified lines | |||
| 412 | 412 | ||
| 413 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) | 413 | static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) |
| 414 | { | 414 | { |
| 415 | struct btrfs_delayed_node *delayed_node = delayed_item->delayed_node; | ||
| 415 | struct rb_root_cached *root; | 416 | struct rb_root_cached *root; |
| 416 | struct btrfs_delayed_root *delayed_root; | 417 | struct btrfs_delayed_root *delayed_root; |
| 417 | 418 | ||
| @@ -419,18 +420,21 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) · 1 unmodified line | |||
| 419 | if (RB_EMPTY_NODE(&delayed_item->rb_node)) | 420 | if (RB_EMPTY_NODE(&delayed_item->rb_node)) |
| 420 | return; | 421 | return; |
| 421 | 422 | ||
| 422 | delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; | 423 | /* If it's in a rbtree, then we need to have delayed node locked. */ |
| 424 | lockdep_assert_held(&delayed_node->mutex); | ||
| 425 | |||
| 426 | delayed_root = delayed_node->root->fs_info->delayed_root; | ||
| 423 | 427 | ||
| 424 | BUG_ON(!delayed_root); | 428 | BUG_ON(!delayed_root); |
| 425 | 429 | ||
| 426 | if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM) | 430 | if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM) |
| 427 | root = &delayed_item->delayed_node->ins_root; | 431 | root = &delayed_node->ins_root; |
| 428 | else | 432 | else |
| 429 | root = &delayed_item->delayed_node->del_root; | 433 | root = &delayed_node->del_root; |
| 430 | 434 | ||
| 431 | rb_erase_cached(&delayed_item->rb_node, root); | 435 | rb_erase_cached(&delayed_item->rb_node, root); |
| 432 | RB_CLEAR_NODE(&delayed_item->rb_node); | 436 | RB_CLEAR_NODE(&delayed_item->rb_node); |
| 433 | delayed_item->delayed_node->count--; | 437 | delayed_node->count--; |
| 434 | 438 | ||
| 435 | finish_one_item(delayed_root); | 439 | finish_one_item(delayed_root); |
| 436 | } | 440 | } |
| @@ -1153,20 +1157,33 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr) · 716 unmodified lines | |||
| 1153 | ret = __btrfs_commit_inode_delayed_items(trans, path, | 1157 | ret = __btrfs_commit_inode_delayed_items(trans, path, |
| 1154 | curr_node); | 1158 | curr_node); |
| 1155 | if (ret) { | 1159 | if (ret) { |
| 1156 | btrfs_release_delayed_node(curr_node); | ||
| 1157 | curr_node = NULL; | ||
| 1158 | btrfs_abort_transaction(trans, ret); | 1160 | btrfs_abort_transaction(trans, ret); |
| 1159 | break; | 1161 | break; |
| 1160 | } | 1162 | } |
| 1161 | 1163 | ||
| 1162 | prev_node = curr_node; | 1164 | prev_node = curr_node; |
| 1163 | curr_node = btrfs_next_delayed_node(curr_node); | 1165 | curr_node = btrfs_next_delayed_node(curr_node); |
| 1166 | /* | ||
| 1167 | * See the comment below about releasing path before releasing | ||
| 1168 | * node. If the commit of delayed items was successful the path | ||
| 1169 | * should always be released, but in case of an error, it may | ||
| 1170 | * point to locked extent buffers (a leaf at the very least). | ||
| 1171 | */ | ||
| 1172 | ASSERT(path->nodes[0] == NULL); | ||
| 1164 | btrfs_release_delayed_node(prev_node); | 1173 | btrfs_release_delayed_node(prev_node); |
| 1165 | } | 1174 | } |
| 1166 | 1175 | ||
| 1176 | /* | ||
| 1177 | * Release the path to avoid a potential deadlock and lockdep splat when | ||
| 1178 | * releasing the delayed node, as that requires taking the delayed node's | ||
| 1179 | * mutex. If another task starts running delayed items before we take | ||
| 1180 | * the mutex, it will first lock the mutex and then it may try to lock | ||
| 1181 | * the same btree path (leaf). | ||
| 1182 | */ | ||
| 1183 | btrfs_free_path(path); | ||
| 1184 | |||
| 1167 | if (curr_node) | 1185 | if (curr_node) |
| 1168 | btrfs_release_delayed_node(curr_node); | 1186 | btrfs_release_delayed_node(curr_node); |
| 1169 | btrfs_free_path(path); | ||
| 1170 | trans->block_rsv = block_rsv; | 1187 | trans->block_rsv = block_rsv; |
| 1171 | 1188 | ||
| 1172 | return ret; | 1189 | return ret; |
| @@ -1413,7 +1430,29 @@ void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info) · 240 unmodified lines | |||
| 1413 | btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); | 1430 | btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); |
| 1414 | } | 1431 | } |
| 1415 | 1432 | ||
| 1416 | /* Will return 0 or -ENOMEM */ | 1433 | static void btrfs_release_dir_index_item_space(struct btrfs_trans_handle *trans) |
| 1434 | { | ||
| 1435 | struct btrfs_fs_info *fs_info = trans->fs_info; | ||
| 1436 | const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); | ||
| 1437 | |||
| 1438 | if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) | ||
| 1439 | return; | ||
| 1440 | |||
| 1441 | /* | ||
| 1442 | * Adding the new dir index item does not require touching another | ||
| 1443 | * leaf, so we can release 1 unit of metadata that was previously | ||
| 1444 | * reserved when starting the transaction. This applies only to | ||
| 1445 | * the case where we had a transaction start and excludes the | ||
| 1446 | * transaction join case (when replaying log trees). | ||
| 1447 | */ | ||
| 1448 | trace_btrfs_space_reservation(fs_info, "transaction", | ||
| 1449 | trans->transid, bytes, 0); | ||
| 1450 | btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); | ||
| 1451 | ASSERT(trans->bytes_reserved >= bytes); | ||
| 1452 | trans->bytes_reserved -= bytes; | ||
| 1453 | } | ||
| 1454 | |||
| 1455 | /* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected). */ | ||
| 1417 | int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, | 1456 | int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, |
| 1418 | const char *name, int name_len, | 1457 | const char *name, int name_len, |
| 1419 | struct btrfs_inode *dir, | 1458 | struct btrfs_inode *dir, |
| @@ -1455,6 +1494,27 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, · 35 unmodified lines | |||
| 1455 | 1494 | ||
| 1456 | mutex_lock(&delayed_node->mutex); | 1495 | mutex_lock(&delayed_node->mutex); |
| 1457 | 1496 | ||
| 1497 | /* | ||
| 1498 | * First attempt to insert the delayed item. This is to make the error | ||
| 1499 | * handling path simpler in case we fail (-EEXIST). There's no risk of | ||
| 1500 | * any other task coming in and running the delayed item before we do | ||
| 1501 | * the metadata space reservation below, because we are holding the | ||
| 1502 | * delayed node's mutex and that mutex must also be locked before the | ||
| 1503 | * node's delayed items can be run. | ||
| 1504 | */ | ||
| 1505 | ret = __btrfs_add_delayed_item(delayed_node, delayed_item); | ||
| 1506 | if (unlikely(ret)) { | ||
| 1507 | btrfs_err(trans->fs_info, | ||
| 1508 | "error adding delayed dir index item, name: %.*s, index: %llu, root: %llu, dir: %llu, dir->index_cnt: %llu, delayed_node->index_cnt: %llu, error: %d", | ||
| 1509 | name_len, name, index, btrfs_root_id(delayed_node->root), | ||
| 1510 | delayed_node->inode_id, dir->index_cnt, | ||
| 1511 | delayed_node->index_cnt, ret); | ||
| 1512 | btrfs_release_delayed_item(delayed_item); | ||
| 1513 | btrfs_release_dir_index_item_space(trans); | ||
| 1514 | mutex_unlock(&delayed_node->mutex); | ||
| 1515 | goto release_node; | ||
| 1516 | } | ||
| 1517 | |||
| 1458 | if (delayed_node->index_item_leaves == 0 || | 1518 | if (delayed_node->index_item_leaves == 0 || |
| 1459 | delayed_node->curr_index_batch_size + data_len > leaf_data_size) { | 1519 | delayed_node->curr_index_batch_size + data_len > leaf_data_size) { |
| 1460 | delayed_node->curr_index_batch_size = data_len; | 1520 | delayed_node->curr_index_batch_size = data_len; |
| @@ -1472,36 +1532,14 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, · 11 unmodified lines | |||
| 1472 | * impossible. | 1532 | * impossible. |
| 1473 | */ | 1533 | */ |
| 1474 | if (WARN_ON(ret)) { | 1534 | if (WARN_ON(ret)) { |
| 1475 | mutex_unlock(&delayed_node->mutex); | ||
| 1476 | btrfs_release_delayed_item(delayed_item); | 1535 | btrfs_release_delayed_item(delayed_item); |
| 1536 | mutex_unlock(&delayed_node->mutex); | ||
| 1477 | goto release_node; | 1537 | goto release_node; |
| 1478 | } | 1538 | } |
| 1479 | 1539 | ||
| 1480 | delayed_node->index_item_leaves++; | 1540 | delayed_node->index_item_leaves++; |
| 1481 | } else if (!test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) { | 1541 | } else { |
| 1482 | const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); | 1542 | btrfs_release_dir_index_item_space(trans); |
| 1483 | |||
| 1484 | /* | ||
| 1485 | * Adding the new dir index item does not require touching another | ||
| 1486 | * leaf, so we can release 1 unit of metadata that was previously | ||
| 1487 | * reserved when starting the transaction. This applies only to | ||
| 1488 | * the case where we had a transaction start and excludes the | ||
| 1489 | * transaction join case (when replaying log trees). | ||
| 1490 | */ | ||
| 1491 | trace_btrfs_space_reservation(fs_info, "transaction", | ||
| 1492 | trans->transid, bytes, 0); | ||
| 1493 | btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); | ||
| 1494 | ASSERT(trans->bytes_reserved >= bytes); | ||
| 1495 | trans->bytes_reserved -= bytes; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | ret = __btrfs_add_delayed_item(delayed_node, delayed_item); | ||
| 1499 | if (unlikely(ret)) { | ||
| 1500 | btrfs_err(trans->fs_info, | ||
| 1501 | "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", | ||
| 1502 | name_len, name, delayed_node->root->root_key.objectid, | ||
| 1503 | delayed_node->inode_id, ret); | ||
| 1504 | BUG(); | ||
| 1505 | } | 1543 | } |
| 1506 | mutex_unlock(&delayed_node->mutex); | 1544 | mutex_unlock(&delayed_node->mutex); |
| 1507 | 1545 | ||
| @@ -103,24 +103,17 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans) · 102 unmodified lines | |||
| 103 | * Transfer bytes to our delayed refs rsv. | 103 | * Transfer bytes to our delayed refs rsv. |
| 104 | * | 104 | * |
| 105 | * @fs_info: the filesystem | 105 | * @fs_info: the filesystem |
| 106 | * @src: source block rsv to transfer from | ||
| 107 | * @num_bytes: number of bytes to transfer | 106 | * @num_bytes: number of bytes to transfer |
| 108 | * | 107 | * |
| 109 | * This transfers up to the num_bytes amount from the src rsv to the | 108 | * This transfers up to the num_bytes amount, previously reserved, to the |
| 110 | * delayed_refs_rsv. Any extra bytes are returned to the space info. | 109 | * delayed_refs_rsv. Any extra bytes are returned to the space info. |
| 111 | */ | 110 | */ |
| 112 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, | 111 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, |
| 113 | struct btrfs_block_rsv *src, | ||
| 114 | u64 num_bytes) | 112 | u64 num_bytes) |
| 115 | { | 113 | { |
| 116 | struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; | 114 | struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv; |
| 117 | u64 to_free = 0; | 115 | u64 to_free = 0; |
| 118 | 116 | ||
| 119 | spin_lock(&src->lock); | ||
| 120 | src->reserved -= num_bytes; | ||
| 121 | src->size -= num_bytes; | ||
| 122 | spin_unlock(&src->lock); | ||
| 123 | |||
| 124 | spin_lock(&delayed_refs_rsv->lock); | 117 | spin_lock(&delayed_refs_rsv->lock); |
| 125 | if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { | 118 | if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) { |
| 126 | u64 delta = delayed_refs_rsv->size - | 119 | u64 delta = delayed_refs_rsv->size - |
| @@ -163,6 +156,8 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, · 36 unmodified lines | |||
| 163 | struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv; | 156 | struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv; |
| 164 | u64 limit = btrfs_calc_delayed_ref_bytes(fs_info, 1); | 157 | u64 limit = btrfs_calc_delayed_ref_bytes(fs_info, 1); |
| 165 | u64 num_bytes = 0; | 158 | u64 num_bytes = 0; |
| 159 | u64 refilled_bytes; | ||
| 160 | u64 to_free; | ||
| 166 | int ret = -ENOSPC; | 161 | int ret = -ENOSPC; |
| 167 | 162 | ||
| 168 | spin_lock(&block_rsv->lock); | 163 | spin_lock(&block_rsv->lock); |
| @@ -178,9 +173,38 @@ int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, · 9 unmodified lines | |||
| 178 | ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, num_bytes, flush); | 173 | ret = btrfs_reserve_metadata_bytes(fs_info, block_rsv, num_bytes, flush); |
| 179 | if (ret) | 174 | if (ret) |
| 180 | return ret; | 175 | return ret; |
| 181 | btrfs_block_rsv_add_bytes(block_rsv, num_bytes, false); | 176 | |
| 182 | trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", | 177 | /* |
| 183 | 0, num_bytes, 1); | 178 | * We may have raced with someone else, so check again if we the block |
| 179 | * reserve is still not full and release any excess space. | ||
| 180 | */ | ||
| 181 | spin_lock(&block_rsv->lock); | ||
| 182 | if (block_rsv->reserved < block_rsv->size) { | ||
| 183 | u64 needed = block_rsv->size - block_rsv->reserved; | ||
| 184 | |||
| 185 | if (num_bytes >= needed) { | ||
| 186 | block_rsv->reserved += needed; | ||
| 187 | block_rsv->full = true; | ||
| 188 | to_free = num_bytes - needed; | ||
| 189 | refilled_bytes = needed; | ||
| 190 | } else { | ||
| 191 | block_rsv->reserved += num_bytes; | ||
| 192 | to_free = 0; | ||
| 193 | refilled_bytes = num_bytes; | ||
| 194 | } | ||
| 195 | } else { | ||
| 196 | to_free = num_bytes; | ||
| 197 | refilled_bytes = 0; | ||
| 198 | } | ||
| 199 | spin_unlock(&block_rsv->lock); | ||
| 200 | |||
| 201 | if (to_free > 0) | ||
| 202 | btrfs_space_info_free_bytes_may_use(fs_info, block_rsv->space_info, | ||
| 203 | to_free); | ||
| 204 | |||
| 205 | if (refilled_bytes > 0) | ||
| 206 | trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv", 0, | ||
| 207 | refilled_bytes, 1); | ||
| 184 | return 0; | 208 | return 0; |
| 185 | } | 209 | } |
| 186 | 210 | ||
| @@ -407,7 +407,6 @@ void btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans); · 406 unmodified lines | |||
| 407 | int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, | 407 | int btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info, |
| 408 | enum btrfs_reserve_flush_enum flush); | 408 | enum btrfs_reserve_flush_enum flush); |
| 409 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, | 409 | void btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info, |
| 410 | struct btrfs_block_rsv *src, | ||
| 411 | u64 num_bytes); | 410 | u64 num_bytes); |
| 412 | bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); | 411 | bool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info); |
| 413 | 412 | ||
| @@ -520,6 +520,7 @@ static bool btree_dirty_folio(struct address_space *mapping, · 519 unmodified lines | |||
| 520 | struct folio *folio) | 520 | struct folio *folio) |
| 521 | { | 521 | { |
| 522 | struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); | 522 | struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); |
| 523 | struct btrfs_subpage_info *spi = fs_info->subpage_info; | ||
| 523 | struct btrfs_subpage *subpage; | 524 | struct btrfs_subpage *subpage; |
| 524 | struct extent_buffer *eb; | 525 | struct extent_buffer *eb; |
| 525 | int cur_bit = 0; | 526 | int cur_bit = 0; |
| @@ -533,18 +534,19 @@ static bool btree_dirty_folio(struct address_space *mapping, · 7 unmodified lines | |||
| 533 | btrfs_assert_tree_write_locked(eb); | 534 | btrfs_assert_tree_write_locked(eb); |
| 534 | return filemap_dirty_folio(mapping, folio); | 535 | return filemap_dirty_folio(mapping, folio); |
| 535 | } | 536 | } |
| 537 | |||
| 538 | ASSERT(spi); | ||
| 536 | subpage = folio_get_private(folio); | 539 | subpage = folio_get_private(folio); |
| 537 | 540 | ||
| 538 | ASSERT(subpage->dirty_bitmap); | 541 | for (cur_bit = spi->dirty_offset; |
| 539 | while (cur_bit < BTRFS_SUBPAGE_BITMAP_SIZE) { | 542 | cur_bit < spi->dirty_offset + spi->bitmap_nr_bits; |
| 543 | cur_bit++) { | ||
| 540 | unsigned long flags; | 544 | unsigned long flags; |
| 541 | u64 cur; | 545 | u64 cur; |
| 542 | u16 tmp = (1 << cur_bit); | ||
| 543 | 546 | ||
| 544 | spin_lock_irqsave(&subpage->lock, flags); | 547 | spin_lock_irqsave(&subpage->lock, flags); |
| 545 | if (!(tmp & subpage->dirty_bitmap)) { | 548 | if (!test_bit(cur_bit, subpage->bitmaps)) { |
| 546 | spin_unlock_irqrestore(&subpage->lock, flags); | 549 | spin_unlock_irqrestore(&subpage->lock, flags); |
| 547 | cur_bit++; | ||
| 548 | continue; | 550 | continue; |
| 549 | } | 551 | } |
| 550 | spin_unlock_irqrestore(&subpage->lock, flags); | 552 | spin_unlock_irqrestore(&subpage->lock, flags); |
| @@ -557,7 +559,7 @@ static bool btree_dirty_folio(struct address_space *mapping, · 6 unmodified lines | |||
| 557 | btrfs_assert_tree_write_locked(eb); | 559 | btrfs_assert_tree_write_locked(eb); |
| 558 | free_extent_buffer(eb); | 560 | free_extent_buffer(eb); |
| 559 | 561 | ||
| 560 | cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits); | 562 | cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits) - 1; |
| 561 | } | 563 | } |
| 562 | return filemap_dirty_folio(mapping, folio); | 564 | return filemap_dirty_folio(mapping, folio); |
| 563 | } | 565 | } |
| @@ -1547,7 +1549,7 @@ static int transaction_kthread(void *arg) · 983 unmodified lines | |||
| 1547 | 1549 | ||
| 1548 | delta = ktime_get_seconds() - cur->start_time; | 1550 | delta = ktime_get_seconds() - cur->start_time; |
| 1549 | if (!test_and_clear_bit(BTRFS_FS_COMMIT_TRANS, &fs_info->flags) && | 1551 | if (!test_and_clear_bit(BTRFS_FS_COMMIT_TRANS, &fs_info->flags) && |
| 1550 | cur->state < TRANS_STATE_COMMIT_START && | 1552 | cur->state < TRANS_STATE_COMMIT_PREP && |
| 1551 | delta < fs_info->commit_interval) { | 1553 | delta < fs_info->commit_interval) { |
| 1552 | spin_unlock(&fs_info->trans_lock); | 1554 | spin_unlock(&fs_info->trans_lock); |
| 1553 | delay -= msecs_to_jiffies((delta - 1) * 1000); | 1555 | delay -= msecs_to_jiffies((delta - 1) * 1000); |
| @@ -2682,8 +2684,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info) · 1128 unmodified lines | |||
| 2682 | btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); | 2684 | btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters); |
| 2683 | btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered); | 2685 | btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered); |
| 2684 | btrfs_lockdep_init_map(fs_info, btrfs_ordered_extent); | 2686 | btrfs_lockdep_init_map(fs_info, btrfs_ordered_extent); |
| 2685 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start, | 2687 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_prep, |
| 2686 | BTRFS_LOCKDEP_TRANS_COMMIT_START); | 2688 | BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 2687 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked, | 2689 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked, |
| 2688 | BTRFS_LOCKDEP_TRANS_UNBLOCKED); | 2690 | BTRFS_LOCKDEP_TRANS_UNBLOCKED); |
| 2689 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_super_committed, | 2691 | btrfs_state_lockdep_init_map(fs_info, btrfs_trans_super_committed, |
| @@ -4870,7 +4872,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) · 2180 unmodified lines | |||
| 4870 | while (!list_empty(&fs_info->trans_list)) { | 4872 | while (!list_empty(&fs_info->trans_list)) { |
| 4871 | t = list_first_entry(&fs_info->trans_list, | 4873 | t = list_first_entry(&fs_info->trans_list, |
| 4872 | struct btrfs_transaction, list); | 4874 | struct btrfs_transaction, list); |
| 4873 | if (t->state >= TRANS_STATE_COMMIT_START) { | 4875 | if (t->state >= TRANS_STATE_COMMIT_PREP) { |
| 4874 | refcount_inc(&t->use_count); | 4876 | refcount_inc(&t->use_count); |
| 4875 | spin_unlock(&fs_info->trans_lock); | 4877 | spin_unlock(&fs_info->trans_lock); |
| 4876 | btrfs_wait_for_commit(fs_info, t->transid); | 4878 | btrfs_wait_for_commit(fs_info, t->transid); |
| @@ -1514,15 +1514,14 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, · 1513 unmodified lines | |||
| 1514 | btrfs_release_path(path); | 1514 | btrfs_release_path(path); |
| 1515 | 1515 | ||
| 1516 | /* now insert the actual backref */ | 1516 | /* now insert the actual backref */ |
| 1517 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 1517 | if (owner < BTRFS_FIRST_FREE_OBJECTID) |
| 1518 | BUG_ON(refs_to_add != 1); | ||
| 1519 | ret = insert_tree_block_ref(trans, path, bytenr, parent, | 1518 | ret = insert_tree_block_ref(trans, path, bytenr, parent, |
| 1520 | root_objectid); | 1519 | root_objectid); |
| 1521 | } else { | 1520 | else |
| 1522 | ret = insert_extent_data_ref(trans, path, bytenr, parent, | 1521 | ret = insert_extent_data_ref(trans, path, bytenr, parent, |
| 1523 | root_objectid, owner, offset, | 1522 | root_objectid, owner, offset, |
| 1524 | refs_to_add); | 1523 | refs_to_add); |
| 1525 | } | 1524 | |
| 1526 | if (ret) | 1525 | if (ret) |
| 1527 | btrfs_abort_transaction(trans, ret); | 1526 | btrfs_abort_transaction(trans, ret); |
| 1528 | out: | 1527 | out: |
| @@ -1656,7 +1655,10 @@ again: · 127 unmodified lines | |||
| 1656 | goto again; | 1655 | goto again; |
| 1657 | } | 1656 | } |
| 1658 | } else { | 1657 | } else { |
| 1659 | err = -EIO; | 1658 | err = -EUCLEAN; |
| 1659 | btrfs_err(fs_info, | ||
| 1660 | "missing extent item for extent %llu num_bytes %llu level %d", | ||
| 1661 | head->bytenr, head->num_bytes, extent_op->level); | ||
| 1660 | goto out; | 1662 | goto out; |
| 1661 | } | 1663 | } |
| 1662 | } | 1664 | } |
| @@ -1699,12 +1701,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, · 36 unmodified lines | |||
| 1699 | parent = ref->parent; | 1701 | parent = ref->parent; |
| 1700 | ref_root = ref->root; | 1702 | ref_root = ref->root; |
| 1701 | 1703 | ||
| 1702 | if (node->ref_mod != 1) { | 1704 | if (unlikely(node->ref_mod != 1)) { |
| 1703 | btrfs_err(trans->fs_info, | 1705 | btrfs_err(trans->fs_info, |
| 1704 | "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", | 1706 | "btree block %llu has %d references rather than 1: action %d ref_root %llu parent %llu", |
| 1705 | node->bytenr, node->ref_mod, node->action, ref_root, | 1707 | node->bytenr, node->ref_mod, node->action, ref_root, |
| 1706 | parent); | 1708 | parent); |
| 1707 | return -EIO; | 1709 | return -EUCLEAN; |
| 1708 | } | 1710 | } |
| 1709 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { | 1711 | if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { |
| 1710 | BUG_ON(!extent_op || !extent_op->update_flags); | 1712 | BUG_ON(!extent_op || !extent_op->update_flags); |
| @@ -484,10 +484,8 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio) · 483 unmodified lines | |||
| 484 | bvec->bv_offset, bvec->bv_len); | 484 | bvec->bv_offset, bvec->bv_len); |
| 485 | 485 | ||
| 486 | btrfs_finish_ordered_extent(bbio->ordered, page, start, len, !error); | 486 | btrfs_finish_ordered_extent(bbio->ordered, page, start, len, !error); |
| 487 | if (error) { | 487 | if (error) |
| 488 | btrfs_page_clear_uptodate(fs_info, page, start, len); | ||
| 489 | mapping_set_error(page->mapping, error); | 488 | mapping_set_error(page->mapping, error); |
| 490 | } | ||
| 491 | btrfs_page_clear_writeback(fs_info, page, start, len); | 489 | btrfs_page_clear_writeback(fs_info, page, start, len); |
| 492 | } | 490 | } |
| 493 | 491 | ||
| @@ -1456,8 +1454,6 @@ done: · 962 unmodified lines | |||
| 1456 | if (ret) { | 1454 | if (ret) { |
| 1457 | btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, page_start, | 1455 | btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, page_start, |
| 1458 | PAGE_SIZE, !ret); | 1456 | PAGE_SIZE, !ret); |
| 1459 | btrfs_page_clear_uptodate(btrfs_sb(inode->i_sb), page, | ||
| 1460 | page_start, PAGE_SIZE); | ||
| 1461 | mapping_set_error(page->mapping, ret); | 1457 | mapping_set_error(page->mapping, ret); |
| 1462 | } | 1458 | } |
| 1463 | unlock_page(page); | 1459 | unlock_page(page); |
| @@ -1624,8 +1620,6 @@ static void extent_buffer_write_end_io(struct btrfs_bio *bbio) · 160 unmodified lines | |||
| 1624 | struct page *page = bvec->bv_page; | 1620 | struct page *page = bvec->bv_page; |
| 1625 | u32 len = bvec->bv_len; | 1621 | u32 len = bvec->bv_len; |
| 1626 | 1622 | ||
| 1627 | if (!uptodate) | ||
| 1628 | btrfs_page_clear_uptodate(fs_info, page, start, len); | ||
| 1629 | btrfs_page_clear_writeback(fs_info, page, start, len); | 1623 | btrfs_page_clear_writeback(fs_info, page, start, len); |
| 1630 | bio_offset += len; | 1624 | bio_offset += len; |
| 1631 | } | 1625 | } |
| @@ -2201,7 +2195,6 @@ void extent_write_locked_range(struct inode *inode, struct page *locked_page, · 569 unmodified lines | |||
| 2201 | if (ret) { | 2195 | if (ret) { |
| 2202 | btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, | 2196 | btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, |
| 2203 | cur, cur_len, !ret); | 2197 | cur, cur_len, !ret); |
| 2204 | btrfs_page_clear_uptodate(fs_info, page, cur, cur_len); | ||
| 2205 | mapping_set_error(page->mapping, ret); | 2198 | mapping_set_error(page->mapping, ret); |
| 2206 | } | 2199 | } |
| 2207 | btrfs_page_unlock_writer(fs_info, page, cur, cur_len); | 2200 | btrfs_page_unlock_writer(fs_info, page, cur, cur_len); |
| @@ -4002,8 +3995,14 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv, · 1794 unmodified lines | |||
| 4002 | char *dst = (char *)dstv; | 3995 | char *dst = (char *)dstv; |
| 4003 | unsigned long i = get_eb_page_index(start); | 3996 | unsigned long i = get_eb_page_index(start); |
| 4004 | 3997 | ||
| 4005 | if (check_eb_range(eb, start, len)) | 3998 | if (check_eb_range(eb, start, len)) { |
| 3999 | /* | ||
| 4000 | * Invalid range hit, reset the memory, so callers won't get | ||
| 4001 | * some random garbage for their uninitialzed memory. | ||
| 4002 | */ | ||
| 4003 | memset(dstv, 0, len); | ||
| 4006 | return; | 4004 | return; |
| 4005 | } | ||
| 4007 | 4006 | ||
| 4008 | offset = get_eb_offset_in_page(eb, start); | 4007 | offset = get_eb_offset_in_page(eb, start); |
| 4009 | 4008 | ||
| @@ -1106,6 +1106,25 @@ void btrfs_check_nocow_unlock(struct btrfs_inode *inode) · 1105 unmodified lines | |||
| 1106 | btrfs_drew_write_unlock(&inode->root->snapshot_lock); | 1106 | btrfs_drew_write_unlock(&inode->root->snapshot_lock); |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | static void update_time_for_write(struct inode *inode) | ||
| 1110 | { | ||
| 1111 | struct timespec64 now, ctime; | ||
| 1112 | |||
| 1113 | if (IS_NOCMTIME(inode)) | ||
| 1114 | return; | ||
| 1115 | |||
| 1116 | now = current_time(inode); | ||
| 1117 | if (!timespec64_equal(&inode->i_mtime, &now)) | ||
| 1118 | inode->i_mtime = now; | ||
| 1119 | |||
| 1120 | ctime = inode_get_ctime(inode); | ||
| 1121 | if (!timespec64_equal(&ctime, &now)) | ||
| 1122 | inode_set_ctime_to_ts(inode, now); | ||
| 1123 | |||
| 1124 | if (IS_I_VERSION(inode)) | ||
| 1125 | inode_inc_iversion(inode); | ||
| 1126 | } | ||
| 1127 | |||
| 1109 | static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, | 1128 | static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, |
| 1110 | size_t count) | 1129 | size_t count) |
| 1111 | { | 1130 | { |
| @@ -1137,10 +1156,7 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, · 25 unmodified lines | |||
| 1137 | * need to start yet another transaction to update the inode as we will | 1156 | * need to start yet another transaction to update the inode as we will |
| 1138 | * update the inode when we finish writing whatever data we write. | 1157 | * update the inode when we finish writing whatever data we write. |
| 1139 | */ | 1158 | */ |
| 1140 | if (!IS_NOCMTIME(inode)) { | 1159 | update_time_for_write(inode); |
| 1141 | inode->i_mtime = inode_set_ctime_current(inode); | ||
| 1142 | inode_inc_iversion(inode); | ||
| 1143 | } | ||
| 1144 | 1160 | ||
| 1145 | start_pos = round_down(pos, fs_info->sectorsize); | 1161 | start_pos = round_down(pos, fs_info->sectorsize); |
| 1146 | oldsize = i_size_read(inode); | 1162 | oldsize = i_size_read(inode); |
| @@ -1451,8 +1467,13 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) · 304 unmodified lines | |||
| 1451 | if (iocb->ki_flags & IOCB_NOWAIT) | 1467 | if (iocb->ki_flags & IOCB_NOWAIT) |
| 1452 | ilock_flags |= BTRFS_ILOCK_TRY; | 1468 | ilock_flags |= BTRFS_ILOCK_TRY; |
| 1453 | 1469 | ||
| 1454 | /* If the write DIO is within EOF, use a shared lock */ | 1470 | /* |
| 1455 | if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode)) | 1471 | * If the write DIO is within EOF, use a shared lock and also only if |
| 1472 | * security bits will likely not be dropped by file_remove_privs() called | ||
| 1473 | * from btrfs_write_check(). Either will need to be rechecked after the | ||
| 1474 | * lock was acquired. | ||
| 1475 | */ | ||
| 1476 | if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode) && IS_NOSEC(inode)) | ||
| 1456 | ilock_flags |= BTRFS_ILOCK_SHARED; | 1477 | ilock_flags |= BTRFS_ILOCK_SHARED; |
| 1457 | 1478 | ||
| 1458 | relock: | 1479 | relock: |
| @@ -1460,6 +1481,13 @@ relock: · 1 unmodified line | |||
| 1460 | if (err < 0) | 1481 | if (err < 0) |
| 1461 | return err; | 1482 | return err; |
| 1462 | 1483 | ||
| 1484 | /* Shared lock cannot be used with security bits set. */ | ||
| 1485 | if ((ilock_flags & BTRFS_ILOCK_SHARED) && !IS_NOSEC(inode)) { | ||
| 1486 | btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); | ||
| 1487 | ilock_flags &= ~BTRFS_ILOCK_SHARED; | ||
| 1488 | goto relock; | ||
| 1489 | } | ||
| 1490 | |||
| 1463 | err = generic_write_checks(iocb, from); | 1491 | err = generic_write_checks(iocb, from); |
| 1464 | if (err <= 0) { | 1492 | if (err <= 0) { |
| 1465 | btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); | 1493 | btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); |
| @@ -1085,9 +1085,6 @@ static void submit_uncompressed_range(struct btrfs_inode *inode, · 1084 unmodified lines | |||
| 1085 | btrfs_mark_ordered_io_finished(inode, locked_page, | 1085 | btrfs_mark_ordered_io_finished(inode, locked_page, |
| 1086 | page_start, PAGE_SIZE, | 1086 | page_start, PAGE_SIZE, |
| 1087 | !ret); | 1087 | !ret); |
| 1088 | btrfs_page_clear_uptodate(inode->root->fs_info, | ||
| 1089 | locked_page, page_start, | ||
| 1090 | PAGE_SIZE); | ||
| 1091 | mapping_set_error(locked_page->mapping, ret); | 1088 | mapping_set_error(locked_page->mapping, ret); |
| 1092 | unlock_page(locked_page); | 1089 | unlock_page(locked_page); |
| 1093 | } | 1090 | } |
| @@ -2791,7 +2788,6 @@ out_page: · 1697 unmodified lines | |||
| 2791 | mapping_set_error(page->mapping, ret); | 2788 | mapping_set_error(page->mapping, ret); |
| 2792 | btrfs_mark_ordered_io_finished(inode, page, page_start, | 2789 | btrfs_mark_ordered_io_finished(inode, page, page_start, |
| 2793 | PAGE_SIZE, !ret); | 2790 | PAGE_SIZE, !ret); |
| 2794 | btrfs_page_clear_uptodate(fs_info, page, page_start, PAGE_SIZE); | ||
| 2795 | clear_page_dirty_for_io(page); | 2791 | clear_page_dirty_for_io(page); |
| 2796 | } | 2792 | } |
| 2797 | btrfs_page_clear_checked(fs_info, page, page_start, PAGE_SIZE); | 2793 | btrfs_page_clear_checked(fs_info, page, page_start, PAGE_SIZE); |
| @@ -5769,20 +5765,24 @@ out: · 2971 unmodified lines | |||
| 5769 | 5765 | ||
| 5770 | static int btrfs_get_dir_last_index(struct btrfs_inode *dir, u64 *index) | 5766 | static int btrfs_get_dir_last_index(struct btrfs_inode *dir, u64 *index) |
| 5771 | { | 5767 | { |
| 5772 | if (dir->index_cnt == (u64)-1) { | 5768 | int ret = 0; |
| 5773 | int ret; | ||
| 5774 | 5769 | ||
| 5770 | btrfs_inode_lock(dir, 0); | ||
| 5771 | if (dir->index_cnt == (u64)-1) { | ||
| 5775 | ret = btrfs_inode_delayed_dir_index_count(dir); | 5772 | ret = btrfs_inode_delayed_dir_index_count(dir); |
| 5776 | if (ret) { | 5773 | if (ret) { |
| 5777 | ret = btrfs_set_inode_index_count(dir); | 5774 | ret = btrfs_set_inode_index_count(dir); |
| 5778 | if (ret) | 5775 | if (ret) |
| 5779 | return ret; | 5776 | goto out; |
| 5780 | } | 5777 | } |
| 5781 | } | 5778 | } |
| 5782 | 5779 | ||
| 5783 | *index = dir->index_cnt; | 5780 | /* index_cnt is the index number of next new entry, so decrement it. */ |
| 5781 | *index = dir->index_cnt - 1; | ||
| 5782 | out: | ||
| 5783 | btrfs_inode_unlock(dir, 0); | ||
| 5784 | 5784 | ||
| 5785 | return 0; | 5785 | return ret; |
| 5786 | } | 5786 | } |
| 5787 | 5787 | ||
| 5788 | /* | 5788 | /* |
| @@ -5817,6 +5817,19 @@ static int btrfs_opendir(struct inode *inode, struct file *file) · 28 unmodified lines | |||
| 5817 | return 0; | 5817 | return 0; |
| 5818 | } | 5818 | } |
| 5819 | 5819 | ||
| 5820 | static loff_t btrfs_dir_llseek(struct file *file, loff_t offset, int whence) | ||
| 5821 | { | ||
| 5822 | struct btrfs_file_private *private = file->private_data; | ||
| 5823 | int ret; | ||
| 5824 | |||
| 5825 | ret = btrfs_get_dir_last_index(BTRFS_I(file_inode(file)), | ||
| 5826 | &private->last_index); | ||
| 5827 | if (ret) | ||
| 5828 | return ret; | ||
| 5829 | |||
| 5830 | return generic_file_llseek(file, offset, whence); | ||
| 5831 | } | ||
| 5832 | |||
| 5820 | struct dir_entry { | 5833 | struct dir_entry { |
| 5821 | u64 ino; | 5834 | u64 ino; |
| 5822 | u64 offset; | 5835 | u64 offset; |
| @@ -10868,7 +10881,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { · 5045 unmodified lines | |||
| 10868 | }; | 10881 | }; |
| 10869 | 10882 | ||
| 10870 | static const struct file_operations btrfs_dir_file_operations = { | 10883 | static const struct file_operations btrfs_dir_file_operations = { |
| 10871 | .llseek = generic_file_llseek, | 10884 | .llseek = btrfs_dir_llseek, |
| 10872 | .read = generic_read_dir, | 10885 | .read = generic_read_dir, |
| 10873 | .iterate_shared = btrfs_real_readdir, | 10886 | .iterate_shared = btrfs_real_readdir, |
| 10874 | .open = btrfs_opendir, | 10887 | .open = btrfs_opendir, |
| @@ -1958,6 +1958,13 @@ static int btrfs_search_path_in_tree_user(struct mnt_idmap *idmap, · 1957 unmodified lines | |||
| 1958 | goto out_put; | 1958 | goto out_put; |
| 1959 | } | 1959 | } |
| 1960 | 1960 | ||
| 1961 | /* | ||
| 1962 | * We don't need the path anymore, so release it and | ||
| 1963 | * avoid deadlocks and lockdep warnings in case | ||
| 1964 | * btrfs_iget() needs to lookup the inode from its root | ||
| 1965 | * btree and lock the same leaf. | ||
| 1966 | */ | ||
| 1967 | btrfs_release_path(path); | ||
| 1961 | temp_inode = btrfs_iget(sb, key2.objectid, root); | 1968 | temp_inode = btrfs_iget(sb, key2.objectid, root); |
| 1962 | if (IS_ERR(temp_inode)) { | 1969 | if (IS_ERR(temp_inode)) { |
| 1963 | ret = PTR_ERR(temp_inode); | 1970 | ret = PTR_ERR(temp_inode); |
| @@ -1978,7 +1985,6 @@ static int btrfs_search_path_in_tree_user(struct mnt_idmap *idmap, · 14 unmodified lines | |||
| 1978 | goto out_put; | 1985 | goto out_put; |
| 1979 | } | 1986 | } |
| 1980 | 1987 | ||
| 1981 | btrfs_release_path(path); | ||
| 1982 | key.objectid = key.offset; | 1988 | key.objectid = key.offset; |
| 1983 | key.offset = (u64)-1; | 1989 | key.offset = (u64)-1; |
| 1984 | dirid = key.objectid; | 1990 | dirid = key.objectid; |
| @@ -79,7 +79,7 @@ enum btrfs_lock_nesting { · 78 unmodified lines | |||
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | enum btrfs_lockdep_trans_states { | 81 | enum btrfs_lockdep_trans_states { |
| 82 | BTRFS_LOCKDEP_TRANS_COMMIT_START, | 82 | BTRFS_LOCKDEP_TRANS_COMMIT_PREP, |
| 83 | BTRFS_LOCKDEP_TRANS_UNBLOCKED, | 83 | BTRFS_LOCKDEP_TRANS_UNBLOCKED, |
| 84 | BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED, | 84 | BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED, |
| 85 | BTRFS_LOCKDEP_TRANS_COMPLETED, | 85 | BTRFS_LOCKDEP_TRANS_COMPLETED, |
| @@ -639,7 +639,7 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode, · 638 unmodified lines | |||
| 639 | refcount_inc(&trans->use_count); | 639 | refcount_inc(&trans->use_count); |
| 640 | spin_unlock(&fs_info->trans_lock); | 640 | spin_unlock(&fs_info->trans_lock); |
| 641 | 641 | ||
| 642 | ASSERT(trans); | 642 | ASSERT(trans || BTRFS_FS_ERROR(fs_info)); |
| 643 | if (trans) { | 643 | if (trans) { |
| 644 | if (atomic_dec_and_test(&trans->pending_ordered)) | 644 | if (atomic_dec_and_test(&trans->pending_ordered)) |
| 645 | wake_up(&trans->pending_wait); | 645 | wake_up(&trans->pending_wait); |
| @@ -2117,7 +2117,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 2116 unmodified lines | |||
| 2117 | * calculated f_bavail. | 2117 | * calculated f_bavail. |
| 2118 | */ | 2118 | */ |
| 2119 | if (!mixed && block_rsv->space_info->full && | 2119 | if (!mixed && block_rsv->space_info->full && |
| 2120 | total_free_meta - thresh < block_rsv->size) | 2120 | (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) |
| 2121 | buf->f_bavail = 0; | 2121 | buf->f_bavail = 0; |
| 2122 | 2122 | ||
| 2123 | buf->f_type = BTRFS_SUPER_MAGIC; | 2123 | buf->f_type = BTRFS_SUPER_MAGIC; |
| @@ -2150,7 +2150,7 @@ static struct file_system_type btrfs_fs_type = { · 26 unmodified lines | |||
| 2150 | .name = "btrfs", | 2150 | .name = "btrfs", |
| 2151 | .mount = btrfs_mount, | 2151 | .mount = btrfs_mount, |
| 2152 | .kill_sb = btrfs_kill_super, | 2152 | .kill_sb = btrfs_kill_super, |
| 2153 | .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_MGTIME, | 2153 | .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA, |
| 2154 | }; | 2154 | }; |
| 2155 | 2155 | ||
| 2156 | static struct file_system_type btrfs_root_fs_type = { | 2156 | static struct file_system_type btrfs_root_fs_type = { |
| @@ -2158,8 +2158,7 @@ static struct file_system_type btrfs_root_fs_type = { · 1 unmodified line | |||
| 2158 | .name = "btrfs", | 2158 | .name = "btrfs", |
| 2159 | .mount = btrfs_mount_root, | 2159 | .mount = btrfs_mount_root, |
| 2160 | .kill_sb = btrfs_kill_super, | 2160 | .kill_sb = btrfs_kill_super, |
| 2161 | .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | | 2161 | .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_ALLOW_IDMAP, |
| 2162 | FS_ALLOW_IDMAP | FS_MGTIME, | ||
| 2163 | }; | 2162 | }; |
| 2164 | 2163 | ||
| 2165 | MODULE_ALIAS_FS("btrfs"); | 2164 | MODULE_ALIAS_FS("btrfs"); |
| @@ -56,12 +56,17 @@ static struct kmem_cache *btrfs_trans_handle_cachep; · 55 unmodified lines | |||
| 56 | * | Call btrfs_commit_transaction() on any trans handle attached to | 56 | * | Call btrfs_commit_transaction() on any trans handle attached to |
| 57 | * | transaction N | 57 | * | transaction N |
| 58 | * V | 58 | * V |
| 59 | * Transaction N [[TRANS_STATE_COMMIT_START]] | 59 | * Transaction N [[TRANS_STATE_COMMIT_PREP]] |
| 60 | * | | ||
| 61 | * | If there are simultaneous calls to btrfs_commit_transaction() one will win | ||
| 62 | * | the race and the rest will wait for the winner to commit the transaction. | ||
| 63 | * | | ||
| 64 | * | The winner will wait for previous running transaction to completely finish | ||
| 65 | * | if there is one. | ||
| 60 | * | | 66 | * | |
| 61 | * | Will wait for previous running transaction to completely finish if there | 67 | * Transaction N [[TRANS_STATE_COMMIT_START]] |
| 62 | * | is one | ||
| 63 | * | | 68 | * | |
| 64 | * | Then one of the following happes: | 69 | * | Then one of the following happens: |
| 65 | * | - Wait for all other trans handle holders to release. | 70 | * | - Wait for all other trans handle holders to release. |
| 66 | * | The btrfs_commit_transaction() caller will do the commit work. | 71 | * | The btrfs_commit_transaction() caller will do the commit work. |
| 67 | * | - Wait for current transaction to be committed by others. | 72 | * | - Wait for current transaction to be committed by others. |
| @@ -112,6 +117,7 @@ static struct kmem_cache *btrfs_trans_handle_cachep; · 44 unmodified lines | |||
| 112 | */ | 117 | */ |
| 113 | static const unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = { | 118 | static const unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = { |
| 114 | [TRANS_STATE_RUNNING] = 0U, | 119 | [TRANS_STATE_RUNNING] = 0U, |
| 120 | [TRANS_STATE_COMMIT_PREP] = 0U, | ||
| 115 | [TRANS_STATE_COMMIT_START] = (__TRANS_START | __TRANS_ATTACH), | 121 | [TRANS_STATE_COMMIT_START] = (__TRANS_START | __TRANS_ATTACH), |
| 116 | [TRANS_STATE_COMMIT_DOING] = (__TRANS_START | | 122 | [TRANS_STATE_COMMIT_DOING] = (__TRANS_START | |
| 117 | __TRANS_ATTACH | | 123 | __TRANS_ATTACH | |
| @@ -625,14 +631,14 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, · 507 unmodified lines | |||
| 625 | reloc_reserved = true; | 631 | reloc_reserved = true; |
| 626 | } | 632 | } |
| 627 | 633 | ||
| 628 | ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes, flush); | 634 | ret = btrfs_reserve_metadata_bytes(fs_info, rsv, num_bytes, flush); |
| 629 | if (ret) | 635 | if (ret) |
| 630 | goto reserve_fail; | 636 | goto reserve_fail; |
| 631 | if (delayed_refs_bytes) { | 637 | if (delayed_refs_bytes) { |
| 632 | btrfs_migrate_to_delayed_refs_rsv(fs_info, rsv, | 638 | btrfs_migrate_to_delayed_refs_rsv(fs_info, delayed_refs_bytes); |
| 633 | delayed_refs_bytes); | ||
| 634 | num_bytes -= delayed_refs_bytes; | 639 | num_bytes -= delayed_refs_bytes; |
| 635 | } | 640 | } |
| 641 | btrfs_block_rsv_add_bytes(rsv, num_bytes, true); | ||
| 636 | 642 | ||
| 637 | if (rsv->space_info->force_alloc) | 643 | if (rsv->space_info->force_alloc) |
| 638 | do_chunk_alloc = true; | 644 | do_chunk_alloc = true; |
| @@ -1982,7 +1988,7 @@ void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans) · 1343 unmodified lines | |||
| 1982 | * Wait for the current transaction commit to start and block | 1988 | * Wait for the current transaction commit to start and block |
| 1983 | * subsequent transaction joins | 1989 | * subsequent transaction joins |
| 1984 | */ | 1990 | */ |
| 1985 | btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); | 1991 | btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 1986 | wait_event(fs_info->transaction_blocked_wait, | 1992 | wait_event(fs_info->transaction_blocked_wait, |
| 1987 | cur_trans->state >= TRANS_STATE_COMMIT_START || | 1993 | cur_trans->state >= TRANS_STATE_COMMIT_START || |
| 1988 | TRANS_ABORTED(cur_trans)); | 1994 | TRANS_ABORTED(cur_trans)); |
| @@ -2129,7 +2135,7 @@ static void add_pending_snapshot(struct btrfs_trans_handle *trans) · 140 unmodified lines | |||
| 2129 | return; | 2135 | return; |
| 2130 | 2136 | ||
| 2131 | lockdep_assert_held(&trans->fs_info->trans_lock); | 2137 | lockdep_assert_held(&trans->fs_info->trans_lock); |
| 2132 | ASSERT(cur_trans->state >= TRANS_STATE_COMMIT_START); | 2138 | ASSERT(cur_trans->state >= TRANS_STATE_COMMIT_PREP); |
| 2133 | 2139 | ||
| 2134 | list_add(&trans->pending_snapshot->list, &cur_trans->pending_snapshots); | 2140 | list_add(&trans->pending_snapshot->list, &cur_trans->pending_snapshots); |
| 2135 | } | 2141 | } |
| @@ -2153,7 +2159,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 17 unmodified lines | |||
| 2153 | ktime_t interval; | 2159 | ktime_t interval; |
| 2154 | 2160 | ||
| 2155 | ASSERT(refcount_read(&trans->use_count) == 1); | 2161 | ASSERT(refcount_read(&trans->use_count) == 1); |
| 2156 | btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); | 2162 | btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 2157 | 2163 | ||
| 2158 | clear_bit(BTRFS_FS_NEED_TRANS_COMMIT, &fs_info->flags); | 2164 | clear_bit(BTRFS_FS_NEED_TRANS_COMMIT, &fs_info->flags); |
| 2159 | 2165 | ||
| @@ -2213,7 +2219,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 53 unmodified lines | |||
| 2213 | } | 2219 | } |
| 2214 | 2220 | ||
| 2215 | spin_lock(&fs_info->trans_lock); | 2221 | spin_lock(&fs_info->trans_lock); |
| 2216 | if (cur_trans->state >= TRANS_STATE_COMMIT_START) { | 2222 | if (cur_trans->state >= TRANS_STATE_COMMIT_PREP) { |
| 2217 | enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED; | 2223 | enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED; |
| 2218 | 2224 | ||
| 2219 | add_pending_snapshot(trans); | 2225 | add_pending_snapshot(trans); |
| @@ -2225,7 +2231,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 5 unmodified lines | |||
| 2225 | want_state = TRANS_STATE_SUPER_COMMITTED; | 2231 | want_state = TRANS_STATE_SUPER_COMMITTED; |
| 2226 | 2232 | ||
| 2227 | btrfs_trans_state_lockdep_release(fs_info, | 2233 | btrfs_trans_state_lockdep_release(fs_info, |
| 2228 | BTRFS_LOCKDEP_TRANS_COMMIT_START); | 2234 | BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 2229 | ret = btrfs_end_transaction(trans); | 2235 | ret = btrfs_end_transaction(trans); |
| 2230 | wait_for_commit(cur_trans, want_state); | 2236 | wait_for_commit(cur_trans, want_state); |
| 2231 | 2237 | ||
| @@ -2237,9 +2243,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 5 unmodified lines | |||
| 2237 | return ret; | 2243 | return ret; |
| 2238 | } | 2244 | } |
| 2239 | 2245 | ||
| 2240 | cur_trans->state = TRANS_STATE_COMMIT_START; | 2246 | cur_trans->state = TRANS_STATE_COMMIT_PREP; |
| 2241 | wake_up(&fs_info->transaction_blocked_wait); | 2247 | wake_up(&fs_info->transaction_blocked_wait); |
| 2242 | btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); | 2248 | btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 2243 | 2249 | ||
| 2244 | if (cur_trans->list.prev != &fs_info->trans_list) { | 2250 | if (cur_trans->list.prev != &fs_info->trans_list) { |
| 2245 | enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED; | 2251 | enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED; |
| @@ -2260,11 +2266,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 14 unmodified lines | |||
| 2260 | btrfs_put_transaction(prev_trans); | 2266 | btrfs_put_transaction(prev_trans); |
| 2261 | if (ret) | 2267 | if (ret) |
| 2262 | goto lockdep_release; | 2268 | goto lockdep_release; |
| 2263 | } else { | 2269 | spin_lock(&fs_info->trans_lock); |
| 2264 | spin_unlock(&fs_info->trans_lock); | ||
| 2265 | } | 2270 | } |
| 2266 | } else { | 2271 | } else { |
| 2267 | spin_unlock(&fs_info->trans_lock); | ||
| 2268 | /* | 2272 | /* |
| 2269 | * The previous transaction was aborted and was already removed | 2273 | * The previous transaction was aborted and was already removed |
| 2270 | * from the list of transactions at fs_info->trans_list. So we | 2274 | * from the list of transactions at fs_info->trans_list. So we |
| @@ -2272,11 +2276,16 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) · 1 unmodified line | |||
| 2272 | * corrupt state (pointing to trees with unwritten nodes/leafs). | 2276 | * corrupt state (pointing to trees with unwritten nodes/leafs). |
| 2273 | */ | 2277 | */ |
| 2274 | if (BTRFS_FS_ERROR(fs_info)) { | 2278 | if (BTRFS_FS_ERROR(fs_info)) { |
| 2279 | spin_unlock(&fs_info->trans_lock); | ||
| 2275 | ret = -EROFS; | 2280 | ret = -EROFS; |
| 2276 | goto lockdep_release; | 2281 | goto lockdep_release; |
| 2277 | } | 2282 | } |
| 2278 | } | 2283 | } |
| 2279 | 2284 | ||
| 2285 | cur_trans->state = TRANS_STATE_COMMIT_START; | ||
| 2286 | wake_up(&fs_info->transaction_blocked_wait); | ||
| 2287 | spin_unlock(&fs_info->trans_lock); | ||
| 2288 | |||
| 2280 | /* | 2289 | /* |
| 2281 | * Get the time spent on the work done by the commit thread and not | 2290 | * Get the time spent on the work done by the commit thread and not |
| 2282 | * the time spent waiting on a previous commit | 2291 | * the time spent waiting on a previous commit |
| @@ -2586,7 +2595,7 @@ lockdep_release: · 303 unmodified lines | |||
| 2586 | goto cleanup_transaction; | 2595 | goto cleanup_transaction; |
| 2587 | 2596 | ||
| 2588 | lockdep_trans_commit_start_release: | 2597 | lockdep_trans_commit_start_release: |
| 2589 | btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START); | 2598 | btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_PREP); |
| 2590 | btrfs_end_transaction(trans); | 2599 | btrfs_end_transaction(trans); |
| 2591 | return ret; | 2600 | return ret; |
| 2592 | } | 2601 | } |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | enum btrfs_trans_state { | 15 | enum btrfs_trans_state { |
| 16 | TRANS_STATE_RUNNING, | 16 | TRANS_STATE_RUNNING, |
| 17 | TRANS_STATE_COMMIT_PREP, | ||
| 17 | TRANS_STATE_COMMIT_START, | 18 | TRANS_STATE_COMMIT_START, |
| 18 | TRANS_STATE_COMMIT_DOING, | 19 | TRANS_STATE_COMMIT_DOING, |
| 19 | TRANS_STATE_UNBLOCKED, | 20 | TRANS_STATE_UNBLOCKED, |
| @@ -4722,7 +4722,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 4721 unmodified lines | |||
| 4722 | struct extent_buffer *leaf; | 4722 | struct extent_buffer *leaf; |
| 4723 | int slot; | 4723 | int slot; |
| 4724 | int ins_nr = 0; | 4724 | int ins_nr = 0; |
| 4725 | int start_slot; | 4725 | int start_slot = 0; |
| 4726 | int ret; | 4726 | int ret; |
| 4727 | 4727 | ||
| 4728 | if (!(inode->flags & BTRFS_INODE_PREALLOC)) | 4728 | if (!(inode->flags & BTRFS_INODE_PREALLOC)) |
| @@ -715,7 +715,7 @@ static struct page *btrfs_read_merkle_tree_page(struct inode *inode, · 714 unmodified lines | |||
| 715 | pgoff_t index, | 715 | pgoff_t index, |
| 716 | unsigned long num_ra_pages) | 716 | unsigned long num_ra_pages) |
| 717 | { | 717 | { |
| 718 | struct page *page; | 718 | struct folio *folio; |
| 719 | u64 off = (u64)index << PAGE_SHIFT; | 719 | u64 off = (u64)index << PAGE_SHIFT; |
| 720 | loff_t merkle_pos = merkle_file_pos(inode); | 720 | loff_t merkle_pos = merkle_file_pos(inode); |
| 721 | int ret; | 721 | int ret; |
| @@ -726,29 +726,36 @@ static struct page *btrfs_read_merkle_tree_page(struct inode *inode, · 4 unmodified lines | |||
| 726 | return ERR_PTR(-EFBIG); | 726 | return ERR_PTR(-EFBIG); |
| 727 | index += merkle_pos >> PAGE_SHIFT; | 727 | index += merkle_pos >> PAGE_SHIFT; |
| 728 | again: | 728 | again: |
| 729 | page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED); | 729 | folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0); |
| 730 | if (page) { | 730 | if (!IS_ERR(folio)) { |
| 731 | if (PageUptodate(page)) | 731 | if (folio_test_uptodate(folio)) |
| 732 | return page; | 732 | goto out; |
| 733 | 733 | ||
| 734 | lock_page(page); | 734 | folio_lock(folio); |
| 735 | /* | 735 | /* If it's not uptodate after we have the lock, we got a read error. */ |
| 736 | * We only insert uptodate pages, so !Uptodate has to be | 736 | if (!folio_test_uptodate(folio)) { |
| 737 | * an error | 737 | folio_unlock(folio); |
| 738 | */ | 738 | folio_put(folio); |
| 739 | if (!PageUptodate(page)) { | ||
| 740 | unlock_page(page); | ||
| 741 | put_page(page); | ||
| 742 | return ERR_PTR(-EIO); | 739 | return ERR_PTR(-EIO); |
| 743 | } | 740 | } |
| 744 | unlock_page(page); | 741 | folio_unlock(folio); |
| 745 | return page; | 742 | goto out; |
| 746 | } | 743 | } |
| 747 | 744 | ||
| 748 | page = __page_cache_alloc(mapping_gfp_constraint(inode->i_mapping, ~__GFP_FS)); | 745 | folio = filemap_alloc_folio(mapping_gfp_constraint(inode->i_mapping, ~__GFP_FS), |
| 749 | if (!page) | 746 | 0); |
| 747 | if (!folio) | ||
| 750 | return ERR_PTR(-ENOMEM); | 748 | return ERR_PTR(-ENOMEM); |
| 751 | 749 | ||
| 750 | ret = filemap_add_folio(inode->i_mapping, folio, index, GFP_NOFS); | ||
| 751 | if (ret) { | ||
| 752 | folio_put(folio); | ||
| 753 | /* Did someone else insert a folio here? */ | ||
| 754 | if (ret == -EEXIST) | ||
| 755 | goto again; | ||
| 756 | return ERR_PTR(ret); | ||
| 757 | } | ||
| 758 | |||
| 752 | /* | 759 | /* |
| 753 | * Merkle item keys are indexed from byte 0 in the merkle tree. | 760 | * Merkle item keys are indexed from byte 0 in the merkle tree. |
| 754 | * They have the form: | 761 | * They have the form: |
| @@ -756,28 +763,19 @@ again: · 1 unmodified line | |||
| 756 | * [ inode objectid, BTRFS_MERKLE_ITEM_KEY, offset in bytes ] | 763 | * [ inode objectid, BTRFS_MERKLE_ITEM_KEY, offset in bytes ] |
| 757 | */ | 764 | */ |
| 758 | ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY, off, | 765 | ret = read_key_bytes(BTRFS_I(inode), BTRFS_VERITY_MERKLE_ITEM_KEY, off, |
| 759 | page_address(page), PAGE_SIZE, page); | 766 | folio_address(folio), PAGE_SIZE, &folio->page); |
| 760 | if (ret < 0) { | 767 | if (ret < 0) { |
| 761 | put_page(page); | 768 | folio_put(folio); |
| 762 | return ERR_PTR(ret); | 769 | return ERR_PTR(ret); |
| 763 | } | 770 | } |
| 764 | if (ret < PAGE_SIZE) | 771 | if (ret < PAGE_SIZE) |
| 765 | memzero_page(page, ret, PAGE_SIZE - ret); | 772 | folio_zero_segment(folio, ret, PAGE_SIZE); |
| 766 | 773 | ||
| 767 | SetPageUptodate(page); | 774 | folio_mark_uptodate(folio); |
| 768 | ret = add_to_page_cache_lru(page, inode->i_mapping, index, GFP_NOFS); | 775 | folio_unlock(folio); |
| 769 | 776 | ||
| 770 | if (!ret) { | 777 | out: |
| 771 | /* Inserted and ready for fsverity */ | 778 | return folio_file_page(folio, index); |
| 772 | unlock_page(page); | ||
| 773 | } else { | ||
| 774 | put_page(page); | ||
| 775 | /* Did someone race us into inserting this page? */ | ||
| 776 | if (ret == -EEXIST) | ||
| 777 | goto again; | ||
| 778 | page = ERR_PTR(ret); | ||
| 779 | } | ||
| 780 | return page; | ||
| 781 | } | 779 | } |
| 782 | 780 | ||
| 783 | /* | 781 | /* |
| @@ -1594,7 +1594,7 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, · 1593 unmodified lines | |||
| 1594 | u64 search_start; | 1594 | u64 search_start; |
| 1595 | u64 hole_size; | 1595 | u64 hole_size; |
| 1596 | u64 max_hole_start; | 1596 | u64 max_hole_start; |
| 1597 | u64 max_hole_size; | 1597 | u64 max_hole_size = 0; |
| 1598 | u64 extent_end; | 1598 | u64 extent_end; |
| 1599 | u64 search_end = device->total_bytes; | 1599 | u64 search_end = device->total_bytes; |
| 1600 | int ret; | 1600 | int ret; |
| @@ -1602,17 +1602,16 @@ static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, · 1 unmodified line | |||
| 1602 | struct extent_buffer *l; | 1602 | struct extent_buffer *l; |
| 1603 | 1603 | ||
| 1604 | search_start = dev_extent_search_start(device); | 1604 | search_start = dev_extent_search_start(device); |
| 1605 | max_hole_start = search_start; | ||
| 1605 | 1606 | ||
| 1606 | WARN_ON(device->zone_info && | 1607 | WARN_ON(device->zone_info && |
| 1607 | !IS_ALIGNED(num_bytes, device->zone_info->zone_size)); | 1608 | !IS_ALIGNED(num_bytes, device->zone_info->zone_size)); |
| 1608 | 1609 | ||
| 1609 | path = btrfs_alloc_path(); | 1610 | path = btrfs_alloc_path(); |
| 1610 | if (!path) | 1611 | if (!path) { |
| 1611 | return -ENOMEM; | 1612 | ret = -ENOMEM; |
| 1612 | 1613 | goto out; | |
| 1613 | max_hole_start = search_start; | 1614 | } |
| 1614 | max_hole_size = 0; | ||
| 1615 | |||
| 1616 | again: | 1615 | again: |
| 1617 | if (search_start >= search_end || | 1616 | if (search_start >= search_end || |
| 1618 | test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) { | 1617 | test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) { |
| @@ -2011,7 +2011,7 @@ void folio_zero_new_buffers(struct folio *folio, size_t from, size_t to) · 2010 unmodified lines | |||
| 2011 | } | 2011 | } |
| 2012 | EXPORT_SYMBOL(folio_zero_new_buffers); | 2012 | EXPORT_SYMBOL(folio_zero_new_buffers); |
| 2013 | 2013 | ||
| 2014 | static void | 2014 | static int |
| 2015 | iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, | 2015 | iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, |
| 2016 | const struct iomap *iomap) | 2016 | const struct iomap *iomap) |
| 2017 | { | 2017 | { |
| @@ -2025,7 +2025,8 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 7 unmodified lines | |||
| 2025 | * current block, then do not map the buffer and let the caller | 2025 | * current block, then do not map the buffer and let the caller |
| 2026 | * handle it. | 2026 | * handle it. |
| 2027 | */ | 2027 | */ |
| 2028 | BUG_ON(offset >= iomap->offset + iomap->length); | 2028 | if (offset >= iomap->offset + iomap->length) |
| 2029 | return -EIO; | ||
| 2029 | 2030 | ||
| 2030 | switch (iomap->type) { | 2031 | switch (iomap->type) { |
| 2031 | case IOMAP_HOLE: | 2032 | case IOMAP_HOLE: |
| @@ -2037,7 +2038,7 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 5 unmodified lines | |||
| 2037 | if (!buffer_uptodate(bh) || | 2038 | if (!buffer_uptodate(bh) || |
| 2038 | (offset >= i_size_read(inode))) | 2039 | (offset >= i_size_read(inode))) |
| 2039 | set_buffer_new(bh); | 2040 | set_buffer_new(bh); |
| 2040 | break; | 2041 | return 0; |
| 2041 | case IOMAP_DELALLOC: | 2042 | case IOMAP_DELALLOC: |
| 2042 | if (!buffer_uptodate(bh) || | 2043 | if (!buffer_uptodate(bh) || |
| 2043 | (offset >= i_size_read(inode))) | 2044 | (offset >= i_size_read(inode))) |
| @@ -2045,7 +2046,7 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 1 unmodified line | |||
| 2045 | set_buffer_uptodate(bh); | 2046 | set_buffer_uptodate(bh); |
| 2046 | set_buffer_mapped(bh); | 2047 | set_buffer_mapped(bh); |
| 2047 | set_buffer_delay(bh); | 2048 | set_buffer_delay(bh); |
| 2048 | break; | 2049 | return 0; |
| 2049 | case IOMAP_UNWRITTEN: | 2050 | case IOMAP_UNWRITTEN: |
| 2050 | /* | 2051 | /* |
| 2051 | * For unwritten regions, we always need to ensure that regions | 2052 | * For unwritten regions, we always need to ensure that regions |
| @@ -2057,12 +2058,24 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh, · 5 unmodified lines | |||
| 2057 | fallthrough; | 2058 | fallthrough; |
| 2058 | case IOMAP_MAPPED: | 2059 | case IOMAP_MAPPED: |
| 2059 | if ((iomap->flags & IOMAP_F_NEW) || | 2060 | if ((iomap->flags & IOMAP_F_NEW) || |
| 2060 | offset >= i_size_read(inode)) | 2061 | offset >= i_size_read(inode)) { |
| 2062 | /* | ||
| 2063 | * This can happen if truncating the block device races | ||
| 2064 | * with the check in the caller as i_size updates on | ||
| 2065 | * block devices aren't synchronized by i_rwsem for | ||
| 2066 | * block devices. | ||
| 2067 | */ | ||
| 2068 | if (S_ISBLK(inode->i_mode)) | ||
| 2069 | return -EIO; | ||
| 2061 | set_buffer_new(bh); | 2070 | set_buffer_new(bh); |
| 2071 | } | ||
| 2062 | bh->b_blocknr = (iomap->addr + offset - iomap->offset) >> | 2072 | bh->b_blocknr = (iomap->addr + offset - iomap->offset) >> |
| 2063 | inode->i_blkbits; | 2073 | inode->i_blkbits; |
| 2064 | set_buffer_mapped(bh); | 2074 | set_buffer_mapped(bh); |
| 2065 | break; | 2075 | return 0; |
| 2076 | default: | ||
| 2077 | WARN_ON_ONCE(1); | ||
| 2078 | return -EIO; | ||
| 2066 | } | 2079 | } |
| 2067 | } | 2080 | } |
| 2068 | 2081 | ||
| @@ -2103,13 +2116,12 @@ int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len, · 34 unmodified lines | |||
| 2103 | clear_buffer_new(bh); | 2116 | clear_buffer_new(bh); |
| 2104 | if (!buffer_mapped(bh)) { | 2117 | if (!buffer_mapped(bh)) { |
| 2105 | WARN_ON(bh->b_size != blocksize); | 2118 | WARN_ON(bh->b_size != blocksize); |
| 2106 | if (get_block) { | 2119 | if (get_block) |
| 2107 | err = get_block(inode, block, bh, 1); | 2120 | err = get_block(inode, block, bh, 1); |
| 2108 | if (err) | 2121 | else |
| 2109 | break; | 2122 | err = iomap_to_bh(inode, block, bh, iomap); |
| 2110 | } else { | 2123 | if (err) |
| 2111 | iomap_to_bh(inode, block, bh, iomap); | 2124 | break; |
| 2112 | } | ||
| 2113 | 2125 | ||
| 2114 | if (buffer_new(bh)) { | 2126 | if (buffer_new(bh)) { |
| 2115 | clean_bdev_bh_alias(bh); | 2127 | clean_bdev_bh_alias(bh); |
| @@ -249,11 +249,9 @@ static struct inode *parse_longname(const struct inode *parent, · 248 unmodified lines | |||
| 249 | if (!dir) { | 249 | if (!dir) { |
| 250 | /* This can happen if we're not mounting cephfs on the root */ | 250 | /* This can happen if we're not mounting cephfs on the root */ |
| 251 | dir = ceph_get_inode(parent->i_sb, vino, NULL); | 251 | dir = ceph_get_inode(parent->i_sb, vino, NULL); |
| 252 | if (!dir) | 252 | if (IS_ERR(dir)) |
| 253 | dir = ERR_PTR(-ENOENT); | 253 | dout("Can't find inode %s (%s)\n", inode_number, name); |
| 254 | } | 254 | } |
| 255 | if (IS_ERR(dir)) | ||
| 256 | dout("Can't find inode %s (%s)\n", inode_number, name); | ||
| 257 | 255 | ||
| 258 | out: | 256 | out: |
| 259 | kfree(inode_number); | 257 | kfree(inode_number); |
| @@ -32,10 +32,16 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 31 unmodified lines | |||
| 32 | u64 storage_space, remaining_space, max_variable_size; | 32 | u64 storage_space, remaining_space, max_variable_size; |
| 33 | efi_status_t status; | 33 | efi_status_t status; |
| 34 | 34 | ||
| 35 | status = efivar_query_variable_info(attr, &storage_space, &remaining_space, | 35 | /* Some UEFI firmware does not implement QueryVariableInfo() */ |
| 36 | &max_variable_size); | 36 | storage_space = remaining_space = 0; |
| 37 | if (status != EFI_SUCCESS) | 37 | if (efi_rt_services_supported(EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO)) { |
| 38 | return efi_status_to_err(status); | 38 | status = efivar_query_variable_info(attr, &storage_space, |
| 39 | &remaining_space, | ||
| 40 | &max_variable_size); | ||
| 41 | if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) | ||
| 42 | pr_warn_ratelimited("query_variable_info() failed: 0x%lx\n", | ||
| 43 | status); | ||
| 44 | } | ||
| 39 | 45 | ||
| 40 | /* | 46 | /* |
| 41 | * This is not a normal filesystem, so no point in pretending it has a block | 47 | * This is not a normal filesystem, so no point in pretending it has a block |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
| 17 | #include <linux/nospec.h> | 17 | #include <linux/nospec.h> |
| 18 | #include <linux/backing-dev.h> | 18 | #include <linux/backing-dev.h> |
| 19 | #include <linux/freezer.h> | ||
| 19 | #include <trace/events/ext4.h> | 20 | #include <trace/events/ext4.h> |
| 20 | 21 | ||
| 21 | /* | 22 | /* |
| @@ -6906,6 +6907,21 @@ __acquires(bitlock) · 6884 unmodified lines | |||
| 6906 | return ret; | 6907 | return ret; |
| 6907 | } | 6908 | } |
| 6908 | 6909 | ||
| 6910 | static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, | ||
| 6911 | ext4_group_t grp) | ||
| 6912 | { | ||
| 6913 | if (grp < ext4_get_groups_count(sb)) | ||
| 6914 | return EXT4_CLUSTERS_PER_GROUP(sb) - 1; | ||
| 6915 | return (ext4_blocks_count(EXT4_SB(sb)->s_es) - | ||
| 6916 | ext4_group_first_block_no(sb, grp) - 1) >> | ||
| 6917 | EXT4_CLUSTER_BITS(sb); | ||
| 6918 | } | ||
| 6919 | |||
| 6920 | static bool ext4_trim_interrupted(void) | ||
| 6921 | { | ||
| 6922 | return fatal_signal_pending(current) || freezing(current); | ||
| 6923 | } | ||
| 6924 | |||
| 6909 | static int ext4_try_to_trim_range(struct super_block *sb, | 6925 | static int ext4_try_to_trim_range(struct super_block *sb, |
| 6910 | struct ext4_buddy *e4b, ext4_grpblk_t start, | 6926 | struct ext4_buddy *e4b, ext4_grpblk_t start, |
| 6911 | ext4_grpblk_t max, ext4_grpblk_t minblocks) | 6927 | ext4_grpblk_t max, ext4_grpblk_t minblocks) |
| @@ -6913,9 +6929,12 @@ __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) · 1 unmodified line | |||
| 6913 | __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) | 6929 | __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) |
| 6914 | { | 6930 | { |
| 6915 | ext4_grpblk_t next, count, free_count; | 6931 | ext4_grpblk_t next, count, free_count; |
| 6932 | bool set_trimmed = false; | ||
| 6916 | void *bitmap; | 6933 | void *bitmap; |
| 6917 | 6934 | ||
| 6918 | bitmap = e4b->bd_bitmap; | 6935 | bitmap = e4b->bd_bitmap; |
| 6936 | if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) | ||
| 6937 | set_trimmed = true; | ||
| 6919 | start = max(e4b->bd_info->bb_first_free, start); | 6938 | start = max(e4b->bd_info->bb_first_free, start); |
| 6920 | count = 0; | 6939 | count = 0; |
| 6921 | free_count = 0; | 6940 | free_count = 0; |
| @@ -6930,16 +6949,14 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 8 unmodified lines | |||
| 6930 | int ret = ext4_trim_extent(sb, start, next - start, e4b); | 6949 | int ret = ext4_trim_extent(sb, start, next - start, e4b); |
| 6931 | 6950 | ||
| 6932 | if (ret && ret != -EOPNOTSUPP) | 6951 | if (ret && ret != -EOPNOTSUPP) |
| 6933 | break; | 6952 | return count; |
| 6934 | count += next - start; | 6953 | count += next - start; |
| 6935 | } | 6954 | } |
| 6936 | free_count += next - start; | 6955 | free_count += next - start; |
| 6937 | start = next + 1; | 6956 | start = next + 1; |
| 6938 | 6957 | ||
| 6939 | if (fatal_signal_pending(current)) { | 6958 | if (ext4_trim_interrupted()) |
| 6940 | count = -ERESTARTSYS; | 6959 | return count; |
| 6941 | break; | ||
| 6942 | } | ||
| 6943 | 6960 | ||
| 6944 | if (need_resched()) { | 6961 | if (need_resched()) { |
| 6945 | ext4_unlock_group(sb, e4b->bd_group); | 6962 | ext4_unlock_group(sb, e4b->bd_group); |
| @@ -6951,6 +6968,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 5 unmodified lines | |||
| 6951 | break; | 6968 | break; |
| 6952 | } | 6969 | } |
| 6953 | 6970 | ||
| 6971 | if (set_trimmed) | ||
| 6972 | EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); | ||
| 6973 | |||
| 6954 | return count; | 6974 | return count; |
| 6955 | } | 6975 | } |
| 6956 | 6976 | ||
| @@ -6961,7 +6981,6 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 4 unmodified lines | |||
| 6961 | * @start: first group block to examine | 6981 | * @start: first group block to examine |
| 6962 | * @max: last group block to examine | 6982 | * @max: last group block to examine |
| 6963 | * @minblocks: minimum extent block count | 6983 | * @minblocks: minimum extent block count |
| 6964 | * @set_trimmed: set the trimmed flag if at least one block is trimmed | ||
| 6965 | * | 6984 | * |
| 6966 | * ext4_trim_all_free walks through group's block bitmap searching for free | 6985 | * ext4_trim_all_free walks through group's block bitmap searching for free |
| 6967 | * extents. When the free extent is found, mark it as used in group buddy | 6986 | * extents. When the free extent is found, mark it as used in group buddy |
| @@ -6971,7 +6990,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 3 unmodified lines | |||
| 6971 | static ext4_grpblk_t | 6990 | static ext4_grpblk_t |
| 6972 | ext4_trim_all_free(struct super_block *sb, ext4_group_t group, | 6991 | ext4_trim_all_free(struct super_block *sb, ext4_group_t group, |
| 6973 | ext4_grpblk_t start, ext4_grpblk_t max, | 6992 | ext4_grpblk_t start, ext4_grpblk_t max, |
| 6974 | ext4_grpblk_t minblocks, bool set_trimmed) | 6993 | ext4_grpblk_t minblocks) |
| 6975 | { | 6994 | { |
| 6976 | struct ext4_buddy e4b; | 6995 | struct ext4_buddy e4b; |
| 6977 | int ret; | 6996 | int ret; |
| @@ -6988,13 +7007,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, · 10 unmodified lines | |||
| 6988 | ext4_lock_group(sb, group); | 7007 | ext4_lock_group(sb, group); |
| 6989 | 7008 | ||
| 6990 | if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || | 7009 | if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || |
| 6991 | minblocks < EXT4_SB(sb)->s_last_trim_minblks) { | 7010 | minblocks < EXT4_SB(sb)->s_last_trim_minblks) |
| 6992 | ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); | 7011 | ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); |
| 6993 | if (ret >= 0 && set_trimmed) | 7012 | else |
| 6994 | EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); | ||
| 6995 | } else { | ||
| 6996 | ret = 0; | 7013 | ret = 0; |
| 6997 | } | ||
| 6998 | 7014 | ||
| 6999 | ext4_unlock_group(sb, group); | 7015 | ext4_unlock_group(sb, group); |
| 7000 | ext4_mb_unload_buddy(&e4b); | 7016 | ext4_mb_unload_buddy(&e4b); |
| @@ -7027,7 +7043,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 26 unmodified lines | |||
| 7027 | ext4_fsblk_t first_data_blk = | 7043 | ext4_fsblk_t first_data_blk = |
| 7028 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); | 7044 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); |
| 7029 | ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); | 7045 | ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); |
| 7030 | bool whole_group, eof = false; | ||
| 7031 | int ret = 0; | 7046 | int ret = 0; |
| 7032 | 7047 | ||
| 7033 | start = range->start >> sb->s_blocksize_bits; | 7048 | start = range->start >> sb->s_blocksize_bits; |
| @@ -7046,10 +7061,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 12 unmodified lines | |||
| 7046 | if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) | 7061 | if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) |
| 7047 | goto out; | 7062 | goto out; |
| 7048 | } | 7063 | } |
| 7049 | if (end >= max_blks - 1) { | 7064 | if (end >= max_blks - 1) |
| 7050 | end = max_blks - 1; | 7065 | end = max_blks - 1; |
| 7051 | eof = true; | ||
| 7052 | } | ||
| 7053 | if (end <= first_data_blk) | 7066 | if (end <= first_data_blk) |
| 7054 | goto out; | 7067 | goto out; |
| 7055 | if (start < first_data_blk) | 7068 | if (start < first_data_blk) |
| @@ -7063,9 +7076,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 7 unmodified lines | |||
| 7063 | 7076 | ||
| 7064 | /* end now represents the last cluster to discard in this group */ | 7077 | /* end now represents the last cluster to discard in this group */ |
| 7065 | end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; | 7078 | end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; |
| 7066 | whole_group = true; | ||
| 7067 | 7079 | ||
| 7068 | for (group = first_group; group <= last_group; group++) { | 7080 | for (group = first_group; group <= last_group; group++) { |
| 7081 | if (ext4_trim_interrupted()) | ||
| 7082 | break; | ||
| 7069 | grp = ext4_get_group_info(sb, group); | 7083 | grp = ext4_get_group_info(sb, group); |
| 7070 | if (!grp) | 7084 | if (!grp) |
| 7071 | continue; | 7085 | continue; |
| @@ -7082,13 +7096,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 10 unmodified lines | |||
| 7082 | * change it for the last group, note that last_cluster is | 7096 | * change it for the last group, note that last_cluster is |
| 7083 | * already computed earlier by ext4_get_group_no_and_offset() | 7097 | * already computed earlier by ext4_get_group_no_and_offset() |
| 7084 | */ | 7098 | */ |
| 7085 | if (group == last_group) { | 7099 | if (group == last_group) |
| 7086 | end = last_cluster; | 7100 | end = last_cluster; |
| 7087 | whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; | ||
| 7088 | } | ||
| 7089 | if (grp->bb_free >= minlen) { | 7101 | if (grp->bb_free >= minlen) { |
| 7090 | cnt = ext4_trim_all_free(sb, group, first_cluster, | 7102 | cnt = ext4_trim_all_free(sb, group, first_cluster, |
| 7091 | end, minlen, whole_group); | 7103 | end, minlen); |
| 7092 | if (cnt < 0) { | 7104 | if (cnt < 0) { |
| 7093 | ret = cnt; | 7105 | ret = cnt; |
| 7094 | break; | 7106 | break; |
| @@ -343,17 +343,17 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, · 342 unmodified lines | |||
| 343 | struct buffer_head *bh) | 343 | struct buffer_head *bh) |
| 344 | { | 344 | { |
| 345 | struct ext4_dir_entry_tail *t; | 345 | struct ext4_dir_entry_tail *t; |
| 346 | int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); | ||
| 346 | 347 | ||
| 347 | #ifdef PARANOID | 348 | #ifdef PARANOID |
| 348 | struct ext4_dir_entry *d, *top; | 349 | struct ext4_dir_entry *d, *top; |
| 349 | 350 | ||
| 350 | d = (struct ext4_dir_entry *)bh->b_data; | 351 | d = (struct ext4_dir_entry *)bh->b_data; |
| 351 | top = (struct ext4_dir_entry *)(bh->b_data + | 352 | top = (struct ext4_dir_entry *)(bh->b_data + |
| 352 | (EXT4_BLOCK_SIZE(inode->i_sb) - | 353 | (blocksize - sizeof(struct ext4_dir_entry_tail))); |
| 353 | sizeof(struct ext4_dir_entry_tail))); | 354 | while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) |
| 354 | while (d < top && d->rec_len) | ||
| 355 | d = (struct ext4_dir_entry *)(((void *)d) + | 355 | d = (struct ext4_dir_entry *)(((void *)d) + |
| 356 | le16_to_cpu(d->rec_len)); | 356 | ext4_rec_len_from_disk(d->rec_len, blocksize)); |
| 357 | 357 | ||
| 358 | if (d != top) | 358 | if (d != top) |
| 359 | return NULL; | 359 | return NULL; |
| @@ -364,7 +364,8 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, · 4 unmodified lines | |||
| 364 | #endif | 364 | #endif |
| 365 | 365 | ||
| 366 | if (t->det_reserved_zero1 || | 366 | if (t->det_reserved_zero1 || |
| 367 | le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || | 367 | (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != |
| 368 | sizeof(struct ext4_dir_entry_tail)) || | ||
| 368 | t->det_reserved_zero2 || | 369 | t->det_reserved_zero2 || |
| 369 | t->det_reserved_ft != EXT4_FT_DIR_CSUM) | 370 | t->det_reserved_ft != EXT4_FT_DIR_CSUM) |
| 370 | return NULL; | 371 | return NULL; |
| @@ -445,13 +446,14 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode, · 74 unmodified lines | |||
| 445 | struct ext4_dir_entry *dp; | 446 | struct ext4_dir_entry *dp; |
| 446 | struct dx_root_info *root; | 447 | struct dx_root_info *root; |
| 447 | int count_offset; | 448 | int count_offset; |
| 449 | int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); | ||
| 450 | unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); | ||
| 448 | 451 | ||
| 449 | if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) | 452 | if (rlen == blocksize) |
| 450 | count_offset = 8; | 453 | count_offset = 8; |
| 451 | else if (le16_to_cpu(dirent->rec_len) == 12) { | 454 | else if (rlen == 12) { |
| 452 | dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); | 455 | dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); |
| 453 | if (le16_to_cpu(dp->rec_len) != | 456 | if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) |
| 454 | EXT4_BLOCK_SIZE(inode->i_sb) - 12) | ||
| 455 | return NULL; | 457 | return NULL; |
| 456 | root = (struct dx_root_info *)(((void *)dp + 12)); | 458 | root = (struct dx_root_info *)(((void *)dp + 12)); |
| 457 | if (root->reserved_zero || | 459 | if (root->reserved_zero || |
| @@ -1315,6 +1317,7 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, · 857 unmodified lines | |||
| 1315 | unsigned int buflen = bh->b_size; | 1317 | unsigned int buflen = bh->b_size; |
| 1316 | char *base = bh->b_data; | 1318 | char *base = bh->b_data; |
| 1317 | struct dx_hash_info h = *hinfo; | 1319 | struct dx_hash_info h = *hinfo; |
| 1320 | int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); | ||
| 1318 | 1321 | ||
| 1319 | if (ext4_has_metadata_csum(dir->i_sb)) | 1322 | if (ext4_has_metadata_csum(dir->i_sb)) |
| 1320 | buflen -= sizeof(struct ext4_dir_entry_tail); | 1323 | buflen -= sizeof(struct ext4_dir_entry_tail); |
| @@ -1335,11 +1338,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, · 14 unmodified lines | |||
| 1335 | map_tail--; | 1338 | map_tail--; |
| 1336 | map_tail->hash = h.hash; | 1339 | map_tail->hash = h.hash; |
| 1337 | map_tail->offs = ((char *) de - base)>>2; | 1340 | map_tail->offs = ((char *) de - base)>>2; |
| 1338 | map_tail->size = le16_to_cpu(de->rec_len); | 1341 | map_tail->size = ext4_rec_len_from_disk(de->rec_len, |
| 1342 | blocksize); | ||
| 1339 | count++; | 1343 | count++; |
| 1340 | cond_resched(); | 1344 | cond_resched(); |
| 1341 | } | 1345 | } |
| 1342 | de = ext4_next_entry(de, dir->i_sb->s_blocksize); | 1346 | de = ext4_next_entry(de, blocksize); |
| 1343 | } | 1347 | } |
| 1344 | return count; | 1348 | return count; |
| 1345 | } | 1349 | } |
| @@ -7314,7 +7314,7 @@ static struct file_system_type ext4_fs_type = { · 7313 unmodified lines | |||
| 7314 | .init_fs_context = ext4_init_fs_context, | 7314 | .init_fs_context = ext4_init_fs_context, |
| 7315 | .parameters = ext4_param_specs, | 7315 | .parameters = ext4_param_specs, |
| 7316 | .kill_sb = ext4_kill_sb, | 7316 | .kill_sb = ext4_kill_sb, |
| 7317 | .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP | FS_MGTIME, | 7317 | .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP, |
| 7318 | }; | 7318 | }; |
| 7319 | MODULE_ALIAS_FS("ext4"); | 7319 | MODULE_ALIAS_FS("ext4"); |
| 7320 | 7320 | ||
| @@ -1535,10 +1535,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb, · 1534 unmodified lines | |||
| 1535 | 1535 | ||
| 1536 | if (wbc->pages_skipped) { | 1536 | if (wbc->pages_skipped) { |
| 1537 | /* | 1537 | /* |
| 1538 | * writeback is not making progress due to locked | 1538 | * Writeback is not making progress due to locked buffers. |
| 1539 | * buffers. Skip this inode for now. | 1539 | * Skip this inode for now. Although having skipped pages |
| 1540 | * is odd for clean inodes, it can happen for some | ||
| 1541 | * filesystems so handle that gracefully. | ||
| 1540 | */ | 1542 | */ |
| 1541 | redirty_tail_locked(inode, wb); | 1543 | if (inode->i_state & I_DIRTY_ALL) |
| 1544 | redirty_tail_locked(inode, wb); | ||
| 1545 | else | ||
| 1546 | inode_cgwb_move_to_attached(inode, wb); | ||
| 1542 | return; | 1547 | return; |
| 1543 | } | 1548 | } |
| 1544 | 1549 | ||
| @@ -2010,7 +2010,9 @@ static long gfs2_scan_glock_lru(int nr) · 2009 unmodified lines | |||
| 2010 | if (!test_bit(GLF_LOCK, &gl->gl_flags)) { | 2010 | if (!test_bit(GLF_LOCK, &gl->gl_flags)) { |
| 2011 | if (!spin_trylock(&gl->gl_lockref.lock)) | 2011 | if (!spin_trylock(&gl->gl_lockref.lock)) |
| 2012 | continue; | 2012 | continue; |
| 2013 | if (!gl->gl_lockref.count) { | 2013 | if (gl->gl_lockref.count <= 1 && |
| 2014 | (gl->gl_state == LM_ST_UNLOCKED || | ||
| 2015 | demote_ok(gl))) { | ||
| 2014 | list_move(&gl->gl_lru, &dispose); | 2016 | list_move(&gl->gl_lru, &dispose); |
| 2015 | atomic_dec(&lru_count); | 2017 | atomic_dec(&lru_count); |
| 2016 | freed++; | 2018 | freed++; |
| @@ -567,15 +567,16 @@ static void freeze_go_callback(struct gfs2_glock *gl, bool remote) · 566 unmodified lines | |||
| 567 | struct super_block *sb = sdp->sd_vfs; | 567 | struct super_block *sb = sdp->sd_vfs; |
| 568 | 568 | ||
| 569 | if (!remote || | 569 | if (!remote || |
| 570 | gl->gl_state != LM_ST_SHARED || | 570 | (gl->gl_state != LM_ST_SHARED && |
| 571 | gl->gl_state != LM_ST_UNLOCKED) || | ||
| 571 | gl->gl_demote_state != LM_ST_UNLOCKED) | 572 | gl->gl_demote_state != LM_ST_UNLOCKED) |
| 572 | return; | 573 | return; |
| 573 | 574 | ||
| 574 | /* | 575 | /* |
| 575 | * Try to get an active super block reference to prevent racing with | 576 | * Try to get an active super block reference to prevent racing with |
| 576 | * unmount (see trylock_super()). But note that unmount isn't the only | 577 | * unmount (see super_trylock_shared()). But note that unmount isn't |
| 577 | * place where a write lock on s_umount is taken, and we can fail here | 578 | * the only place where a write lock on s_umount is taken, and we can |
| 578 | * because of things like remount as well. | 579 | * fail here because of things like remount as well. |
| 579 | */ | 580 | */ |
| 580 | if (down_read_trylock(&sb->s_umount)) { | 581 | if (down_read_trylock(&sb->s_umount)) { |
| 581 | atomic_inc(&sb->s_active); | 582 | atomic_inc(&sb->s_active); |
| @@ -50,7 +50,8 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip, · 49 unmodified lines | |||
| 50 | ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); | 50 | ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE); |
| 51 | if (ret) | 51 | if (ret) |
| 52 | return ret; | 52 | return ret; |
| 53 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 53 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON && |
| 54 | sdp->sd_args.ar_quota != GFS2_QUOTA_QUIET) | ||
| 54 | return 0; | 55 | return 0; |
| 55 | ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid, ap); | 56 | ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid, ap); |
| 56 | if (ret) | 57 | if (ret) |
| @@ -2102,52 +2102,10 @@ int file_remove_privs(struct file *file) · 2101 unmodified lines | |||
| 2102 | } | 2102 | } |
| 2103 | EXPORT_SYMBOL(file_remove_privs); | 2103 | EXPORT_SYMBOL(file_remove_privs); |
| 2104 | 2104 | ||
| 2105 | /** | ||
| 2106 | * current_mgtime - Return FS time (possibly fine-grained) | ||
| 2107 | * @inode: inode. | ||
| 2108 | * | ||
| 2109 | * Return the current time truncated to the time granularity supported by | ||
| 2110 | * the fs, as suitable for a ctime/mtime change. If the ctime is flagged | ||
| 2111 | * as having been QUERIED, get a fine-grained timestamp. | ||
| 2112 | */ | ||
| 2113 | struct timespec64 current_mgtime(struct inode *inode) | ||
| 2114 | { | ||
| 2115 | struct timespec64 now, ctime; | ||
| 2116 | atomic_long_t *pnsec = (atomic_long_t *)&inode->__i_ctime.tv_nsec; | ||
| 2117 | long nsec = atomic_long_read(pnsec); | ||
| 2118 | |||
| 2119 | if (nsec & I_CTIME_QUERIED) { | ||
| 2120 | ktime_get_real_ts64(&now); | ||
| 2121 | return timestamp_truncate(now, inode); | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | ktime_get_coarse_real_ts64(&now); | ||
| 2125 | now = timestamp_truncate(now, inode); | ||
| 2126 | |||
| 2127 | /* | ||
| 2128 | * If we've recently fetched a fine-grained timestamp | ||
| 2129 | * then the coarse-grained one may still be earlier than the | ||
| 2130 | * existing ctime. Just keep the existing value if so. | ||
| 2131 | */ | ||
| 2132 | ctime = inode_get_ctime(inode); | ||
| 2133 | if (timespec64_compare(&ctime, &now) > 0) | ||
| 2134 | now = ctime; | ||
| 2135 | |||
| 2136 | return now; | ||
| 2137 | } | ||
| 2138 | EXPORT_SYMBOL(current_mgtime); | ||
| 2139 | |||
| 2140 | static struct timespec64 current_ctime(struct inode *inode) | ||
| 2141 | { | ||
| 2142 | if (is_mgtime(inode)) | ||
| 2143 | return current_mgtime(inode); | ||
| 2144 | return current_time(inode); | ||
| 2145 | } | ||
| 2146 | |||
| 2147 | static int inode_needs_update_time(struct inode *inode) | 2105 | static int inode_needs_update_time(struct inode *inode) |
| 2148 | { | 2106 | { |
| 2149 | int sync_it = 0; | 2107 | int sync_it = 0; |
| 2150 | struct timespec64 now = current_ctime(inode); | 2108 | struct timespec64 now = current_time(inode); |
| 2151 | struct timespec64 ctime; | 2109 | struct timespec64 ctime; |
| 2152 | 2110 | ||
| 2153 | /* First try to exhaust all avenues to not sync */ | 2111 | /* First try to exhaust all avenues to not sync */ |
| @@ -2578,43 +2536,9 @@ EXPORT_SYMBOL(current_time); · 424 unmodified lines | |||
| 2578 | */ | 2536 | */ |
| 2579 | struct timespec64 inode_set_ctime_current(struct inode *inode) | 2537 | struct timespec64 inode_set_ctime_current(struct inode *inode) |
| 2580 | { | 2538 | { |
| 2581 | struct timespec64 now; | 2539 | struct timespec64 now = current_time(inode); |
| 2582 | struct timespec64 ctime; | ||
| 2583 | |||
| 2584 | ctime.tv_nsec = READ_ONCE(inode->__i_ctime.tv_nsec); | ||
| 2585 | if (!(ctime.tv_nsec & I_CTIME_QUERIED)) { | ||
| 2586 | now = current_time(inode); | ||
| 2587 | 2540 | ||
| 2588 | /* Just copy it into place if it's not multigrain */ | 2541 | inode_set_ctime(inode, now.tv_sec, now.tv_nsec); |
| 2589 | if (!is_mgtime(inode)) { | ||
| 2590 | inode_set_ctime_to_ts(inode, now); | ||
| 2591 | return now; | ||
| 2592 | } | ||
| 2593 | |||
| 2594 | /* | ||
| 2595 | * If we've recently updated with a fine-grained timestamp, | ||
| 2596 | * then the coarse-grained one may still be earlier than the | ||
| 2597 | * existing ctime. Just keep the existing value if so. | ||
| 2598 | */ | ||
| 2599 | ctime.tv_sec = inode->__i_ctime.tv_sec; | ||
| 2600 | if (timespec64_compare(&ctime, &now) > 0) | ||
| 2601 | return ctime; | ||
| 2602 | |||
| 2603 | /* | ||
| 2604 | * Ctime updates are usually protected by the inode_lock, but | ||
| 2605 | * we can still race with someone setting the QUERIED flag. | ||
| 2606 | * Try to swap the new nsec value into place. If it's changed | ||
| 2607 | * in the interim, then just go with a fine-grained timestamp. | ||
| 2608 | */ | ||
| 2609 | if (cmpxchg(&inode->__i_ctime.tv_nsec, ctime.tv_nsec, | ||
| 2610 | now.tv_nsec) != ctime.tv_nsec) | ||
| 2611 | goto fine_grained; | ||
| 2612 | inode->__i_ctime.tv_sec = now.tv_sec; | ||
| 2613 | return now; | ||
| 2614 | } | ||
| 2615 | fine_grained: | ||
| 2616 | ktime_get_real_ts64(&now); | ||
| 2617 | inode_set_ctime_to_ts(inode, timestamp_truncate(now, inode)); | ||
| 2618 | return now; | 2542 | return now; |
| 2619 | } | 2543 | } |
| 2620 | EXPORT_SYMBOL(inode_set_ctime_current); | 2544 | EXPORT_SYMBOL(inode_set_ctime_current); |
| @@ -640,11 +640,13 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos, · 639 unmodified lines | |||
| 640 | size_t poff, plen; | 640 | size_t poff, plen; |
| 641 | 641 | ||
| 642 | /* | 642 | /* |
| 643 | * If the write completely overlaps the current folio, then | 643 | * If the write or zeroing completely overlaps the current folio, then |
| 644 | * entire folio will be dirtied so there is no need for | 644 | * entire folio will be dirtied so there is no need for |
| 645 | * per-block state tracking structures to be attached to this folio. | 645 | * per-block state tracking structures to be attached to this folio. |
| 646 | * For the unshare case, we must read in the ondisk contents because we | ||
| 647 | * are not changing pagecache contents. | ||
| 646 | */ | 648 | */ |
| 647 | if (pos <= folio_pos(folio) && | 649 | if (!(iter->flags & IOMAP_UNSHARE) && pos <= folio_pos(folio) && |
| 648 | pos + len >= folio_pos(folio) + folio_size(folio)) | 650 | pos + len >= folio_pos(folio) + folio_size(folio)) |
| 649 | return 0; | 651 | return 0; |
| 650 | 652 | ||
| @@ -1047,7 +1049,7 @@ static int iomap_write_delalloc_punch(struct inode *inode, struct folio *folio, · 396 unmodified lines | |||
| 1047 | 1049 | ||
| 1048 | /* | 1050 | /* |
| 1049 | * Scan the data range passed to us for dirty page cache folios. If we find a | 1051 | * Scan the data range passed to us for dirty page cache folios. If we find a |
| 1050 | * dirty folio, punch out the preceeding range and update the offset from which | 1052 | * dirty folio, punch out the preceding range and update the offset from which |
| 1051 | * the next punch will start from. | 1053 | * the next punch will start from. |
| 1052 | * | 1054 | * |
| 1053 | * We can punch out storage reservations under clean pages because they either | 1055 | * We can punch out storage reservations under clean pages because they either |
| @@ -1261,7 +1263,6 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) · 207 unmodified lines | |||
| 1261 | const struct iomap *srcmap = iomap_iter_srcmap(iter); | 1263 | const struct iomap *srcmap = iomap_iter_srcmap(iter); |
| 1262 | loff_t pos = iter->pos; | 1264 | loff_t pos = iter->pos; |
| 1263 | loff_t length = iomap_length(iter); | 1265 | loff_t length = iomap_length(iter); |
| 1264 | long status = 0; | ||
| 1265 | loff_t written = 0; | 1266 | loff_t written = 0; |
| 1266 | 1267 | ||
| 1267 | /* don't bother with blocks that are not shared to start with */ | 1268 | /* don't bother with blocks that are not shared to start with */ |
| @@ -1272,28 +1273,33 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter) · 4 unmodified lines | |||
| 1272 | return length; | 1273 | return length; |
| 1273 | 1274 | ||
| 1274 | do { | 1275 | do { |
| 1275 | unsigned long offset = offset_in_page(pos); | ||
| 1276 | unsigned long bytes = min_t(loff_t, PAGE_SIZE - offset, length); | ||
| 1277 | struct folio *folio; | 1276 | struct folio *folio; |
| 1277 | int status; | ||
| 1278 | size_t offset; | ||
| 1279 | size_t bytes = min_t(u64, SIZE_MAX, length); | ||
| 1278 | 1280 | ||
| 1279 | status = iomap_write_begin(iter, pos, bytes, &folio); | 1281 | status = iomap_write_begin(iter, pos, bytes, &folio); |
| 1280 | if (unlikely(status)) | 1282 | if (unlikely(status)) |
| 1281 | return status; | 1283 | return status; |
| 1282 | if (iter->iomap.flags & IOMAP_F_STALE) | 1284 | if (iomap->flags & IOMAP_F_STALE) |
| 1283 | break; | 1285 | break; |
| 1284 | 1286 | ||
| 1285 | status = iomap_write_end(iter, pos, bytes, bytes, folio); | 1287 | offset = offset_in_folio(folio, pos); |
| 1286 | if (WARN_ON_ONCE(status == 0)) | 1288 | if (bytes > folio_size(folio) - offset) |
| 1289 | bytes = folio_size(folio) - offset; | ||
| 1290 | |||
| 1291 | bytes = iomap_write_end(iter, pos, bytes, bytes, folio); | ||
| 1292 | if (WARN_ON_ONCE(bytes == 0)) | ||
| 1287 | return -EIO; | 1293 | return -EIO; |
| 1288 | 1294 | ||
| 1289 | cond_resched(); | 1295 | cond_resched(); |
| 1290 | 1296 | ||
| 1291 | pos += status; | 1297 | pos += bytes; |
| 1292 | written += status; | 1298 | written += bytes; |
| 1293 | length -= status; | 1299 | length -= bytes; |
| 1294 | 1300 | ||
| 1295 | balance_dirty_pages_ratelimited(iter->inode->i_mapping); | 1301 | balance_dirty_pages_ratelimited(iter->inode->i_mapping); |
| 1296 | } while (length); | 1302 | } while (length > 0); |
| 1297 | 1303 | ||
| 1298 | return written; | 1304 | return written; |
| 1299 | } | 1305 | } |
| @@ -298,14 +298,12 @@ static int journal_finish_inode_data_buffers(journal_t *journal, · 297 unmodified lines | |||
| 298 | 298 | ||
| 299 | static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) | 299 | static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) |
| 300 | { | 300 | { |
| 301 | struct page *page = bh->b_page; | ||
| 302 | char *addr; | 301 | char *addr; |
| 303 | __u32 checksum; | 302 | __u32 checksum; |
| 304 | 303 | ||
| 305 | addr = kmap_atomic(page); | 304 | addr = kmap_local_folio(bh->b_folio, bh_offset(bh)); |
| 306 | checksum = crc32_be(crc32_sum, | 305 | checksum = crc32_be(crc32_sum, addr, bh->b_size); |
| 307 | (void *)(addr + offset_in_page(bh->b_data)), bh->b_size); | 306 | kunmap_local(addr); |
| 308 | kunmap_atomic(addr); | ||
| 309 | 307 | ||
| 310 | return checksum; | 308 | return checksum; |
| 311 | } | 309 | } |
| @@ -322,7 +320,6 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, · 10 unmodified lines | |||
| 322 | struct buffer_head *bh, __u32 sequence) | 320 | struct buffer_head *bh, __u32 sequence) |
| 323 | { | 321 | { |
| 324 | journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; | 322 | journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; |
| 325 | struct page *page = bh->b_page; | ||
| 326 | __u8 *addr; | 323 | __u8 *addr; |
| 327 | __u32 csum32; | 324 | __u32 csum32; |
| 328 | __be32 seq; | 325 | __be32 seq; |
| @@ -331,11 +328,10 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, · 2 unmodified lines | |||
| 331 | return; | 328 | return; |
| 332 | 329 | ||
| 333 | seq = cpu_to_be32(sequence); | 330 | seq = cpu_to_be32(sequence); |
| 334 | addr = kmap_atomic(page); | 331 | addr = kmap_local_folio(bh->b_folio, bh_offset(bh)); |
| 335 | csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq)); | 332 | csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq)); |
| 336 | csum32 = jbd2_chksum(j, csum32, addr + offset_in_page(bh->b_data), | 333 | csum32 = jbd2_chksum(j, csum32, addr, bh->b_size); |
| 337 | bh->b_size); | 334 | kunmap_local(addr); |
| 338 | kunmap_atomic(addr); | ||
| 339 | 335 | ||
| 340 | if (jbd2_has_feature_csum3(j)) | 336 | if (jbd2_has_feature_csum3(j)) |
| 341 | tag3->t_checksum = cpu_to_be32(csum32); | 337 | tag3->t_checksum = cpu_to_be32(csum32); |
| @@ -1601,6 +1601,8 @@ static journal_t *journal_init_common(struct block_device *bdev, · 1600 unmodified lines | |||
| 1601 | 1601 | ||
| 1602 | err_cleanup: | 1602 | err_cleanup: |
| 1603 | percpu_counter_destroy(&journal->j_checkpoint_jh_count); | 1603 | percpu_counter_destroy(&journal->j_checkpoint_jh_count); |
| 1604 | if (journal->j_chksum_driver) | ||
| 1605 | crypto_free_shash(journal->j_chksum_driver); | ||
| 1604 | kfree(journal->j_wbuf); | 1606 | kfree(journal->j_wbuf); |
| 1605 | jbd2_journal_destroy_revoke(journal); | 1607 | jbd2_journal_destroy_revoke(journal); |
| 1606 | journal_fail_superblock(journal); | 1608 | journal_fail_superblock(journal); |
| @@ -935,19 +935,15 @@ static void warn_dirty_buffer(struct buffer_head *bh) · 934 unmodified lines | |||
| 935 | /* Call t_frozen trigger and copy buffer data into jh->b_frozen_data. */ | 935 | /* Call t_frozen trigger and copy buffer data into jh->b_frozen_data. */ |
| 936 | static void jbd2_freeze_jh_data(struct journal_head *jh) | 936 | static void jbd2_freeze_jh_data(struct journal_head *jh) |
| 937 | { | 937 | { |
| 938 | struct page *page; | ||
| 939 | int offset; | ||
| 940 | char *source; | 938 | char *source; |
| 941 | struct buffer_head *bh = jh2bh(jh); | 939 | struct buffer_head *bh = jh2bh(jh); |
| 942 | 940 | ||
| 943 | J_EXPECT_JH(jh, buffer_uptodate(bh), "Possible IO failure.\n"); | 941 | J_EXPECT_JH(jh, buffer_uptodate(bh), "Possible IO failure.\n"); |
| 944 | page = bh->b_page; | 942 | source = kmap_local_folio(bh->b_folio, bh_offset(bh)); |
| 945 | offset = offset_in_page(bh->b_data); | ||
| 946 | source = kmap_atomic(page); | ||
| 947 | /* Fire data frozen trigger just before we copy the data */ | 943 | /* Fire data frozen trigger just before we copy the data */ |
| 948 | jbd2_buffer_frozen_trigger(jh, source + offset, jh->b_triggers); | 944 | jbd2_buffer_frozen_trigger(jh, source, jh->b_triggers); |
| 949 | memcpy(jh->b_frozen_data, source + offset, bh->b_size); | 945 | memcpy(jh->b_frozen_data, source, bh->b_size); |
| 950 | kunmap_atomic(source); | 946 | kunmap_local(source); |
| 951 | 947 | ||
| 952 | /* | 948 | /* |
| 953 | * Now that the frozen data is saved off, we need to store any matching | 949 | * Now that the frozen data is saved off, we need to store any matching |
| @@ -1903,6 +1903,7 @@ ssize_t direct_write_fallback(struct kiocb *iocb, struct iov_iter *iter, · 1902 unmodified lines | |||
| 1903 | * We don't know how much we wrote, so just return the number of | 1903 | * We don't know how much we wrote, so just return the number of |
| 1904 | * bytes which were direct-written | 1904 | * bytes which were direct-written |
| 1905 | */ | 1905 | */ |
| 1906 | iocb->ki_pos -= buffered_written; | ||
| 1906 | if (direct_written) | 1907 | if (direct_written) |
| 1907 | return direct_written; | 1908 | return direct_written; |
| 1908 | return err; | 1909 | return err; |
| @@ -47,12 +47,14 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq) · 46 unmodified lines | |||
| 47 | xas_for_each(&xas, folio, last_page) { | 47 | xas_for_each(&xas, folio, last_page) { |
| 48 | loff_t pg_end; | 48 | loff_t pg_end; |
| 49 | bool pg_failed = false; | 49 | bool pg_failed = false; |
| 50 | bool folio_started; | ||
| 50 | 51 | ||
| 51 | if (xas_retry(&xas, folio)) | 52 | if (xas_retry(&xas, folio)) |
| 52 | continue; | 53 | continue; |
| 53 | 54 | ||
| 54 | pg_end = folio_pos(folio) + folio_size(folio) - 1; | 55 | pg_end = folio_pos(folio) + folio_size(folio) - 1; |
| 55 | 56 | ||
| 57 | folio_started = false; | ||
| 56 | for (;;) { | 58 | for (;;) { |
| 57 | loff_t sreq_end; | 59 | loff_t sreq_end; |
| 58 | 60 | ||
| @@ -60,8 +62,10 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq) · 1 unmodified line | |||
| 60 | pg_failed = true; | 62 | pg_failed = true; |
| 61 | break; | 63 | break; |
| 62 | } | 64 | } |
| 63 | if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) | 65 | if (!folio_started && test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) { |
| 64 | folio_start_fscache(folio); | 66 | folio_start_fscache(folio); |
| 67 | folio_started = true; | ||
| 68 | } | ||
| 65 | pg_failed |= subreq_failed; | 69 | pg_failed |= subreq_failed; |
| 66 | sreq_end = subreq->start + subreq->len - 1; | 70 | sreq_end = subreq->start + subreq->len - 1; |
| 67 | if (pg_end < sreq_end) | 71 | if (pg_end < sreq_end) |
| @@ -93,12 +93,10 @@ nfs_direct_handle_truncated(struct nfs_direct_req *dreq, · 92 unmodified lines | |||
| 93 | dreq->max_count = dreq_len; | 93 | dreq->max_count = dreq_len; |
| 94 | if (dreq->count > dreq_len) | 94 | if (dreq->count > dreq_len) |
| 95 | dreq->count = dreq_len; | 95 | dreq->count = dreq_len; |
| 96 | |||
| 97 | if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) | ||
| 98 | dreq->error = hdr->error; | ||
| 99 | else /* Clear outstanding error if this is EOF */ | ||
| 100 | dreq->error = 0; | ||
| 101 | } | 96 | } |
| 97 | |||
| 98 | if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && !dreq->error) | ||
| 99 | dreq->error = hdr->error; | ||
| 102 | } | 100 | } |
| 103 | 101 | ||
| 104 | static void | 102 | static void |
| @@ -120,6 +118,18 @@ nfs_direct_count_bytes(struct nfs_direct_req *dreq, · 15 unmodified lines | |||
| 120 | dreq->count = dreq_len; | 118 | dreq->count = dreq_len; |
| 121 | } | 119 | } |
| 122 | 120 | ||
| 121 | static void nfs_direct_truncate_request(struct nfs_direct_req *dreq, | ||
| 122 | struct nfs_page *req) | ||
| 123 | { | ||
| 124 | loff_t offs = req_offset(req); | ||
| 125 | size_t req_start = (size_t)(offs - dreq->io_start); | ||
| 126 | |||
| 127 | if (req_start < dreq->max_count) | ||
| 128 | dreq->max_count = req_start; | ||
| 129 | if (req_start < dreq->count) | ||
| 130 | dreq->count = req_start; | ||
| 131 | } | ||
| 132 | |||
| 123 | /** | 133 | /** |
| 124 | * nfs_swap_rw - NFS address space operation for swap I/O | 134 | * nfs_swap_rw - NFS address space operation for swap I/O |
| 125 | * @iocb: target I/O control block | 135 | * @iocb: target I/O control block |
| @@ -488,7 +498,9 @@ static void nfs_direct_add_page_head(struct list_head *list, · 362 unmodified lines | |||
| 488 | kref_get(&head->wb_kref); | 498 | kref_get(&head->wb_kref); |
| 489 | } | 499 | } |
| 490 | 500 | ||
| 491 | static void nfs_direct_join_group(struct list_head *list, struct inode *inode) | 501 | static void nfs_direct_join_group(struct list_head *list, |
| 502 | struct nfs_commit_info *cinfo, | ||
| 503 | struct inode *inode) | ||
| 492 | { | 504 | { |
| 493 | struct nfs_page *req, *subreq; | 505 | struct nfs_page *req, *subreq; |
| 494 | 506 | ||
| @@ -510,7 +522,7 @@ static void nfs_direct_join_group(struct list_head *list, struct inode *inode) · 15 unmodified lines | |||
| 510 | nfs_release_request(subreq); | 522 | nfs_release_request(subreq); |
| 511 | } | 523 | } |
| 512 | } while ((subreq = subreq->wb_this_page) != req); | 524 | } while ((subreq = subreq->wb_this_page) != req); |
| 513 | nfs_join_page_group(req, inode); | 525 | nfs_join_page_group(req, cinfo, inode); |
| 514 | } | 526 | } |
| 515 | } | 527 | } |
| 516 | 528 | ||
| @@ -528,20 +540,15 @@ nfs_direct_write_scan_commit_list(struct inode *inode, · 11 unmodified lines | |||
| 528 | static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | 540 | static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) |
| 529 | { | 541 | { |
| 530 | struct nfs_pageio_descriptor desc; | 542 | struct nfs_pageio_descriptor desc; |
| 531 | struct nfs_page *req, *tmp; | 543 | struct nfs_page *req; |
| 532 | LIST_HEAD(reqs); | 544 | LIST_HEAD(reqs); |
| 533 | struct nfs_commit_info cinfo; | 545 | struct nfs_commit_info cinfo; |
| 534 | LIST_HEAD(failed); | ||
| 535 | 546 | ||
| 536 | nfs_init_cinfo_from_dreq(&cinfo, dreq); | 547 | nfs_init_cinfo_from_dreq(&cinfo, dreq); |
| 537 | nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); | 548 | nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); |
| 538 | 549 | ||
| 539 | nfs_direct_join_group(&reqs, dreq->inode); | 550 | nfs_direct_join_group(&reqs, &cinfo, dreq->inode); |
| 540 | 551 | ||
| 541 | dreq->count = 0; | ||
| 542 | dreq->max_count = 0; | ||
| 543 | list_for_each_entry(req, &reqs, wb_list) | ||
| 544 | dreq->max_count += req->wb_bytes; | ||
| 545 | nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); | 552 | nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); |
| 546 | get_dreq(dreq); | 553 | get_dreq(dreq); |
| 547 | 554 | ||
| @@ -549,27 +556,40 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) · 1 unmodified line | |||
| 549 | &nfs_direct_write_completion_ops); | 556 | &nfs_direct_write_completion_ops); |
| 550 | desc.pg_dreq = dreq; | 557 | desc.pg_dreq = dreq; |
| 551 | 558 | ||
| 552 | list_for_each_entry_safe(req, tmp, &reqs, wb_list) { | 559 | while (!list_empty(&reqs)) { |
| 560 | req = nfs_list_entry(reqs.next); | ||
| 553 | /* Bump the transmission count */ | 561 | /* Bump the transmission count */ |
| 554 | req->wb_nio++; | 562 | req->wb_nio++; |
| 555 | if (!nfs_pageio_add_request(&desc, req)) { | 563 | if (!nfs_pageio_add_request(&desc, req)) { |
| 556 | nfs_list_move_request(req, &failed); | 564 | spin_lock(&dreq->lock); |
| 557 | spin_lock(&cinfo.inode->i_lock); | 565 | if (dreq->error < 0) { |
| 558 | dreq->flags = 0; | 566 | desc.pg_error = dreq->error; |
| 559 | if (desc.pg_error < 0) | 567 | } else if (desc.pg_error != -EAGAIN) { |
| 568 | dreq->flags = 0; | ||
| 569 | if (!desc.pg_error) | ||
| 570 | desc.pg_error = -EIO; | ||
| 560 | dreq->error = desc.pg_error; | 571 | dreq->error = desc.pg_error; |
| 561 | else | 572 | } else |
| 562 | dreq->error = -EIO; | 573 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; |
| 563 | spin_unlock(&cinfo.inode->i_lock); | 574 | spin_unlock(&dreq->lock); |
| 575 | break; | ||
| 564 | } | 576 | } |
| 565 | nfs_release_request(req); | 577 | nfs_release_request(req); |
| 566 | } | 578 | } |
| 567 | nfs_pageio_complete(&desc); | 579 | nfs_pageio_complete(&desc); |
| 568 | 580 | ||
| 569 | while (!list_empty(&failed)) { | 581 | while (!list_empty(&reqs)) { |
| 570 | req = nfs_list_entry(failed.next); | 582 | req = nfs_list_entry(reqs.next); |
| 571 | nfs_list_remove_request(req); | 583 | nfs_list_remove_request(req); |
| 572 | nfs_unlock_and_release_request(req); | 584 | nfs_unlock_and_release_request(req); |
| 585 | if (desc.pg_error == -EAGAIN) { | ||
| 586 | nfs_mark_request_commit(req, NULL, &cinfo, 0); | ||
| 587 | } else { | ||
| 588 | spin_lock(&dreq->lock); | ||
| 589 | nfs_direct_truncate_request(dreq, req); | ||
| 590 | spin_unlock(&dreq->lock); | ||
| 591 | nfs_release_request(req); | ||
| 592 | } | ||
| 573 | } | 593 | } |
| 574 | 594 | ||
| 575 | if (put_dreq(dreq)) | 595 | if (put_dreq(dreq)) |
| @@ -589,8 +609,6 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) · 13 unmodified lines | |||
| 589 | if (status < 0) { | 609 | if (status < 0) { |
| 590 | /* Errors in commit are fatal */ | 610 | /* Errors in commit are fatal */ |
| 591 | dreq->error = status; | 611 | dreq->error = status; |
| 592 | dreq->max_count = 0; | ||
| 593 | dreq->count = 0; | ||
| 594 | dreq->flags = NFS_ODIRECT_DONE; | 612 | dreq->flags = NFS_ODIRECT_DONE; |
| 595 | } else { | 613 | } else { |
| 596 | status = dreq->error; | 614 | status = dreq->error; |
| @@ -601,7 +619,12 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) · 4 unmodified lines | |||
| 601 | while (!list_empty(&data->pages)) { | 619 | while (!list_empty(&data->pages)) { |
| 602 | req = nfs_list_entry(data->pages.next); | 620 | req = nfs_list_entry(data->pages.next); |
| 603 | nfs_list_remove_request(req); | 621 | nfs_list_remove_request(req); |
| 604 | if (status >= 0 && !nfs_write_match_verf(verf, req)) { | 622 | if (status < 0) { |
| 623 | spin_lock(&dreq->lock); | ||
| 624 | nfs_direct_truncate_request(dreq, req); | ||
| 625 | spin_unlock(&dreq->lock); | ||
| 626 | nfs_release_request(req); | ||
| 627 | } else if (!nfs_write_match_verf(verf, req)) { | ||
| 605 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | 628 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; |
| 606 | /* | 629 | /* |
| 607 | * Despite the reboot, the write was successful, | 630 | * Despite the reboot, the write was successful, |
| @@ -609,7 +632,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) · 1 unmodified line | |||
| 609 | */ | 632 | */ |
| 610 | req->wb_nio = 0; | 633 | req->wb_nio = 0; |
| 611 | nfs_mark_request_commit(req, NULL, &cinfo, 0); | 634 | nfs_mark_request_commit(req, NULL, &cinfo, 0); |
| 612 | } else /* Error or match */ | 635 | } else |
| 613 | nfs_release_request(req); | 636 | nfs_release_request(req); |
| 614 | nfs_unlock_and_release_request(req); | 637 | nfs_unlock_and_release_request(req); |
| 615 | } | 638 | } |
| @@ -662,6 +685,7 @@ static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq) · 46 unmodified lines | |||
| 662 | while (!list_empty(&reqs)) { | 685 | while (!list_empty(&reqs)) { |
| 663 | req = nfs_list_entry(reqs.next); | 686 | req = nfs_list_entry(reqs.next); |
| 664 | nfs_list_remove_request(req); | 687 | nfs_list_remove_request(req); |
| 688 | nfs_direct_truncate_request(dreq, req); | ||
| 665 | nfs_release_request(req); | 689 | nfs_release_request(req); |
| 666 | nfs_unlock_and_release_request(req); | 690 | nfs_unlock_and_release_request(req); |
| 667 | } | 691 | } |
| @@ -711,7 +735,8 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) · 43 unmodified lines | |||
| 711 | } | 735 | } |
| 712 | 736 | ||
| 713 | nfs_direct_count_bytes(dreq, hdr); | 737 | nfs_direct_count_bytes(dreq, hdr); |
| 714 | if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags)) { | 738 | if (test_bit(NFS_IOHDR_UNSTABLE_WRITES, &hdr->flags) && |
| 739 | !test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { | ||
| 715 | if (!dreq->flags) | 740 | if (!dreq->flags) |
| 716 | dreq->flags = NFS_ODIRECT_DO_COMMIT; | 741 | dreq->flags = NFS_ODIRECT_DO_COMMIT; |
| 717 | flags = dreq->flags; | 742 | flags = dreq->flags; |
| @@ -755,18 +780,23 @@ static void nfs_write_sync_pgio_error(struct list_head *head, int error) · 37 unmodified lines | |||
| 755 | static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) | 780 | static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) |
| 756 | { | 781 | { |
| 757 | struct nfs_direct_req *dreq = hdr->dreq; | 782 | struct nfs_direct_req *dreq = hdr->dreq; |
| 783 | struct nfs_page *req; | ||
| 784 | struct nfs_commit_info cinfo; | ||
| 758 | 785 | ||
| 759 | trace_nfs_direct_write_reschedule_io(dreq); | 786 | trace_nfs_direct_write_reschedule_io(dreq); |
| 760 | 787 | ||
| 788 | nfs_init_cinfo_from_dreq(&cinfo, dreq); | ||
| 761 | spin_lock(&dreq->lock); | 789 | spin_lock(&dreq->lock); |
| 762 | if (dreq->error == 0) { | 790 | if (dreq->error == 0) |
| 763 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | 791 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; |
| 764 | /* fake unstable write to let common nfs resend pages */ | 792 | set_bit(NFS_IOHDR_REDO, &hdr->flags); |
| 765 | hdr->verf.committed = NFS_UNSTABLE; | ||
| 766 | hdr->good_bytes = hdr->args.offset + hdr->args.count - | ||
| 767 | hdr->io_start; | ||
| 768 | } | ||
| 769 | spin_unlock(&dreq->lock); | 793 | spin_unlock(&dreq->lock); |
| 794 | while (!list_empty(&hdr->pages)) { | ||
| 795 | req = nfs_list_entry(hdr->pages.next); | ||
| 796 | nfs_list_remove_request(req); | ||
| 797 | nfs_unlock_request(req); | ||
| 798 | nfs_mark_request_commit(req, NULL, &cinfo, 0); | ||
| 799 | } | ||
| 770 | } | 800 | } |
| 771 | 801 | ||
| 772 | static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { | 802 | static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { |
| @@ -794,9 +824,11 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, · 21 unmodified lines | |||
| 794 | { | 824 | { |
| 795 | struct nfs_pageio_descriptor desc; | 825 | struct nfs_pageio_descriptor desc; |
| 796 | struct inode *inode = dreq->inode; | 826 | struct inode *inode = dreq->inode; |
| 827 | struct nfs_commit_info cinfo; | ||
| 797 | ssize_t result = 0; | 828 | ssize_t result = 0; |
| 798 | size_t requested_bytes = 0; | 829 | size_t requested_bytes = 0; |
| 799 | size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); | 830 | size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); |
| 831 | bool defer = false; | ||
| 800 | 832 | ||
| 801 | trace_nfs_direct_write_schedule_iovec(dreq); | 833 | trace_nfs_direct_write_schedule_iovec(dreq); |
| 802 | 834 | ||
| @@ -837,17 +869,37 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, · 34 unmodified lines | |||
| 837 | break; | 869 | break; |
| 838 | } | 870 | } |
| 839 | 871 | ||
| 840 | nfs_lock_request(req); | ||
| 841 | if (!nfs_pageio_add_request(&desc, req)) { | ||
| 842 | result = desc.pg_error; | ||
| 843 | nfs_unlock_and_release_request(req); | ||
| 844 | break; | ||
| 845 | } | ||
| 846 | pgbase = 0; | 872 | pgbase = 0; |
| 847 | bytes -= req_len; | 873 | bytes -= req_len; |
| 848 | requested_bytes += req_len; | 874 | requested_bytes += req_len; |
| 849 | pos += req_len; | 875 | pos += req_len; |
| 850 | dreq->bytes_left -= req_len; | 876 | dreq->bytes_left -= req_len; |
| 877 | |||
| 878 | if (defer) { | ||
| 879 | nfs_mark_request_commit(req, NULL, &cinfo, 0); | ||
| 880 | continue; | ||
| 881 | } | ||
| 882 | |||
| 883 | nfs_lock_request(req); | ||
| 884 | if (nfs_pageio_add_request(&desc, req)) | ||
| 885 | continue; | ||
| 886 | |||
| 887 | /* Exit on hard errors */ | ||
| 888 | if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { | ||
| 889 | result = desc.pg_error; | ||
| 890 | nfs_unlock_and_release_request(req); | ||
| 891 | break; | ||
| 892 | } | ||
| 893 | |||
| 894 | /* If the error is soft, defer remaining requests */ | ||
| 895 | nfs_init_cinfo_from_dreq(&cinfo, dreq); | ||
| 896 | spin_lock(&dreq->lock); | ||
| 897 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | ||
| 898 | spin_unlock(&dreq->lock); | ||
| 899 | nfs_unlock_request(req); | ||
| 900 | nfs_mark_request_commit(req, NULL, &cinfo, 0); | ||
| 901 | desc.pg_error = 0; | ||
| 902 | defer = true; | ||
| 851 | } | 903 | } |
| 852 | nfs_direct_release_pages(pagevec, npages); | 904 | nfs_direct_release_pages(pagevec, npages); |
| 853 | kvfree(pagevec); | 905 | kvfree(pagevec); |
| @@ -1235,6 +1235,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, · 1234 unmodified lines | |||
| 1235 | case -EPFNOSUPPORT: | 1235 | case -EPFNOSUPPORT: |
| 1236 | case -EPROTONOSUPPORT: | 1236 | case -EPROTONOSUPPORT: |
| 1237 | case -EOPNOTSUPP: | 1237 | case -EOPNOTSUPP: |
| 1238 | case -EINVAL: | ||
| 1238 | case -ECONNREFUSED: | 1239 | case -ECONNREFUSED: |
| 1239 | case -ECONNRESET: | 1240 | case -ECONNRESET: |
| 1240 | case -EHOSTDOWN: | 1241 | case -EHOSTDOWN: |
| @@ -417,6 +417,8 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) · 416 unmodified lines | |||
| 417 | .net = old->cl_net, | 417 | .net = old->cl_net, |
| 418 | .servername = old->cl_hostname, | 418 | .servername = old->cl_hostname, |
| 419 | }; | 419 | }; |
| 420 | int max_connect = test_bit(NFS_CS_PNFS, &clp->cl_flags) ? | ||
| 421 | clp->cl_max_connect : old->cl_max_connect; | ||
| 420 | 422 | ||
| 421 | if (clp->cl_proto != old->cl_proto) | 423 | if (clp->cl_proto != old->cl_proto) |
| 422 | return; | 424 | return; |
| @@ -430,7 +432,7 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old) · 7 unmodified lines | |||
| 430 | xprt_args.addrlen = clp_salen; | 432 | xprt_args.addrlen = clp_salen; |
| 431 | 433 | ||
| 432 | rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args, | 434 | rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args, |
| 433 | rpc_clnt_test_and_add_xprt, NULL); | 435 | rpc_clnt_test_and_add_xprt, &max_connect); |
| 434 | } | 436 | } |
| 435 | 437 | ||
| 436 | /** | 438 | /** |
| @@ -1010,6 +1012,8 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, · 573 unmodified lines | |||
| 1010 | __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); | 1012 | __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); |
| 1011 | 1013 | ||
| 1012 | __set_bit(NFS_CS_DS, &cl_init.init_flags); | 1014 | __set_bit(NFS_CS_DS, &cl_init.init_flags); |
| 1015 | __set_bit(NFS_CS_PNFS, &cl_init.init_flags); | ||
| 1016 | cl_init.max_connect = NFS_MAX_TRANSPORTS; | ||
| 1013 | /* | 1017 | /* |
| 1014 | * Set an authflavor equual to the MDS value. Use the MDS nfs_client | 1018 | * Set an authflavor equual to the MDS value. Use the MDS nfs_client |
| 1015 | * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS | 1019 | * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS |
| @@ -2703,8 +2703,12 @@ static int _nfs4_proc_open(struct nfs4_opendata *data, · 2702 unmodified lines | |||
| 2703 | return status; | 2703 | return status; |
| 2704 | } | 2704 | } |
| 2705 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) { | 2705 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) { |
| 2706 | struct nfs_fh *fh = &o_res->fh; | ||
| 2707 | |||
| 2706 | nfs4_sequence_free_slot(&o_res->seq_res); | 2708 | nfs4_sequence_free_slot(&o_res->seq_res); |
| 2707 | nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL); | 2709 | if (o_arg->claim == NFS4_OPEN_CLAIM_FH) |
| 2710 | fh = NFS_FH(d_inode(data->dentry)); | ||
| 2711 | nfs4_proc_getattr(server, fh, o_res->f_attr, NULL); | ||
| 2708 | } | 2712 | } |
| 2709 | return 0; | 2713 | return 0; |
| 2710 | } | 2714 | } |
| @@ -59,7 +59,8 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops; · 58 unmodified lines | |||
| 59 | static const struct nfs_commit_completion_ops nfs_commit_completion_ops; | 59 | static const struct nfs_commit_completion_ops nfs_commit_completion_ops; |
| 60 | static const struct nfs_rw_ops nfs_rw_write_ops; | 60 | static const struct nfs_rw_ops nfs_rw_write_ops; |
| 61 | static void nfs_inode_remove_request(struct nfs_page *req); | 61 | static void nfs_inode_remove_request(struct nfs_page *req); |
| 62 | static void nfs_clear_request_commit(struct nfs_page *req); | 62 | static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, |
| 63 | struct nfs_page *req); | ||
| 63 | static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, | 64 | static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo, |
| 64 | struct inode *inode); | 65 | struct inode *inode); |
| 65 | static struct nfs_page * | 66 | static struct nfs_page * |
| @@ -502,8 +503,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, · 436 unmodified lines | |||
| 502 | * the (former) group. All subrequests are removed from any write or commit | 503 | * the (former) group. All subrequests are removed from any write or commit |
| 503 | * lists, unlinked from the group and destroyed. | 504 | * lists, unlinked from the group and destroyed. |
| 504 | */ | 505 | */ |
| 505 | void | 506 | void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo, |
| 506 | nfs_join_page_group(struct nfs_page *head, struct inode *inode) | 507 | struct inode *inode) |
| 507 | { | 508 | { |
| 508 | struct nfs_page *subreq; | 509 | struct nfs_page *subreq; |
| 509 | struct nfs_page *destroy_list = NULL; | 510 | struct nfs_page *destroy_list = NULL; |
| @@ -533,7 +534,7 @@ nfs_join_page_group(struct nfs_page *head, struct inode *inode) · 23 unmodified lines | |||
| 533 | * Commit list removal accounting is done after locks are dropped */ | 534 | * Commit list removal accounting is done after locks are dropped */ |
| 534 | subreq = head; | 535 | subreq = head; |
| 535 | do { | 536 | do { |
| 536 | nfs_clear_request_commit(subreq); | 537 | nfs_clear_request_commit(cinfo, subreq); |
| 537 | subreq = subreq->wb_this_page; | 538 | subreq = subreq->wb_this_page; |
| 538 | } while (subreq != head); | 539 | } while (subreq != head); |
| 539 | 540 | ||
| @@ -566,8 +567,10 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio) · 26 unmodified lines | |||
| 566 | { | 567 | { |
| 567 | struct inode *inode = folio_file_mapping(folio)->host; | 568 | struct inode *inode = folio_file_mapping(folio)->host; |
| 568 | struct nfs_page *head; | 569 | struct nfs_page *head; |
| 570 | struct nfs_commit_info cinfo; | ||
| 569 | int ret; | 571 | int ret; |
| 570 | 572 | ||
| 573 | nfs_init_cinfo_from_inode(&cinfo, inode); | ||
| 571 | /* | 574 | /* |
| 572 | * A reference is taken only on the head request which acts as a | 575 | * A reference is taken only on the head request which acts as a |
| 573 | * reference to the whole page group - the group will not be destroyed | 576 | * reference to the whole page group - the group will not be destroyed |
| @@ -584,7 +587,7 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio) · 10 unmodified lines | |||
| 584 | return ERR_PTR(ret); | 587 | return ERR_PTR(ret); |
| 585 | } | 588 | } |
| 586 | 589 | ||
| 587 | nfs_join_page_group(head, inode); | 590 | nfs_join_page_group(head, &cinfo, inode); |
| 588 | 591 | ||
| 589 | return head; | 592 | return head; |
| 590 | } | 593 | } |
| @@ -955,18 +958,16 @@ static void nfs_folio_clear_commit(struct folio *folio) · 364 unmodified lines | |||
| 955 | } | 958 | } |
| 956 | 959 | ||
| 957 | /* Called holding the request lock on @req */ | 960 | /* Called holding the request lock on @req */ |
| 958 | static void | 961 | static void nfs_clear_request_commit(struct nfs_commit_info *cinfo, |
| 959 | nfs_clear_request_commit(struct nfs_page *req) | 962 | struct nfs_page *req) |
| 960 | { | 963 | { |
| 961 | if (test_bit(PG_CLEAN, &req->wb_flags)) { | 964 | if (test_bit(PG_CLEAN, &req->wb_flags)) { |
| 962 | struct nfs_open_context *ctx = nfs_req_openctx(req); | 965 | struct nfs_open_context *ctx = nfs_req_openctx(req); |
| 963 | struct inode *inode = d_inode(ctx->dentry); | 966 | struct inode *inode = d_inode(ctx->dentry); |
| 964 | struct nfs_commit_info cinfo; | ||
| 965 | 967 | ||
| 966 | nfs_init_cinfo_from_inode(&cinfo, inode); | ||
| 967 | mutex_lock(&NFS_I(inode)->commit_mutex); | 968 | mutex_lock(&NFS_I(inode)->commit_mutex); |
| 968 | if (!pnfs_clear_request_commit(req, &cinfo)) { | 969 | if (!pnfs_clear_request_commit(req, cinfo)) { |
| 969 | nfs_request_remove_commit_list(req, &cinfo); | 970 | nfs_request_remove_commit_list(req, cinfo); |
| 970 | } | 971 | } |
| 971 | mutex_unlock(&NFS_I(inode)->commit_mutex); | 972 | mutex_unlock(&NFS_I(inode)->commit_mutex); |
| 972 | nfs_folio_clear_commit(nfs_page_to_folio(req)); | 973 | nfs_folio_clear_commit(nfs_page_to_folio(req)); |
| @@ -1058,8 +1058,8 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, · 1057 unmodified lines | |||
| 1058 | rename->rn_tname, rename->rn_tnamelen); | 1058 | rename->rn_tname, rename->rn_tnamelen); |
| 1059 | if (status) | 1059 | if (status) |
| 1060 | return status; | 1060 | return status; |
| 1061 | set_change_info(&rename->rn_sinfo, &cstate->current_fh); | 1061 | set_change_info(&rename->rn_sinfo, &cstate->save_fh); |
| 1062 | set_change_info(&rename->rn_tinfo, &cstate->save_fh); | 1062 | set_change_info(&rename->rn_tinfo, &cstate->current_fh); |
| 1063 | return nfs_ok; | 1063 | return nfs_ok; |
| 1064 | } | 1064 | } |
| 1065 | 1065 | ||
| @@ -4113,6 +4113,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, · 4112 unmodified lines | |||
| 4113 | struct file *file, unsigned long maxcount) | 4113 | struct file *file, unsigned long maxcount) |
| 4114 | { | 4114 | { |
| 4115 | struct xdr_stream *xdr = resp->xdr; | 4115 | struct xdr_stream *xdr = resp->xdr; |
| 4116 | unsigned int base = xdr->buf->page_len & ~PAGE_MASK; | ||
| 4116 | unsigned int starting_len = xdr->buf->len; | 4117 | unsigned int starting_len = xdr->buf->len; |
| 4117 | __be32 zero = xdr_zero; | 4118 | __be32 zero = xdr_zero; |
| 4118 | __be32 nfserr; | 4119 | __be32 nfserr; |
| @@ -4121,8 +4122,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, · 2 unmodified lines | |||
| 4121 | return nfserr_resource; | 4122 | return nfserr_resource; |
| 4122 | 4123 | ||
| 4123 | nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, file, | 4124 | nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, file, |
| 4124 | read->rd_offset, &maxcount, | 4125 | read->rd_offset, &maxcount, base, |
| 4125 | xdr->buf->page_len & ~PAGE_MASK, | ||
| 4126 | &read->rd_eof); | 4126 | &read->rd_eof); |
| 4127 | read->rd_length = maxcount; | 4127 | read->rd_length = maxcount; |
| 4128 | if (nfserr) | 4128 | if (nfserr) |
| @@ -1082,11 +1082,12 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file) · 1081 unmodified lines | |||
| 1082 | 1082 | ||
| 1083 | int nfsd_pool_stats_release(struct inode *inode, struct file *file) | 1083 | int nfsd_pool_stats_release(struct inode *inode, struct file *file) |
| 1084 | { | 1084 | { |
| 1085 | struct seq_file *seq = file->private_data; | ||
| 1086 | struct svc_serv *serv = seq->private; | ||
| 1085 | int ret = seq_release(inode, file); | 1087 | int ret = seq_release(inode, file); |
| 1086 | struct net *net = inode->i_sb->s_fs_info; | ||
| 1087 | 1088 | ||
| 1088 | mutex_lock(&nfsd_mutex); | 1089 | mutex_lock(&nfsd_mutex); |
| 1089 | nfsd_put(net); | 1090 | svc_put(serv); |
| 1090 | mutex_unlock(&nfsd_mutex); | 1091 | mutex_unlock(&nfsd_mutex); |
| 1091 | return ret; | 1092 | return ret; |
| 1092 | } | 1093 | } |
| @@ -73,10 +73,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, · 72 unmodified lines | |||
| 73 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | 73 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
| 74 | 74 | ||
| 75 | err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); | 75 | err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); |
| 76 | if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ | 76 | if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ |
| 77 | brelse(bh); | ||
| 78 | goto failed; | 77 | goto failed; |
| 79 | } | ||
| 80 | } | 78 | } |
| 81 | 79 | ||
| 82 | lock_buffer(bh); | 80 | lock_buffer(bh); |
| @@ -102,6 +100,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, · 19 unmodified lines | |||
| 102 | failed: | 100 | failed: |
| 103 | unlock_page(bh->b_page); | 101 | unlock_page(bh->b_page); |
| 104 | put_page(bh->b_page); | 102 | put_page(bh->b_page); |
| 103 | if (unlikely(err)) | ||
| 104 | brelse(bh); | ||
| 105 | return err; | 105 | return err; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| @@ -1562,6 +1562,7 @@ load_root: · 1561 unmodified lines | |||
| 1562 | put_inode_out: | 1562 | put_inode_out: |
| 1563 | iput(inode); | 1563 | iput(inode); |
| 1564 | out: | 1564 | out: |
| 1565 | ntfs3_put_sbi(sbi); | ||
| 1565 | kfree(boot2); | 1566 | kfree(boot2); |
| 1566 | return err; | 1567 | return err; |
| 1567 | } | 1568 | } |
| @@ -337,7 +337,7 @@ static int ovl_set_timestamps(struct ovl_fs *ofs, struct dentry *upperdentry, · 336 unmodified lines | |||
| 337 | { | 337 | { |
| 338 | struct iattr attr = { | 338 | struct iattr attr = { |
| 339 | .ia_valid = | 339 | .ia_valid = |
| 340 | ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET, | 340 | ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME, |
| 341 | .ia_atime = stat->atime, | 341 | .ia_atime = stat->atime, |
| 342 | .ia_mtime = stat->mtime, | 342 | .ia_mtime = stat->mtime, |
| 343 | }; | 343 | }; |
| @@ -618,7 +618,8 @@ static int ovl_copy_up_metadata(struct ovl_copy_up_ctx *c, struct dentry *temp) · 274 unmodified lines | |||
| 618 | if (err) | 618 | if (err) |
| 619 | return err; | 619 | return err; |
| 620 | 620 | ||
| 621 | if (inode->i_flags & OVL_COPY_I_FLAGS_MASK) { | 621 | if (inode->i_flags & OVL_COPY_I_FLAGS_MASK && |
| 622 | (S_ISREG(c->stat.mode) || S_ISDIR(c->stat.mode))) { | ||
| 622 | /* | 623 | /* |
| 623 | * Copy the fileattr inode flags that are the source of already | 624 | * Copy the fileattr inode flags that are the source of already |
| 624 | * copied i_flags | 625 | * copied i_flags |
| @@ -19,7 +19,6 @@ struct ovl_aio_req { · 18 unmodified lines | |||
| 19 | struct kiocb iocb; | 19 | struct kiocb iocb; |
| 20 | refcount_t ref; | 20 | refcount_t ref; |
| 21 | struct kiocb *orig_iocb; | 21 | struct kiocb *orig_iocb; |
| 22 | struct fd fd; | ||
| 23 | }; | 22 | }; |
| 24 | 23 | ||
| 25 | static struct kmem_cache *ovl_aio_request_cachep; | 24 | static struct kmem_cache *ovl_aio_request_cachep; |
| @@ -280,7 +279,7 @@ static rwf_t ovl_iocb_to_rwf(int ifl) · 254 unmodified lines | |||
| 280 | static inline void ovl_aio_put(struct ovl_aio_req *aio_req) | 279 | static inline void ovl_aio_put(struct ovl_aio_req *aio_req) |
| 281 | { | 280 | { |
| 282 | if (refcount_dec_and_test(&aio_req->ref)) { | 281 | if (refcount_dec_and_test(&aio_req->ref)) { |
| 283 | fdput(aio_req->fd); | 282 | fput(aio_req->iocb.ki_filp); |
| 284 | kmem_cache_free(ovl_aio_request_cachep, aio_req); | 283 | kmem_cache_free(ovl_aio_request_cachep, aio_req); |
| 285 | } | 284 | } |
| 286 | } | 285 | } |
| @@ -342,10 +341,9 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter) · 55 unmodified lines | |||
| 342 | if (!aio_req) | 341 | if (!aio_req) |
| 343 | goto out; | 342 | goto out; |
| 344 | 343 | ||
| 345 | aio_req->fd = real; | ||
| 346 | real.flags = 0; | 344 | real.flags = 0; |
| 347 | aio_req->orig_iocb = iocb; | 345 | aio_req->orig_iocb = iocb; |
| 348 | kiocb_clone(&aio_req->iocb, iocb, real.file); | 346 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
| 349 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; | 347 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; |
| 350 | refcount_set(&aio_req->ref, 2); | 348 | refcount_set(&aio_req->ref, 2); |
| 351 | ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); | 349 | ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); |
| @@ -393,6 +391,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) · 41 unmodified lines | |||
| 393 | if (!ovl_should_sync(OVL_FS(inode->i_sb))) | 391 | if (!ovl_should_sync(OVL_FS(inode->i_sb))) |
| 394 | ifl &= ~(IOCB_DSYNC | IOCB_SYNC); | 392 | ifl &= ~(IOCB_DSYNC | IOCB_SYNC); |
| 395 | 393 | ||
| 394 | /* | ||
| 395 | * Overlayfs doesn't support deferred completions, don't copy | ||
| 396 | * this property in case it is set by the issuer. | ||
| 397 | */ | ||
| 398 | ifl &= ~IOCB_DIO_CALLER_COMP; | ||
| 399 | |||
| 396 | old_cred = ovl_override_creds(file_inode(file)->i_sb); | 400 | old_cred = ovl_override_creds(file_inode(file)->i_sb); |
| 397 | if (is_sync_kiocb(iocb)) { | 401 | if (is_sync_kiocb(iocb)) { |
| 398 | file_start_write(real.file); | 402 | file_start_write(real.file); |
| @@ -409,10 +413,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) · 10 unmodified lines | |||
| 409 | if (!aio_req) | 413 | if (!aio_req) |
| 410 | goto out; | 414 | goto out; |
| 411 | 415 | ||
| 412 | aio_req->fd = real; | ||
| 413 | real.flags = 0; | 416 | real.flags = 0; |
| 414 | aio_req->orig_iocb = iocb; | 417 | aio_req->orig_iocb = iocb; |
| 415 | kiocb_clone(&aio_req->iocb, iocb, real.file); | 418 | kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
| 416 | aio_req->iocb.ki_flags = ifl; | 419 | aio_req->iocb.ki_flags = ifl; |
| 417 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; | 420 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; |
| 418 | refcount_set(&aio_req->ref, 2); | 421 | refcount_set(&aio_req->ref, 2); |
| @@ -537,7 +537,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) · 536 unmodified lines | |||
| 537 | break; | 537 | break; |
| 538 | } | 538 | } |
| 539 | ret += copied; | 539 | ret += copied; |
| 540 | buf->offset = 0; | ||
| 541 | buf->len = copied; | 540 | buf->len = copied; |
| 542 | 541 | ||
| 543 | if (!iov_iter_count(from)) | 542 | if (!iov_iter_count(from)) |
| @@ -289,9 +289,7 @@ struct proc_maps_private { · 288 unmodified lines | |||
| 289 | struct inode *inode; | 289 | struct inode *inode; |
| 290 | struct task_struct *task; | 290 | struct task_struct *task; |
| 291 | struct mm_struct *mm; | 291 | struct mm_struct *mm; |
| 292 | #ifdef CONFIG_MMU | ||
| 293 | struct vma_iterator iter; | 292 | struct vma_iterator iter; |
| 294 | #endif | ||
| 295 | #ifdef CONFIG_NUMA | 293 | #ifdef CONFIG_NUMA |
| 296 | struct mempolicy *task_mempolicy; | 294 | struct mempolicy *task_mempolicy; |
| 297 | #endif | 295 | #endif |
| @@ -175,15 +175,28 @@ static int show_map(struct seq_file *m, void *_p) · 174 unmodified lines | |||
| 175 | return nommu_vma_show(m, _p); | 175 | return nommu_vma_show(m, _p); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | static void *m_start(struct seq_file *m, loff_t *pos) | 178 | static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv, |
| 179 | loff_t *ppos) | ||
| 180 | { | ||
| 181 | struct vm_area_struct *vma = vma_next(&priv->iter); | ||
| 182 | |||
| 183 | if (vma) { | ||
| 184 | *ppos = vma->vm_start; | ||
| 185 | } else { | ||
| 186 | *ppos = -1UL; | ||
| 187 | } | ||
| 188 | |||
| 189 | return vma; | ||
| 190 | } | ||
| 191 | |||
| 192 | static void *m_start(struct seq_file *m, loff_t *ppos) | ||
| 179 | { | 193 | { |
| 180 | struct proc_maps_private *priv = m->private; | 194 | struct proc_maps_private *priv = m->private; |
| 195 | unsigned long last_addr = *ppos; | ||
| 181 | struct mm_struct *mm; | 196 | struct mm_struct *mm; |
| 182 | struct vm_area_struct *vma; | ||
| 183 | unsigned long addr = *pos; | ||
| 184 | 197 | ||
| 185 | /* See m_next(). Zero at the start or after lseek. */ | 198 | /* See proc_get_vma(). Zero at the start or after lseek. */ |
| 186 | if (addr == -1UL) | 199 | if (last_addr == -1UL) |
| 187 | return NULL; | 200 | return NULL; |
| 188 | 201 | ||
| 189 | /* pin the task and mm whilst we play with them */ | 202 | /* pin the task and mm whilst we play with them */ |
| @@ -192,44 +205,41 @@ static void *m_start(struct seq_file *m, loff_t *pos) · 2 unmodified lines | |||
| 192 | return ERR_PTR(-ESRCH); | 205 | return ERR_PTR(-ESRCH); |
| 193 | 206 | ||
| 194 | mm = priv->mm; | 207 | mm = priv->mm; |
| 195 | if (!mm || !mmget_not_zero(mm)) | 208 | if (!mm || !mmget_not_zero(mm)) { |
| 209 | put_task_struct(priv->task); | ||
| 210 | priv->task = NULL; | ||
| 196 | return NULL; | 211 | return NULL; |
| 212 | } | ||
| 197 | 213 | ||
| 198 | if (mmap_read_lock_killable(mm)) { | 214 | if (mmap_read_lock_killable(mm)) { |
| 199 | mmput(mm); | 215 | mmput(mm); |
| 216 | put_task_struct(priv->task); | ||
| 217 | priv->task = NULL; | ||
| 200 | return ERR_PTR(-EINTR); | 218 | return ERR_PTR(-EINTR); |
| 201 | } | 219 | } |
| 202 | 220 | ||
| 203 | /* start the next element from addr */ | 221 | vma_iter_init(&priv->iter, mm, last_addr); |
| 204 | vma = find_vma(mm, addr); | ||
| 205 | if (vma) | ||
| 206 | return vma; | ||
| 207 | 222 | ||
| 208 | mmap_read_unlock(mm); | 223 | return proc_get_vma(priv, ppos); |
| 209 | mmput(mm); | ||
| 210 | return NULL; | ||
| 211 | } | 224 | } |
| 212 | 225 | ||
| 213 | static void m_stop(struct seq_file *m, void *_vml) | 226 | static void m_stop(struct seq_file *m, void *v) |
| 214 | { | 227 | { |
| 215 | struct proc_maps_private *priv = m->private; | 228 | struct proc_maps_private *priv = m->private; |
| 229 | struct mm_struct *mm = priv->mm; | ||
| 216 | 230 | ||
| 217 | if (!IS_ERR_OR_NULL(_vml)) { | 231 | if (!priv->task) |
| 218 | mmap_read_unlock(priv->mm); | 232 | return; |
| 219 | mmput(priv->mm); | 233 | |
| 220 | } | 234 | mmap_read_unlock(mm); |
| 221 | if (priv->task) { | 235 | mmput(mm); |
| 222 | put_task_struct(priv->task); | 236 | put_task_struct(priv->task); |
| 223 | priv->task = NULL; | 237 | priv->task = NULL; |
| 224 | } | ||
| 225 | } | 238 | } |
| 226 | 239 | ||
| 227 | static void *m_next(struct seq_file *m, void *_p, loff_t *pos) | 240 | static void *m_next(struct seq_file *m, void *_p, loff_t *ppos) |
| 228 | { | 241 | { |
| 229 | struct vm_area_struct *vma = _p; | 242 | return proc_get_vma(m->private, ppos); |
| 230 | |||
| 231 | *pos = vma->vm_end; | ||
| 232 | return find_vma(vma->vm_mm, vma->vm_end); | ||
| 233 | } | 243 | } |
| 234 | 244 | ||
| 235 | static const struct seq_operations proc_pid_maps_ops = { | 245 | static const struct seq_operations proc_pid_maps_ops = { |
| @@ -2699,7 +2699,7 @@ struct reiserfs_iget_args { · 2698 unmodified lines | |||
| 2699 | #define get_journal_desc_magic(bh) (bh->b_data + bh->b_size - 12) | 2699 | #define get_journal_desc_magic(bh) (bh->b_data + bh->b_size - 12) |
| 2700 | 2700 | ||
| 2701 | #define journal_trans_half(blocksize) \ | 2701 | #define journal_trans_half(blocksize) \ |
| 2702 | ((blocksize - sizeof (struct reiserfs_journal_desc) + sizeof (__u32) - 12) / sizeof (__u32)) | 2702 | ((blocksize - sizeof(struct reiserfs_journal_desc) - 12) / sizeof(__u32)) |
| 2703 | 2703 | ||
| 2704 | /* journal.c see journal.c for all the comments here */ | 2704 | /* journal.c see journal.c for all the comments here */ |
| 2705 | 2705 | ||
| @@ -2711,7 +2711,7 @@ struct reiserfs_journal_desc { · 5 unmodified lines | |||
| 2711 | __le32 j_len; | 2711 | __le32 j_len; |
| 2712 | 2712 | ||
| 2713 | __le32 j_mount_id; /* mount id of this trans */ | 2713 | __le32 j_mount_id; /* mount id of this trans */ |
| 2714 | __le32 j_realblock[1]; /* real locations for each block */ | 2714 | __le32 j_realblock[]; /* real locations for each block */ |
| 2715 | }; | 2715 | }; |
| 2716 | 2716 | ||
| 2717 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) | 2717 | #define get_desc_trans_id(d) le32_to_cpu((d)->j_trans_id) |
| @@ -2726,7 +2726,7 @@ struct reiserfs_journal_desc { · 8 unmodified lines | |||
| 2726 | struct reiserfs_journal_commit { | 2726 | struct reiserfs_journal_commit { |
| 2727 | __le32 j_trans_id; /* must match j_trans_id from the desc block */ | 2727 | __le32 j_trans_id; /* must match j_trans_id from the desc block */ |
| 2728 | __le32 j_len; /* ditto */ | 2728 | __le32 j_len; /* ditto */ |
| 2729 | __le32 j_realblock[1]; /* real locations for each block */ | 2729 | __le32 j_realblock[]; /* real locations for each block */ |
| 2730 | }; | 2730 | }; |
| 2731 | 2731 | ||
| 2732 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) | 2732 | #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id) |
| @@ -452,6 +452,9 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) · 451 unmodified lines | |||
| 452 | struct cached_fid *cfid, *q; | 452 | struct cached_fid *cfid, *q; |
| 453 | LIST_HEAD(entry); | 453 | LIST_HEAD(entry); |
| 454 | 454 | ||
| 455 | if (cfids == NULL) | ||
| 456 | return; | ||
| 457 | |||
| 455 | spin_lock(&cfids->cfid_list_lock); | 458 | spin_lock(&cfids->cfid_list_lock); |
| 456 | list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { | 459 | list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { |
| 457 | list_move(&cfid->entry, &entry); | 460 | list_move(&cfid->entry, &entry); |
| @@ -651,6 +654,9 @@ void free_cached_dirs(struct cached_fids *cfids) · 193 unmodified lines | |||
| 651 | struct cached_fid *cfid, *q; | 654 | struct cached_fid *cfid, *q; |
| 652 | LIST_HEAD(entry); | 655 | LIST_HEAD(entry); |
| 653 | 656 | ||
| 657 | if (cfids == NULL) | ||
| 658 | return; | ||
| 659 | |||
| 654 | if (cfids->laundromat) { | 660 | if (cfids->laundromat) { |
| 655 | kthread_stop(cfids->laundromat); | 661 | kthread_stop(cfids->laundromat); |
| 656 | cfids->laundromat = NULL; | 662 | cfids->laundromat = NULL; |
| @@ -1807,6 +1807,7 @@ static inline bool is_retryable_error(int error) · 1806 unmodified lines | |||
| 1807 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ | 1807 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ |
| 1808 | #define MID_RESPONSE_MALFORMED 0x10 | 1808 | #define MID_RESPONSE_MALFORMED 0x10 |
| 1809 | #define MID_SHUTDOWN 0x20 | 1809 | #define MID_SHUTDOWN 0x20 |
| 1810 | #define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ | ||
| 1810 | 1811 | ||
| 1811 | /* Flags */ | 1812 | /* Flags */ |
| 1812 | #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ | 1813 | #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ |
| @@ -1943,7 +1944,7 @@ require use of the stronger protocol */ · 130 unmodified lines | |||
| 1943 | * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once | 1944 | * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once |
| 1944 | * ->can_cache_brlcks | 1945 | * ->can_cache_brlcks |
| 1945 | * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc | 1946 | * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc |
| 1946 | * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc | 1947 | * cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc |
| 1947 | * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo | 1948 | * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo |
| 1948 | * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo | 1949 | * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo |
| 1949 | * ->invalidHandle initiate_cifs_search | 1950 | * ->invalidHandle initiate_cifs_search |
| @@ -512,7 +512,7 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses); · 511 unmodified lines | |||
| 512 | 512 | ||
| 513 | extern struct cifs_ses *sesInfoAlloc(void); | 513 | extern struct cifs_ses *sesInfoAlloc(void); |
| 514 | extern void sesInfoFree(struct cifs_ses *); | 514 | extern void sesInfoFree(struct cifs_ses *); |
| 515 | extern struct cifs_tcon *tconInfoAlloc(void); | 515 | extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled); |
| 516 | extern void tconInfoFree(struct cifs_tcon *); | 516 | extern void tconInfoFree(struct cifs_tcon *); |
| 517 | 517 | ||
| 518 | extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, | 518 | extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, |
| @@ -1882,7 +1882,8 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) · 1881 unmodified lines | |||
| 1882 | } | 1882 | } |
| 1883 | } | 1883 | } |
| 1884 | 1884 | ||
| 1885 | tcon = tconInfoAlloc(); | 1885 | /* no need to setup directory caching on IPC share, so pass in false */ |
| 1886 | tcon = tcon_info_alloc(false); | ||
| 1886 | if (tcon == NULL) | 1887 | if (tcon == NULL) |
| 1887 | return -ENOMEM; | 1888 | return -ENOMEM; |
| 1888 | 1889 | ||
| @@ -2492,7 +2493,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) · 603 unmodified lines | |||
| 2492 | goto out_fail; | 2493 | goto out_fail; |
| 2493 | } | 2494 | } |
| 2494 | 2495 | ||
| 2495 | tcon = tconInfoAlloc(); | 2496 | if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) |
| 2497 | tcon = tcon_info_alloc(true); | ||
| 2498 | else | ||
| 2499 | tcon = tcon_info_alloc(false); | ||
| 2496 | if (tcon == NULL) { | 2500 | if (tcon == NULL) { |
| 2497 | rc = -ENOMEM; | 2501 | rc = -ENOMEM; |
| 2498 | goto out_fail; | 2502 | goto out_fail; |
| @@ -1541,6 +1541,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, · 1540 unmodified lines | |||
| 1541 | 1541 | ||
| 1542 | cifs_parse_mount_err: | 1542 | cifs_parse_mount_err: |
| 1543 | kfree_sensitive(ctx->password); | 1543 | kfree_sensitive(ctx->password); |
| 1544 | ctx->password = NULL; | ||
| 1544 | return -EINVAL; | 1545 | return -EINVAL; |
| 1545 | } | 1546 | } |
| 1546 | 1547 | ||
| @@ -2680,7 +2680,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, · 2679 unmodified lines | |||
| 2680 | } | 2680 | } |
| 2681 | 2681 | ||
| 2682 | cifsFileInfo_put(cfile); | 2682 | cifsFileInfo_put(cfile); |
| 2683 | return -ENOTSUPP; | 2683 | return -EOPNOTSUPP; |
| 2684 | } | 2684 | } |
| 2685 | 2685 | ||
| 2686 | int cifs_truncate_page(struct address_space *mapping, loff_t from) | 2686 | int cifs_truncate_page(struct address_space *mapping, loff_t from) |
| @@ -113,18 +113,22 @@ sesInfoFree(struct cifs_ses *buf_to_free) · 112 unmodified lines | |||
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | struct cifs_tcon * | 115 | struct cifs_tcon * |
| 116 | tconInfoAlloc(void) | 116 | tcon_info_alloc(bool dir_leases_enabled) |
| 117 | { | 117 | { |
| 118 | struct cifs_tcon *ret_buf; | 118 | struct cifs_tcon *ret_buf; |
| 119 | 119 | ||
| 120 | ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); | 120 | ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); |
| 121 | if (!ret_buf) | 121 | if (!ret_buf) |
| 122 | return NULL; | 122 | return NULL; |
| 123 | ret_buf->cfids = init_cached_dirs(); | 123 | |
| 124 | if (!ret_buf->cfids) { | 124 | if (dir_leases_enabled == true) { |
| 125 | kfree(ret_buf); | 125 | ret_buf->cfids = init_cached_dirs(); |
| 126 | return NULL; | 126 | if (!ret_buf->cfids) { |
| 127 | kfree(ret_buf); | ||
| 128 | return NULL; | ||
| 129 | } | ||
| 127 | } | 130 | } |
| 131 | /* else ret_buf->cfids is already set to NULL above */ | ||
| 128 | 132 | ||
| 129 | atomic_inc(&tconInfoAllocCount); | 133 | atomic_inc(&tconInfoAllocCount); |
| 130 | ret_buf->status = TID_NEW; | 134 | ret_buf->status = TID_NEW; |
| @@ -539,6 +539,9 @@ static int parse_create_response(struct cifs_open_info_data *data, · 538 unmodified lines | |||
| 539 | int rc = 0; | 539 | int rc = 0; |
| 540 | 540 | ||
| 541 | switch (rsp->hdr.Status) { | 541 | switch (rsp->hdr.Status) { |
| 542 | case STATUS_IO_REPARSE_TAG_NOT_HANDLED: | ||
| 543 | reparse_point = true; | ||
| 544 | break; | ||
| 542 | case STATUS_STOPPED_ON_SYMLINK: | 545 | case STATUS_STOPPED_ON_SYMLINK: |
| 543 | rc = smb2_parse_symlink_response(cifs_sb, iov, | 546 | rc = smb2_parse_symlink_response(cifs_sb, iov, |
| 544 | &data->symlink_target); | 547 | &data->symlink_target); |
| @@ -877,8 +877,6 @@ static const struct status_to_posix_error smb2_error_map_table[] = { · 876 unmodified lines | |||
| 877 | "STATUS_IO_REPARSE_TAG_MISMATCH"}, | 877 | "STATUS_IO_REPARSE_TAG_MISMATCH"}, |
| 878 | {STATUS_IO_REPARSE_DATA_INVALID, -EIO, | 878 | {STATUS_IO_REPARSE_DATA_INVALID, -EIO, |
| 879 | "STATUS_IO_REPARSE_DATA_INVALID"}, | 879 | "STATUS_IO_REPARSE_DATA_INVALID"}, |
| 880 | {STATUS_IO_REPARSE_TAG_NOT_HANDLED, -EIO, | ||
| 881 | "STATUS_IO_REPARSE_TAG_NOT_HANDLED"}, | ||
| 882 | {STATUS_REPARSE_POINT_NOT_RESOLVED, -EIO, | 880 | {STATUS_REPARSE_POINT_NOT_RESOLVED, -EIO, |
| 883 | "STATUS_REPARSE_POINT_NOT_RESOLVED"}, | 881 | "STATUS_REPARSE_POINT_NOT_RESOLVED"}, |
| 884 | {STATUS_DIRECTORY_IS_A_REPARSE_POINT, -EIO, | 882 | {STATUS_DIRECTORY_IS_A_REPARSE_POINT, -EIO, |
| @@ -297,7 +297,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, · 296 unmodified lines | |||
| 297 | cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", | 297 | cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", |
| 298 | credits->value, new_val); | 298 | credits->value, new_val); |
| 299 | 299 | ||
| 300 | return -ENOTSUPP; | 300 | return -EOPNOTSUPP; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | spin_lock(&server->req_lock); | 303 | spin_lock(&server->req_lock); |
| @@ -1161,7 +1161,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, · 857 unmodified lines | |||
| 1161 | /* Use a fudge factor of 256 bytes in case we collide | 1161 | /* Use a fudge factor of 256 bytes in case we collide |
| 1162 | * with a different set_EAs command. | 1162 | * with a different set_EAs command. |
| 1163 | */ | 1163 | */ |
| 1164 | if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - | 1164 | if (CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - |
| 1165 | MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 < | 1165 | MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 < |
| 1166 | used_len + ea_name_len + ea_value_len + 1) { | 1166 | used_len + ea_name_len + ea_value_len + 1) { |
| 1167 | rc = -ENOSPC; | 1167 | rc = -ENOSPC; |
| @@ -4591,7 +4591,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 3423 unmodified lines | |||
| 4591 | 4591 | ||
| 4592 | if (shdr->Command != SMB2_READ) { | 4592 | if (shdr->Command != SMB2_READ) { |
| 4593 | cifs_server_dbg(VFS, "only big read responses are supported\n"); | 4593 | cifs_server_dbg(VFS, "only big read responses are supported\n"); |
| 4594 | return -ENOTSUPP; | 4594 | return -EOPNOTSUPP; |
| 4595 | } | 4595 | } |
| 4596 | 4596 | ||
| 4597 | if (server->ops->is_session_expired && | 4597 | if (server->ops->is_session_expired && |
| @@ -89,20 +89,26 @@ smb2_hdr_assemble(struct smb2_hdr *shdr, __le16 smb2_cmd, · 88 unmodified lines | |||
| 89 | struct TCP_Server_Info *server) | 89 | struct TCP_Server_Info *server) |
| 90 | { | 90 | { |
| 91 | struct smb3_hdr_req *smb3_hdr; | 91 | struct smb3_hdr_req *smb3_hdr; |
| 92 | |||
| 92 | shdr->ProtocolId = SMB2_PROTO_NUMBER; | 93 | shdr->ProtocolId = SMB2_PROTO_NUMBER; |
| 93 | shdr->StructureSize = cpu_to_le16(64); | 94 | shdr->StructureSize = cpu_to_le16(64); |
| 94 | shdr->Command = smb2_cmd; | 95 | shdr->Command = smb2_cmd; |
| 95 | if (server->dialect >= SMB30_PROT_ID) { | 96 | |
| 96 | /* After reconnect SMB3 must set ChannelSequence on subsequent reqs */ | ||
| 97 | smb3_hdr = (struct smb3_hdr_req *)shdr; | ||
| 98 | /* if primary channel is not set yet, use default channel for chan sequence num */ | ||
| 99 | if (SERVER_IS_CHAN(server)) | ||
| 100 | smb3_hdr->ChannelSequence = | ||
| 101 | cpu_to_le16(server->primary_server->channel_sequence_num); | ||
| 102 | else | ||
| 103 | smb3_hdr->ChannelSequence = cpu_to_le16(server->channel_sequence_num); | ||
| 104 | } | ||
| 105 | if (server) { | 97 | if (server) { |
| 98 | /* After reconnect SMB3 must set ChannelSequence on subsequent reqs */ | ||
| 99 | if (server->dialect >= SMB30_PROT_ID) { | ||
| 100 | smb3_hdr = (struct smb3_hdr_req *)shdr; | ||
| 101 | /* | ||
| 102 | * if primary channel is not set yet, use default | ||
| 103 | * channel for chan sequence num | ||
| 104 | */ | ||
| 105 | if (SERVER_IS_CHAN(server)) | ||
| 106 | smb3_hdr->ChannelSequence = | ||
| 107 | cpu_to_le16(server->primary_server->channel_sequence_num); | ||
| 108 | else | ||
| 109 | smb3_hdr->ChannelSequence = | ||
| 110 | cpu_to_le16(server->channel_sequence_num); | ||
| 111 | } | ||
| 106 | spin_lock(&server->req_lock); | 112 | spin_lock(&server->req_lock); |
| 107 | /* Request up to 10 credits but don't go over the limit. */ | 113 | /* Request up to 10 credits but don't go over the limit. */ |
| 108 | if (server->credits >= server->max_credits) | 114 | if (server->credits >= server->max_credits) |
| @@ -842,7 +848,7 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) · 733 unmodified lines | |||
| 842 | 848 | ||
| 843 | iov[num].iov_base = create_posix_buf(mode); | 849 | iov[num].iov_base = create_posix_buf(mode); |
| 844 | if (mode == ACL_NO_MODE) | 850 | if (mode == ACL_NO_MODE) |
| 845 | cifs_dbg(FYI, "Invalid mode\n"); | 851 | cifs_dbg(FYI, "%s: no mode\n", __func__); |
| 846 | if (iov[num].iov_base == NULL) | 852 | if (iov[num].iov_base == NULL) |
| 847 | return -ENOMEM; | 853 | return -ENOMEM; |
| 848 | iov[num].iov_len = sizeof(struct create_posix); | 854 | iov[num].iov_len = sizeof(struct create_posix); |
| @@ -2234,7 +2240,7 @@ create_durable_v2_buf(struct cifs_open_parms *oparms) · 1385 unmodified lines | |||
| 2234 | * (most servers default to 120 seconds) and most clients default to 0. | 2240 | * (most servers default to 120 seconds) and most clients default to 0. |
| 2235 | * This can be overridden at mount ("handletimeout=") if the user wants | 2241 | * This can be overridden at mount ("handletimeout=") if the user wants |
| 2236 | * a different persistent (or resilient) handle timeout for all opens | 2242 | * a different persistent (or resilient) handle timeout for all opens |
| 2237 | * opens on a particular SMB3 mount. | 2243 | * on a particular SMB3 mount. |
| 2238 | */ | 2244 | */ |
| 2239 | buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout); | 2245 | buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout); |
| 2240 | buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); | 2246 | buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT); |
| @@ -2379,7 +2385,7 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) · 138 unmodified lines | |||
| 2379 | return 0; | 2385 | return 0; |
| 2380 | } | 2386 | } |
| 2381 | 2387 | ||
| 2382 | /* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */ | 2388 | /* See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */ |
| 2383 | static void setup_owner_group_sids(char *buf) | 2389 | static void setup_owner_group_sids(char *buf) |
| 2384 | { | 2390 | { |
| 2385 | struct owner_group_sids *sids = (struct owner_group_sids *)buf; | 2391 | struct owner_group_sids *sids = (struct owner_group_sids *)buf; |
| @@ -3124,6 +3130,7 @@ void · 738 unmodified lines | |||
| 3124 | SMB2_ioctl_free(struct smb_rqst *rqst) | 3130 | SMB2_ioctl_free(struct smb_rqst *rqst) |
| 3125 | { | 3131 | { |
| 3126 | int i; | 3132 | int i; |
| 3133 | |||
| 3127 | if (rqst && rqst->rq_iov) { | 3134 | if (rqst && rqst->rq_iov) { |
| 3128 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | 3135 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ |
| 3129 | for (i = 1; i < rqst->rq_nvec; i++) | 3136 | for (i = 1; i < rqst->rq_nvec; i++) |
| @@ -3871,7 +3878,7 @@ void smb2_reconnect_server(struct work_struct *work) · 741 unmodified lines | |||
| 3871 | goto done; | 3878 | goto done; |
| 3872 | 3879 | ||
| 3873 | /* allocate a dummy tcon struct used for reconnect */ | 3880 | /* allocate a dummy tcon struct used for reconnect */ |
| 3874 | tcon = tconInfoAlloc(); | 3881 | tcon = tcon_info_alloc(false); |
| 3875 | if (!tcon) { | 3882 | if (!tcon) { |
| 3876 | resched = true; | 3883 | resched = true; |
| 3877 | list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { | 3884 | list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { |
| @@ -1401,10 +1401,13 @@ create_conn: · 1400 unmodified lines | |||
| 1401 | server->smbd_conn = smbd_get_connection( | 1401 | server->smbd_conn = smbd_get_connection( |
| 1402 | server, (struct sockaddr *) &server->dstaddr); | 1402 | server, (struct sockaddr *) &server->dstaddr); |
| 1403 | 1403 | ||
| 1404 | if (server->smbd_conn) | 1404 | if (server->smbd_conn) { |
| 1405 | cifs_dbg(VFS, "RDMA transport re-established\n"); | 1405 | cifs_dbg(VFS, "RDMA transport re-established\n"); |
| 1406 | 1406 | trace_smb3_smbd_connect_done(server->hostname, server->conn_id, &server->dstaddr); | |
| 1407 | return server->smbd_conn ? 0 : -ENOENT; | 1407 | return 0; |
| 1408 | } | ||
| 1409 | trace_smb3_smbd_connect_err(server->hostname, server->conn_id, &server->dstaddr); | ||
| 1410 | return -ENOENT; | ||
| 1408 | } | 1411 | } |
| 1409 | 1412 | ||
| 1410 | static void destroy_caches_and_workqueue(struct smbd_connection *info) | 1413 | static void destroy_caches_and_workqueue(struct smbd_connection *info) |
| @@ -935,6 +935,8 @@ DEFINE_EVENT(smb3_connect_class, smb3_##name, \ · 934 unmodified lines | |||
| 935 | TP_ARGS(hostname, conn_id, addr)) | 935 | TP_ARGS(hostname, conn_id, addr)) |
| 936 | 936 | ||
| 937 | DEFINE_SMB3_CONNECT_EVENT(connect_done); | 937 | DEFINE_SMB3_CONNECT_EVENT(connect_done); |
| 938 | DEFINE_SMB3_CONNECT_EVENT(smbd_connect_done); | ||
| 939 | DEFINE_SMB3_CONNECT_EVENT(smbd_connect_err); | ||
| 938 | 940 | ||
| 939 | DECLARE_EVENT_CLASS(smb3_connect_err_class, | 941 | DECLARE_EVENT_CLASS(smb3_connect_err_class, |
| 940 | TP_PROTO(char *hostname, __u64 conn_id, | 942 | TP_PROTO(char *hostname, __u64 conn_id, |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/bvec.h> | 18 | #include <linux/bvec.h> |
| 19 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
| 20 | #include <linux/uaccess.h> | 20 | #include <linux/uaccess.h> |
| 21 | #include <asm/processor.h> | 21 | #include <linux/processor.h> |
| 22 | #include <linux/mempool.h> | 22 | #include <linux/mempool.h> |
| 23 | #include <linux/sched/signal.h> | 23 | #include <linux/sched/signal.h> |
| 24 | #include <linux/task_io_accounting_ops.h> | 24 | #include <linux/task_io_accounting_ops.h> |
| @@ -35,6 +35,8 @@ · 10 unmodified lines | |||
| 35 | void | 35 | void |
| 36 | cifs_wake_up_task(struct mid_q_entry *mid) | 36 | cifs_wake_up_task(struct mid_q_entry *mid) |
| 37 | { | 37 | { |
| 38 | if (mid->mid_state == MID_RESPONSE_RECEIVED) | ||
| 39 | mid->mid_state = MID_RESPONSE_READY; | ||
| 38 | wake_up_process(mid->callback_data); | 40 | wake_up_process(mid->callback_data); |
| 39 | } | 41 | } |
| 40 | 42 | ||
| @@ -87,7 +89,8 @@ static void __release_mid(struct kref *refcount) · 46 unmodified lines | |||
| 87 | struct TCP_Server_Info *server = midEntry->server; | 89 | struct TCP_Server_Info *server = midEntry->server; |
| 88 | 90 | ||
| 89 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && | 91 | if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && |
| 90 | midEntry->mid_state == MID_RESPONSE_RECEIVED && | 92 | (midEntry->mid_state == MID_RESPONSE_RECEIVED || |
| 93 | midEntry->mid_state == MID_RESPONSE_READY) && | ||
| 91 | server->ops->handle_cancelled_mid) | 94 | server->ops->handle_cancelled_mid) |
| 92 | server->ops->handle_cancelled_mid(midEntry, server); | 95 | server->ops->handle_cancelled_mid(midEntry, server); |
| 93 | 96 | ||
| @@ -737,7 +740,8 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) · 643 unmodified lines | |||
| 737 | int error; | 740 | int error; |
| 738 | 741 | ||
| 739 | error = wait_event_state(server->response_q, | 742 | error = wait_event_state(server->response_q, |
| 740 | midQ->mid_state != MID_REQUEST_SUBMITTED, | 743 | midQ->mid_state != MID_REQUEST_SUBMITTED && |
| 744 | midQ->mid_state != MID_RESPONSE_RECEIVED, | ||
| 741 | (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); | 745 | (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); |
| 742 | if (error < 0) | 746 | if (error < 0) |
| 743 | return -ERESTARTSYS; | 747 | return -ERESTARTSYS; |
| @@ -890,7 +894,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) · 146 unmodified lines | |||
| 890 | 894 | ||
| 891 | spin_lock(&server->mid_lock); | 895 | spin_lock(&server->mid_lock); |
| 892 | switch (mid->mid_state) { | 896 | switch (mid->mid_state) { |
| 893 | case MID_RESPONSE_RECEIVED: | 897 | case MID_RESPONSE_READY: |
| 894 | spin_unlock(&server->mid_lock); | 898 | spin_unlock(&server->mid_lock); |
| 895 | return rc; | 899 | return rc; |
| 896 | case MID_RETRY_NEEDED: | 900 | case MID_RETRY_NEEDED: |
| @@ -989,6 +993,9 @@ cifs_compound_callback(struct mid_q_entry *mid) · 92 unmodified lines | |||
| 989 | credits.instance = server->reconnect_instance; | 993 | credits.instance = server->reconnect_instance; |
| 990 | 994 | ||
| 991 | add_credits(server, &credits, mid->optype); | 995 | add_credits(server, &credits, mid->optype); |
| 996 | |||
| 997 | if (mid->mid_state == MID_RESPONSE_RECEIVED) | ||
| 998 | mid->mid_state = MID_RESPONSE_READY; | ||
| 992 | } | 999 | } |
| 993 | 1000 | ||
| 994 | static void | 1001 | static void |
| @@ -1209,7 +1216,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 214 unmodified lines | |||
| 1209 | send_cancel(server, &rqst[i], midQ[i]); | 1216 | send_cancel(server, &rqst[i], midQ[i]); |
| 1210 | spin_lock(&server->mid_lock); | 1217 | spin_lock(&server->mid_lock); |
| 1211 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; | 1218 | midQ[i]->mid_flags |= MID_WAIT_CANCELLED; |
| 1212 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { | 1219 | if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || |
| 1220 | midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1213 | midQ[i]->callback = cifs_cancelled_callback; | 1221 | midQ[i]->callback = cifs_cancelled_callback; |
| 1214 | cancelled_mid[i] = true; | 1222 | cancelled_mid[i] = true; |
| 1215 | credits[i].value = 0; | 1223 | credits[i].value = 0; |
| @@ -1230,7 +1238,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 14 unmodified lines | |||
| 1230 | } | 1238 | } |
| 1231 | 1239 | ||
| 1232 | if (!midQ[i]->resp_buf || | 1240 | if (!midQ[i]->resp_buf || |
| 1233 | midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { | 1241 | midQ[i]->mid_state != MID_RESPONSE_READY) { |
| 1234 | rc = -EIO; | 1242 | rc = -EIO; |
| 1235 | cifs_dbg(FYI, "Bad MID state?\n"); | 1243 | cifs_dbg(FYI, "Bad MID state?\n"); |
| 1236 | goto out; | 1244 | goto out; |
| @@ -1417,7 +1425,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 180 unmodified lines | |||
| 1417 | if (rc != 0) { | 1425 | if (rc != 0) { |
| 1418 | send_cancel(server, &rqst, midQ); | 1426 | send_cancel(server, &rqst, midQ); |
| 1419 | spin_lock(&server->mid_lock); | 1427 | spin_lock(&server->mid_lock); |
| 1420 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { | 1428 | if (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1429 | midQ->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1421 | /* no longer considered to be "in-flight" */ | 1430 | /* no longer considered to be "in-flight" */ |
| 1422 | midQ->callback = release_mid; | 1431 | midQ->callback = release_mid; |
| 1423 | spin_unlock(&server->mid_lock); | 1432 | spin_unlock(&server->mid_lock); |
| @@ -1434,7 +1443,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 10 unmodified lines | |||
| 1434 | } | 1443 | } |
| 1435 | 1444 | ||
| 1436 | if (!midQ->resp_buf || !out_buf || | 1445 | if (!midQ->resp_buf || !out_buf || |
| 1437 | midQ->mid_state != MID_RESPONSE_RECEIVED) { | 1446 | midQ->mid_state != MID_RESPONSE_READY) { |
| 1438 | rc = -EIO; | 1447 | rc = -EIO; |
| 1439 | cifs_server_dbg(VFS, "Bad MID state?\n"); | 1448 | cifs_server_dbg(VFS, "Bad MID state?\n"); |
| 1440 | goto out; | 1449 | goto out; |
| @@ -1558,14 +1567,16 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 117 unmodified lines | |||
| 1558 | 1567 | ||
| 1559 | /* Wait for a reply - allow signals to interrupt. */ | 1568 | /* Wait for a reply - allow signals to interrupt. */ |
| 1560 | rc = wait_event_interruptible(server->response_q, | 1569 | rc = wait_event_interruptible(server->response_q, |
| 1561 | (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || | 1570 | (!(midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1571 | midQ->mid_state == MID_RESPONSE_RECEIVED)) || | ||
| 1562 | ((server->tcpStatus != CifsGood) && | 1572 | ((server->tcpStatus != CifsGood) && |
| 1563 | (server->tcpStatus != CifsNew))); | 1573 | (server->tcpStatus != CifsNew))); |
| 1564 | 1574 | ||
| 1565 | /* Were we interrupted by a signal ? */ | 1575 | /* Were we interrupted by a signal ? */ |
| 1566 | spin_lock(&server->srv_lock); | 1576 | spin_lock(&server->srv_lock); |
| 1567 | if ((rc == -ERESTARTSYS) && | 1577 | if ((rc == -ERESTARTSYS) && |
| 1568 | (midQ->mid_state == MID_REQUEST_SUBMITTED) && | 1578 | (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1579 | midQ->mid_state == MID_RESPONSE_RECEIVED) && | ||
| 1569 | ((server->tcpStatus == CifsGood) || | 1580 | ((server->tcpStatus == CifsGood) || |
| 1570 | (server->tcpStatus == CifsNew))) { | 1581 | (server->tcpStatus == CifsNew))) { |
| 1571 | spin_unlock(&server->srv_lock); | 1582 | spin_unlock(&server->srv_lock); |
| @@ -1596,7 +1607,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 24 unmodified lines | |||
| 1596 | if (rc) { | 1607 | if (rc) { |
| 1597 | send_cancel(server, &rqst, midQ); | 1608 | send_cancel(server, &rqst, midQ); |
| 1598 | spin_lock(&server->mid_lock); | 1609 | spin_lock(&server->mid_lock); |
| 1599 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { | 1610 | if (midQ->mid_state == MID_REQUEST_SUBMITTED || |
| 1611 | midQ->mid_state == MID_RESPONSE_RECEIVED) { | ||
| 1600 | /* no longer considered to be "in-flight" */ | 1612 | /* no longer considered to be "in-flight" */ |
| 1601 | midQ->callback = release_mid; | 1613 | midQ->callback = release_mid; |
| 1602 | spin_unlock(&server->mid_lock); | 1614 | spin_unlock(&server->mid_lock); |
| @@ -1616,7 +1628,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 13 unmodified lines | |||
| 1616 | return rc; | 1628 | return rc; |
| 1617 | 1629 | ||
| 1618 | /* rcvd frame is ok */ | 1630 | /* rcvd frame is ok */ |
| 1619 | if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { | 1631 | if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { |
| 1620 | rc = -EIO; | 1632 | rc = -EIO; |
| 1621 | cifs_tcon_dbg(VFS, "Bad MID state?\n"); | 1633 | cifs_tcon_dbg(VFS, "Bad MID state?\n"); |
| 1622 | goto out; | 1634 | goto out; |
| @@ -197,6 +197,9 @@ int ksmbd_conn_write(struct ksmbd_work *work) · 196 unmodified lines | |||
| 197 | if (work->send_no_response) | 197 | if (work->send_no_response) |
| 198 | return 0; | 198 | return 0; |
| 199 | 199 | ||
| 200 | if (!work->iov_idx) | ||
| 201 | return -EINVAL; | ||
| 202 | |||
| 200 | ksmbd_conn_lock(conn); | 203 | ksmbd_conn_lock(conn); |
| 201 | sent = conn->transport->ops->writev(conn->transport, work->iov, | 204 | sent = conn->transport->ops->writev(conn->transport, work->iov, |
| 202 | work->iov_cnt, | 205 | work->iov_cnt, |
| @@ -115,8 +115,10 @@ static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, · 114 unmodified lines | |||
| 115 | if (check_conn_state(work)) | 115 | if (check_conn_state(work)) |
| 116 | return SERVER_HANDLER_CONTINUE; | 116 | return SERVER_HANDLER_CONTINUE; |
| 117 | 117 | ||
| 118 | if (ksmbd_verify_smb_message(work)) | 118 | if (ksmbd_verify_smb_message(work)) { |
| 119 | conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); | ||
| 119 | return SERVER_HANDLER_ABORT; | 120 | return SERVER_HANDLER_ABORT; |
| 121 | } | ||
| 120 | 122 | ||
| 121 | command = conn->ops->get_cmd_val(work); | 123 | command = conn->ops->get_cmd_val(work); |
| 122 | *cmd = command; | 124 | *cmd = command; |
| @@ -440,10 +440,8 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work) · 439 unmodified lines | |||
| 440 | 440 | ||
| 441 | validate_credit: | 441 | validate_credit: |
| 442 | if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && | 442 | if ((work->conn->vals->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU) && |
| 443 | smb2_validate_credit_charge(work->conn, hdr)) { | 443 | smb2_validate_credit_charge(work->conn, hdr)) |
| 444 | work->conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); | ||
| 445 | return 1; | 444 | return 1; |
| 446 | } | ||
| 447 | 445 | ||
| 448 | return 0; | 446 | return 0; |
| 449 | } | 447 | } |
| @@ -6312,7 +6312,7 @@ int smb2_read(struct ksmbd_work *work) · 6311 unmodified lines | |||
| 6312 | aux_payload_buf, | 6312 | aux_payload_buf, |
| 6313 | nbytes); | 6313 | nbytes); |
| 6314 | kvfree(aux_payload_buf); | 6314 | kvfree(aux_payload_buf); |
| 6315 | 6315 | aux_payload_buf = NULL; | |
| 6316 | nbytes = 0; | 6316 | nbytes = 0; |
| 6317 | if (remain_bytes < 0) { | 6317 | if (remain_bytes < 0) { |
| 6318 | err = (int)remain_bytes; | 6318 | err = (int)remain_bytes; |
| @@ -1420,7 +1420,6 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, · 1419 unmodified lines | |||
| 1420 | out: | 1420 | out: |
| 1421 | posix_acl_release(fattr.cf_acls); | 1421 | posix_acl_release(fattr.cf_acls); |
| 1422 | posix_acl_release(fattr.cf_dacls); | 1422 | posix_acl_release(fattr.cf_dacls); |
| 1423 | mark_inode_dirty(inode); | ||
| 1424 | return rc; | 1423 | return rc; |
| 1425 | } | 1424 | } |
| 1426 | 1425 | ||
| @@ -26,37 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include "internal.h" | 26 | #include "internal.h" |
| 27 | #include "mount.h" | 27 | #include "mount.h" |
| 28 | 28 | ||
| 29 | /** | ||
| 30 | * fill_mg_cmtime - Fill in the mtime and ctime and flag ctime as QUERIED | ||
| 31 | * @stat: where to store the resulting values | ||
| 32 | * @request_mask: STATX_* values requested | ||
| 33 | * @inode: inode from which to grab the c/mtime | ||
| 34 | * | ||
| 35 | * Given @inode, grab the ctime and mtime out if it and store the result | ||
| 36 | * in @stat. When fetching the value, flag it as queried so the next write | ||
| 37 | * will use a fine-grained timestamp. | ||
| 38 | */ | ||
| 39 | void fill_mg_cmtime(struct kstat *stat, u32 request_mask, struct inode *inode) | ||
| 40 | { | ||
| 41 | atomic_long_t *pnsec = (atomic_long_t *)&inode->__i_ctime.tv_nsec; | ||
| 42 | |||
| 43 | /* If neither time was requested, then don't report them */ | ||
| 44 | if (!(request_mask & (STATX_CTIME|STATX_MTIME))) { | ||
| 45 | stat->result_mask &= ~(STATX_CTIME|STATX_MTIME); | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | |||
| 49 | stat->mtime = inode->i_mtime; | ||
| 50 | stat->ctime.tv_sec = inode->__i_ctime.tv_sec; | ||
| 51 | /* | ||
| 52 | * Atomically set the QUERIED flag and fetch the new value with | ||
| 53 | * the flag masked off. | ||
| 54 | */ | ||
| 55 | stat->ctime.tv_nsec = atomic_long_fetch_or(I_CTIME_QUERIED, pnsec) & | ||
| 56 | ~I_CTIME_QUERIED; | ||
| 57 | } | ||
| 58 | EXPORT_SYMBOL(fill_mg_cmtime); | ||
| 59 | |||
| 60 | /** | 29 | /** |
| 61 | * generic_fillattr - Fill in the basic attributes from the inode struct | 30 | * generic_fillattr - Fill in the basic attributes from the inode struct |
| 62 | * @idmap: idmap of the mount the inode was found from | 31 | * @idmap: idmap of the mount the inode was found from |
| @@ -89,14 +58,8 @@ void generic_fillattr(struct mnt_idmap *idmap, u32 request_mask, · 26 unmodified lines | |||
| 89 | stat->rdev = inode->i_rdev; | 58 | stat->rdev = inode->i_rdev; |
| 90 | stat->size = i_size_read(inode); | 59 | stat->size = i_size_read(inode); |
| 91 | stat->atime = inode->i_atime; | 60 | stat->atime = inode->i_atime; |
| 92 | 61 | stat->mtime = inode->i_mtime; | |
| 93 | if (is_mgtime(inode)) { | 62 | stat->ctime = inode_get_ctime(inode); |
| 94 | fill_mg_cmtime(stat, request_mask, inode); | ||
| 95 | } else { | ||
| 96 | stat->mtime = inode->i_mtime; | ||
| 97 | stat->ctime = inode_get_ctime(inode); | ||
| 98 | } | ||
| 99 | |||
| 100 | stat->blksize = i_blocksize(inode); | 63 | stat->blksize = i_blocksize(inode); |
| 101 | stat->blocks = inode->i_blocks; | 64 | stat->blocks = inode->i_blocks; |
| 102 | 65 | ||
| @@ -419,12 +382,6 @@ SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, stat · 316 unmodified lines | |||
| 419 | 382 | ||
| 420 | #ifdef __ARCH_WANT_NEW_STAT | 383 | #ifdef __ARCH_WANT_NEW_STAT |
| 421 | 384 | ||
| 422 | #if BITS_PER_LONG == 32 | ||
| 423 | # define choose_32_64(a,b) a | ||
| 424 | #else | ||
| 425 | # define choose_32_64(a,b) b | ||
| 426 | #endif | ||
| 427 | |||
| 428 | #ifndef INIT_STRUCT_STAT_PADDING | 385 | #ifndef INIT_STRUCT_STAT_PADDING |
| 429 | # define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st)) | 386 | # define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st)) |
| 430 | #endif | 387 | #endif |
| @@ -70,6 +70,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 69 unmodified lines | |||
| 70 | struct dentry *dentry, | 70 | struct dentry *dentry, |
| 71 | unsigned int flags); | 71 | unsigned int flags); |
| 72 | static int dcache_dir_open_wrapper(struct inode *inode, struct file *file); | 72 | static int dcache_dir_open_wrapper(struct inode *inode, struct file *file); |
| 73 | static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx); | ||
| 73 | static int eventfs_release(struct inode *inode, struct file *file); | 74 | static int eventfs_release(struct inode *inode, struct file *file); |
| 74 | 75 | ||
| 75 | static const struct inode_operations eventfs_root_dir_inode_operations = { | 76 | static const struct inode_operations eventfs_root_dir_inode_operations = { |
| @@ -79,7 +80,7 @@ static const struct inode_operations eventfs_root_dir_inode_operations = { · 3 unmodified lines | |||
| 79 | static const struct file_operations eventfs_file_operations = { | 80 | static const struct file_operations eventfs_file_operations = { |
| 80 | .open = dcache_dir_open_wrapper, | 81 | .open = dcache_dir_open_wrapper, |
| 81 | .read = generic_read_dir, | 82 | .read = generic_read_dir, |
| 82 | .iterate_shared = dcache_readdir, | 83 | .iterate_shared = dcache_readdir_wrapper, |
| 83 | .llseek = generic_file_llseek, | 84 | .llseek = generic_file_llseek, |
| 84 | .release = eventfs_release, | 85 | .release = eventfs_release, |
| 85 | }; | 86 | }; |
| @@ -185,17 +186,49 @@ static struct dentry *create_dir(const char *name, struct dentry *parent, void * · 99 unmodified lines | |||
| 185 | 186 | ||
| 186 | /** | 187 | /** |
| 187 | * eventfs_set_ef_status_free - set the ef->status to free | 188 | * eventfs_set_ef_status_free - set the ef->status to free |
| 189 | * @ti: the tracefs_inode of the dentry | ||
| 188 | * @dentry: dentry who's status to be freed | 190 | * @dentry: dentry who's status to be freed |
| 189 | * | 191 | * |
| 190 | * eventfs_set_ef_status_free will be called if no more | 192 | * eventfs_set_ef_status_free will be called if no more |
| 191 | * references remain | 193 | * references remain |
| 192 | */ | 194 | */ |
| 193 | void eventfs_set_ef_status_free(struct dentry *dentry) | 195 | void eventfs_set_ef_status_free(struct tracefs_inode *ti, struct dentry *dentry) |
| 194 | { | 196 | { |
| 195 | struct tracefs_inode *ti_parent; | 197 | struct tracefs_inode *ti_parent; |
| 196 | struct eventfs_file *ef; | 198 | struct eventfs_inode *ei; |
| 199 | struct eventfs_file *ef, *tmp; | ||
| 200 | |||
| 201 | /* The top level events directory may be freed by this */ | ||
| 202 | if (unlikely(ti->flags & TRACEFS_EVENT_TOP_INODE)) { | ||
| 203 | LIST_HEAD(ef_del_list); | ||
| 204 | |||
| 205 | mutex_lock(&eventfs_mutex); | ||
| 206 | |||
| 207 | ei = ti->private; | ||
| 208 | |||
| 209 | /* Record all the top level files */ | ||
| 210 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, | ||
| 211 | lockdep_is_held(&eventfs_mutex)) { | ||
| 212 | list_add_tail(&ef->del_list, &ef_del_list); | ||
| 213 | } | ||
| 214 | |||
| 215 | /* Nothing should access this, but just in case! */ | ||
| 216 | ti->private = NULL; | ||
| 217 | |||
| 218 | mutex_unlock(&eventfs_mutex); | ||
| 219 | |||
| 220 | /* Now safely free the top level files and their children */ | ||
| 221 | list_for_each_entry_safe(ef, tmp, &ef_del_list, del_list) { | ||
| 222 | list_del(&ef->del_list); | ||
| 223 | eventfs_remove(ef); | ||
| 224 | } | ||
| 225 | |||
| 226 | kfree(ei); | ||
| 227 | return; | ||
| 228 | } | ||
| 197 | 229 | ||
| 198 | mutex_lock(&eventfs_mutex); | 230 | mutex_lock(&eventfs_mutex); |
| 231 | |||
| 199 | ti_parent = get_tracefs(dentry->d_parent->d_inode); | 232 | ti_parent = get_tracefs(dentry->d_parent->d_inode); |
| 200 | if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE)) | 233 | if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE)) |
| 201 | goto out; | 234 | goto out; |
| @@ -364,6 +397,11 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 162 unmodified lines | |||
| 364 | return ret; | 397 | return ret; |
| 365 | } | 398 | } |
| 366 | 399 | ||
| 400 | struct dentry_list { | ||
| 401 | void *cursor; | ||
| 402 | struct dentry **dentries; | ||
| 403 | }; | ||
| 404 | |||
| 367 | /** | 405 | /** |
| 368 | * eventfs_release - called to release eventfs file/dir | 406 | * eventfs_release - called to release eventfs file/dir |
| 369 | * @inode: inode to be released | 407 | * @inode: inode to be released |
| @@ -372,26 +410,25 @@ static struct dentry *eventfs_root_lookup(struct inode *dir, · 2 unmodified lines | |||
| 372 | static int eventfs_release(struct inode *inode, struct file *file) | 410 | static int eventfs_release(struct inode *inode, struct file *file) |
| 373 | { | 411 | { |
| 374 | struct tracefs_inode *ti; | 412 | struct tracefs_inode *ti; |
| 375 | struct eventfs_inode *ei; | 413 | struct dentry_list *dlist = file->private_data; |
| 376 | struct eventfs_file *ef; | 414 | void *cursor; |
| 377 | struct dentry *dentry; | 415 | int i; |
| 378 | int idx; | ||
| 379 | 416 | ||
| 380 | ti = get_tracefs(inode); | 417 | ti = get_tracefs(inode); |
| 381 | if (!(ti->flags & TRACEFS_EVENT_INODE)) | 418 | if (!(ti->flags & TRACEFS_EVENT_INODE)) |
| 382 | return -EINVAL; | 419 | return -EINVAL; |
| 383 | 420 | ||
| 384 | ei = ti->private; | 421 | if (WARN_ON_ONCE(!dlist)) |
| 385 | idx = srcu_read_lock(&eventfs_srcu); | 422 | return -EINVAL; |
| 386 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, | 423 | |
| 387 | srcu_read_lock_held(&eventfs_srcu)) { | 424 | for (i = 0; dlist->dentries && dlist->dentries[i]; i++) { |
| 388 | mutex_lock(&eventfs_mutex); | 425 | dput(dlist->dentries[i]); |
| 389 | dentry = ef->dentry; | ||
| 390 | mutex_unlock(&eventfs_mutex); | ||
| 391 | if (dentry) | ||
| 392 | dput(dentry); | ||
| 393 | } | 426 | } |
| 394 | srcu_read_unlock(&eventfs_srcu, idx); | 427 | |
| 428 | cursor = dlist->cursor; | ||
| 429 | kfree(dlist->dentries); | ||
| 430 | kfree(dlist); | ||
| 431 | file->private_data = cursor; | ||
| 395 | return dcache_dir_close(inode, file); | 432 | return dcache_dir_close(inode, file); |
| 396 | } | 433 | } |
| 397 | 434 | ||
| @@ -410,21 +447,70 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file) · 12 unmodified lines | |||
| 410 | struct tracefs_inode *ti; | 447 | struct tracefs_inode *ti; |
| 411 | struct eventfs_inode *ei; | 448 | struct eventfs_inode *ei; |
| 412 | struct eventfs_file *ef; | 449 | struct eventfs_file *ef; |
| 450 | struct dentry_list *dlist; | ||
| 451 | struct dentry **dentries = NULL; | ||
| 413 | struct dentry *dentry = file_dentry(file); | 452 | struct dentry *dentry = file_dentry(file); |
| 453 | struct dentry *d; | ||
| 414 | struct inode *f_inode = file_inode(file); | 454 | struct inode *f_inode = file_inode(file); |
| 455 | int cnt = 0; | ||
| 415 | int idx; | 456 | int idx; |
| 457 | int ret; | ||
| 416 | 458 | ||
| 417 | ti = get_tracefs(f_inode); | 459 | ti = get_tracefs(f_inode); |
| 418 | if (!(ti->flags & TRACEFS_EVENT_INODE)) | 460 | if (!(ti->flags & TRACEFS_EVENT_INODE)) |
| 419 | return -EINVAL; | 461 | return -EINVAL; |
| 420 | 462 | ||
| 463 | if (WARN_ON_ONCE(file->private_data)) | ||
| 464 | return -EINVAL; | ||
| 465 | |||
| 466 | dlist = kmalloc(sizeof(*dlist), GFP_KERNEL); | ||
| 467 | if (!dlist) | ||
| 468 | return -ENOMEM; | ||
| 469 | |||
| 421 | ei = ti->private; | 470 | ei = ti->private; |
| 422 | idx = srcu_read_lock(&eventfs_srcu); | 471 | idx = srcu_read_lock(&eventfs_srcu); |
| 423 | list_for_each_entry_rcu(ef, &ei->e_top_files, list) { | 472 | list_for_each_entry_srcu(ef, &ei->e_top_files, list, |
| 424 | create_dentry(ef, dentry, false); | 473 | srcu_read_lock_held(&eventfs_srcu)) { |
| 474 | d = create_dentry(ef, dentry, false); | ||
| 475 | if (d) { | ||
| 476 | struct dentry **tmp; | ||
| 477 | |||
| 478 | tmp = krealloc(dentries, sizeof(d) * (cnt + 2), GFP_KERNEL); | ||
| 479 | if (!tmp) | ||
| 480 | break; | ||
| 481 | tmp[cnt] = d; | ||
| 482 | tmp[cnt + 1] = NULL; | ||
| 483 | cnt++; | ||
| 484 | dentries = tmp; | ||
| 485 | } | ||
| 425 | } | 486 | } |
| 426 | srcu_read_unlock(&eventfs_srcu, idx); | 487 | srcu_read_unlock(&eventfs_srcu, idx); |
| 427 | return dcache_dir_open(inode, file); | 488 | ret = dcache_dir_open(inode, file); |
| 489 | |||
| 490 | /* | ||
| 491 | * dcache_dir_open() sets file->private_data to a dentry cursor. | ||
| 492 | * Need to save that but also save all the dentries that were | ||
| 493 | * opened by this function. | ||
| 494 | */ | ||
| 495 | dlist->cursor = file->private_data; | ||
| 496 | dlist->dentries = dentries; | ||
| 497 | file->private_data = dlist; | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | * This just sets the file->private_data back to the cursor and back. | ||
| 503 | */ | ||
| 504 | static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx) | ||
| 505 | { | ||
| 506 | struct dentry_list *dlist = file->private_data; | ||
| 507 | int ret; | ||
| 508 | |||
| 509 | file->private_data = dlist->cursor; | ||
| 510 | ret = dcache_readdir(file, ctx); | ||
| 511 | dlist->cursor = file->private_data; | ||
| 512 | file->private_data = dlist; | ||
| 513 | return ret; | ||
| 428 | } | 514 | } |
| 429 | 515 | ||
| 430 | /** | 516 | /** |
| @@ -491,6 +577,9 @@ struct dentry *eventfs_create_events_dir(const char *name, · 60 unmodified lines | |||
| 491 | struct tracefs_inode *ti; | 577 | struct tracefs_inode *ti; |
| 492 | struct inode *inode; | 578 | struct inode *inode; |
| 493 | 579 | ||
| 580 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 581 | return NULL; | ||
| 582 | |||
| 494 | if (IS_ERR(dentry)) | 583 | if (IS_ERR(dentry)) |
| 495 | return dentry; | 584 | return dentry; |
| 496 | 585 | ||
| @@ -507,7 +596,7 @@ struct dentry *eventfs_create_events_dir(const char *name, · 10 unmodified lines | |||
| 507 | INIT_LIST_HEAD(&ei->e_top_files); | 596 | INIT_LIST_HEAD(&ei->e_top_files); |
| 508 | 597 | ||
| 509 | ti = get_tracefs(inode); | 598 | ti = get_tracefs(inode); |
| 510 | ti->flags |= TRACEFS_EVENT_INODE; | 599 | ti->flags |= TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE; |
| 511 | ti->private = ei; | 600 | ti->private = ei; |
| 512 | 601 | ||
| 513 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; | 602 | inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; |
| @@ -538,6 +627,9 @@ struct eventfs_file *eventfs_add_subsystem_dir(const char *name, · 24 unmodified lines | |||
| 538 | struct eventfs_inode *ei_parent; | 627 | struct eventfs_inode *ei_parent; |
| 539 | struct eventfs_file *ef; | 628 | struct eventfs_file *ef; |
| 540 | 629 | ||
| 630 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 631 | return NULL; | ||
| 632 | |||
| 541 | if (!parent) | 633 | if (!parent) |
| 542 | return ERR_PTR(-EINVAL); | 634 | return ERR_PTR(-EINVAL); |
| 543 | 635 | ||
| @@ -569,6 +661,9 @@ struct eventfs_file *eventfs_add_dir(const char *name, · 25 unmodified lines | |||
| 569 | { | 661 | { |
| 570 | struct eventfs_file *ef; | 662 | struct eventfs_file *ef; |
| 571 | 663 | ||
| 664 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 665 | return NULL; | ||
| 666 | |||
| 572 | if (!ef_parent) | 667 | if (!ef_parent) |
| 573 | return ERR_PTR(-EINVAL); | 668 | return ERR_PTR(-EINVAL); |
| 574 | 669 | ||
| @@ -606,6 +701,9 @@ int eventfs_add_events_file(const char *name, umode_t mode, · 31 unmodified lines | |||
| 606 | struct eventfs_inode *ei; | 701 | struct eventfs_inode *ei; |
| 607 | struct eventfs_file *ef; | 702 | struct eventfs_file *ef; |
| 608 | 703 | ||
| 704 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 705 | return -ENODEV; | ||
| 706 | |||
| 609 | if (!parent) | 707 | if (!parent) |
| 610 | return -EINVAL; | 708 | return -EINVAL; |
| 611 | 709 | ||
| @@ -654,6 +752,9 @@ int eventfs_add_file(const char *name, umode_t mode, · 42 unmodified lines | |||
| 654 | { | 752 | { |
| 655 | struct eventfs_file *ef; | 753 | struct eventfs_file *ef; |
| 656 | 754 | ||
| 755 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 756 | return -ENODEV; | ||
| 757 | |||
| 657 | if (!ef_parent) | 758 | if (!ef_parent) |
| 658 | return -EINVAL; | 759 | return -EINVAL; |
| 659 | 760 | ||
| @@ -791,7 +892,6 @@ void eventfs_remove(struct eventfs_file *ef) · 131 unmodified lines | |||
| 791 | void eventfs_remove_events_dir(struct dentry *dentry) | 892 | void eventfs_remove_events_dir(struct dentry *dentry) |
| 792 | { | 893 | { |
| 793 | struct tracefs_inode *ti; | 894 | struct tracefs_inode *ti; |
| 794 | struct eventfs_inode *ei; | ||
| 795 | 895 | ||
| 796 | if (!dentry || !dentry->d_inode) | 896 | if (!dentry || !dentry->d_inode) |
| 797 | return; | 897 | return; |
| @@ -800,8 +900,6 @@ void eventfs_remove_events_dir(struct dentry *dentry) · 2 unmodified lines | |||
| 800 | if (!ti || !(ti->flags & TRACEFS_EVENT_INODE)) | 900 | if (!ti || !(ti->flags & TRACEFS_EVENT_INODE)) |
| 801 | return; | 901 | return; |
| 802 | 902 | ||
| 803 | ei = ti->private; | ||
| 804 | d_invalidate(dentry); | 903 | d_invalidate(dentry); |
| 805 | dput(dentry); | 904 | dput(dentry); |
| 806 | kfree(ei); | ||
| 807 | } | 905 | } |
| @@ -385,7 +385,7 @@ static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode) · 384 unmodified lines | |||
| 385 | 385 | ||
| 386 | ti = get_tracefs(inode); | 386 | ti = get_tracefs(inode); |
| 387 | if (ti && ti->flags & TRACEFS_EVENT_INODE) | 387 | if (ti && ti->flags & TRACEFS_EVENT_INODE) |
| 388 | eventfs_set_ef_status_free(dentry); | 388 | eventfs_set_ef_status_free(ti, dentry); |
| 389 | iput(inode); | 389 | iput(inode); |
| 390 | } | 390 | } |
| 391 | 391 | ||
| @@ -673,6 +673,9 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, · 281 unmodified lines | |||
| 673 | */ | 673 | */ |
| 674 | struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) | 674 | struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) |
| 675 | { | 675 | { |
| 676 | if (security_locked_down(LOCKDOWN_TRACEFS)) | ||
| 677 | return NULL; | ||
| 678 | |||
| 676 | return __create_dir(name, parent, &simple_dir_inode_operations); | 679 | return __create_dir(name, parent, &simple_dir_inode_operations); |
| 677 | } | 680 | } |
| 678 | 681 | ||
| @@ -3,7 +3,8 @@ · 2 unmodified lines | |||
| 3 | #define _TRACEFS_INTERNAL_H | 3 | #define _TRACEFS_INTERNAL_H |
| 4 | 4 | ||
| 5 | enum { | 5 | enum { |
| 6 | TRACEFS_EVENT_INODE = BIT(1), | 6 | TRACEFS_EVENT_INODE = BIT(1), |
| 7 | TRACEFS_EVENT_TOP_INODE = BIT(2), | ||
| 7 | }; | 8 | }; |
| 8 | 9 | ||
| 9 | struct tracefs_inode { | 10 | struct tracefs_inode { |
| @@ -24,6 +25,6 @@ struct inode *tracefs_get_inode(struct super_block *sb); · 14 unmodified lines | |||
| 24 | struct dentry *eventfs_start_creating(const char *name, struct dentry *parent); | 25 | struct dentry *eventfs_start_creating(const char *name, struct dentry *parent); |
| 25 | struct dentry *eventfs_failed_creating(struct dentry *dentry); | 26 | struct dentry *eventfs_failed_creating(struct dentry *dentry); |
| 26 | struct dentry *eventfs_end_creating(struct dentry *dentry); | 27 | struct dentry *eventfs_end_creating(struct dentry *dentry); |
| 27 | void eventfs_set_ef_status_free(struct dentry *dentry); | 28 | void eventfs_set_ef_status_free(struct tracefs_inode *ti, struct dentry *dentry); |
| 28 | 29 | ||
| 29 | #endif /* _TRACEFS_INTERNAL_H */ | 30 | #endif /* _TRACEFS_INTERNAL_H */ |
| @@ -147,7 +147,7 @@ config XFS_ONLINE_SCRUB_STATS · 146 unmodified lines | |||
| 147 | bool "XFS online metadata check usage data collection" | 147 | bool "XFS online metadata check usage data collection" |
| 148 | default y | 148 | default y |
| 149 | depends on XFS_ONLINE_SCRUB | 149 | depends on XFS_ONLINE_SCRUB |
| 150 | select FS_DEBUG | 150 | select XFS_DEBUG |
| 151 | help | 151 | help |
| 152 | If you say Y here, the kernel will gather usage data about | 152 | If you say Y here, the kernel will gather usage data about |
| 153 | the online metadata check subsystem. This includes the number | 153 | the online metadata check subsystem. This includes the number |
| @@ -131,4 +131,26 @@ void xlog_check_buf_cancel_table(struct xlog *log); · 130 unmodified lines | |||
| 131 | #define xlog_check_buf_cancel_table(log) do { } while (0) | 131 | #define xlog_check_buf_cancel_table(log) do { } while (0) |
| 132 | #endif | 132 | #endif |
| 133 | 133 | ||
| 134 | /* | ||
| 135 | * Transform a regular reservation into one suitable for recovery of a log | ||
| 136 | * intent item. | ||
| 137 | * | ||
| 138 | * Intent recovery only runs a single step of the transaction chain and defers | ||
| 139 | * the rest to a separate transaction. Therefore, we reduce logcount to 1 here | ||
| 140 | * to avoid livelocks if the log grant space is nearly exhausted due to the | ||
| 141 | * recovered intent pinning the tail. Keep the same logflags to avoid tripping | ||
| 142 | * asserts elsewhere. Struct copies abound below. | ||
| 143 | */ | ||
| 144 | static inline struct xfs_trans_res | ||
| 145 | xlog_recover_resv(const struct xfs_trans_res *r) | ||
| 146 | { | ||
| 147 | struct xfs_trans_res ret = { | ||
| 148 | .tr_logres = r->tr_logres, | ||
| 149 | .tr_logcount = 1, | ||
| 150 | .tr_logflags = r->tr_logflags, | ||
| 151 | }; | ||
| 152 | |||
| 153 | return ret; | ||
| 154 | } | ||
| 155 | |||
| 134 | #endif /* __XFS_LOG_RECOVER_H__ */ | 156 | #endif /* __XFS_LOG_RECOVER_H__ */ |
| @@ -266,7 +266,8 @@ xfs_validate_sb_write( · 265 unmodified lines | |||
| 266 | return -EFSCORRUPTED; | 266 | return -EFSCORRUPTED; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | if (xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { | 269 | if (!xfs_is_readonly(mp) && |
| 270 | xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) { | ||
| 270 | xfs_alert(mp, | 271 | xfs_alert(mp, |
| 271 | "Corruption detected in superblock read-only compatible features (0x%x)!", | 272 | "Corruption detected in superblock read-only compatible features (0x%x)!", |
| 272 | (sbp->sb_features_ro_compat & | 273 | (sbp->sb_features_ro_compat & |
| @@ -62,12 +62,12 @@ xfs_trans_ichgtime( · 61 unmodified lines | |||
| 62 | ASSERT(tp); | 62 | ASSERT(tp); |
| 63 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 63 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
| 64 | 64 | ||
| 65 | /* If the mtime changes, then ctime must also change */ | 65 | tv = current_time(inode); |
| 66 | ASSERT(flags & XFS_ICHGTIME_CHG); | ||
| 67 | 66 | ||
| 68 | tv = inode_set_ctime_current(inode); | ||
| 69 | if (flags & XFS_ICHGTIME_MOD) | 67 | if (flags & XFS_ICHGTIME_MOD) |
| 70 | inode->i_mtime = tv; | 68 | inode->i_mtime = tv; |
| 69 | if (flags & XFS_ICHGTIME_CHG) | ||
| 70 | inode_set_ctime_to_ts(inode, tv); | ||
| 71 | if (flags & XFS_ICHGTIME_CREATE) | 71 | if (flags & XFS_ICHGTIME_CREATE) |
| 72 | ip->i_crtime = tv; | 72 | ip->i_crtime = tv; |
| 73 | } | 73 | } |
| @@ -588,6 +588,8 @@ out_nofix: · 587 unmodified lines | |||
| 588 | out_teardown: | 588 | out_teardown: |
| 589 | error = xchk_teardown(sc, error); | 589 | error = xchk_teardown(sc, error); |
| 590 | out_sc: | 590 | out_sc: |
| 591 | if (error != -ENOENT) | ||
| 592 | xchk_stats_merge(mp, sm, &run); | ||
| 591 | kfree(sc); | 593 | kfree(sc); |
| 592 | out: | 594 | out: |
| 593 | trace_xchk_done(XFS_I(file_inode(file)), sm, error); | 595 | trace_xchk_done(XFS_I(file_inode(file)), sm, error); |
| @@ -595,8 +597,6 @@ out: · 1 unmodified line | |||
| 595 | sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; | 597 | sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; |
| 596 | error = 0; | 598 | error = 0; |
| 597 | } | 599 | } |
| 598 | if (error != -ENOENT) | ||
| 599 | xchk_stats_merge(mp, sm, &run); | ||
| 600 | return error; | 600 | return error; |
| 601 | need_drain: | 601 | need_drain: |
| 602 | error = xchk_teardown(sc, 0); | 602 | error = xchk_teardown(sc, 0); |
| @@ -185,7 +185,10 @@ xchk_stats_merge_one( · 184 unmodified lines | |||
| 185 | { | 185 | { |
| 186 | struct xchk_scrub_stats *css; | 186 | struct xchk_scrub_stats *css; |
| 187 | 187 | ||
| 188 | ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR); | 188 | if (sm->sm_type >= XFS_SCRUB_TYPE_NR) { |
| 189 | ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR); | ||
| 190 | return; | ||
| 191 | } | ||
| 189 | 192 | ||
| 190 | css = &cs->cs_stats[sm->sm_type]; | 193 | css = &cs->cs_stats[sm->sm_type]; |
| 191 | spin_lock(&css->css_lock); | 194 | spin_lock(&css->css_lock); |
| @@ -333,7 +333,6 @@ xfs_attr_inactive( · 332 unmodified lines | |||
| 333 | int error = 0; | 333 | int error = 0; |
| 334 | 334 | ||
| 335 | mp = dp->i_mount; | 335 | mp = dp->i_mount; |
| 336 | ASSERT(! XFS_NOT_DQATTACHED(mp, dp)); | ||
| 337 | 336 | ||
| 338 | xfs_ilock(dp, lock_mode); | 337 | xfs_ilock(dp, lock_mode); |
| 339 | if (!xfs_inode_has_attr_fork(dp)) | 338 | if (!xfs_inode_has_attr_fork(dp)) |
| @@ -547,7 +547,7 @@ xfs_attri_item_recover( · 546 unmodified lines | |||
| 547 | struct xfs_inode *ip; | 547 | struct xfs_inode *ip; |
| 548 | struct xfs_da_args *args; | 548 | struct xfs_da_args *args; |
| 549 | struct xfs_trans *tp; | 549 | struct xfs_trans *tp; |
| 550 | struct xfs_trans_res tres; | 550 | struct xfs_trans_res resv; |
| 551 | struct xfs_attri_log_format *attrp; | 551 | struct xfs_attri_log_format *attrp; |
| 552 | struct xfs_attri_log_nameval *nv = attrip->attri_nameval; | 552 | struct xfs_attri_log_nameval *nv = attrip->attri_nameval; |
| 553 | int error; | 553 | int error; |
| @@ -618,8 +618,9 @@ xfs_attri_item_recover( · 64 unmodified lines | |||
| 618 | goto out; | 618 | goto out; |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | xfs_init_attr_trans(args, &tres, &total); | 621 | xfs_init_attr_trans(args, &resv, &total); |
| 622 | error = xfs_trans_alloc(mp, &tres, total, 0, XFS_TRANS_RESERVE, &tp); | 622 | resv = xlog_recover_resv(&resv); |
| 623 | error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp); | ||
| 623 | if (error) | 624 | if (error) |
| 624 | goto out; | 625 | goto out; |
| 625 | 626 | ||
| @@ -490,6 +490,7 @@ xfs_bui_item_recover( · 489 unmodified lines | |||
| 490 | struct list_head *capture_list) | 490 | struct list_head *capture_list) |
| 491 | { | 491 | { |
| 492 | struct xfs_bmap_intent fake = { }; | 492 | struct xfs_bmap_intent fake = { }; |
| 493 | struct xfs_trans_res resv; | ||
| 493 | struct xfs_bui_log_item *buip = BUI_ITEM(lip); | 494 | struct xfs_bui_log_item *buip = BUI_ITEM(lip); |
| 494 | struct xfs_trans *tp; | 495 | struct xfs_trans *tp; |
| 495 | struct xfs_inode *ip = NULL; | 496 | struct xfs_inode *ip = NULL; |
| @@ -515,7 +516,8 @@ xfs_bui_item_recover( · 19 unmodified lines | |||
| 515 | return error; | 516 | return error; |
| 516 | 517 | ||
| 517 | /* Allocate transaction and do the work. */ | 518 | /* Allocate transaction and do the work. */ |
| 518 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, | 519 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 520 | error = xfs_trans_alloc(mp, &resv, | ||
| 519 | XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); | 521 | XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); |
| 520 | if (error) | 522 | if (error) |
| 521 | goto err_rele; | 523 | goto err_rele; |
| @@ -146,6 +146,20 @@ xfs_nfs_get_inode( · 145 unmodified lines | |||
| 146 | return ERR_PTR(error); | 146 | return ERR_PTR(error); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | /* | ||
| 150 | * Reload the incore unlinked list to avoid failure in inodegc. | ||
| 151 | * Use an unlocked check here because unrecovered unlinked inodes | ||
| 152 | * should be somewhat rare. | ||
| 153 | */ | ||
| 154 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 155 | error = xfs_inode_reload_unlinked(ip); | ||
| 156 | if (error) { | ||
| 157 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 158 | xfs_irele(ip); | ||
| 159 | return ERR_PTR(error); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 149 | if (VFS_I(ip)->i_generation != generation) { | 163 | if (VFS_I(ip)->i_generation != generation) { |
| 150 | xfs_irele(ip); | 164 | xfs_irele(ip); |
| 151 | return ERR_PTR(-ESTALE); | 165 | return ERR_PTR(-ESTALE); |
| @@ -660,6 +660,7 @@ xfs_efi_item_recover( · 659 unmodified lines | |||
| 660 | struct xfs_log_item *lip, | 660 | struct xfs_log_item *lip, |
| 661 | struct list_head *capture_list) | 661 | struct list_head *capture_list) |
| 662 | { | 662 | { |
| 663 | struct xfs_trans_res resv; | ||
| 663 | struct xfs_efi_log_item *efip = EFI_ITEM(lip); | 664 | struct xfs_efi_log_item *efip = EFI_ITEM(lip); |
| 664 | struct xfs_mount *mp = lip->li_log->l_mp; | 665 | struct xfs_mount *mp = lip->li_log->l_mp; |
| 665 | struct xfs_efd_log_item *efdp; | 666 | struct xfs_efd_log_item *efdp; |
| @@ -683,7 +684,8 @@ xfs_efi_item_recover( · 17 unmodified lines | |||
| 683 | } | 684 | } |
| 684 | } | 685 | } |
| 685 | 686 | ||
| 686 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); | 687 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 688 | error = xfs_trans_alloc(mp, &resv, 0, 0, 0, &tp); | ||
| 687 | if (error) | 689 | if (error) |
| 688 | return error; | 690 | return error; |
| 689 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); | 691 | efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); |
| @@ -565,6 +565,19 @@ err: · 564 unmodified lines | |||
| 565 | } | 565 | } |
| 566 | #endif /* CONFIG_XFS_RT */ | 566 | #endif /* CONFIG_XFS_RT */ |
| 567 | 567 | ||
| 568 | static inline bool | ||
| 569 | rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r) | ||
| 570 | { | ||
| 571 | if (!xfs_has_reflink(mp)) | ||
| 572 | return true; | ||
| 573 | if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner)) | ||
| 574 | return true; | ||
| 575 | if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK | | ||
| 576 | XFS_RMAP_UNWRITTEN)) | ||
| 577 | return true; | ||
| 578 | return false; | ||
| 579 | } | ||
| 580 | |||
| 568 | /* Execute a getfsmap query against the regular data device. */ | 581 | /* Execute a getfsmap query against the regular data device. */ |
| 569 | STATIC int | 582 | STATIC int |
| 570 | __xfs_getfsmap_datadev( | 583 | __xfs_getfsmap_datadev( |
| @@ -598,7 +611,6 @@ __xfs_getfsmap_datadev( · 27 unmodified lines | |||
| 598 | * low to the fsmap low key and max out the high key to the end | 611 | * low to the fsmap low key and max out the high key to the end |
| 599 | * of the AG. | 612 | * of the AG. |
| 600 | */ | 613 | */ |
| 601 | info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); | ||
| 602 | info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); | 614 | info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); |
| 603 | error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); | 615 | error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); |
| 604 | if (error) | 616 | if (error) |
| @@ -608,12 +620,9 @@ __xfs_getfsmap_datadev( · 3 unmodified lines | |||
| 608 | 620 | ||
| 609 | /* Adjust the low key if we are continuing from where we left off. */ | 621 | /* Adjust the low key if we are continuing from where we left off. */ |
| 610 | if (info->low.rm_blockcount == 0) { | 622 | if (info->low.rm_blockcount == 0) { |
| 611 | /* empty */ | 623 | /* No previous record from which to continue */ |
| 612 | } else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) || | 624 | } else if (rmap_not_shareable(mp, &info->low)) { |
| 613 | (info->low.rm_flags & (XFS_RMAP_ATTR_FORK | | 625 | /* Last record seen was an unshareable extent */ |
| 614 | XFS_RMAP_BMBT_BLOCK | | ||
| 615 | XFS_RMAP_UNWRITTEN))) { | ||
| 616 | info->low.rm_startblock += info->low.rm_blockcount; | ||
| 617 | info->low.rm_owner = 0; | 626 | info->low.rm_owner = 0; |
| 618 | info->low.rm_offset = 0; | 627 | info->low.rm_offset = 0; |
| 619 | 628 | ||
| @@ -621,8 +630,10 @@ __xfs_getfsmap_datadev( · 1 unmodified line | |||
| 621 | if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) | 630 | if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) |
| 622 | return 0; | 631 | return 0; |
| 623 | } else { | 632 | } else { |
| 633 | /* Last record seen was a shareable file data extent */ | ||
| 624 | info->low.rm_offset += info->low.rm_blockcount; | 634 | info->low.rm_offset += info->low.rm_blockcount; |
| 625 | } | 635 | } |
| 636 | info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb); | ||
| 626 | 637 | ||
| 627 | info->high.rm_startblock = -1U; | 638 | info->high.rm_startblock = -1U; |
| 628 | info->high.rm_owner = ULLONG_MAX; | 639 | info->high.rm_owner = ULLONG_MAX; |
| @@ -113,7 +113,7 @@ xfs_inode_alloc( · 112 unmodified lines | |||
| 113 | INIT_LIST_HEAD(&ip->i_ioend_list); | 113 | INIT_LIST_HEAD(&ip->i_ioend_list); |
| 114 | spin_lock_init(&ip->i_ioend_lock); | 114 | spin_lock_init(&ip->i_ioend_lock); |
| 115 | ip->i_next_unlinked = NULLAGINO; | 115 | ip->i_next_unlinked = NULLAGINO; |
| 116 | ip->i_prev_unlinked = NULLAGINO; | 116 | ip->i_prev_unlinked = 0; |
| 117 | 117 | ||
| 118 | return ip; | 118 | return ip; |
| 119 | } | 119 | } |
| @@ -443,7 +443,7 @@ xfs_inodegc_queue_all( · 323 unmodified lines | |||
| 443 | int cpu; | 443 | int cpu; |
| 444 | bool ret = false; | 444 | bool ret = false; |
| 445 | 445 | ||
| 446 | for_each_online_cpu(cpu) { | 446 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 447 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 447 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 448 | if (!llist_empty(&gc->list)) { | 448 | if (!llist_empty(&gc->list)) { |
| 449 | mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); | 449 | mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); |
| @@ -463,7 +463,7 @@ xfs_inodegc_wait_all( · 13 unmodified lines | |||
| 463 | int error = 0; | 463 | int error = 0; |
| 464 | 464 | ||
| 465 | flush_workqueue(mp->m_inodegc_wq); | 465 | flush_workqueue(mp->m_inodegc_wq); |
| 466 | for_each_online_cpu(cpu) { | 466 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 467 | struct xfs_inodegc *gc; | 467 | struct xfs_inodegc *gc; |
| 468 | 468 | ||
| 469 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 469 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| @@ -1845,9 +1845,17 @@ xfs_inodegc_worker( · 1375 unmodified lines | |||
| 1845 | struct xfs_inodegc, work); | 1845 | struct xfs_inodegc, work); |
| 1846 | struct llist_node *node = llist_del_all(&gc->list); | 1846 | struct llist_node *node = llist_del_all(&gc->list); |
| 1847 | struct xfs_inode *ip, *n; | 1847 | struct xfs_inode *ip, *n; |
| 1848 | struct xfs_mount *mp = gc->mp; | ||
| 1848 | unsigned int nofs_flag; | 1849 | unsigned int nofs_flag; |
| 1849 | 1850 | ||
| 1850 | ASSERT(gc->cpu == smp_processor_id()); | 1851 | /* |
| 1852 | * Clear the cpu mask bit and ensure that we have seen the latest | ||
| 1853 | * update of the gc structure associated with this CPU. This matches | ||
| 1854 | * with the release semantics used when setting the cpumask bit in | ||
| 1855 | * xfs_inodegc_queue. | ||
| 1856 | */ | ||
| 1857 | cpumask_clear_cpu(gc->cpu, &mp->m_inodegc_cpumask); | ||
| 1858 | smp_mb__after_atomic(); | ||
| 1851 | 1859 | ||
| 1852 | WRITE_ONCE(gc->items, 0); | 1860 | WRITE_ONCE(gc->items, 0); |
| 1853 | 1861 | ||
| @@ -1862,7 +1870,7 @@ xfs_inodegc_worker( · 8 unmodified lines | |||
| 1862 | nofs_flag = memalloc_nofs_save(); | 1870 | nofs_flag = memalloc_nofs_save(); |
| 1863 | 1871 | ||
| 1864 | ip = llist_entry(node, struct xfs_inode, i_gclist); | 1872 | ip = llist_entry(node, struct xfs_inode, i_gclist); |
| 1865 | trace_xfs_inodegc_worker(ip->i_mount, READ_ONCE(gc->shrinker_hits)); | 1873 | trace_xfs_inodegc_worker(mp, READ_ONCE(gc->shrinker_hits)); |
| 1866 | 1874 | ||
| 1867 | WRITE_ONCE(gc->shrinker_hits, 0); | 1875 | WRITE_ONCE(gc->shrinker_hits, 0); |
| 1868 | llist_for_each_entry_safe(ip, n, node, i_gclist) { | 1876 | llist_for_each_entry_safe(ip, n, node, i_gclist) { |
| @@ -2057,6 +2065,7 @@ xfs_inodegc_queue( · 188 unmodified lines | |||
| 2057 | struct xfs_inodegc *gc; | 2065 | struct xfs_inodegc *gc; |
| 2058 | int items; | 2066 | int items; |
| 2059 | unsigned int shrinker_hits; | 2067 | unsigned int shrinker_hits; |
| 2068 | unsigned int cpu_nr; | ||
| 2060 | unsigned long queue_delay = 1; | 2069 | unsigned long queue_delay = 1; |
| 2061 | 2070 | ||
| 2062 | trace_xfs_inode_set_need_inactive(ip); | 2071 | trace_xfs_inode_set_need_inactive(ip); |
| @@ -2064,18 +2073,28 @@ xfs_inodegc_queue( · 1 unmodified line | |||
| 2064 | ip->i_flags |= XFS_NEED_INACTIVE; | 2073 | ip->i_flags |= XFS_NEED_INACTIVE; |
| 2065 | spin_unlock(&ip->i_flags_lock); | 2074 | spin_unlock(&ip->i_flags_lock); |
| 2066 | 2075 | ||
| 2067 | gc = get_cpu_ptr(mp->m_inodegc); | 2076 | cpu_nr = get_cpu(); |
| 2077 | gc = this_cpu_ptr(mp->m_inodegc); | ||
| 2068 | llist_add(&ip->i_gclist, &gc->list); | 2078 | llist_add(&ip->i_gclist, &gc->list); |
| 2069 | items = READ_ONCE(gc->items); | 2079 | items = READ_ONCE(gc->items); |
| 2070 | WRITE_ONCE(gc->items, items + 1); | 2080 | WRITE_ONCE(gc->items, items + 1); |
| 2071 | shrinker_hits = READ_ONCE(gc->shrinker_hits); | 2081 | shrinker_hits = READ_ONCE(gc->shrinker_hits); |
| 2072 | 2082 | ||
| 2083 | /* | ||
| 2084 | * Ensure the list add is always seen by anyone who finds the cpumask | ||
| 2085 | * bit set. This effectively gives the cpumask bit set operation | ||
| 2086 | * release ordering semantics. | ||
| 2087 | */ | ||
| 2088 | smp_mb__before_atomic(); | ||
| 2089 | if (!cpumask_test_cpu(cpu_nr, &mp->m_inodegc_cpumask)) | ||
| 2090 | cpumask_test_and_set_cpu(cpu_nr, &mp->m_inodegc_cpumask); | ||
| 2091 | |||
| 2073 | /* | 2092 | /* |
| 2074 | * We queue the work while holding the current CPU so that the work | 2093 | * We queue the work while holding the current CPU so that the work |
| 2075 | * is scheduled to run on this CPU. | 2094 | * is scheduled to run on this CPU. |
| 2076 | */ | 2095 | */ |
| 2077 | if (!xfs_is_inodegc_enabled(mp)) { | 2096 | if (!xfs_is_inodegc_enabled(mp)) { |
| 2078 | put_cpu_ptr(gc); | 2097 | put_cpu(); |
| 2079 | return; | 2098 | return; |
| 2080 | } | 2099 | } |
| 2081 | 2100 | ||
| @@ -2085,7 +2104,7 @@ xfs_inodegc_queue( · 3 unmodified lines | |||
| 2085 | trace_xfs_inodegc_queue(mp, __return_address); | 2104 | trace_xfs_inodegc_queue(mp, __return_address); |
| 2086 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, | 2105 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, |
| 2087 | queue_delay); | 2106 | queue_delay); |
| 2088 | put_cpu_ptr(gc); | 2107 | put_cpu(); |
| 2089 | 2108 | ||
| 2090 | if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { | 2109 | if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { |
| 2091 | trace_xfs_inodegc_throttle(mp, __return_address); | 2110 | trace_xfs_inodegc_throttle(mp, __return_address); |
| @@ -2093,47 +2112,6 @@ xfs_inodegc_queue( · 1 unmodified line | |||
| 2093 | } | 2112 | } |
| 2094 | } | 2113 | } |
| 2095 | 2114 | ||
| 2096 | /* | ||
| 2097 | * Fold the dead CPU inodegc queue into the current CPUs queue. | ||
| 2098 | */ | ||
| 2099 | void | ||
| 2100 | xfs_inodegc_cpu_dead( | ||
| 2101 | struct xfs_mount *mp, | ||
| 2102 | unsigned int dead_cpu) | ||
| 2103 | { | ||
| 2104 | struct xfs_inodegc *dead_gc, *gc; | ||
| 2105 | struct llist_node *first, *last; | ||
| 2106 | unsigned int count = 0; | ||
| 2107 | |||
| 2108 | dead_gc = per_cpu_ptr(mp->m_inodegc, dead_cpu); | ||
| 2109 | cancel_delayed_work_sync(&dead_gc->work); | ||
| 2110 | |||
| 2111 | if (llist_empty(&dead_gc->list)) | ||
| 2112 | return; | ||
| 2113 | |||
| 2114 | first = dead_gc->list.first; | ||
| 2115 | last = first; | ||
| 2116 | while (last->next) { | ||
| 2117 | last = last->next; | ||
| 2118 | count++; | ||
| 2119 | } | ||
| 2120 | dead_gc->list.first = NULL; | ||
| 2121 | dead_gc->items = 0; | ||
| 2122 | |||
| 2123 | /* Add pending work to current CPU */ | ||
| 2124 | gc = get_cpu_ptr(mp->m_inodegc); | ||
| 2125 | llist_add_batch(first, last, &gc->list); | ||
| 2126 | count += READ_ONCE(gc->items); | ||
| 2127 | WRITE_ONCE(gc->items, count); | ||
| 2128 | |||
| 2129 | if (xfs_is_inodegc_enabled(mp)) { | ||
| 2130 | trace_xfs_inodegc_queue(mp, __return_address); | ||
| 2131 | mod_delayed_work_on(current_cpu(), mp->m_inodegc_wq, &gc->work, | ||
| 2132 | 0); | ||
| 2133 | } | ||
| 2134 | put_cpu_ptr(gc); | ||
| 2135 | } | ||
| 2136 | |||
| 2137 | /* | 2115 | /* |
| 2138 | * We set the inode flag atomically with the radix tree tag. Once we get tag | 2116 | * We set the inode flag atomically with the radix tree tag. Once we get tag |
| 2139 | * lookups on the radix tree, this inode flag can go away. | 2117 | * lookups on the radix tree, this inode flag can go away. |
| @@ -2195,7 +2173,7 @@ xfs_inodegc_shrinker_count( · 55 unmodified lines | |||
| 2195 | if (!xfs_is_inodegc_enabled(mp)) | 2173 | if (!xfs_is_inodegc_enabled(mp)) |
| 2196 | return 0; | 2174 | return 0; |
| 2197 | 2175 | ||
| 2198 | for_each_online_cpu(cpu) { | 2176 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 2199 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 2177 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 2200 | if (!llist_empty(&gc->list)) | 2178 | if (!llist_empty(&gc->list)) |
| 2201 | return XFS_INODEGC_SHRINKER_COUNT; | 2179 | return XFS_INODEGC_SHRINKER_COUNT; |
| @@ -2220,7 +2198,7 @@ xfs_inodegc_shrinker_scan( · 18 unmodified lines | |||
| 2220 | 2198 | ||
| 2221 | trace_xfs_inodegc_shrinker_scan(mp, sc, __return_address); | 2199 | trace_xfs_inodegc_shrinker_scan(mp, sc, __return_address); |
| 2222 | 2200 | ||
| 2223 | for_each_online_cpu(cpu) { | 2201 | for_each_cpu(cpu, &mp->m_inodegc_cpumask) { |
| 2224 | gc = per_cpu_ptr(mp->m_inodegc, cpu); | 2202 | gc = per_cpu_ptr(mp->m_inodegc, cpu); |
| 2225 | if (!llist_empty(&gc->list)) { | 2203 | if (!llist_empty(&gc->list)) { |
| 2226 | unsigned int h = READ_ONCE(gc->shrinker_hits); | 2204 | unsigned int h = READ_ONCE(gc->shrinker_hits); |
| @@ -79,7 +79,6 @@ void xfs_inodegc_push(struct xfs_mount *mp); · 78 unmodified lines | |||
| 79 | int xfs_inodegc_flush(struct xfs_mount *mp); | 79 | int xfs_inodegc_flush(struct xfs_mount *mp); |
| 80 | void xfs_inodegc_stop(struct xfs_mount *mp); | 80 | void xfs_inodegc_stop(struct xfs_mount *mp); |
| 81 | void xfs_inodegc_start(struct xfs_mount *mp); | 81 | void xfs_inodegc_start(struct xfs_mount *mp); |
| 82 | void xfs_inodegc_cpu_dead(struct xfs_mount *mp, unsigned int cpu); | ||
| 83 | int xfs_inodegc_register_shrinker(struct xfs_mount *mp); | 82 | int xfs_inodegc_register_shrinker(struct xfs_mount *mp); |
| 84 | 83 | ||
| 85 | #endif | 84 | #endif |
| @@ -1642,8 +1642,11 @@ xfs_inode_needs_inactive( · 1641 unmodified lines | |||
| 1642 | if (VFS_I(ip)->i_mode == 0) | 1642 | if (VFS_I(ip)->i_mode == 0) |
| 1643 | return false; | 1643 | return false; |
| 1644 | 1644 | ||
| 1645 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1645 | /* |
| 1646 | if (xfs_is_readonly(mp)) | 1646 | * If this is a read-only mount, don't do this (would generate I/O) |
| 1647 | * unless we're in log recovery and cleaning the iunlinked list. | ||
| 1648 | */ | ||
| 1649 | if (xfs_is_readonly(mp) && !xlog_recovery_needed(mp->m_log)) | ||
| 1647 | return false; | 1650 | return false; |
| 1648 | 1651 | ||
| 1649 | /* If the log isn't running, push inodes straight to reclaim. */ | 1652 | /* If the log isn't running, push inodes straight to reclaim. */ |
| @@ -1703,8 +1706,11 @@ xfs_inactive( · 53 unmodified lines | |||
| 1703 | mp = ip->i_mount; | 1706 | mp = ip->i_mount; |
| 1704 | ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY)); | 1707 | ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY)); |
| 1705 | 1708 | ||
| 1706 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1709 | /* |
| 1707 | if (xfs_is_readonly(mp)) | 1710 | * If this is a read-only mount, don't do this (would generate I/O) |
| 1711 | * unless we're in log recovery and cleaning the iunlinked list. | ||
| 1712 | */ | ||
| 1713 | if (xfs_is_readonly(mp) && !xlog_recovery_needed(mp->m_log)) | ||
| 1708 | goto out; | 1714 | goto out; |
| 1709 | 1715 | ||
| 1710 | /* Metadata inodes require explicit resource cleanup. */ | 1716 | /* Metadata inodes require explicit resource cleanup. */ |
| @@ -1736,9 +1742,21 @@ xfs_inactive( · 25 unmodified lines | |||
| 1736 | ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) | 1742 | ip->i_df.if_nextents > 0 || ip->i_delayed_blks > 0)) |
| 1737 | truncate = 1; | 1743 | truncate = 1; |
| 1738 | 1744 | ||
| 1739 | error = xfs_qm_dqattach(ip); | 1745 | if (xfs_iflags_test(ip, XFS_IQUOTAUNCHECKED)) { |
| 1740 | if (error) | 1746 | /* |
| 1741 | goto out; | 1747 | * If this inode is being inactivated during a quotacheck and |
| 1748 | * has not yet been scanned by quotacheck, we /must/ remove | ||
| 1749 | * the dquots from the inode before inactivation changes the | ||
| 1750 | * block and inode counts. Most probably this is a result of | ||
| 1751 | * reloading the incore iunlinked list to purge unrecovered | ||
| 1752 | * unlinked inodes. | ||
| 1753 | */ | ||
| 1754 | xfs_qm_dqdetach(ip); | ||
| 1755 | } else { | ||
| 1756 | error = xfs_qm_dqattach(ip); | ||
| 1757 | if (error) | ||
| 1758 | goto out; | ||
| 1759 | } | ||
| 1742 | 1760 | ||
| 1743 | if (S_ISLNK(VFS_I(ip)->i_mode)) | 1761 | if (S_ISLNK(VFS_I(ip)->i_mode)) |
| 1744 | error = xfs_inactive_symlink(ip); | 1762 | error = xfs_inactive_symlink(ip); |
| @@ -1822,12 +1840,17 @@ xfs_iunlink_lookup( · 77 unmodified lines | |||
| 1822 | 1840 | ||
| 1823 | rcu_read_lock(); | 1841 | rcu_read_lock(); |
| 1824 | ip = radix_tree_lookup(&pag->pag_ici_root, agino); | 1842 | ip = radix_tree_lookup(&pag->pag_ici_root, agino); |
| 1843 | if (!ip) { | ||
| 1844 | /* Caller can handle inode not being in memory. */ | ||
| 1845 | rcu_read_unlock(); | ||
| 1846 | return NULL; | ||
| 1847 | } | ||
| 1825 | 1848 | ||
| 1826 | /* | 1849 | /* |
| 1827 | * Inode not in memory or in RCU freeing limbo should not happen. | 1850 | * Inode in RCU freeing limbo should not happen. Warn about this and |
| 1828 | * Warn about this and let the caller handle the failure. | 1851 | * let the caller handle the failure. |
| 1829 | */ | 1852 | */ |
| 1830 | if (WARN_ON_ONCE(!ip || !ip->i_ino)) { | 1853 | if (WARN_ON_ONCE(!ip->i_ino)) { |
| 1831 | rcu_read_unlock(); | 1854 | rcu_read_unlock(); |
| 1832 | return NULL; | 1855 | return NULL; |
| 1833 | } | 1856 | } |
| @@ -1836,7 +1859,10 @@ xfs_iunlink_lookup( · 2 unmodified lines | |||
| 1836 | return ip; | 1859 | return ip; |
| 1837 | } | 1860 | } |
| 1838 | 1861 | ||
| 1839 | /* Update the prev pointer of the next agino. */ | 1862 | /* |
| 1863 | * Update the prev pointer of the next agino. Returns -ENOLINK if the inode | ||
| 1864 | * is not in cache. | ||
| 1865 | */ | ||
| 1840 | static int | 1866 | static int |
| 1841 | xfs_iunlink_update_backref( | 1867 | xfs_iunlink_update_backref( |
| 1842 | struct xfs_perag *pag, | 1868 | struct xfs_perag *pag, |
| @@ -1851,7 +1877,8 @@ xfs_iunlink_update_backref( · 8 unmodified lines | |||
| 1851 | 1877 | ||
| 1852 | ip = xfs_iunlink_lookup(pag, next_agino); | 1878 | ip = xfs_iunlink_lookup(pag, next_agino); |
| 1853 | if (!ip) | 1879 | if (!ip) |
| 1854 | return -EFSCORRUPTED; | 1880 | return -ENOLINK; |
| 1881 | |||
| 1855 | ip->i_prev_unlinked = prev_agino; | 1882 | ip->i_prev_unlinked = prev_agino; |
| 1856 | return 0; | 1883 | return 0; |
| 1857 | } | 1884 | } |
| @@ -1895,6 +1922,64 @@ xfs_iunlink_update_bucket( · 37 unmodified lines | |||
| 1895 | return 0; | 1922 | return 0; |
| 1896 | } | 1923 | } |
| 1897 | 1924 | ||
| 1925 | /* | ||
| 1926 | * Load the inode @next_agino into the cache and set its prev_unlinked pointer | ||
| 1927 | * to @prev_agino. Caller must hold the AGI to synchronize with other changes | ||
| 1928 | * to the unlinked list. | ||
| 1929 | */ | ||
| 1930 | STATIC int | ||
| 1931 | xfs_iunlink_reload_next( | ||
| 1932 | struct xfs_trans *tp, | ||
| 1933 | struct xfs_buf *agibp, | ||
| 1934 | xfs_agino_t prev_agino, | ||
| 1935 | xfs_agino_t next_agino) | ||
| 1936 | { | ||
| 1937 | struct xfs_perag *pag = agibp->b_pag; | ||
| 1938 | struct xfs_mount *mp = pag->pag_mount; | ||
| 1939 | struct xfs_inode *next_ip = NULL; | ||
| 1940 | xfs_ino_t ino; | ||
| 1941 | int error; | ||
| 1942 | |||
| 1943 | ASSERT(next_agino != NULLAGINO); | ||
| 1944 | |||
| 1945 | #ifdef DEBUG | ||
| 1946 | rcu_read_lock(); | ||
| 1947 | next_ip = radix_tree_lookup(&pag->pag_ici_root, next_agino); | ||
| 1948 | ASSERT(next_ip == NULL); | ||
| 1949 | rcu_read_unlock(); | ||
| 1950 | #endif | ||
| 1951 | |||
| 1952 | xfs_info_ratelimited(mp, | ||
| 1953 | "Found unrecovered unlinked inode 0x%x in AG 0x%x. Initiating recovery.", | ||
| 1954 | next_agino, pag->pag_agno); | ||
| 1955 | |||
| 1956 | /* | ||
| 1957 | * Use an untrusted lookup just to be cautious in case the AGI has been | ||
| 1958 | * corrupted and now points at a free inode. That shouldn't happen, | ||
| 1959 | * but we'd rather shut down now since we're already running in a weird | ||
| 1960 | * situation. | ||
| 1961 | */ | ||
| 1962 | ino = XFS_AGINO_TO_INO(mp, pag->pag_agno, next_agino); | ||
| 1963 | error = xfs_iget(mp, tp, ino, XFS_IGET_UNTRUSTED, 0, &next_ip); | ||
| 1964 | if (error) | ||
| 1965 | return error; | ||
| 1966 | |||
| 1967 | /* If this is not an unlinked inode, something is very wrong. */ | ||
| 1968 | if (VFS_I(next_ip)->i_nlink != 0) { | ||
| 1969 | error = -EFSCORRUPTED; | ||
| 1970 | goto rele; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | next_ip->i_prev_unlinked = prev_agino; | ||
| 1974 | trace_xfs_iunlink_reload_next(next_ip); | ||
| 1975 | rele: | ||
| 1976 | ASSERT(!(VFS_I(next_ip)->i_state & I_DONTCACHE)); | ||
| 1977 | if (xfs_is_quotacheck_running(mp) && next_ip) | ||
| 1978 | xfs_iflags_set(next_ip, XFS_IQUOTAUNCHECKED); | ||
| 1979 | xfs_irele(next_ip); | ||
| 1980 | return error; | ||
| 1981 | } | ||
| 1982 | |||
| 1898 | static int | 1983 | static int |
| 1899 | xfs_iunlink_insert_inode( | 1984 | xfs_iunlink_insert_inode( |
| 1900 | struct xfs_trans *tp, | 1985 | struct xfs_trans *tp, |
| @@ -1926,6 +2011,8 @@ xfs_iunlink_insert_inode( · 25 unmodified lines | |||
| 1926 | * inode. | 2011 | * inode. |
| 1927 | */ | 2012 | */ |
| 1928 | error = xfs_iunlink_update_backref(pag, agino, next_agino); | 2013 | error = xfs_iunlink_update_backref(pag, agino, next_agino); |
| 2014 | if (error == -ENOLINK) | ||
| 2015 | error = xfs_iunlink_reload_next(tp, agibp, agino, next_agino); | ||
| 1929 | if (error) | 2016 | if (error) |
| 1930 | return error; | 2017 | return error; |
| 1931 | 2018 | ||
| @@ -1941,6 +2028,7 @@ xfs_iunlink_insert_inode( · 9 unmodified lines | |||
| 1941 | } | 2028 | } |
| 1942 | 2029 | ||
| 1943 | /* Point the head of the list to point to this inode. */ | 2030 | /* Point the head of the list to point to this inode. */ |
| 2031 | ip->i_prev_unlinked = NULLAGINO; | ||
| 1944 | return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino); | 2032 | return xfs_iunlink_update_bucket(tp, pag, agibp, bucket_index, agino); |
| 1945 | } | 2033 | } |
| 1946 | 2034 | ||
| @@ -2020,6 +2108,9 @@ xfs_iunlink_remove_inode( · 73 unmodified lines | |||
| 2020 | */ | 2108 | */ |
| 2021 | error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked, | 2109 | error = xfs_iunlink_update_backref(pag, ip->i_prev_unlinked, |
| 2022 | ip->i_next_unlinked); | 2110 | ip->i_next_unlinked); |
| 2111 | if (error == -ENOLINK) | ||
| 2112 | error = xfs_iunlink_reload_next(tp, agibp, ip->i_prev_unlinked, | ||
| 2113 | ip->i_next_unlinked); | ||
| 2023 | if (error) | 2114 | if (error) |
| 2024 | return error; | 2115 | return error; |
| 2025 | 2116 | ||
| @@ -2040,7 +2131,7 @@ xfs_iunlink_remove_inode( · 14 unmodified lines | |||
| 2040 | } | 2131 | } |
| 2041 | 2132 | ||
| 2042 | ip->i_next_unlinked = NULLAGINO; | 2133 | ip->i_next_unlinked = NULLAGINO; |
| 2043 | ip->i_prev_unlinked = NULLAGINO; | 2134 | ip->i_prev_unlinked = 0; |
| 2044 | return error; | 2135 | return error; |
| 2045 | } | 2136 | } |
| 2046 | 2137 | ||
| @@ -3529,3 +3620,117 @@ xfs_iunlock2_io_mmap( · 1482 unmodified lines | |||
| 3529 | if (ip1 != ip2) | 3620 | if (ip1 != ip2) |
| 3530 | inode_unlock(VFS_I(ip1)); | 3621 | inode_unlock(VFS_I(ip1)); |
| 3531 | } | 3622 | } |
| 3623 | |||
| 3624 | /* | ||
| 3625 | * Reload the incore inode list for this inode. Caller should ensure that | ||
| 3626 | * the link count cannot change, either by taking ILOCK_SHARED or otherwise | ||
| 3627 | * preventing other threads from executing. | ||
| 3628 | */ | ||
| 3629 | int | ||
| 3630 | xfs_inode_reload_unlinked_bucket( | ||
| 3631 | struct xfs_trans *tp, | ||
| 3632 | struct xfs_inode *ip) | ||
| 3633 | { | ||
| 3634 | struct xfs_mount *mp = tp->t_mountp; | ||
| 3635 | struct xfs_buf *agibp; | ||
| 3636 | struct xfs_agi *agi; | ||
| 3637 | struct xfs_perag *pag; | ||
| 3638 | xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | ||
| 3639 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
| 3640 | xfs_agino_t prev_agino, next_agino; | ||
| 3641 | unsigned int bucket; | ||
| 3642 | bool foundit = false; | ||
| 3643 | int error; | ||
| 3644 | |||
| 3645 | /* Grab the first inode in the list */ | ||
| 3646 | pag = xfs_perag_get(mp, agno); | ||
| 3647 | error = xfs_ialloc_read_agi(pag, tp, &agibp); | ||
| 3648 | xfs_perag_put(pag); | ||
| 3649 | if (error) | ||
| 3650 | return error; | ||
| 3651 | |||
| 3652 | /* | ||
| 3653 | * We've taken ILOCK_SHARED and the AGI buffer lock to stabilize the | ||
| 3654 | * incore unlinked list pointers for this inode. Check once more to | ||
| 3655 | * see if we raced with anyone else to reload the unlinked list. | ||
| 3656 | */ | ||
| 3657 | if (!xfs_inode_unlinked_incomplete(ip)) { | ||
| 3658 | foundit = true; | ||
| 3659 | goto out_agibp; | ||
| 3660 | } | ||
| 3661 | |||
| 3662 | bucket = agino % XFS_AGI_UNLINKED_BUCKETS; | ||
| 3663 | agi = agibp->b_addr; | ||
| 3664 | |||
| 3665 | trace_xfs_inode_reload_unlinked_bucket(ip); | ||
| 3666 | |||
| 3667 | xfs_info_ratelimited(mp, | ||
| 3668 | "Found unrecovered unlinked inode 0x%x in AG 0x%x. Initiating list recovery.", | ||
| 3669 | agino, agno); | ||
| 3670 | |||
| 3671 | prev_agino = NULLAGINO; | ||
| 3672 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket]); | ||
| 3673 | while (next_agino != NULLAGINO) { | ||
| 3674 | struct xfs_inode *next_ip = NULL; | ||
| 3675 | |||
| 3676 | /* Found this caller's inode, set its backlink. */ | ||
| 3677 | if (next_agino == agino) { | ||
| 3678 | next_ip = ip; | ||
| 3679 | next_ip->i_prev_unlinked = prev_agino; | ||
| 3680 | foundit = true; | ||
| 3681 | goto next_inode; | ||
| 3682 | } | ||
| 3683 | |||
| 3684 | /* Try in-memory lookup first. */ | ||
| 3685 | next_ip = xfs_iunlink_lookup(pag, next_agino); | ||
| 3686 | if (next_ip) | ||
| 3687 | goto next_inode; | ||
| 3688 | |||
| 3689 | /* Inode not in memory, try reloading it. */ | ||
| 3690 | error = xfs_iunlink_reload_next(tp, agibp, prev_agino, | ||
| 3691 | next_agino); | ||
| 3692 | if (error) | ||
| 3693 | break; | ||
| 3694 | |||
| 3695 | /* Grab the reloaded inode. */ | ||
| 3696 | next_ip = xfs_iunlink_lookup(pag, next_agino); | ||
| 3697 | if (!next_ip) { | ||
| 3698 | /* No incore inode at all? We reloaded it... */ | ||
| 3699 | ASSERT(next_ip != NULL); | ||
| 3700 | error = -EFSCORRUPTED; | ||
| 3701 | break; | ||
| 3702 | } | ||
| 3703 | |||
| 3704 | next_inode: | ||
| 3705 | prev_agino = next_agino; | ||
| 3706 | next_agino = next_ip->i_next_unlinked; | ||
| 3707 | } | ||
| 3708 | |||
| 3709 | out_agibp: | ||
| 3710 | xfs_trans_brelse(tp, agibp); | ||
| 3711 | /* Should have found this inode somewhere in the iunlinked bucket. */ | ||
| 3712 | if (!error && !foundit) | ||
| 3713 | error = -EFSCORRUPTED; | ||
| 3714 | return error; | ||
| 3715 | } | ||
| 3716 | |||
| 3717 | /* Decide if this inode is missing its unlinked list and reload it. */ | ||
| 3718 | int | ||
| 3719 | xfs_inode_reload_unlinked( | ||
| 3720 | struct xfs_inode *ip) | ||
| 3721 | { | ||
| 3722 | struct xfs_trans *tp; | ||
| 3723 | int error; | ||
| 3724 | |||
| 3725 | error = xfs_trans_alloc_empty(ip->i_mount, &tp); | ||
| 3726 | if (error) | ||
| 3727 | return error; | ||
| 3728 | |||
| 3729 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
| 3730 | if (xfs_inode_unlinked_incomplete(ip)) | ||
| 3731 | error = xfs_inode_reload_unlinked_bucket(tp, ip); | ||
| 3732 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 3733 | xfs_trans_cancel(tp); | ||
| 3734 | |||
| 3735 | return error; | ||
| 3736 | } | ||
| @@ -68,8 +68,21 @@ typedef struct xfs_inode { · 67 unmodified lines | |||
| 68 | uint64_t i_diflags2; /* XFS_DIFLAG2_... */ | 68 | uint64_t i_diflags2; /* XFS_DIFLAG2_... */ |
| 69 | struct timespec64 i_crtime; /* time created */ | 69 | struct timespec64 i_crtime; /* time created */ |
| 70 | 70 | ||
| 71 | /* unlinked list pointers */ | 71 | /* |
| 72 | * Unlinked list pointers. These point to the next and previous inodes | ||
| 73 | * in the AGI unlinked bucket list, respectively. These fields can | ||
| 74 | * only be updated with the AGI locked. | ||
| 75 | * | ||
| 76 | * i_next_unlinked caches di_next_unlinked. | ||
| 77 | */ | ||
| 72 | xfs_agino_t i_next_unlinked; | 78 | xfs_agino_t i_next_unlinked; |
| 79 | |||
| 80 | /* | ||
| 81 | * If the inode is not on an unlinked list, this field is zero. If the | ||
| 82 | * inode is the first element in an unlinked list, this field is | ||
| 83 | * NULLAGINO. Otherwise, i_prev_unlinked points to the previous inode | ||
| 84 | * in the unlinked list. | ||
| 85 | */ | ||
| 73 | xfs_agino_t i_prev_unlinked; | 86 | xfs_agino_t i_prev_unlinked; |
| 74 | 87 | ||
| 75 | /* VFS inode */ | 88 | /* VFS inode */ |
| @@ -81,6 +94,11 @@ typedef struct xfs_inode { · 5 unmodified lines | |||
| 81 | struct list_head i_ioend_list; | 94 | struct list_head i_ioend_list; |
| 82 | } xfs_inode_t; | 95 | } xfs_inode_t; |
| 83 | 96 | ||
| 97 | static inline bool xfs_inode_on_unlinked_list(const struct xfs_inode *ip) | ||
| 98 | { | ||
| 99 | return ip->i_prev_unlinked != 0; | ||
| 100 | } | ||
| 101 | |||
| 84 | static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip) | 102 | static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip) |
| 85 | { | 103 | { |
| 86 | return ip->i_forkoff > 0; | 104 | return ip->i_forkoff > 0; |
| @@ -326,6 +344,9 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) · 239 unmodified lines | |||
| 326 | */ | 344 | */ |
| 327 | #define XFS_INACTIVATING (1 << 13) | 345 | #define XFS_INACTIVATING (1 << 13) |
| 328 | 346 | ||
| 347 | /* Quotacheck is running but inode has not been added to quota counts. */ | ||
| 348 | #define XFS_IQUOTAUNCHECKED (1 << 14) | ||
| 349 | |||
| 329 | /* All inode state flags related to inode reclaim. */ | 350 | /* All inode state flags related to inode reclaim. */ |
| 330 | #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ | 351 | #define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ |
| 331 | XFS_IRECLAIM | \ | 352 | XFS_IRECLAIM | \ |
| @@ -340,7 +361,7 @@ static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip) · 8 unmodified lines | |||
| 340 | #define XFS_IRECLAIM_RESET_FLAGS \ | 361 | #define XFS_IRECLAIM_RESET_FLAGS \ |
| 341 | (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ | 362 | (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ |
| 342 | XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ | 363 | XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ |
| 343 | XFS_INACTIVATING) | 364 | XFS_INACTIVATING | XFS_IQUOTAUNCHECKED) |
| 344 | 365 | ||
| 345 | /* | 366 | /* |
| 346 | * Flags for inode locking. | 367 | * Flags for inode locking. |
| @@ -575,4 +596,13 @@ void xfs_end_io(struct work_struct *work); · 228 unmodified lines | |||
| 575 | int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); | 596 | int xfs_ilock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); |
| 576 | void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); | 597 | void xfs_iunlock2_io_mmap(struct xfs_inode *ip1, struct xfs_inode *ip2); |
| 577 | 598 | ||
| 599 | static inline bool | ||
| 600 | xfs_inode_unlinked_incomplete( | ||
| 601 | struct xfs_inode *ip) | ||
| 602 | { | ||
| 603 | return VFS_I(ip)->i_nlink == 0 && !xfs_inode_on_unlinked_list(ip); | ||
| 604 | } | ||
| 605 | int xfs_inode_reload_unlinked_bucket(struct xfs_trans *tp, struct xfs_inode *ip); | ||
| 606 | int xfs_inode_reload_unlinked(struct xfs_inode *ip); | ||
| 607 | |||
| 578 | #endif /* __XFS_INODE_H__ */ | 608 | #endif /* __XFS_INODE_H__ */ |
| @@ -573,10 +573,10 @@ xfs_vn_getattr( · 572 unmodified lines | |||
| 573 | stat->gid = vfsgid_into_kgid(vfsgid); | 573 | stat->gid = vfsgid_into_kgid(vfsgid); |
| 574 | stat->ino = ip->i_ino; | 574 | stat->ino = ip->i_ino; |
| 575 | stat->atime = inode->i_atime; | 575 | stat->atime = inode->i_atime; |
| 576 | stat->mtime = inode->i_mtime; | ||
| 577 | stat->ctime = inode_get_ctime(inode); | ||
| 576 | stat->blocks = XFS_FSB_TO_BB(mp, ip->i_nblocks + ip->i_delayed_blks); | 578 | stat->blocks = XFS_FSB_TO_BB(mp, ip->i_nblocks + ip->i_delayed_blks); |
| 577 | 579 | ||
| 578 | fill_mg_cmtime(stat, request_mask, inode); | ||
| 579 | |||
| 580 | if (xfs_has_v3inodes(mp)) { | 580 | if (xfs_has_v3inodes(mp)) { |
| 581 | if (request_mask & STATX_BTIME) { | 581 | if (request_mask & STATX_BTIME) { |
| 582 | stat->result_mask |= STATX_BTIME; | 582 | stat->result_mask |= STATX_BTIME; |
| @@ -917,7 +917,7 @@ xfs_setattr_size( · 334 unmodified lines | |||
| 917 | if (newsize != oldsize && | 917 | if (newsize != oldsize && |
| 918 | !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { | 918 | !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) { |
| 919 | iattr->ia_ctime = iattr->ia_mtime = | 919 | iattr->ia_ctime = iattr->ia_mtime = |
| 920 | current_mgtime(inode); | 920 | current_time(inode); |
| 921 | iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; | 921 | iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; |
| 922 | } | 922 | } |
| 923 | 923 | ||
| @@ -80,6 +80,17 @@ xfs_bulkstat_one_int( · 79 unmodified lines | |||
| 80 | if (error) | 80 | if (error) |
| 81 | goto out; | 81 | goto out; |
| 82 | 82 | ||
| 83 | /* Reload the incore unlinked list to avoid failure in inodegc. */ | ||
| 84 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 85 | error = xfs_inode_reload_unlinked_bucket(tp, ip); | ||
| 86 | if (error) { | ||
| 87 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
| 88 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 89 | xfs_irele(ip); | ||
| 90 | return error; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 83 | ASSERT(ip != NULL); | 94 | ASSERT(ip != NULL); |
| 84 | ASSERT(ip->i_imap.im_blkno != 0); | 95 | ASSERT(ip->i_imap.im_blkno != 0); |
| 85 | inode = VFS_I(ip); | 96 | inode = VFS_I(ip); |
| @@ -715,15 +715,7 @@ xfs_log_mount( · 714 unmodified lines | |||
| 715 | * just worked. | 715 | * just worked. |
| 716 | */ | 716 | */ |
| 717 | if (!xfs_has_norecovery(mp)) { | 717 | if (!xfs_has_norecovery(mp)) { |
| 718 | /* | ||
| 719 | * log recovery ignores readonly state and so we need to clear | ||
| 720 | * mount-based read only state so it can write to disk. | ||
| 721 | */ | ||
| 722 | bool readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, | ||
| 723 | &mp->m_opstate); | ||
| 724 | error = xlog_recover(log); | 718 | error = xlog_recover(log); |
| 725 | if (readonly) | ||
| 726 | set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 727 | if (error) { | 719 | if (error) { |
| 728 | xfs_warn(mp, "log mount/recovery failed: error %d", | 720 | xfs_warn(mp, "log mount/recovery failed: error %d", |
| 729 | error); | 721 | error); |
| @@ -772,7 +764,6 @@ xfs_log_mount_finish( · 42 unmodified lines | |||
| 772 | struct xfs_mount *mp) | 764 | struct xfs_mount *mp) |
| 773 | { | 765 | { |
| 774 | struct xlog *log = mp->m_log; | 766 | struct xlog *log = mp->m_log; |
| 775 | bool readonly; | ||
| 776 | int error = 0; | 767 | int error = 0; |
| 777 | 768 | ||
| 778 | if (xfs_has_norecovery(mp)) { | 769 | if (xfs_has_norecovery(mp)) { |
| @@ -780,12 +771,6 @@ xfs_log_mount_finish( · 1 unmodified line | |||
| 780 | return 0; | 771 | return 0; |
| 781 | } | 772 | } |
| 782 | 773 | ||
| 783 | /* | ||
| 784 | * log recovery ignores readonly state and so we need to clear | ||
| 785 | * mount-based read only state so it can write to disk. | ||
| 786 | */ | ||
| 787 | readonly = test_and_clear_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 788 | |||
| 789 | /* | 774 | /* |
| 790 | * During the second phase of log recovery, we need iget and | 775 | * During the second phase of log recovery, we need iget and |
| 791 | * iput to behave like they do for an active filesystem. | 776 | * iput to behave like they do for an active filesystem. |
| @@ -835,8 +820,6 @@ xfs_log_mount_finish( · 43 unmodified lines | |||
| 835 | xfs_buftarg_drain(mp->m_ddev_targp); | 820 | xfs_buftarg_drain(mp->m_ddev_targp); |
| 836 | 821 | ||
| 837 | clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate); | 822 | clear_bit(XLOG_RECOVERY_NEEDED, &log->l_opstate); |
| 838 | if (readonly) | ||
| 839 | set_bit(XFS_OPSTATE_READONLY, &mp->m_opstate); | ||
| 840 | 823 | ||
| 841 | /* Make sure the log is dead if we're returning failure. */ | 824 | /* Make sure the log is dead if we're returning failure. */ |
| 842 | ASSERT(!error || xlog_is_shutdown(log)); | 825 | ASSERT(!error || xlog_is_shutdown(log)); |
| @@ -124,7 +124,7 @@ xlog_cil_push_pcp_aggregate( · 123 unmodified lines | |||
| 124 | struct xlog_cil_pcp *cilpcp; | 124 | struct xlog_cil_pcp *cilpcp; |
| 125 | int cpu; | 125 | int cpu; |
| 126 | 126 | ||
| 127 | for_each_online_cpu(cpu) { | 127 | for_each_cpu(cpu, &ctx->cil_pcpmask) { |
| 128 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | 128 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); |
| 129 | 129 | ||
| 130 | ctx->ticket->t_curr_res += cilpcp->space_reserved; | 130 | ctx->ticket->t_curr_res += cilpcp->space_reserved; |
| @@ -165,7 +165,13 @@ xlog_cil_insert_pcp_aggregate( · 34 unmodified lines | |||
| 165 | if (!test_and_clear_bit(XLOG_CIL_PCP_SPACE, &cil->xc_flags)) | 165 | if (!test_and_clear_bit(XLOG_CIL_PCP_SPACE, &cil->xc_flags)) |
| 166 | return; | 166 | return; |
| 167 | 167 | ||
| 168 | for_each_online_cpu(cpu) { | 168 | /* |
| 169 | * We can race with other cpus setting cil_pcpmask. However, we've | ||
| 170 | * atomically cleared PCP_SPACE which forces other threads to add to | ||
| 171 | * the global space used count. cil_pcpmask is a superset of cilpcp | ||
| 172 | * structures that could have a nonzero space_used. | ||
| 173 | */ | ||
| 174 | for_each_cpu(cpu, &ctx->cil_pcpmask) { | ||
| 169 | int old, prev; | 175 | int old, prev; |
| 170 | 176 | ||
| 171 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | 177 | cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); |
| @@ -554,6 +560,7 @@ xlog_cil_insert_items( · 382 unmodified lines | |||
| 554 | int iovhdr_res = 0, split_res = 0, ctx_res = 0; | 560 | int iovhdr_res = 0, split_res = 0, ctx_res = 0; |
| 555 | int space_used; | 561 | int space_used; |
| 556 | int order; | 562 | int order; |
| 563 | unsigned int cpu_nr; | ||
| 557 | struct xlog_cil_pcp *cilpcp; | 564 | struct xlog_cil_pcp *cilpcp; |
| 558 | 565 | ||
| 559 | ASSERT(tp); | 566 | ASSERT(tp); |
| @@ -577,7 +584,12 @@ xlog_cil_insert_items( · 17 unmodified lines | |||
| 577 | * can't be scheduled away between split sample/update operations that | 584 | * can't be scheduled away between split sample/update operations that |
| 578 | * are done without outside locking to serialise them. | 585 | * are done without outside locking to serialise them. |
| 579 | */ | 586 | */ |
| 580 | cilpcp = get_cpu_ptr(cil->xc_pcp); | 587 | cpu_nr = get_cpu(); |
| 588 | cilpcp = this_cpu_ptr(cil->xc_pcp); | ||
| 589 | |||
| 590 | /* Tell the future push that there was work added by this CPU. */ | ||
| 591 | if (!cpumask_test_cpu(cpu_nr, &ctx->cil_pcpmask)) | ||
| 592 | cpumask_test_and_set_cpu(cpu_nr, &ctx->cil_pcpmask); | ||
| 581 | 593 | ||
| 582 | /* | 594 | /* |
| 583 | * We need to take the CIL checkpoint unit reservation on the first | 595 | * We need to take the CIL checkpoint unit reservation on the first |
| @@ -663,7 +675,7 @@ xlog_cil_insert_items( · 79 unmodified lines | |||
| 663 | continue; | 675 | continue; |
| 664 | list_add_tail(&lip->li_cil, &cilpcp->log_items); | 676 | list_add_tail(&lip->li_cil, &cilpcp->log_items); |
| 665 | } | 677 | } |
| 666 | put_cpu_ptr(cilpcp); | 678 | put_cpu(); |
| 667 | 679 | ||
| 668 | /* | 680 | /* |
| 669 | * If we've overrun the reservation, dump the tx details before we move | 681 | * If we've overrun the reservation, dump the tx details before we move |
| @@ -1790,38 +1802,6 @@ out_shutdown: · 1120 unmodified lines | |||
| 1790 | return 0; | 1802 | return 0; |
| 1791 | } | 1803 | } |
| 1792 | 1804 | ||
| 1793 | /* | ||
| 1794 | * Move dead percpu state to the relevant CIL context structures. | ||
| 1795 | * | ||
| 1796 | * We have to lock the CIL context here to ensure that nothing is modifying | ||
| 1797 | * the percpu state, either addition or removal. Both of these are done under | ||
| 1798 | * the CIL context lock, so grabbing that exclusively here will ensure we can | ||
| 1799 | * safely drain the cilpcp for the CPU that is dying. | ||
| 1800 | */ | ||
| 1801 | void | ||
| 1802 | xlog_cil_pcp_dead( | ||
| 1803 | struct xlog *log, | ||
| 1804 | unsigned int cpu) | ||
| 1805 | { | ||
| 1806 | struct xfs_cil *cil = log->l_cilp; | ||
| 1807 | struct xlog_cil_pcp *cilpcp = per_cpu_ptr(cil->xc_pcp, cpu); | ||
| 1808 | struct xfs_cil_ctx *ctx; | ||
| 1809 | |||
| 1810 | down_write(&cil->xc_ctx_lock); | ||
| 1811 | ctx = cil->xc_ctx; | ||
| 1812 | if (ctx->ticket) | ||
| 1813 | ctx->ticket->t_curr_res += cilpcp->space_reserved; | ||
| 1814 | cilpcp->space_reserved = 0; | ||
| 1815 | |||
| 1816 | if (!list_empty(&cilpcp->log_items)) | ||
| 1817 | list_splice_init(&cilpcp->log_items, &ctx->log_items); | ||
| 1818 | if (!list_empty(&cilpcp->busy_extents)) | ||
| 1819 | list_splice_init(&cilpcp->busy_extents, &ctx->busy_extents); | ||
| 1820 | atomic_add(cilpcp->space_used, &ctx->space_used); | ||
| 1821 | cilpcp->space_used = 0; | ||
| 1822 | up_write(&cil->xc_ctx_lock); | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | /* | 1805 | /* |
| 1826 | * Perform initial CIL structure initialisation. | 1806 | * Perform initial CIL structure initialisation. |
| 1827 | */ | 1807 | */ |
| @@ -231,6 +231,12 @@ struct xfs_cil_ctx { · 230 unmodified lines | |||
| 231 | struct work_struct discard_endio_work; | 231 | struct work_struct discard_endio_work; |
| 232 | struct work_struct push_work; | 232 | struct work_struct push_work; |
| 233 | atomic_t order_id; | 233 | atomic_t order_id; |
| 234 | |||
| 235 | /* | ||
| 236 | * CPUs that could have added items to the percpu CIL data. Access is | ||
| 237 | * coordinated with xc_ctx_lock. | ||
| 238 | */ | ||
| 239 | struct cpumask cil_pcpmask; | ||
| 234 | }; | 240 | }; |
| 235 | 241 | ||
| 236 | /* | 242 | /* |
| @@ -278,9 +284,6 @@ struct xfs_cil { · 41 unmodified lines | |||
| 278 | wait_queue_head_t xc_push_wait; /* background push throttle */ | 284 | wait_queue_head_t xc_push_wait; /* background push throttle */ |
| 279 | 285 | ||
| 280 | void __percpu *xc_pcp; /* percpu CIL structures */ | 286 | void __percpu *xc_pcp; /* percpu CIL structures */ |
| 281 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 282 | struct list_head xc_pcp_list; | ||
| 283 | #endif | ||
| 284 | } ____cacheline_aligned_in_smp; | 287 | } ____cacheline_aligned_in_smp; |
| 285 | 288 | ||
| 286 | /* xc_flags bit values */ | 289 | /* xc_flags bit values */ |
| @@ -705,9 +708,4 @@ xlog_kvmalloc( · 418 unmodified lines | |||
| 705 | return p; | 708 | return p; |
| 706 | } | 709 | } |
| 707 | 710 | ||
| 708 | /* | ||
| 709 | * CIL CPU dead notifier | ||
| 710 | */ | ||
| 711 | void xlog_cil_pcp_dead(struct xlog *log, unsigned int cpu); | ||
| 712 | |||
| 713 | #endif /* __XFS_LOG_PRIV_H__ */ | 711 | #endif /* __XFS_LOG_PRIV_H__ */ |
| @@ -329,7 +329,7 @@ xlog_find_verify_cycle( · 328 unmodified lines | |||
| 329 | * try a smaller size. We need to be able to read at least | 329 | * try a smaller size. We need to be able to read at least |
| 330 | * a log sector, or we're out of luck. | 330 | * a log sector, or we're out of luck. |
| 331 | */ | 331 | */ |
| 332 | bufblks = 1 << ffs(nbblks); | 332 | bufblks = roundup_pow_of_two(nbblks); |
| 333 | while (bufblks > log->l_logBBsize) | 333 | while (bufblks > log->l_logBBsize) |
| 334 | bufblks >>= 1; | 334 | bufblks >>= 1; |
| 335 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { | 335 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { |
| @@ -1528,7 +1528,7 @@ xlog_write_log_records( · 1192 unmodified lines | |||
| 1528 | * a smaller size. We need to be able to write at least a | 1528 | * a smaller size. We need to be able to write at least a |
| 1529 | * log sector, or we're out of luck. | 1529 | * log sector, or we're out of luck. |
| 1530 | */ | 1530 | */ |
| 1531 | bufblks = 1 << ffs(blocks); | 1531 | bufblks = roundup_pow_of_two(blocks); |
| 1532 | while (bufblks > log->l_logBBsize) | 1532 | while (bufblks > log->l_logBBsize) |
| 1533 | bufblks >>= 1; | 1533 | bufblks >>= 1; |
| 1534 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { | 1534 | while (!(buffer = xlog_alloc_buffer(log, bufblks))) { |
| @@ -60,6 +60,7 @@ struct xfs_error_cfg { · 59 unmodified lines | |||
| 60 | * Per-cpu deferred inode inactivation GC lists. | 60 | * Per-cpu deferred inode inactivation GC lists. |
| 61 | */ | 61 | */ |
| 62 | struct xfs_inodegc { | 62 | struct xfs_inodegc { |
| 63 | struct xfs_mount *mp; | ||
| 63 | struct llist_head list; | 64 | struct llist_head list; |
| 64 | struct delayed_work work; | 65 | struct delayed_work work; |
| 65 | int error; | 66 | int error; |
| @@ -67,9 +68,7 @@ struct xfs_inodegc { · 1 unmodified line | |||
| 67 | /* approximate count of inodes in the list */ | 68 | /* approximate count of inodes in the list */ |
| 68 | unsigned int items; | 69 | unsigned int items; |
| 69 | unsigned int shrinker_hits; | 70 | unsigned int shrinker_hits; |
| 70 | #if defined(DEBUG) || defined(XFS_WARN) | ||
| 71 | unsigned int cpu; | 71 | unsigned int cpu; |
| 72 | #endif | ||
| 73 | }; | 72 | }; |
| 74 | 73 | ||
| 75 | /* | 74 | /* |
| @@ -98,7 +97,6 @@ typedef struct xfs_mount { · 22 unmodified lines | |||
| 98 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ | 97 | xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ |
| 99 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ | 98 | xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ |
| 100 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ | 99 | xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ |
| 101 | struct list_head m_mount_list; /* global mount list */ | ||
| 102 | void __percpu *m_inodegc; /* percpu inodegc structures */ | 100 | void __percpu *m_inodegc; /* percpu inodegc structures */ |
| 103 | 101 | ||
| 104 | /* | 102 | /* |
| @@ -249,6 +247,9 @@ typedef struct xfs_mount { · 144 unmodified lines | |||
| 249 | unsigned int *m_errortag; | 247 | unsigned int *m_errortag; |
| 250 | struct xfs_kobj m_errortag_kobj; | 248 | struct xfs_kobj m_errortag_kobj; |
| 251 | #endif | 249 | #endif |
| 250 | |||
| 251 | /* cpus that have inodes queued for inactivation */ | ||
| 252 | struct cpumask m_inodegc_cpumask; | ||
| 252 | } xfs_mount_t; | 253 | } xfs_mount_t; |
| 253 | 254 | ||
| 254 | #define M_IGEO(mp) (&(mp)->m_ino_geo) | 255 | #define M_IGEO(mp) (&(mp)->m_ino_geo) |
| @@ -404,6 +405,8 @@ __XFS_HAS_FEAT(nouuid, NOUUID) · 149 unmodified lines | |||
| 404 | #define XFS_OPSTATE_WARNED_SHRINK 8 | 405 | #define XFS_OPSTATE_WARNED_SHRINK 8 |
| 405 | /* Kernel has logged a warning about logged xattr updates being used. */ | 406 | /* Kernel has logged a warning about logged xattr updates being used. */ |
| 406 | #define XFS_OPSTATE_WARNED_LARP 9 | 407 | #define XFS_OPSTATE_WARNED_LARP 9 |
| 408 | /* Mount time quotacheck is running */ | ||
| 409 | #define XFS_OPSTATE_QUOTACHECK_RUNNING 10 | ||
| 407 | 410 | ||
| 408 | #define __XFS_IS_OPSTATE(name, NAME) \ | 411 | #define __XFS_IS_OPSTATE(name, NAME) \ |
| 409 | static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ | 412 | static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ |
| @@ -426,6 +429,11 @@ __XFS_IS_OPSTATE(inode32, INODE32) · 16 unmodified lines | |||
| 426 | __XFS_IS_OPSTATE(readonly, READONLY) | 429 | __XFS_IS_OPSTATE(readonly, READONLY) |
| 427 | __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) | 430 | __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) |
| 428 | __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) | 431 | __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) |
| 432 | #ifdef CONFIG_XFS_QUOTA | ||
| 433 | __XFS_IS_OPSTATE(quotacheck_running, QUOTACHECK_RUNNING) | ||
| 434 | #else | ||
| 435 | # define xfs_is_quotacheck_running(mp) (false) | ||
| 436 | #endif | ||
| 429 | 437 | ||
| 430 | static inline bool | 438 | static inline bool |
| 431 | xfs_should_warn(struct xfs_mount *mp, long nr) | 439 | xfs_should_warn(struct xfs_mount *mp, long nr) |
| @@ -443,7 +451,8 @@ xfs_should_warn(struct xfs_mount *mp, long nr) · 11 unmodified lines | |||
| 443 | { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED), "blockgc" }, \ | 451 | { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED), "blockgc" }, \ |
| 444 | { (1UL << XFS_OPSTATE_WARNED_SCRUB), "wscrub" }, \ | 452 | { (1UL << XFS_OPSTATE_WARNED_SCRUB), "wscrub" }, \ |
| 445 | { (1UL << XFS_OPSTATE_WARNED_SHRINK), "wshrink" }, \ | 453 | { (1UL << XFS_OPSTATE_WARNED_SHRINK), "wshrink" }, \ |
| 446 | { (1UL << XFS_OPSTATE_WARNED_LARP), "wlarp" } | 454 | { (1UL << XFS_OPSTATE_WARNED_LARP), "wlarp" }, \ |
| 455 | { (1UL << XFS_OPSTATE_QUOTACHECK_RUNNING), "quotacheck" } | ||
| 447 | 456 | ||
| 448 | /* | 457 | /* |
| 449 | * Max and min values for mount-option defined I/O | 458 | * Max and min values for mount-option defined I/O |
| @@ -1160,6 +1160,19 @@ xfs_qm_dqusage_adjust( · 1159 unmodified lines | |||
| 1160 | if (error) | 1160 | if (error) |
| 1161 | return error; | 1161 | return error; |
| 1162 | 1162 | ||
| 1163 | /* | ||
| 1164 | * Reload the incore unlinked list to avoid failure in inodegc. | ||
| 1165 | * Use an unlocked check here because unrecovered unlinked inodes | ||
| 1166 | * should be somewhat rare. | ||
| 1167 | */ | ||
| 1168 | if (xfs_inode_unlinked_incomplete(ip)) { | ||
| 1169 | error = xfs_inode_reload_unlinked(ip); | ||
| 1170 | if (error) { | ||
| 1171 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | ||
| 1172 | goto error0; | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | |||
| 1163 | ASSERT(ip->i_delayed_blks == 0); | 1176 | ASSERT(ip->i_delayed_blks == 0); |
| 1164 | 1177 | ||
| 1165 | if (XFS_IS_REALTIME_INODE(ip)) { | 1178 | if (XFS_IS_REALTIME_INODE(ip)) { |
| @@ -1173,6 +1186,7 @@ xfs_qm_dqusage_adjust( · 7 unmodified lines | |||
| 1173 | } | 1186 | } |
| 1174 | 1187 | ||
| 1175 | nblks = (xfs_qcnt_t)ip->i_nblocks - rtblks; | 1188 | nblks = (xfs_qcnt_t)ip->i_nblocks - rtblks; |
| 1189 | xfs_iflags_clear(ip, XFS_IQUOTAUNCHECKED); | ||
| 1176 | 1190 | ||
| 1177 | /* | 1191 | /* |
| 1178 | * Add the (disk blocks and inode) resources occupied by this | 1192 | * Add the (disk blocks and inode) resources occupied by this |
| @@ -1319,8 +1333,10 @@ xfs_qm_quotacheck( · 140 unmodified lines | |||
| 1319 | flags |= XFS_PQUOTA_CHKD; | 1333 | flags |= XFS_PQUOTA_CHKD; |
| 1320 | } | 1334 | } |
| 1321 | 1335 | ||
| 1336 | xfs_set_quotacheck_running(mp); | ||
| 1322 | error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, | 1337 | error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, |
| 1323 | NULL); | 1338 | NULL); |
| 1339 | xfs_clear_quotacheck_running(mp); | ||
| 1324 | 1340 | ||
| 1325 | /* | 1341 | /* |
| 1326 | * On error, the inode walk may have partially populated the dquot | 1342 | * On error, the inode walk may have partially populated the dquot |
| @@ -477,6 +477,7 @@ xfs_cui_item_recover( · 476 unmodified lines | |||
| 477 | struct xfs_log_item *lip, | 477 | struct xfs_log_item *lip, |
| 478 | struct list_head *capture_list) | 478 | struct list_head *capture_list) |
| 479 | { | 479 | { |
| 480 | struct xfs_trans_res resv; | ||
| 480 | struct xfs_cui_log_item *cuip = CUI_ITEM(lip); | 481 | struct xfs_cui_log_item *cuip = CUI_ITEM(lip); |
| 481 | struct xfs_cud_log_item *cudp; | 482 | struct xfs_cud_log_item *cudp; |
| 482 | struct xfs_trans *tp; | 483 | struct xfs_trans *tp; |
| @@ -514,8 +515,9 @@ xfs_cui_item_recover( · 31 unmodified lines | |||
| 514 | * doesn't fit. We need to reserve enough blocks to handle a | 515 | * doesn't fit. We need to reserve enough blocks to handle a |
| 515 | * full btree split on either end of the refcount range. | 516 | * full btree split on either end of the refcount range. |
| 516 | */ | 517 | */ |
| 517 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, | 518 | resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); |
| 518 | mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp); | 519 | error = xfs_trans_alloc(mp, &resv, mp->m_refc_maxlevels * 2, 0, |
| 520 | XFS_TRANS_RESERVE, &tp); | ||
| 519 | if (error) | 521 | if (error) |
| 520 | return error; | 522 | return error; |
| 521 | 523 | ||
| @@ -507,6 +507,7 @@ xfs_rui_item_recover( · 506 unmodified lines | |||
| 507 | struct xfs_log_item *lip, | 507 | struct xfs_log_item *lip, |
| 508 | struct list_head *capture_list) | 508 | struct list_head *capture_list) |
| 509 | { | 509 | { |
| 510 | struct xfs_trans_res resv; | ||
| 510 | struct xfs_rui_log_item *ruip = RUI_ITEM(lip); | 511 | struct xfs_rui_log_item *ruip = RUI_ITEM(lip); |
| 511 | struct xfs_rud_log_item *rudp; | 512 | struct xfs_rud_log_item *rudp; |
| 512 | struct xfs_trans *tp; | 513 | struct xfs_trans *tp; |
12 more lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 484 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 337 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 219 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 509 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 299 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.