Cross-merge networking fixes after downstream PR (net-6.17-rc4). No conflicts. Adjacent changes: drivers/net/ethernet/intel/idpf/idpf_txrx.c 02614eee26fb ("idpf: do not linearize big TSO packets") 6c4e68480238 ("idpf: remove obsolete stashing code")
Unified · Split
| @@ -226,6 +226,8 @@ Domen Puncer <domen@coderock.org> · 225 unmodified lines | |||
| 226 | Douglas Gilbert <dougg@torque.net> | 226 | Douglas Gilbert <dougg@torque.net> |
| 227 | Drew Fustini <fustini@kernel.org> <drew@pdp7.com> | 227 | Drew Fustini <fustini@kernel.org> <drew@pdp7.com> |
| 228 | <duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr> | 228 | <duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr> |
| 229 | Easwar Hariharan <easwar.hariharan@linux.microsoft.com> <easwar.hariharan@intel.com> | ||
| 230 | Easwar Hariharan <easwar.hariharan@linux.microsoft.com> <eahariha@linux.microsoft.com> | ||
| 229 | Ed L. Cashin <ecashin@coraid.com> | 231 | Ed L. Cashin <ecashin@coraid.com> |
| 230 | Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org> | 232 | Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org> |
| 231 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> | 233 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> |
| @@ -3222,6 +3222,10 @@ D: AIC5800 IEEE 1394, RAW I/O on 1394 · 3221 unmodified lines | |||
| 3222 | D: Starter of Linux1394 effort | 3222 | D: Starter of Linux1394 effort |
| 3223 | S: ask per mail for current address | 3223 | S: ask per mail for current address |
| 3224 | 3224 | ||
| 3225 | N: Boris Pismenny | ||
| 3226 | E: borisp@mellanox.com | ||
| 3227 | D: Kernel TLS implementation and offload support. | ||
| 3228 | |||
| 3225 | N: Nicolas Pitre | 3229 | N: Nicolas Pitre |
| 3226 | E: nico@fluxnic.net | 3230 | E: nico@fluxnic.net |
| 3227 | D: StrongARM SA1100 support integrator & hacker | 3231 | D: StrongARM SA1100 support integrator & hacker |
| @@ -4168,6 +4172,9 @@ S: 1513 Brewster Dr. · 940 unmodified lines | |||
| 4168 | S: Carrollton, TX 75010 | 4172 | S: Carrollton, TX 75010 |
| 4169 | S: USA | 4173 | S: USA |
| 4170 | 4174 | ||
| 4175 | N: Dave Watson | ||
| 4176 | D: Kernel TLS implementation. | ||
| 4177 | |||
| 4171 | N: Tim Waugh | 4178 | N: Tim Waugh |
| 4172 | E: tim@cyberelk.net | 4179 | E: tim@cyberelk.net |
| 4173 | D: Co-architect of the parallel-port sharing system | 4180 | D: Co-architect of the parallel-port sharing system |
| @@ -435,8 +435,8 @@ both cgroups. · 434 unmodified lines | |||
| 435 | Controlling Controllers | 435 | Controlling Controllers |
| 436 | ----------------------- | 436 | ----------------------- |
| 437 | 437 | ||
| 438 | Availablity | 438 | Availability |
| 439 | ~~~~~~~~~~~ | 439 | ~~~~~~~~~~~~ |
| 440 | 440 | ||
| 441 | A controller is available in a cgroup when it is supported by the kernel (i.e., | 441 | A controller is available in a cgroup when it is supported by the kernel (i.e., |
| 442 | compiled in, not disabled and not attached to a v1 hierarchy) and listed in the | 442 | compiled in, not disabled and not attached to a v1 hierarchy) and listed in the |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Infineon Buck Regulators with PMBUS interfaces | 7 | title: Infineon Buck Regulators with PMBUS interfaces |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Not Me. | 10 | - Guenter Roeck <linux@roeck-us.net> |
| 11 | 11 | ||
| 12 | allOf: | 12 | allOf: |
| 13 | - $ref: regulator.yaml# | 13 | - $ref: regulator.yaml# |
| @@ -507,6 +507,8 @@ patternProperties: · 506 unmodified lines | |||
| 507 | description: Espressif Systems Co. Ltd. | 507 | description: Espressif Systems Co. Ltd. |
| 508 | "^est,.*": | 508 | "^est,.*": |
| 509 | description: ESTeem Wireless Modems | 509 | description: ESTeem Wireless Modems |
| 510 | "^eswin,.*": | ||
| 511 | description: Beijing ESWIN Technology Group Co. Ltd. | ||
| 510 | "^ettus,.*": | 512 | "^ettus,.*": |
| 511 | description: NI Ettus Research | 513 | description: NI Ettus Research |
| 512 | "^eukrea,.*": | 514 | "^eukrea,.*": |
| @@ -8,8 +8,22 @@ like to know when a security bug is found so that it can be fixed and · 7 unmodified lines | |||
| 8 | disclosed as quickly as possible. Please report security bugs to the | 8 | disclosed as quickly as possible. Please report security bugs to the |
| 9 | Linux kernel security team. | 9 | Linux kernel security team. |
| 10 | 10 | ||
| 11 | Contact | 11 | The security team and maintainers almost always require additional |
| 12 | ------- | 12 | information beyond what was initially provided in a report and rely on |
| 13 | active and efficient collaboration with the reporter to perform further | ||
| 14 | testing (e.g., verifying versions, configuration options, mitigations, or | ||
| 15 | patches). Before contacting the security team, the reporter must ensure | ||
| 16 | they are available to explain their findings, engage in discussions, and | ||
| 17 | run additional tests. Reports where the reporter does not respond promptly | ||
| 18 | or cannot effectively discuss their findings may be abandoned if the | ||
| 19 | communication does not quickly improve. | ||
| 20 | |||
| 21 | As it is with any bug, the more information provided the easier it | ||
| 22 | will be to diagnose and fix. Please review the procedure outlined in | ||
| 23 | 'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what | ||
| 24 | information is helpful. Any exploit code is very helpful and will not | ||
| 25 | be released without consent from the reporter unless it has already been | ||
| 26 | made public. | ||
| 13 | 27 | ||
| 14 | The Linux kernel security team can be contacted by email at | 28 | The Linux kernel security team can be contacted by email at |
| 15 | <security@kernel.org>. This is a private list of security officers | 29 | <security@kernel.org>. This is a private list of security officers |
| @@ -19,13 +33,6 @@ that can speed up the process considerably. It is possible that the · 3 unmodified lines | |||
| 19 | security team will bring in extra help from area maintainers to | 33 | security team will bring in extra help from area maintainers to |
| 20 | understand and fix the security vulnerability. | 34 | understand and fix the security vulnerability. |
| 21 | 35 | ||
| 22 | As it is with any bug, the more information provided the easier it | ||
| 23 | will be to diagnose and fix. Please review the procedure outlined in | ||
| 24 | 'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what | ||
| 25 | information is helpful. Any exploit code is very helpful and will not | ||
| 26 | be released without consent from the reporter unless it has already been | ||
| 27 | made public. | ||
| 28 | |||
| 29 | Please send plain text emails without attachments where possible. | 36 | Please send plain text emails without attachments where possible. |
| 30 | It is much harder to have a context-quoted discussion about a complex | 37 | It is much harder to have a context-quoted discussion about a complex |
| 31 | issue if all the details are hidden away in attachments. Think of it like a | 38 | issue if all the details are hidden away in attachments. Think of it like a |
| @@ -43,7 +43,7 @@ Following IOMMUFD objects are exposed to userspace: · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | - IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table | 44 | - IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table |
| 45 | (i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING" | 45 | (i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING" |
| 46 | primarly indicates this type of HWPT should be linked to an IOAS. It also | 46 | primarily indicates this type of HWPT should be linked to an IOAS. It also |
| 47 | indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING | 47 | indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING |
| 48 | feature flag. This can be either an UNMANAGED stage-1 domain for a device | 48 | feature flag. This can be either an UNMANAGED stage-1 domain for a device |
| 49 | running in the user space, or a nesting parent stage-2 domain for mappings | 49 | running in the user space, or a nesting parent stage-2 domain for mappings |
| @@ -76,7 +76,7 @@ Following IOMMUFD objects are exposed to userspace: · 26 unmodified lines | |||
| 76 | 76 | ||
| 77 | * Security namespace for guest owned ID, e.g. guest-controlled cache tags | 77 | * Security namespace for guest owned ID, e.g. guest-controlled cache tags |
| 78 | * Non-device-affiliated event reporting, e.g. invalidation queue errors | 78 | * Non-device-affiliated event reporting, e.g. invalidation queue errors |
| 79 | * Access to a sharable nesting parent pagetable across physical IOMMUs | 79 | * Access to a shareable nesting parent pagetable across physical IOMMUs |
| 80 | * Virtualization of various platforms IDs, e.g. RIDs and others | 80 | * Virtualization of various platforms IDs, e.g. RIDs and others |
| 81 | * Delivery of paravirtualized invalidation | 81 | * Delivery of paravirtualized invalidation |
| 82 | * Direct assigned invalidation queues | 82 | * Direct assigned invalidation queues |
| @@ -937,7 +937,7 @@ S: Maintained · 936 unmodified lines | |||
| 937 | F: drivers/gpio/gpio-altera.c | 937 | F: drivers/gpio/gpio-altera.c |
| 938 | 938 | ||
| 939 | ALTERA TRIPLE SPEED ETHERNET DRIVER | 939 | ALTERA TRIPLE SPEED ETHERNET DRIVER |
| 940 | M: Joyce Ooi <joyce.ooi@intel.com> | 940 | M: Boon Khai Ng <boon.khai.ng@altera.com> |
| 941 | L: netdev@vger.kernel.org | 941 | L: netdev@vger.kernel.org |
| 942 | S: Maintained | 942 | S: Maintained |
| 943 | F: drivers/net/ethernet/altera/ | 943 | F: drivers/net/ethernet/altera/ |
| @@ -4216,7 +4216,7 @@ F: drivers/md/bcache/ · 3272 unmodified lines | |||
| 4216 | BCACHEFS | 4216 | BCACHEFS |
| 4217 | M: Kent Overstreet <kent.overstreet@linux.dev> | 4217 | M: Kent Overstreet <kent.overstreet@linux.dev> |
| 4218 | L: linux-bcachefs@vger.kernel.org | 4218 | L: linux-bcachefs@vger.kernel.org |
| 4219 | S: Supported | 4219 | S: Externally maintained |
| 4220 | C: irc://irc.oftc.net/bcache | 4220 | C: irc://irc.oftc.net/bcache |
| 4221 | P: Documentation/filesystems/bcachefs/SubmittingPatches.rst | 4221 | P: Documentation/filesystems/bcachefs/SubmittingPatches.rst |
| 4222 | T: git https://evilpiepirate.org/git/bcachefs.git | 4222 | T: git https://evilpiepirate.org/git/bcachefs.git |
| @@ -8427,6 +8427,17 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git · 4204 unmodified lines | |||
| 8427 | F: drivers/gpu/drm/scheduler/ | 8427 | F: drivers/gpu/drm/scheduler/ |
| 8428 | F: include/drm/gpu_scheduler.h | 8428 | F: include/drm/gpu_scheduler.h |
| 8429 | 8429 | ||
| 8430 | DRM GPUVM | ||
| 8431 | M: Danilo Krummrich <dakr@kernel.org> | ||
| 8432 | R: Matthew Brost <matthew.brost@intel.com> | ||
| 8433 | R: Thomas Hellström <thomas.hellstrom@linux.intel.com> | ||
| 8434 | R: Alice Ryhl <aliceryhl@google.com> | ||
| 8435 | L: dri-devel@lists.freedesktop.org | ||
| 8436 | S: Supported | ||
| 8437 | T: git https://gitlab.freedesktop.org/drm/misc/kernel.git | ||
| 8438 | F: drivers/gpu/drm/drm_gpuvm.c | ||
| 8439 | F: include/drm/drm_gpuvm.h | ||
| 8440 | |||
| 8430 | DRM LOG | 8441 | DRM LOG |
| 8431 | M: Jocelyn Falempe <jfalempe@redhat.com> | 8442 | M: Jocelyn Falempe <jfalempe@redhat.com> |
| 8432 | M: Javier Martinez Canillas <javierm@redhat.com> | 8443 | M: Javier Martinez Canillas <javierm@redhat.com> |
| @@ -10656,7 +10667,8 @@ S: Maintained · 2223 unmodified lines | |||
| 10656 | F: block/partitions/efi.* | 10667 | F: block/partitions/efi.* |
| 10657 | 10668 | ||
| 10658 | HABANALABS PCI DRIVER | 10669 | HABANALABS PCI DRIVER |
| 10659 | M: Yaron Avizrat <yaron.avizrat@intel.com> | 10670 | M: Koby Elbaz <koby.elbaz@intel.com> |
| 10671 | M: Konstantin Sinyuk <konstantin.sinyuk@intel.com> | ||
| 10660 | L: dri-devel@lists.freedesktop.org | 10672 | L: dri-devel@lists.freedesktop.org |
| 10661 | S: Supported | 10673 | S: Supported |
| 10662 | C: irc://irc.oftc.net/dri-devel | 10674 | C: irc://irc.oftc.net/dri-devel |
| @@ -11014,7 +11026,7 @@ F: Documentation/admin-guide/perf/hns3-pmu.rst · 351 unmodified lines | |||
| 11014 | F: drivers/perf/hisilicon/hns3_pmu.c | 11026 | F: drivers/perf/hisilicon/hns3_pmu.c |
| 11015 | 11027 | ||
| 11016 | HISILICON I2C CONTROLLER DRIVER | 11028 | HISILICON I2C CONTROLLER DRIVER |
| 11017 | M: Yicong Yang <yangyicong@hisilicon.com> | 11029 | M: Devyn Liu <liudingyuan@h-partners.com> |
| 11018 | L: linux-i2c@vger.kernel.org | 11030 | L: linux-i2c@vger.kernel.org |
| 11019 | S: Maintained | 11031 | S: Maintained |
| 11020 | W: https://www.hisilicon.com | 11032 | W: https://www.hisilicon.com |
| @@ -12282,7 +12294,6 @@ F: include/linux/avf/virtchnl.h · 1261 unmodified lines | |||
| 12282 | F: include/linux/net/intel/*/ | 12294 | F: include/linux/net/intel/*/ |
| 12283 | 12295 | ||
| 12284 | INTEL ETHERNET PROTOCOL DRIVER FOR RDMA | 12296 | INTEL ETHERNET PROTOCOL DRIVER FOR RDMA |
| 12285 | M: Mustafa Ismail <mustafa.ismail@intel.com> | ||
| 12286 | M: Tatyana Nikolova <tatyana.e.nikolova@intel.com> | 12297 | M: Tatyana Nikolova <tatyana.e.nikolova@intel.com> |
| 12287 | L: linux-rdma@vger.kernel.org | 12298 | L: linux-rdma@vger.kernel.org |
| 12288 | S: Supported | 12299 | S: Supported |
| @@ -16059,6 +16070,23 @@ F: mm/mempolicy.c · 3770 unmodified lines | |||
| 16059 | F: mm/migrate.c | 16070 | F: mm/migrate.c |
| 16060 | F: mm/migrate_device.c | 16071 | F: mm/migrate_device.c |
| 16061 | 16072 | ||
| 16073 | MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU) | ||
| 16074 | M: Andrew Morton <akpm@linux-foundation.org> | ||
| 16075 | M: Axel Rasmussen <axelrasmussen@google.com> | ||
| 16076 | M: Yuanchu Xie <yuanchu@google.com> | ||
| 16077 | R: Wei Xu <weixugc@google.com> | ||
| 16078 | L: linux-mm@kvack.org | ||
| 16079 | S: Maintained | ||
| 16080 | W: http://www.linux-mm.org | ||
| 16081 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | ||
| 16082 | F: Documentation/admin-guide/mm/multigen_lru.rst | ||
| 16083 | F: Documentation/mm/multigen_lru.rst | ||
| 16084 | F: include/linux/mm_inline.h | ||
| 16085 | F: include/linux/mmzone.h | ||
| 16086 | F: mm/swap.c | ||
| 16087 | F: mm/vmscan.c | ||
| 16088 | F: mm/workingset.c | ||
| 16089 | |||
| 16062 | MEMORY MANAGEMENT - MISC | 16090 | MEMORY MANAGEMENT - MISC |
| 16063 | M: Andrew Morton <akpm@linux-foundation.org> | 16091 | M: Andrew Morton <akpm@linux-foundation.org> |
| 16064 | M: David Hildenbrand <david@redhat.com> | 16092 | M: David Hildenbrand <david@redhat.com> |
| @@ -16249,8 +16277,10 @@ S: Maintained · 184 unmodified lines | |||
| 16249 | W: http://www.linux-mm.org | 16277 | W: http://www.linux-mm.org |
| 16250 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm | 16278 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm |
| 16251 | F: rust/helpers/mm.c | 16279 | F: rust/helpers/mm.c |
| 16280 | F: rust/helpers/page.c | ||
| 16252 | F: rust/kernel/mm.rs | 16281 | F: rust/kernel/mm.rs |
| 16253 | F: rust/kernel/mm/ | 16282 | F: rust/kernel/mm/ |
| 16283 | F: rust/kernel/page.rs | ||
| 16254 | 16284 | ||
| 16255 | MEMORY MAPPING | 16285 | MEMORY MAPPING |
| 16256 | M: Andrew Morton <akpm@linux-foundation.org> | 16286 | M: Andrew Morton <akpm@linux-foundation.org> |
| @@ -17819,7 +17849,6 @@ F: net/ipv6/syncookies.c · 1562 unmodified lines | |||
| 17819 | F: net/ipv6/tcp*.c | 17849 | F: net/ipv6/tcp*.c |
| 17820 | 17850 | ||
| 17821 | NETWORKING [TLS] | 17851 | NETWORKING [TLS] |
| 17822 | M: Boris Pismenny <borisp@nvidia.com> | ||
| 17823 | M: John Fastabend <john.fastabend@gmail.com> | 17852 | M: John Fastabend <john.fastabend@gmail.com> |
| 17824 | M: Jakub Kicinski <kuba@kernel.org> | 17853 | M: Jakub Kicinski <kuba@kernel.org> |
| 17825 | L: netdev@vger.kernel.org | 17854 | L: netdev@vger.kernel.org |
| @@ -20857,8 +20886,8 @@ S: Maintained · 3031 unmodified lines | |||
| 20857 | F: drivers/firmware/qcom/qcom_qseecom_uefisecapp.c | 20886 | F: drivers/firmware/qcom/qcom_qseecom_uefisecapp.c |
| 20858 | 20887 | ||
| 20859 | QUALCOMM RMNET DRIVER | 20888 | QUALCOMM RMNET DRIVER |
| 20860 | M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com> | 20889 | M: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@oss.qualcomm.com> |
| 20861 | M: Sean Tranchetti <quic_stranche@quicinc.com> | 20890 | M: Sean Tranchetti <sean.tranchetti@oss.qualcomm.com> |
| 20862 | L: netdev@vger.kernel.org | 20891 | L: netdev@vger.kernel.org |
| 20863 | S: Maintained | 20892 | S: Maintained |
| 20864 | F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst | 20893 | F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 17 | 3 | PATCHLEVEL = 17 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc3 |
| 6 | NAME = Baby Opossum Posse | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -82,13 +82,16 @@ · 81 unmodified lines | |||
| 82 | }; | 82 | }; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | etop@e180000 { | 85 | ethernet@e180000 { |
| 86 | compatible = "lantiq,etop-xway"; | 86 | compatible = "lantiq,etop-xway"; |
| 87 | reg = <0xe180000 0x40000>; | 87 | reg = <0xe180000 0x40000>; |
| 88 | interrupt-parent = <&icu0>; | 88 | interrupt-parent = <&icu0>; |
| 89 | interrupts = <73 78>; | 89 | interrupts = <73 78>; |
| 90 | interrupt-names = "tx", "rx"; | ||
| 90 | phy-mode = "rmii"; | 91 | phy-mode = "rmii"; |
| 91 | mac-address = [ 00 11 22 33 44 55 ]; | 92 | mac-address = [ 00 11 22 33 44 55 ]; |
| 93 | lantiq,rx-burst-length = <4>; | ||
| 94 | lantiq,tx-burst-length = <4>; | ||
| 92 | }; | 95 | }; |
| 93 | 96 | ||
| 94 | stp0: stp@e100bb0 { | 97 | stp0: stp@e100bb0 { |
| @@ -497,7 +497,7 @@ void __init ltq_soc_init(void) · 496 unmodified lines | |||
| 497 | ifccr = CGU_IFCCR_VR9; | 497 | ifccr = CGU_IFCCR_VR9; |
| 498 | pcicr = CGU_PCICR_VR9; | 498 | pcicr = CGU_PCICR_VR9; |
| 499 | } else { | 499 | } else { |
| 500 | clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE); | 500 | clkdev_add_pmu("1e180000.ethernet", NULL, 1, 0, PMU_PPE); |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | if (!of_machine_is_compatible("lantiq,ase")) | 503 | if (!of_machine_is_compatible("lantiq,ase")) |
| @@ -531,9 +531,9 @@ void __init ltq_soc_init(void) · 27 unmodified lines | |||
| 531 | CLOCK_133M, CLOCK_133M); | 531 | CLOCK_133M, CLOCK_133M); |
| 532 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); | 532 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); |
| 533 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); | 533 | clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); |
| 534 | clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE); | 534 | clkdev_add_pmu("1e180000.ethernet", "ppe", 1, 0, PMU_PPE); |
| 535 | clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY); | 535 | clkdev_add_cgu("1e180000.ethernet", "ephycgu", CGU_EPHY); |
| 536 | clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY); | 536 | clkdev_add_pmu("1e180000.ethernet", "ephy", 1, 0, PMU_EPHY); |
| 537 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO); | 537 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO); |
| 538 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | 538 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); |
| 539 | } else if (of_machine_is_compatible("lantiq,grx390")) { | 539 | } else if (of_machine_is_compatible("lantiq,grx390")) { |
| @@ -592,7 +592,7 @@ void __init ltq_soc_init(void) · 52 unmodified lines | |||
| 592 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); | 592 | clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); |
| 593 | clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); | 593 | clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); |
| 594 | clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); | 594 | clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); |
| 595 | clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); | 595 | clkdev_add_pmu("1e180000.ethernet", "switch", 1, 0, PMU_SWITCH); |
| 596 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); | 596 | clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); |
| 597 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); | 597 | clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); |
| 598 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); | 598 | clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); |
| @@ -243,13 +243,13 @@ $(obj)/wrapper.a: $(obj-wlib) FORCE · 242 unmodified lines | |||
| 243 | hostprogs := addnote hack-coff mktree | 243 | hostprogs := addnote hack-coff mktree |
| 244 | 244 | ||
| 245 | targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) zImage.lds | 245 | targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) zImage.lds |
| 246 | extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ | 246 | always-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ |
| 247 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds | 247 | $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds |
| 248 | 248 | ||
| 249 | dtstree := $(src)/dts | 249 | dtstree := $(src)/dts |
| 250 | 250 | ||
| 251 | wrapper := $(src)/wrapper | 251 | wrapper := $(src)/wrapper |
| 252 | wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ | 252 | wrapperbits := $(always-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ |
| 253 | $(wrapper) FORCE | 253 | $(wrapper) FORCE |
| 254 | 254 | ||
| 255 | ############# | 255 | ############# |
| @@ -456,7 +456,7 @@ WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts · 200 unmodified lines | |||
| 456 | WRAPPER_BINDIR := /usr/sbin | 456 | WRAPPER_BINDIR := /usr/sbin |
| 457 | INSTALL := install | 457 | INSTALL := install |
| 458 | 458 | ||
| 459 | extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) | 459 | extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(always-y)) |
| 460 | hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs)) | 460 | hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs)) |
| 461 | wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper | 461 | wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper |
| 462 | dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts)) | 462 | dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts)) |
| @@ -19,19 +19,19 @@ · 18 unmodified lines | |||
| 19 | set -e | 19 | set -e |
| 20 | 20 | ||
| 21 | # this should work for both the pSeries zImage and the iSeries vmlinux.sm | 21 | # this should work for both the pSeries zImage and the iSeries vmlinux.sm |
| 22 | image_name=`basename $2` | 22 | image_name=$(basename "$2") |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | echo "Warning: '${INSTALLKERNEL}' command not available... Copying" \ | 25 | echo "Warning: '${INSTALLKERNEL}' command not available... Copying" \ |
| 26 | "directly to $4/$image_name-$1" >&2 | 26 | "directly to $4/$image_name-$1" >&2 |
| 27 | 27 | ||
| 28 | if [ -f $4/$image_name-$1 ]; then | 28 | if [ -f "$4"/"$image_name"-"$1" ]; then |
| 29 | mv $4/$image_name-$1 $4/$image_name-$1.old | 29 | mv "$4"/"$image_name"-"$1" "$4"/"$image_name"-"$1".old |
| 30 | fi | 30 | fi |
| 31 | 31 | ||
| 32 | if [ -f $4/System.map-$1 ]; then | 32 | if [ -f "$4"/System.map-"$1" ]; then |
| 33 | mv $4/System.map-$1 $4/System-$1.old | 33 | mv "$4"/System.map-"$1" "$4"/System-"$1".old |
| 34 | fi | 34 | fi |
| 35 | 35 | ||
| 36 | cat $2 > $4/$image_name-$1 | 36 | cat "$2" > "$4"/"$image_name"-"$1" |
| 37 | cp $3 $4/System.map-$1 | 37 | cp "$3" "$4"/System.map-"$1" |
| @@ -199,7 +199,9 @@ obj-$(CONFIG_ALTIVEC) += vector.o · 198 unmodified lines | |||
| 199 | 199 | ||
| 200 | obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o | 200 | obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o |
| 201 | obj64-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_entry_64.o | 201 | obj64-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_entry_64.o |
| 202 | extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check | 202 | ifdef KBUILD_BUILTIN |
| 203 | always-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check | ||
| 204 | endif | ||
| 203 | 205 | ||
| 204 | obj-$(CONFIG_PPC64) += $(obj64-y) | 206 | obj-$(CONFIG_PPC64) += $(obj64-y) |
| 205 | obj-$(CONFIG_PPC32) += $(obj32-y) | 207 | obj-$(CONFIG_PPC32) += $(obj32-y) |
| @@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features) · 631 unmodified lines | |||
| 632 | #endif | 632 | #endif |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | switch (inst_no_rt & ~KVM_MASK_RB) { | ||
| 636 | #ifdef CONFIG_PPC_BOOK3S_32 | 635 | #ifdef CONFIG_PPC_BOOK3S_32 |
| 636 | switch (inst_no_rt & ~KVM_MASK_RB) { | ||
| 637 | case KVM_INST_MTSRIN: | 637 | case KVM_INST_MTSRIN: |
| 638 | if (features & KVM_MAGIC_FEAT_SR) { | 638 | if (features & KVM_MAGIC_FEAT_SR) { |
| 639 | u32 inst_rb = _inst & KVM_MASK_RB; | 639 | u32 inst_rb = _inst & KVM_MASK_RB; |
| 640 | kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb); | 640 | kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb); |
| 641 | } | 641 | } |
| 642 | break; | 642 | break; |
| 643 | #endif | ||
| 644 | } | 643 | } |
| 644 | #endif | ||
| 645 | 645 | ||
| 646 | switch (_inst) { | ||
| 647 | #ifdef CONFIG_BOOKE | 646 | #ifdef CONFIG_BOOKE |
| 647 | switch (_inst) { | ||
| 648 | case KVM_INST_WRTEEI_0: | 648 | case KVM_INST_WRTEEI_0: |
| 649 | kvm_patch_ins_wrteei_0(inst); | 649 | kvm_patch_ins_wrteei_0(inst); |
| 650 | break; | 650 | break; |
| @@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features) · 1 unmodified line | |||
| 652 | case KVM_INST_WRTEEI_1: | 652 | case KVM_INST_WRTEEI_1: |
| 653 | kvm_patch_ins_wrtee(inst, 0, 1); | 653 | kvm_patch_ins_wrtee(inst, 0, 1); |
| 654 | break; | 654 | break; |
| 655 | #endif | ||
| 656 | } | 655 | } |
| 656 | #endif | ||
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | extern u32 kvm_template_start[]; | 659 | extern u32 kvm_template_start[]; |
| @@ -15,8 +15,8 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | has_renamed_memintrinsics() | 16 | has_renamed_memintrinsics() |
| 17 | { | 17 | { |
| 18 | grep -q "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} && \ | 18 | grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \ |
| 19 | ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" ${KCONFIG_CONFIG} | 19 | ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}" |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | if has_renamed_memintrinsics | 22 | if has_renamed_memintrinsics |
| @@ -42,15 +42,15 @@ check_section() · 19 unmodified lines | |||
| 42 | { | 42 | { |
| 43 | file=$1 | 43 | file=$1 |
| 44 | section=$2 | 44 | section=$2 |
| 45 | size=$(objdump -h -j $section $file 2>/dev/null | awk "\$2 == \"$section\" {print \$3}") | 45 | size=$(objdump -h -j "$section" "$file" 2>/dev/null | awk "\$2 == \"$section\" {print \$3}") |
| 46 | size=${size:-0} | 46 | size=${size:-0} |
| 47 | if [ $size -ne 0 ]; then | 47 | if [ "$size" -ne 0 ]; then |
| 48 | ERROR=1 | 48 | ERROR=1 |
| 49 | echo "Error: Section $section not empty in prom_init.c" >&2 | 49 | echo "Error: Section $section not empty in prom_init.c" >&2 |
| 50 | fi | 50 | fi |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | for UNDEF in $($NM -u $OBJ | awk '{print $2}') | 53 | for UNDEF in $($NM -u "$OBJ" | awk '{print $2}') |
| 54 | do | 54 | do |
| 55 | # On 64-bit nm gives us the function descriptors, which have | 55 | # On 64-bit nm gives us the function descriptors, which have |
| 56 | # a leading . on the name, so strip it off here. | 56 | # a leading . on the name, so strip it off here. |
| @@ -87,8 +87,8 @@ do · 30 unmodified lines | |||
| 87 | fi | 87 | fi |
| 88 | done | 88 | done |
| 89 | 89 | ||
| 90 | check_section $OBJ .data | 90 | check_section "$OBJ" .data |
| 91 | check_section $OBJ .bss | 91 | check_section "$OBJ" .bss |
| 92 | check_section $OBJ .init.data | 92 | check_section "$OBJ" .init.data |
| 93 | 93 | ||
| 94 | exit $ERROR | 94 | exit $ERROR |
| @@ -141,10 +141,7 @@ void __init check_smt_enabled(void) · 140 unmodified lines | |||
| 141 | smt_enabled_at_boot = 0; | 141 | smt_enabled_at_boot = 0; |
| 142 | else { | 142 | else { |
| 143 | int smt; | 143 | int smt; |
| 144 | int rc; | 144 | if (!kstrtoint(smt_enabled_cmdline, 10, &smt)) |
| 145 | |||
| 146 | rc = kstrtoint(smt_enabled_cmdline, 10, &smt); | ||
| 147 | if (!rc) | ||
| 148 | smt_enabled_at_boot = | 145 | smt_enabled_at_boot = |
| 149 | min(threads_per_core, smt); | 146 | min(threads_per_core, smt); |
| 150 | } | 147 | } |
| @@ -69,7 +69,7 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | /* | 70 | /* |
| 71 | * Common checks before entering the guest world. Call with interrupts | 71 | * Common checks before entering the guest world. Call with interrupts |
| 72 | * disabled. | 72 | * enabled. |
| 73 | * | 73 | * |
| 74 | * returns: | 74 | * returns: |
| 75 | * | 75 | * |
| @@ -110,8 +110,7 @@ static int cpm_pic_probe(struct platform_device *pdev) · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | out_be32(&data->reg->cpic_cimr, 0); | 111 | out_be32(&data->reg->cpic_cimr, 0); |
| 112 | 112 | ||
| 113 | data->host = irq_domain_create_linear(of_fwnode_handle(dev->of_node), | 113 | data->host = irq_domain_create_linear(dev_fwnode(dev), 64, &cpm_pic_host_ops, data); |
| 114 | 64, &cpm_pic_host_ops, data); | ||
| 115 | if (!data->host) | 114 | if (!data->host) |
| 116 | return -ENODEV; | 115 | return -ENODEV; |
| 117 | 116 | ||
| @@ -122,16 +122,11 @@ choice · 121 unmodified lines | |||
| 122 | If unsure, select Generic. | 122 | If unsure, select Generic. |
| 123 | 123 | ||
| 124 | config POWERPC64_CPU | 124 | config POWERPC64_CPU |
| 125 | bool "Generic (POWER5 and PowerPC 970 and above)" | 125 | bool "Generic 64 bits powerpc" |
| 126 | depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN | 126 | depends on PPC_BOOK3S_64 |
| 127 | select PPC_64S_HASH_MMU | 127 | select ARCH_HAS_FAST_MULTIPLIER if CPU_LITTLE_ENDIAN |
| 128 | |||
| 129 | config POWERPC64_CPU | ||
| 130 | bool "Generic (POWER8 and above)" | ||
| 131 | depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN | ||
| 132 | select ARCH_HAS_FAST_MULTIPLIER | ||
| 133 | select PPC_64S_HASH_MMU | 128 | select PPC_64S_HASH_MMU |
| 134 | select PPC_HAS_LBARX_LHARX | 129 | select PPC_HAS_LBARX_LHARX if CPU_LITTLE_ENDIAN |
| 135 | 130 | ||
| 136 | config POWERPC_CPU | 131 | config POWERPC_CPU |
| 137 | bool "Generic 32 bits powerpc" | 132 | bool "Generic 32 bits powerpc" |
| @@ -412,9 +412,8 @@ static int fsl_of_msi_probe(struct platform_device *dev) · 411 unmodified lines | |||
| 412 | } | 412 | } |
| 413 | platform_set_drvdata(dev, msi); | 413 | platform_set_drvdata(dev, msi); |
| 414 | 414 | ||
| 415 | msi->irqhost = irq_domain_create_linear(of_fwnode_handle(dev->dev.of_node), | 415 | msi->irqhost = irq_domain_create_linear(dev_fwnode(&dev->dev), NR_MSI_IRQS_MAX, |
| 416 | NR_MSI_IRQS_MAX, &fsl_msi_host_ops, msi); | 416 | &fsl_msi_host_ops, msi); |
| 417 | |||
| 418 | if (msi->irqhost == NULL) { | 417 | if (msi->irqhost == NULL) { |
| 419 | dev_err(&dev->dev, "No memory for MSI irqhost\n"); | 418 | dev_err(&dev->dev, "No memory for MSI irqhost\n"); |
| 420 | err = -ENOMEM; | 419 | err = -ENOMEM; |
| @@ -530,6 +530,9 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l · 529 unmodified lines | |||
| 530 | lowcore_address + sizeof(struct lowcore), | 530 | lowcore_address + sizeof(struct lowcore), |
| 531 | POPULATE_LOWCORE); | 531 | POPULATE_LOWCORE); |
| 532 | for_each_physmem_usable_range(i, &start, &end) { | 532 | for_each_physmem_usable_range(i, &start, &end) { |
| 533 | /* Do not map lowcore with identity mapping */ | ||
| 534 | if (!start) | ||
| 535 | start = sizeof(struct lowcore); | ||
| 533 | pgtable_populate((unsigned long)__identity_va(start), | 536 | pgtable_populate((unsigned long)__identity_va(start), |
| 534 | (unsigned long)__identity_va(end), | 537 | (unsigned long)__identity_va(end), |
| 535 | POPULATE_IDENTITY); | 538 | POPULATE_IDENTITY); |
| @@ -5,6 +5,7 @@ CONFIG_WATCH_QUEUE=y · 4 unmodified lines | |||
| 5 | CONFIG_AUDIT=y | 5 | CONFIG_AUDIT=y |
| 6 | CONFIG_NO_HZ_IDLE=y | 6 | CONFIG_NO_HZ_IDLE=y |
| 7 | CONFIG_HIGH_RES_TIMERS=y | 7 | CONFIG_HIGH_RES_TIMERS=y |
| 8 | CONFIG_POSIX_AUX_CLOCKS=y | ||
| 8 | CONFIG_BPF_SYSCALL=y | 9 | CONFIG_BPF_SYSCALL=y |
| 9 | CONFIG_BPF_JIT=y | 10 | CONFIG_BPF_JIT=y |
| 10 | CONFIG_BPF_JIT_ALWAYS_ON=y | 11 | CONFIG_BPF_JIT_ALWAYS_ON=y |
| @@ -19,6 +20,7 @@ CONFIG_TASK_XACCT=y · 8 unmodified lines | |||
| 19 | CONFIG_TASK_IO_ACCOUNTING=y | 20 | CONFIG_TASK_IO_ACCOUNTING=y |
| 20 | CONFIG_IKCONFIG=y | 21 | CONFIG_IKCONFIG=y |
| 21 | CONFIG_IKCONFIG_PROC=y | 22 | CONFIG_IKCONFIG_PROC=y |
| 23 | CONFIG_SCHED_PROXY_EXEC=y | ||
| 22 | CONFIG_NUMA_BALANCING=y | 24 | CONFIG_NUMA_BALANCING=y |
| 23 | CONFIG_MEMCG=y | 25 | CONFIG_MEMCG=y |
| 24 | CONFIG_BLK_CGROUP=y | 26 | CONFIG_BLK_CGROUP=y |
| @@ -42,6 +44,7 @@ CONFIG_PROFILING=y · 17 unmodified lines | |||
| 42 | CONFIG_KEXEC=y | 44 | CONFIG_KEXEC=y |
| 43 | CONFIG_KEXEC_FILE=y | 45 | CONFIG_KEXEC_FILE=y |
| 44 | CONFIG_KEXEC_SIG=y | 46 | CONFIG_KEXEC_SIG=y |
| 47 | CONFIG_CRASH_DM_CRYPT=y | ||
| 45 | CONFIG_LIVEPATCH=y | 48 | CONFIG_LIVEPATCH=y |
| 46 | CONFIG_MARCH_Z13=y | 49 | CONFIG_MARCH_Z13=y |
| 47 | CONFIG_NR_CPUS=512 | 50 | CONFIG_NR_CPUS=512 |
| @@ -105,6 +108,7 @@ CONFIG_CMA_AREAS=7 · 57 unmodified lines | |||
| 105 | CONFIG_MEM_SOFT_DIRTY=y | 108 | CONFIG_MEM_SOFT_DIRTY=y |
| 106 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | 109 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 107 | CONFIG_IDLE_PAGE_TRACKING=y | 110 | CONFIG_IDLE_PAGE_TRACKING=y |
| 111 | CONFIG_ZONE_DEVICE=y | ||
| 108 | CONFIG_PERCPU_STATS=y | 112 | CONFIG_PERCPU_STATS=y |
| 109 | CONFIG_GUP_TEST=y | 113 | CONFIG_GUP_TEST=y |
| 110 | CONFIG_ANON_VMA_NAME=y | 114 | CONFIG_ANON_VMA_NAME=y |
| @@ -223,17 +227,19 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m · 112 unmodified lines | |||
| 223 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | 227 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m |
| 224 | CONFIG_NETFILTER_XT_TARGET_CT=m | 228 | CONFIG_NETFILTER_XT_TARGET_CT=m |
| 225 | CONFIG_NETFILTER_XT_TARGET_DSCP=m | 229 | CONFIG_NETFILTER_XT_TARGET_DSCP=m |
| 230 | CONFIG_NETFILTER_XT_TARGET_HL=m | ||
| 226 | CONFIG_NETFILTER_XT_TARGET_HMARK=m | 231 | CONFIG_NETFILTER_XT_TARGET_HMARK=m |
| 227 | CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m | 232 | CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m |
| 228 | CONFIG_NETFILTER_XT_TARGET_LOG=m | 233 | CONFIG_NETFILTER_XT_TARGET_LOG=m |
| 229 | CONFIG_NETFILTER_XT_TARGET_MARK=m | 234 | CONFIG_NETFILTER_XT_TARGET_MARK=m |
| 235 | CONFIG_NETFILTER_XT_NAT=m | ||
| 230 | CONFIG_NETFILTER_XT_TARGET_NETMAP=m | 236 | CONFIG_NETFILTER_XT_TARGET_NETMAP=m |
| 231 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m | 237 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m |
| 232 | CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m | 238 | CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m |
| 233 | CONFIG_NETFILTER_XT_TARGET_REDIRECT=m | 239 | CONFIG_NETFILTER_XT_TARGET_REDIRECT=m |
| 240 | CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m | ||
| 234 | CONFIG_NETFILTER_XT_TARGET_TEE=m | 241 | CONFIG_NETFILTER_XT_TARGET_TEE=m |
| 235 | CONFIG_NETFILTER_XT_TARGET_TPROXY=m | 242 | CONFIG_NETFILTER_XT_TARGET_TPROXY=m |
| 236 | CONFIG_NETFILTER_XT_TARGET_TRACE=m | ||
| 237 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m | 243 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m |
| 238 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | 244 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m |
| 239 | CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m | 245 | CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m |
| @@ -248,6 +254,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m · 8 unmodified lines | |||
| 248 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m | 254 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m |
| 249 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | 255 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m |
| 250 | CONFIG_NETFILTER_XT_MATCH_CPU=m | 256 | CONFIG_NETFILTER_XT_MATCH_CPU=m |
| 257 | CONFIG_NETFILTER_XT_MATCH_DCCP=m | ||
| 251 | CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m | 258 | CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m |
| 252 | CONFIG_NETFILTER_XT_MATCH_DSCP=m | 259 | CONFIG_NETFILTER_XT_MATCH_DSCP=m |
| 253 | CONFIG_NETFILTER_XT_MATCH_ESP=m | 260 | CONFIG_NETFILTER_XT_MATCH_ESP=m |
| @@ -318,16 +325,8 @@ CONFIG_IP_NF_MATCH_AH=m · 64 unmodified lines | |||
| 318 | CONFIG_IP_NF_MATCH_ECN=m | 325 | CONFIG_IP_NF_MATCH_ECN=m |
| 319 | CONFIG_IP_NF_MATCH_RPFILTER=m | 326 | CONFIG_IP_NF_MATCH_RPFILTER=m |
| 320 | CONFIG_IP_NF_MATCH_TTL=m | 327 | CONFIG_IP_NF_MATCH_TTL=m |
| 321 | CONFIG_IP_NF_FILTER=m | ||
| 322 | CONFIG_IP_NF_TARGET_REJECT=m | 328 | CONFIG_IP_NF_TARGET_REJECT=m |
| 323 | CONFIG_IP_NF_NAT=m | ||
| 324 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
| 325 | CONFIG_IP_NF_MANGLE=m | ||
| 326 | CONFIG_IP_NF_TARGET_ECN=m | 329 | CONFIG_IP_NF_TARGET_ECN=m |
| 327 | CONFIG_IP_NF_TARGET_TTL=m | ||
| 328 | CONFIG_IP_NF_RAW=m | ||
| 329 | CONFIG_IP_NF_SECURITY=m | ||
| 330 | CONFIG_IP_NF_ARPFILTER=m | ||
| 331 | CONFIG_IP_NF_ARP_MANGLE=m | 330 | CONFIG_IP_NF_ARP_MANGLE=m |
| 332 | CONFIG_NFT_FIB_IPV6=m | 331 | CONFIG_NFT_FIB_IPV6=m |
| 333 | CONFIG_IP6_NF_IPTABLES=m | 332 | CONFIG_IP6_NF_IPTABLES=m |
| @@ -340,15 +339,9 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m · 6 unmodified lines | |||
| 340 | CONFIG_IP6_NF_MATCH_MH=m | 339 | CONFIG_IP6_NF_MATCH_MH=m |
| 341 | CONFIG_IP6_NF_MATCH_RPFILTER=m | 340 | CONFIG_IP6_NF_MATCH_RPFILTER=m |
| 342 | CONFIG_IP6_NF_MATCH_RT=m | 341 | CONFIG_IP6_NF_MATCH_RT=m |
| 343 | CONFIG_IP6_NF_TARGET_HL=m | ||
| 344 | CONFIG_IP6_NF_FILTER=m | ||
| 345 | CONFIG_IP6_NF_TARGET_REJECT=m | 342 | CONFIG_IP6_NF_TARGET_REJECT=m |
| 346 | CONFIG_IP6_NF_MANGLE=m | ||
| 347 | CONFIG_IP6_NF_RAW=m | ||
| 348 | CONFIG_IP6_NF_SECURITY=m | ||
| 349 | CONFIG_IP6_NF_NAT=m | ||
| 350 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | ||
| 351 | CONFIG_NF_TABLES_BRIDGE=m | 343 | CONFIG_NF_TABLES_BRIDGE=m |
| 344 | CONFIG_IP_SCTP=m | ||
| 352 | CONFIG_RDS=m | 345 | CONFIG_RDS=m |
| 353 | CONFIG_RDS_RDMA=m | 346 | CONFIG_RDS_RDMA=m |
| 354 | CONFIG_RDS_TCP=m | 347 | CONFIG_RDS_TCP=m |
| @@ -383,6 +376,7 @@ CONFIG_NET_SCH_FQ_CODEL=m · 28 unmodified lines | |||
| 383 | CONFIG_NET_SCH_INGRESS=m | 376 | CONFIG_NET_SCH_INGRESS=m |
| 384 | CONFIG_NET_SCH_PLUG=m | 377 | CONFIG_NET_SCH_PLUG=m |
| 385 | CONFIG_NET_SCH_ETS=m | 378 | CONFIG_NET_SCH_ETS=m |
| 379 | CONFIG_NET_SCH_DUALPI2=m | ||
| 386 | CONFIG_NET_CLS_BASIC=m | 380 | CONFIG_NET_CLS_BASIC=m |
| 387 | CONFIG_NET_CLS_ROUTE4=m | 381 | CONFIG_NET_CLS_ROUTE4=m |
| 388 | CONFIG_NET_CLS_FW=m | 382 | CONFIG_NET_CLS_FW=m |
| @@ -504,6 +498,7 @@ CONFIG_DM_VDO=m · 115 unmodified lines | |||
| 504 | CONFIG_NETDEVICES=y | 498 | CONFIG_NETDEVICES=y |
| 505 | CONFIG_BONDING=m | 499 | CONFIG_BONDING=m |
| 506 | CONFIG_DUMMY=m | 500 | CONFIG_DUMMY=m |
| 501 | CONFIG_OVPN=m | ||
| 507 | CONFIG_EQUALIZER=m | 502 | CONFIG_EQUALIZER=m |
| 508 | CONFIG_IFB=m | 503 | CONFIG_IFB=m |
| 509 | CONFIG_MACVLAN=m | 504 | CONFIG_MACVLAN=m |
| @@ -641,6 +636,7 @@ CONFIG_VP_VDPA=m · 131 unmodified lines | |||
| 641 | CONFIG_VHOST_NET=m | 636 | CONFIG_VHOST_NET=m |
| 642 | CONFIG_VHOST_VSOCK=m | 637 | CONFIG_VHOST_VSOCK=m |
| 643 | CONFIG_VHOST_VDPA=m | 638 | CONFIG_VHOST_VDPA=m |
| 639 | CONFIG_DEV_DAX=m | ||
| 644 | CONFIG_EXT4_FS=y | 640 | CONFIG_EXT4_FS=y |
| 645 | CONFIG_EXT4_FS_POSIX_ACL=y | 641 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 646 | CONFIG_EXT4_FS_SECURITY=y | 642 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -665,6 +661,7 @@ CONFIG_NILFS2_FS=m · 18 unmodified lines | |||
| 665 | CONFIG_BCACHEFS_FS=y | 661 | CONFIG_BCACHEFS_FS=y |
| 666 | CONFIG_BCACHEFS_QUOTA=y | 662 | CONFIG_BCACHEFS_QUOTA=y |
| 667 | CONFIG_BCACHEFS_POSIX_ACL=y | 663 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 664 | CONFIG_FS_DAX=y | ||
| 668 | CONFIG_EXPORTFS_BLOCK_OPS=y | 665 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 669 | CONFIG_FS_ENCRYPTION=y | 666 | CONFIG_FS_ENCRYPTION=y |
| 670 | CONFIG_FS_VERITY=y | 667 | CONFIG_FS_VERITY=y |
| @@ -755,6 +752,8 @@ CONFIG_HARDENED_USERCOPY=y · 84 unmodified lines | |||
| 755 | CONFIG_BUG_ON_DATA_CORRUPTION=y | 752 | CONFIG_BUG_ON_DATA_CORRUPTION=y |
| 756 | CONFIG_CRYPTO_USER=m | 753 | CONFIG_CRYPTO_USER=m |
| 757 | CONFIG_CRYPTO_SELFTESTS=y | 754 | CONFIG_CRYPTO_SELFTESTS=y |
| 755 | CONFIG_CRYPTO_SELFTESTS_FULL=y | ||
| 756 | CONFIG_CRYPTO_NULL=y | ||
| 758 | CONFIG_CRYPTO_PCRYPT=m | 757 | CONFIG_CRYPTO_PCRYPT=m |
| 759 | CONFIG_CRYPTO_CRYPTD=m | 758 | CONFIG_CRYPTO_CRYPTD=m |
| 760 | CONFIG_CRYPTO_BENCHMARK=m | 759 | CONFIG_CRYPTO_BENCHMARK=m |
| @@ -783,7 +782,6 @@ CONFIG_CRYPTO_HCTR2=m · 22 unmodified lines | |||
| 783 | CONFIG_CRYPTO_LRW=m | 782 | CONFIG_CRYPTO_LRW=m |
| 784 | CONFIG_CRYPTO_PCBC=m | 783 | CONFIG_CRYPTO_PCBC=m |
| 785 | CONFIG_CRYPTO_AEGIS128=m | 784 | CONFIG_CRYPTO_AEGIS128=m |
| 786 | CONFIG_CRYPTO_CHACHA20POLY1305=m | ||
| 787 | CONFIG_CRYPTO_GCM=y | 785 | CONFIG_CRYPTO_GCM=y |
| 788 | CONFIG_CRYPTO_SEQIV=y | 786 | CONFIG_CRYPTO_SEQIV=y |
| 789 | CONFIG_CRYPTO_MD4=m | 787 | CONFIG_CRYPTO_MD4=m |
| @@ -822,6 +820,7 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y · 32 unmodified lines | |||
| 822 | CONFIG_CRYPTO_KRB5=m | 820 | CONFIG_CRYPTO_KRB5=m |
| 823 | CONFIG_CRYPTO_KRB5_SELFTESTS=y | 821 | CONFIG_CRYPTO_KRB5_SELFTESTS=y |
| 824 | CONFIG_CORDIC=m | 822 | CONFIG_CORDIC=m |
| 823 | CONFIG_TRACE_MMIO_ACCESS=y | ||
| 825 | CONFIG_RANDOM32_SELFTEST=y | 824 | CONFIG_RANDOM32_SELFTEST=y |
| 826 | CONFIG_XZ_DEC_MICROLZMA=y | 825 | CONFIG_XZ_DEC_MICROLZMA=y |
| 827 | CONFIG_DMA_CMA=y | 826 | CONFIG_DMA_CMA=y |
| @@ -4,6 +4,7 @@ CONFIG_WATCH_QUEUE=y · 3 unmodified lines | |||
| 4 | CONFIG_AUDIT=y | 4 | CONFIG_AUDIT=y |
| 5 | CONFIG_NO_HZ_IDLE=y | 5 | CONFIG_NO_HZ_IDLE=y |
| 6 | CONFIG_HIGH_RES_TIMERS=y | 6 | CONFIG_HIGH_RES_TIMERS=y |
| 7 | CONFIG_POSIX_AUX_CLOCKS=y | ||
| 7 | CONFIG_BPF_SYSCALL=y | 8 | CONFIG_BPF_SYSCALL=y |
| 8 | CONFIG_BPF_JIT=y | 9 | CONFIG_BPF_JIT=y |
| 9 | CONFIG_BPF_JIT_ALWAYS_ON=y | 10 | CONFIG_BPF_JIT_ALWAYS_ON=y |
| @@ -17,6 +18,7 @@ CONFIG_TASK_XACCT=y · 7 unmodified lines | |||
| 17 | CONFIG_TASK_IO_ACCOUNTING=y | 18 | CONFIG_TASK_IO_ACCOUNTING=y |
| 18 | CONFIG_IKCONFIG=y | 19 | CONFIG_IKCONFIG=y |
| 19 | CONFIG_IKCONFIG_PROC=y | 20 | CONFIG_IKCONFIG_PROC=y |
| 21 | CONFIG_SCHED_PROXY_EXEC=y | ||
| 20 | CONFIG_NUMA_BALANCING=y | 22 | CONFIG_NUMA_BALANCING=y |
| 21 | CONFIG_MEMCG=y | 23 | CONFIG_MEMCG=y |
| 22 | CONFIG_BLK_CGROUP=y | 24 | CONFIG_BLK_CGROUP=y |
| @@ -40,11 +42,12 @@ CONFIG_PROFILING=y · 17 unmodified lines | |||
| 40 | CONFIG_KEXEC=y | 42 | CONFIG_KEXEC=y |
| 41 | CONFIG_KEXEC_FILE=y | 43 | CONFIG_KEXEC_FILE=y |
| 42 | CONFIG_KEXEC_SIG=y | 44 | CONFIG_KEXEC_SIG=y |
| 45 | CONFIG_CRASH_DM_CRYPT=y | ||
| 43 | CONFIG_LIVEPATCH=y | 46 | CONFIG_LIVEPATCH=y |
| 44 | CONFIG_MARCH_Z13=y | 47 | CONFIG_MARCH_Z13=y |
| 45 | CONFIG_NR_CPUS=512 | 48 | CONFIG_NR_CPUS=512 |
| 46 | CONFIG_NUMA=y | 49 | CONFIG_NUMA=y |
| 47 | CONFIG_HZ_100=y | 50 | CONFIG_HZ_1000=y |
| 48 | CONFIG_CERT_STORE=y | 51 | CONFIG_CERT_STORE=y |
| 49 | CONFIG_EXPOLINE=y | 52 | CONFIG_EXPOLINE=y |
| 50 | CONFIG_EXPOLINE_AUTO=y | 53 | CONFIG_EXPOLINE_AUTO=y |
| @@ -97,6 +100,7 @@ CONFIG_CMA_AREAS=7 · 46 unmodified lines | |||
| 97 | CONFIG_MEM_SOFT_DIRTY=y | 100 | CONFIG_MEM_SOFT_DIRTY=y |
| 98 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | 101 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 99 | CONFIG_IDLE_PAGE_TRACKING=y | 102 | CONFIG_IDLE_PAGE_TRACKING=y |
| 103 | CONFIG_ZONE_DEVICE=y | ||
| 100 | CONFIG_PERCPU_STATS=y | 104 | CONFIG_PERCPU_STATS=y |
| 101 | CONFIG_ANON_VMA_NAME=y | 105 | CONFIG_ANON_VMA_NAME=y |
| 102 | CONFIG_USERFAULTFD=y | 106 | CONFIG_USERFAULTFD=y |
| @@ -214,17 +218,19 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m · 111 unmodified lines | |||
| 214 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | 218 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m |
| 215 | CONFIG_NETFILTER_XT_TARGET_CT=m | 219 | CONFIG_NETFILTER_XT_TARGET_CT=m |
| 216 | CONFIG_NETFILTER_XT_TARGET_DSCP=m | 220 | CONFIG_NETFILTER_XT_TARGET_DSCP=m |
| 221 | CONFIG_NETFILTER_XT_TARGET_HL=m | ||
| 217 | CONFIG_NETFILTER_XT_TARGET_HMARK=m | 222 | CONFIG_NETFILTER_XT_TARGET_HMARK=m |
| 218 | CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m | 223 | CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m |
| 219 | CONFIG_NETFILTER_XT_TARGET_LOG=m | 224 | CONFIG_NETFILTER_XT_TARGET_LOG=m |
| 220 | CONFIG_NETFILTER_XT_TARGET_MARK=m | 225 | CONFIG_NETFILTER_XT_TARGET_MARK=m |
| 226 | CONFIG_NETFILTER_XT_NAT=m | ||
| 221 | CONFIG_NETFILTER_XT_TARGET_NETMAP=m | 227 | CONFIG_NETFILTER_XT_TARGET_NETMAP=m |
| 222 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m | 228 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m |
| 223 | CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m | 229 | CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m |
| 224 | CONFIG_NETFILTER_XT_TARGET_REDIRECT=m | 230 | CONFIG_NETFILTER_XT_TARGET_REDIRECT=m |
| 231 | CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m | ||
| 225 | CONFIG_NETFILTER_XT_TARGET_TEE=m | 232 | CONFIG_NETFILTER_XT_TARGET_TEE=m |
| 226 | CONFIG_NETFILTER_XT_TARGET_TPROXY=m | 233 | CONFIG_NETFILTER_XT_TARGET_TPROXY=m |
| 227 | CONFIG_NETFILTER_XT_TARGET_TRACE=m | ||
| 228 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m | 234 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m |
| 229 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | 235 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m |
| 230 | CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m | 236 | CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m |
| @@ -239,6 +245,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m · 8 unmodified lines | |||
| 239 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m | 245 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m |
| 240 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | 246 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m |
| 241 | CONFIG_NETFILTER_XT_MATCH_CPU=m | 247 | CONFIG_NETFILTER_XT_MATCH_CPU=m |
| 248 | CONFIG_NETFILTER_XT_MATCH_DCCP=m | ||
| 242 | CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m | 249 | CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m |
| 243 | CONFIG_NETFILTER_XT_MATCH_DSCP=m | 250 | CONFIG_NETFILTER_XT_MATCH_DSCP=m |
| 244 | CONFIG_NETFILTER_XT_MATCH_ESP=m | 251 | CONFIG_NETFILTER_XT_MATCH_ESP=m |
| @@ -309,16 +316,8 @@ CONFIG_IP_NF_MATCH_AH=m · 64 unmodified lines | |||
| 309 | CONFIG_IP_NF_MATCH_ECN=m | 316 | CONFIG_IP_NF_MATCH_ECN=m |
| 310 | CONFIG_IP_NF_MATCH_RPFILTER=m | 317 | CONFIG_IP_NF_MATCH_RPFILTER=m |
| 311 | CONFIG_IP_NF_MATCH_TTL=m | 318 | CONFIG_IP_NF_MATCH_TTL=m |
| 312 | CONFIG_IP_NF_FILTER=m | ||
| 313 | CONFIG_IP_NF_TARGET_REJECT=m | 319 | CONFIG_IP_NF_TARGET_REJECT=m |
| 314 | CONFIG_IP_NF_NAT=m | ||
| 315 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
| 316 | CONFIG_IP_NF_MANGLE=m | ||
| 317 | CONFIG_IP_NF_TARGET_ECN=m | 320 | CONFIG_IP_NF_TARGET_ECN=m |
| 318 | CONFIG_IP_NF_TARGET_TTL=m | ||
| 319 | CONFIG_IP_NF_RAW=m | ||
| 320 | CONFIG_IP_NF_SECURITY=m | ||
| 321 | CONFIG_IP_NF_ARPFILTER=m | ||
| 322 | CONFIG_IP_NF_ARP_MANGLE=m | 321 | CONFIG_IP_NF_ARP_MANGLE=m |
| 323 | CONFIG_NFT_FIB_IPV6=m | 322 | CONFIG_NFT_FIB_IPV6=m |
| 324 | CONFIG_IP6_NF_IPTABLES=m | 323 | CONFIG_IP6_NF_IPTABLES=m |
| @@ -331,15 +330,9 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m · 6 unmodified lines | |||
| 331 | CONFIG_IP6_NF_MATCH_MH=m | 330 | CONFIG_IP6_NF_MATCH_MH=m |
| 332 | CONFIG_IP6_NF_MATCH_RPFILTER=m | 331 | CONFIG_IP6_NF_MATCH_RPFILTER=m |
| 333 | CONFIG_IP6_NF_MATCH_RT=m | 332 | CONFIG_IP6_NF_MATCH_RT=m |
| 334 | CONFIG_IP6_NF_TARGET_HL=m | ||
| 335 | CONFIG_IP6_NF_FILTER=m | ||
| 336 | CONFIG_IP6_NF_TARGET_REJECT=m | 333 | CONFIG_IP6_NF_TARGET_REJECT=m |
| 337 | CONFIG_IP6_NF_MANGLE=m | ||
| 338 | CONFIG_IP6_NF_RAW=m | ||
| 339 | CONFIG_IP6_NF_SECURITY=m | ||
| 340 | CONFIG_IP6_NF_NAT=m | ||
| 341 | CONFIG_IP6_NF_TARGET_MASQUERADE=m | ||
| 342 | CONFIG_NF_TABLES_BRIDGE=m | 334 | CONFIG_NF_TABLES_BRIDGE=m |
| 335 | CONFIG_IP_SCTP=m | ||
| 343 | CONFIG_RDS=m | 336 | CONFIG_RDS=m |
| 344 | CONFIG_RDS_RDMA=m | 337 | CONFIG_RDS_RDMA=m |
| 345 | CONFIG_RDS_TCP=m | 338 | CONFIG_RDS_TCP=m |
| @@ -373,6 +366,7 @@ CONFIG_NET_SCH_FQ_CODEL=m · 27 unmodified lines | |||
| 373 | CONFIG_NET_SCH_INGRESS=m | 366 | CONFIG_NET_SCH_INGRESS=m |
| 374 | CONFIG_NET_SCH_PLUG=m | 367 | CONFIG_NET_SCH_PLUG=m |
| 375 | CONFIG_NET_SCH_ETS=m | 368 | CONFIG_NET_SCH_ETS=m |
| 369 | CONFIG_NET_SCH_DUALPI2=m | ||
| 376 | CONFIG_NET_CLS_BASIC=m | 370 | CONFIG_NET_CLS_BASIC=m |
| 377 | CONFIG_NET_CLS_ROUTE4=m | 371 | CONFIG_NET_CLS_ROUTE4=m |
| 378 | CONFIG_NET_CLS_FW=m | 372 | CONFIG_NET_CLS_FW=m |
| @@ -494,6 +488,7 @@ CONFIG_DM_VDO=m · 115 unmodified lines | |||
| 494 | CONFIG_NETDEVICES=y | 488 | CONFIG_NETDEVICES=y |
| 495 | CONFIG_BONDING=m | 489 | CONFIG_BONDING=m |
| 496 | CONFIG_DUMMY=m | 490 | CONFIG_DUMMY=m |
| 491 | CONFIG_OVPN=m | ||
| 497 | CONFIG_EQUALIZER=m | 492 | CONFIG_EQUALIZER=m |
| 498 | CONFIG_IFB=m | 493 | CONFIG_IFB=m |
| 499 | CONFIG_MACVLAN=m | 494 | CONFIG_MACVLAN=m |
| @@ -631,6 +626,7 @@ CONFIG_VP_VDPA=m · 131 unmodified lines | |||
| 631 | CONFIG_VHOST_NET=m | 626 | CONFIG_VHOST_NET=m |
| 632 | CONFIG_VHOST_VSOCK=m | 627 | CONFIG_VHOST_VSOCK=m |
| 633 | CONFIG_VHOST_VDPA=m | 628 | CONFIG_VHOST_VDPA=m |
| 629 | CONFIG_DEV_DAX=m | ||
| 634 | CONFIG_EXT4_FS=y | 630 | CONFIG_EXT4_FS=y |
| 635 | CONFIG_EXT4_FS_POSIX_ACL=y | 631 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 636 | CONFIG_EXT4_FS_SECURITY=y | 632 | CONFIG_EXT4_FS_SECURITY=y |
| @@ -652,6 +648,7 @@ CONFIG_NILFS2_FS=m · 15 unmodified lines | |||
| 652 | CONFIG_BCACHEFS_FS=m | 648 | CONFIG_BCACHEFS_FS=m |
| 653 | CONFIG_BCACHEFS_QUOTA=y | 649 | CONFIG_BCACHEFS_QUOTA=y |
| 654 | CONFIG_BCACHEFS_POSIX_ACL=y | 650 | CONFIG_BCACHEFS_POSIX_ACL=y |
| 651 | CONFIG_FS_DAX=y | ||
| 655 | CONFIG_EXPORTFS_BLOCK_OPS=y | 652 | CONFIG_EXPORTFS_BLOCK_OPS=y |
| 656 | CONFIG_FS_ENCRYPTION=y | 653 | CONFIG_FS_ENCRYPTION=y |
| 657 | CONFIG_FS_VERITY=y | 654 | CONFIG_FS_VERITY=y |
| @@ -683,7 +680,6 @@ CONFIG_TMPFS_POSIX_ACL=y · 25 unmodified lines | |||
| 683 | CONFIG_TMPFS_INODE64=y | 680 | CONFIG_TMPFS_INODE64=y |
| 684 | CONFIG_TMPFS_QUOTA=y | 681 | CONFIG_TMPFS_QUOTA=y |
| 685 | CONFIG_HUGETLBFS=y | 682 | CONFIG_HUGETLBFS=y |
| 686 | CONFIG_CONFIGFS_FS=m | ||
| 687 | CONFIG_ECRYPT_FS=m | 683 | CONFIG_ECRYPT_FS=m |
| 688 | CONFIG_CRAMFS=m | 684 | CONFIG_CRAMFS=m |
| 689 | CONFIG_SQUASHFS=m | 685 | CONFIG_SQUASHFS=m |
| @@ -741,6 +737,7 @@ CONFIG_BUG_ON_DATA_CORRUPTION=y · 51 unmodified lines | |||
| 741 | CONFIG_CRYPTO_FIPS=y | 737 | CONFIG_CRYPTO_FIPS=y |
| 742 | CONFIG_CRYPTO_USER=m | 738 | CONFIG_CRYPTO_USER=m |
| 743 | CONFIG_CRYPTO_SELFTESTS=y | 739 | CONFIG_CRYPTO_SELFTESTS=y |
| 740 | CONFIG_CRYPTO_NULL=y | ||
| 744 | CONFIG_CRYPTO_PCRYPT=m | 741 | CONFIG_CRYPTO_PCRYPT=m |
| 745 | CONFIG_CRYPTO_CRYPTD=m | 742 | CONFIG_CRYPTO_CRYPTD=m |
| 746 | CONFIG_CRYPTO_BENCHMARK=m | 743 | CONFIG_CRYPTO_BENCHMARK=m |
| @@ -769,7 +766,6 @@ CONFIG_CRYPTO_HCTR2=m · 22 unmodified lines | |||
| 769 | CONFIG_CRYPTO_LRW=m | 766 | CONFIG_CRYPTO_LRW=m |
| 770 | CONFIG_CRYPTO_PCBC=m | 767 | CONFIG_CRYPTO_PCBC=m |
| 771 | CONFIG_CRYPTO_AEGIS128=m | 768 | CONFIG_CRYPTO_AEGIS128=m |
| 772 | CONFIG_CRYPTO_CHACHA20POLY1305=m | ||
| 773 | CONFIG_CRYPTO_GCM=y | 769 | CONFIG_CRYPTO_GCM=y |
| 774 | CONFIG_CRYPTO_SEQIV=y | 770 | CONFIG_CRYPTO_SEQIV=y |
| 775 | CONFIG_CRYPTO_MD4=m | 771 | CONFIG_CRYPTO_MD4=m |
| @@ -1,5 +1,6 @@ | |||
| 1 | CONFIG_NO_HZ_IDLE=y | 1 | CONFIG_NO_HZ_IDLE=y |
| 2 | CONFIG_HIGH_RES_TIMERS=y | 2 | CONFIG_HIGH_RES_TIMERS=y |
| 3 | CONFIG_POSIX_AUX_CLOCKS=y | ||
| 3 | CONFIG_BPF_SYSCALL=y | 4 | CONFIG_BPF_SYSCALL=y |
| 4 | # CONFIG_CPU_ISOLATION is not set | 5 | # CONFIG_CPU_ISOLATION is not set |
| 5 | # CONFIG_UTS_NS is not set | 6 | # CONFIG_UTS_NS is not set |
| @@ -11,7 +12,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y · 5 unmodified lines | |||
| 11 | CONFIG_KEXEC=y | 12 | CONFIG_KEXEC=y |
| 12 | CONFIG_MARCH_Z13=y | 13 | CONFIG_MARCH_Z13=y |
| 13 | CONFIG_NR_CPUS=2 | 14 | CONFIG_NR_CPUS=2 |
| 14 | CONFIG_HZ_100=y | 15 | CONFIG_HZ_1000=y |
| 15 | # CONFIG_CHSC_SCH is not set | 16 | # CONFIG_CHSC_SCH is not set |
| 16 | # CONFIG_SCM_BUS is not set | 17 | # CONFIG_SCM_BUS is not set |
| 17 | # CONFIG_AP is not set | 18 | # CONFIG_AP is not set |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com> | 6 | * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/security.h> | ||
| 9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 10 | #include "hypfs.h" | 11 | #include "hypfs.h" |
| 11 | 12 | ||
| @@ -66,23 +67,27 @@ static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 54 unmodified lines | |||
| 66 | long rc; | 67 | long rc; |
| 67 | 68 | ||
| 68 | mutex_lock(&df->lock); | 69 | mutex_lock(&df->lock); |
| 69 | if (df->unlocked_ioctl) | 70 | rc = df->unlocked_ioctl(file, cmd, arg); |
| 70 | rc = df->unlocked_ioctl(file, cmd, arg); | ||
| 71 | else | ||
| 72 | rc = -ENOTTY; | ||
| 73 | mutex_unlock(&df->lock); | 71 | mutex_unlock(&df->lock); |
| 74 | return rc; | 72 | return rc; |
| 75 | } | 73 | } |
| 76 | 74 | ||
| 77 | static const struct file_operations dbfs_ops = { | 75 | static const struct file_operations dbfs_ops_ioctl = { |
| 78 | .read = dbfs_read, | 76 | .read = dbfs_read, |
| 79 | .unlocked_ioctl = dbfs_ioctl, | 77 | .unlocked_ioctl = dbfs_ioctl, |
| 80 | }; | 78 | }; |
| 81 | 79 | ||
| 80 | static const struct file_operations dbfs_ops = { | ||
| 81 | .read = dbfs_read, | ||
| 82 | }; | ||
| 83 | |||
| 82 | void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) | 84 | void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) |
| 83 | { | 85 | { |
| 84 | df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, | 86 | const struct file_operations *fops = &dbfs_ops; |
| 85 | &dbfs_ops); | 87 | |
| 88 | if (df->unlocked_ioctl && !security_locked_down(LOCKDOWN_DEBUGFS)) | ||
| 89 | fops = &dbfs_ops_ioctl; | ||
| 90 | df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, fops); | ||
| 86 | mutex_init(&df->lock); | 91 | mutex_init(&df->lock); |
| 87 | } | 92 | } |
| 88 | 93 | ||
| @@ -94,12 +94,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func); · 93 unmodified lines | |||
| 94 | #ifdef MODULE | 94 | #ifdef MODULE |
| 95 | #define __ADDRESSABLE_xen_hypercall | 95 | #define __ADDRESSABLE_xen_hypercall |
| 96 | #else | 96 | #else |
| 97 | #define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall) | 97 | #define __ADDRESSABLE_xen_hypercall \ |
| 98 | __stringify(.global STATIC_CALL_KEY(xen_hypercall);) | ||
| 98 | #endif | 99 | #endif |
| 99 | 100 | ||
| 100 | #define __HYPERCALL \ | 101 | #define __HYPERCALL \ |
| 101 | __ADDRESSABLE_xen_hypercall \ | 102 | __ADDRESSABLE_xen_hypercall \ |
| 102 | "call __SCT__xen_hypercall" | 103 | __stringify(call STATIC_CALL_TRAMP(xen_hypercall)) |
| 103 | 104 | ||
| 104 | #define __HYPERCALL_ENTRY(x) "a" (x) | 105 | #define __HYPERCALL_ENTRY(x) "a" (x) |
| 105 | 106 | ||
| @@ -1326,8 +1326,8 @@ static const char * const s5_reset_reason_txt[] = { · 1325 unmodified lines | |||
| 1326 | 1326 | ||
| 1327 | static __init int print_s5_reset_status_mmio(void) | 1327 | static __init int print_s5_reset_status_mmio(void) |
| 1328 | { | 1328 | { |
| 1329 | unsigned long value; | ||
| 1330 | void __iomem *addr; | 1329 | void __iomem *addr; |
| 1330 | u32 value; | ||
| 1331 | int i; | 1331 | int i; |
| 1332 | 1332 | ||
| 1333 | if (!cpu_feature_enabled(X86_FEATURE_ZEN)) | 1333 | if (!cpu_feature_enabled(X86_FEATURE_ZEN)) |
| @@ -1340,12 +1340,16 @@ static __init int print_s5_reset_status_mmio(void) · 6 unmodified lines | |||
| 1340 | value = ioread32(addr); | 1340 | value = ioread32(addr); |
| 1341 | iounmap(addr); | 1341 | iounmap(addr); |
| 1342 | 1342 | ||
| 1343 | /* Value with "all bits set" is an error response and should be ignored. */ | ||
| 1344 | if (value == U32_MAX) | ||
| 1345 | return 0; | ||
| 1346 | |||
| 1343 | for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) { | 1347 | for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) { |
| 1344 | if (!(value & BIT(i))) | 1348 | if (!(value & BIT(i))) |
| 1345 | continue; | 1349 | continue; |
| 1346 | 1350 | ||
| 1347 | if (s5_reset_reason_txt[i]) { | 1351 | if (s5_reset_reason_txt[i]) { |
| 1348 | pr_info("x86/amd: Previous system reset reason [0x%08lx]: %s\n", | 1352 | pr_info("x86/amd: Previous system reset reason [0x%08x]: %s\n", |
| 1349 | value, s5_reset_reason_txt[i]); | 1353 | value, s5_reset_reason_txt[i]); |
| 1350 | } | 1354 | } |
| 1351 | } | 1355 | } |
| @@ -1068,10 +1068,8 @@ static void __init gds_select_mitigation(void) · 1067 unmodified lines | |||
| 1068 | if (gds_mitigation == GDS_MITIGATION_AUTO) { | 1068 | if (gds_mitigation == GDS_MITIGATION_AUTO) { |
| 1069 | if (should_mitigate_vuln(X86_BUG_GDS)) | 1069 | if (should_mitigate_vuln(X86_BUG_GDS)) |
| 1070 | gds_mitigation = GDS_MITIGATION_FULL; | 1070 | gds_mitigation = GDS_MITIGATION_FULL; |
| 1071 | else { | 1071 | else |
| 1072 | gds_mitigation = GDS_MITIGATION_OFF; | 1072 | gds_mitigation = GDS_MITIGATION_OFF; |
| 1073 | return; | ||
| 1074 | } | ||
| 1075 | } | 1073 | } |
| 1076 | 1074 | ||
| 1077 | /* No microcode */ | 1075 | /* No microcode */ |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <asm/spec-ctrl.h> | 16 | #include <asm/spec-ctrl.h> |
| 17 | #include <asm/delay.h> | 17 | #include <asm/delay.h> |
| 18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
| 19 | #include <asm/resctrl.h> | ||
| 19 | 20 | ||
| 20 | #include "cpu.h" | 21 | #include "cpu.h" |
| 21 | 22 | ||
| @@ -117,6 +118,8 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c) · 95 unmodified lines | |||
| 117 | x86_amd_ls_cfg_ssbd_mask = 1ULL << 10; | 118 | x86_amd_ls_cfg_ssbd_mask = 1ULL << 10; |
| 118 | } | 119 | } |
| 119 | } | 120 | } |
| 121 | |||
| 122 | resctrl_cpu_detect(c); | ||
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | static void early_init_hygon(struct cpuinfo_x86 *c) | 125 | static void early_init_hygon(struct cpuinfo_x86 *c) |
| @@ -557,7 +557,7 @@ static inline int bio_check_eod(struct bio *bio) · 556 unmodified lines | |||
| 557 | sector_t maxsector = bdev_nr_sectors(bio->bi_bdev); | 557 | sector_t maxsector = bdev_nr_sectors(bio->bi_bdev); |
| 558 | unsigned int nr_sectors = bio_sectors(bio); | 558 | unsigned int nr_sectors = bio_sectors(bio); |
| 559 | 559 | ||
| 560 | if (nr_sectors && | 560 | if (nr_sectors && maxsector && |
| 561 | (nr_sectors > maxsector || | 561 | (nr_sectors > maxsector || |
| 562 | bio->bi_iter.bi_sector > maxsector - nr_sectors)) { | 562 | bio->bi_iter.bi_sector > maxsector - nr_sectors)) { |
| 563 | pr_info_ratelimited("%s: attempt to access beyond end of device\n" | 563 | pr_info_ratelimited("%s: attempt to access beyond end of device\n" |
| @@ -95,6 +95,7 @@ static const char *const blk_queue_flag_name[] = { · 94 unmodified lines | |||
| 95 | QUEUE_FLAG_NAME(SQ_SCHED), | 95 | QUEUE_FLAG_NAME(SQ_SCHED), |
| 96 | QUEUE_FLAG_NAME(DISABLE_WBT_DEF), | 96 | QUEUE_FLAG_NAME(DISABLE_WBT_DEF), |
| 97 | QUEUE_FLAG_NAME(NO_ELV_SWITCH), | 97 | QUEUE_FLAG_NAME(NO_ELV_SWITCH), |
| 98 | QUEUE_FLAG_NAME(QOS_ENABLED), | ||
| 98 | }; | 99 | }; |
| 99 | #undef QUEUE_FLAG_NAME | 100 | #undef QUEUE_FLAG_NAME |
| 100 | 101 | ||
| @@ -5033,6 +5033,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 5032 unmodified lines | |||
| 5033 | unsigned int memflags; | 5033 | unsigned int memflags; |
| 5034 | int i; | 5034 | int i; |
| 5035 | struct xarray elv_tbl, et_tbl; | 5035 | struct xarray elv_tbl, et_tbl; |
| 5036 | bool queues_frozen = false; | ||
| 5036 | 5037 | ||
| 5037 | lockdep_assert_held(&set->tag_list_lock); | 5038 | lockdep_assert_held(&set->tag_list_lock); |
| 5038 | 5039 | ||
| @@ -5056,9 +5057,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 17 unmodified lines | |||
| 5056 | blk_mq_sysfs_unregister_hctxs(q); | 5057 | blk_mq_sysfs_unregister_hctxs(q); |
| 5057 | } | 5058 | } |
| 5058 | 5059 | ||
| 5059 | list_for_each_entry(q, &set->tag_list, tag_set_list) | ||
| 5060 | blk_mq_freeze_queue_nomemsave(q); | ||
| 5061 | |||
| 5062 | /* | 5060 | /* |
| 5063 | * Switch IO scheduler to 'none', cleaning up the data associated | 5061 | * Switch IO scheduler to 'none', cleaning up the data associated |
| 5064 | * with the previous scheduler. We will switch back once we are done | 5062 | * with the previous scheduler. We will switch back once we are done |
| @@ -5068,6 +5066,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, · 3 unmodified lines | |||
| 5068 | if (blk_mq_elv_switch_none(q, &elv_tbl)) | 5066 | if (blk_mq_elv_switch_none(q, &elv_tbl)) |
| 5069 | goto switch_back; | 5067 | goto switch_back; |
| 5070 | 5068 | ||
| 5069 | list_for_each_entry(q, &set->tag_list, tag_set_list) | ||
| 5070 | blk_mq_freeze_queue_nomemsave(q); | ||
| 5071 | queues_frozen = true; | ||
| 5071 | if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) | 5072 | if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) |
| 5072 | goto switch_back; | 5073 | goto switch_back; |
| 5073 | 5074 | ||
| @@ -5091,8 +5092,12 @@ fallback: · 17 unmodified lines | |||
| 5091 | } | 5092 | } |
| 5092 | switch_back: | 5093 | switch_back: |
| 5093 | /* The blk_mq_elv_switch_back unfreezes queue for us. */ | 5094 | /* The blk_mq_elv_switch_back unfreezes queue for us. */ |
| 5094 | list_for_each_entry(q, &set->tag_list, tag_set_list) | 5095 | list_for_each_entry(q, &set->tag_list, tag_set_list) { |
| 5096 | /* switch_back expects queue to be frozen */ | ||
| 5097 | if (!queues_frozen) | ||
| 5098 | blk_mq_freeze_queue_nomemsave(q); | ||
| 5095 | blk_mq_elv_switch_back(q, &elv_tbl, &et_tbl); | 5099 | blk_mq_elv_switch_back(q, &elv_tbl, &et_tbl); |
| 5100 | } | ||
| 5096 | 5101 | ||
| 5097 | list_for_each_entry(q, &set->tag_list, tag_set_list) { | 5102 | list_for_each_entry(q, &set->tag_list, tag_set_list) { |
| 5098 | blk_mq_sysfs_register_hctxs(q); | 5103 | blk_mq_sysfs_register_hctxs(q); |
| @@ -2,8 +2,6 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | #include "blk-rq-qos.h" | 3 | #include "blk-rq-qos.h" |
| 4 | 4 | ||
| 5 | __read_mostly DEFINE_STATIC_KEY_FALSE(block_rq_qos); | ||
| 6 | |||
| 7 | /* | 5 | /* |
| 8 | * Increment 'v', if 'v' is below 'below'. Returns true if we succeeded, | 6 | * Increment 'v', if 'v' is below 'below'. Returns true if we succeeded, |
| 9 | * false if 'v' + 1 would be bigger than 'below'. | 7 | * false if 'v' + 1 would be bigger than 'below'. |
| @@ -319,8 +317,8 @@ void rq_qos_exit(struct request_queue *q) · 309 unmodified lines | |||
| 319 | struct rq_qos *rqos = q->rq_qos; | 317 | struct rq_qos *rqos = q->rq_qos; |
| 320 | q->rq_qos = rqos->next; | 318 | q->rq_qos = rqos->next; |
| 321 | rqos->ops->exit(rqos); | 319 | rqos->ops->exit(rqos); |
| 322 | static_branch_dec(&block_rq_qos); | ||
| 323 | } | 320 | } |
| 321 | blk_queue_flag_clear(QUEUE_FLAG_QOS_ENABLED, q); | ||
| 324 | mutex_unlock(&q->rq_qos_mutex); | 322 | mutex_unlock(&q->rq_qos_mutex); |
| 325 | } | 323 | } |
| 326 | 324 | ||
| @@ -346,7 +344,7 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id, · 19 unmodified lines | |||
| 346 | goto ebusy; | 344 | goto ebusy; |
| 347 | rqos->next = q->rq_qos; | 345 | rqos->next = q->rq_qos; |
| 348 | q->rq_qos = rqos; | 346 | q->rq_qos = rqos; |
| 349 | static_branch_inc(&block_rq_qos); | 347 | blk_queue_flag_set(QUEUE_FLAG_QOS_ENABLED, q); |
| 350 | 348 | ||
| 351 | blk_mq_unfreeze_queue(q, memflags); | 349 | blk_mq_unfreeze_queue(q, memflags); |
| 352 | 350 | ||
| @@ -377,6 +375,8 @@ void rq_qos_del(struct rq_qos *rqos) · 24 unmodified lines | |||
| 377 | break; | 375 | break; |
| 378 | } | 376 | } |
| 379 | } | 377 | } |
| 378 | if (!q->rq_qos) | ||
| 379 | blk_queue_flag_clear(QUEUE_FLAG_QOS_ENABLED, q); | ||
| 380 | blk_mq_unfreeze_queue(q, memflags); | 380 | blk_mq_unfreeze_queue(q, memflags); |
| 381 | 381 | ||
| 382 | mutex_lock(&q->debugfs_mutex); | 382 | mutex_lock(&q->debugfs_mutex); |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | #include "blk-mq-debugfs.h" | 12 | #include "blk-mq-debugfs.h" |
| 13 | 13 | ||
| 14 | struct blk_mq_debugfs_attr; | 14 | struct blk_mq_debugfs_attr; |
| 15 | extern struct static_key_false block_rq_qos; | ||
| 16 | 15 | ||
| 17 | enum rq_qos_id { | 16 | enum rq_qos_id { |
| 18 | RQ_QOS_WBT, | 17 | RQ_QOS_WBT, |
| @@ -113,43 +112,55 @@ void __rq_qos_queue_depth_changed(struct rq_qos *rqos); · 94 unmodified lines | |||
| 113 | 112 | ||
| 114 | static inline void rq_qos_cleanup(struct request_queue *q, struct bio *bio) | 113 | static inline void rq_qos_cleanup(struct request_queue *q, struct bio *bio) |
| 115 | { | 114 | { |
| 116 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) | 115 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 116 | q->rq_qos) | ||
| 117 | __rq_qos_cleanup(q->rq_qos, bio); | 117 | __rq_qos_cleanup(q->rq_qos, bio); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static inline void rq_qos_done(struct request_queue *q, struct request *rq) | 120 | static inline void rq_qos_done(struct request_queue *q, struct request *rq) |
| 121 | { | 121 | { |
| 122 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos && | 122 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 123 | !blk_rq_is_passthrough(rq)) | 123 | q->rq_qos && !blk_rq_is_passthrough(rq)) |
| 124 | __rq_qos_done(q->rq_qos, rq); | 124 | __rq_qos_done(q->rq_qos, rq); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static inline void rq_qos_issue(struct request_queue *q, struct request *rq) | 127 | static inline void rq_qos_issue(struct request_queue *q, struct request *rq) |
| 128 | { | 128 | { |
| 129 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) | 129 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 130 | q->rq_qos) | ||
| 130 | __rq_qos_issue(q->rq_qos, rq); | 131 | __rq_qos_issue(q->rq_qos, rq); |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | static inline void rq_qos_requeue(struct request_queue *q, struct request *rq) | 134 | static inline void rq_qos_requeue(struct request_queue *q, struct request *rq) |
| 134 | { | 135 | { |
| 135 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) | 136 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 137 | q->rq_qos) | ||
| 136 | __rq_qos_requeue(q->rq_qos, rq); | 138 | __rq_qos_requeue(q->rq_qos, rq); |
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | static inline void rq_qos_done_bio(struct bio *bio) | 141 | static inline void rq_qos_done_bio(struct bio *bio) |
| 140 | { | 142 | { |
| 141 | if (static_branch_unlikely(&block_rq_qos) && | 143 | struct request_queue *q; |
| 142 | bio->bi_bdev && (bio_flagged(bio, BIO_QOS_THROTTLED) || | 144 | |
| 143 | bio_flagged(bio, BIO_QOS_MERGED))) { | 145 | if (!bio->bi_bdev || (!bio_flagged(bio, BIO_QOS_THROTTLED) && |
| 144 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); | 146 | !bio_flagged(bio, BIO_QOS_MERGED))) |
| 145 | if (q->rq_qos) | 147 | return; |
| 146 | __rq_qos_done_bio(q->rq_qos, bio); | 148 | |
| 147 | } | 149 | q = bdev_get_queue(bio->bi_bdev); |
| 150 | |||
| 151 | /* | ||
| 152 | * If a bio has BIO_QOS_xxx set, it implicitly implies that | ||
| 153 | * q->rq_qos is present. So, we skip re-checking q->rq_qos | ||
| 154 | * here as an extra optimization and directly call | ||
| 155 | * __rq_qos_done_bio(). | ||
| 156 | */ | ||
| 157 | __rq_qos_done_bio(q->rq_qos, bio); | ||
| 148 | } | 158 | } |
| 149 | 159 | ||
| 150 | static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio) | 160 | static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio) |
| 151 | { | 161 | { |
| 152 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) { | 162 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 163 | q->rq_qos) { | ||
| 153 | bio_set_flag(bio, BIO_QOS_THROTTLED); | 164 | bio_set_flag(bio, BIO_QOS_THROTTLED); |
| 154 | __rq_qos_throttle(q->rq_qos, bio); | 165 | __rq_qos_throttle(q->rq_qos, bio); |
| 155 | } | 166 | } |
| @@ -158,14 +169,16 @@ static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio) · 2 unmodified lines | |||
| 158 | static inline void rq_qos_track(struct request_queue *q, struct request *rq, | 169 | static inline void rq_qos_track(struct request_queue *q, struct request *rq, |
| 159 | struct bio *bio) | 170 | struct bio *bio) |
| 160 | { | 171 | { |
| 161 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) | 172 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 173 | q->rq_qos) | ||
| 162 | __rq_qos_track(q->rq_qos, rq, bio); | 174 | __rq_qos_track(q->rq_qos, rq, bio); |
| 163 | } | 175 | } |
| 164 | 176 | ||
| 165 | static inline void rq_qos_merge(struct request_queue *q, struct request *rq, | 177 | static inline void rq_qos_merge(struct request_queue *q, struct request *rq, |
| 166 | struct bio *bio) | 178 | struct bio *bio) |
| 167 | { | 179 | { |
| 168 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) { | 180 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 181 | q->rq_qos) { | ||
| 169 | bio_set_flag(bio, BIO_QOS_MERGED); | 182 | bio_set_flag(bio, BIO_QOS_MERGED); |
| 170 | __rq_qos_merge(q->rq_qos, rq, bio); | 183 | __rq_qos_merge(q->rq_qos, rq, bio); |
| 171 | } | 184 | } |
| @@ -173,7 +186,8 @@ static inline void rq_qos_merge(struct request_queue *q, struct request *rq, · 1 unmodified line | |||
| 173 | 186 | ||
| 174 | static inline void rq_qos_queue_depth_changed(struct request_queue *q) | 187 | static inline void rq_qos_queue_depth_changed(struct request_queue *q) |
| 175 | { | 188 | { |
| 176 | if (static_branch_unlikely(&block_rq_qos) && q->rq_qos) | 189 | if (unlikely(test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags)) && |
| 190 | q->rq_qos) | ||
| 177 | __rq_qos_queue_depth_changed(q->rq_qos); | 191 | __rq_qos_queue_depth_changed(q->rq_qos); |
| 178 | } | 192 | } |
| 179 | 193 | ||
| @@ -157,16 +157,14 @@ static int blk_validate_integrity_limits(struct queue_limits *lim) · 156 unmodified lines | |||
| 157 | switch (bi->csum_type) { | 157 | switch (bi->csum_type) { |
| 158 | case BLK_INTEGRITY_CSUM_NONE: | 158 | case BLK_INTEGRITY_CSUM_NONE: |
| 159 | if (bi->pi_tuple_size) { | 159 | if (bi->pi_tuple_size) { |
| 160 | pr_warn("pi_tuple_size must be 0 when checksum type \ | 160 | pr_warn("pi_tuple_size must be 0 when checksum type is none\n"); |
| 161 | is none\n"); | ||
| 162 | return -EINVAL; | 161 | return -EINVAL; |
| 163 | } | 162 | } |
| 164 | break; | 163 | break; |
| 165 | case BLK_INTEGRITY_CSUM_CRC: | 164 | case BLK_INTEGRITY_CSUM_CRC: |
| 166 | case BLK_INTEGRITY_CSUM_IP: | 165 | case BLK_INTEGRITY_CSUM_IP: |
| 167 | if (bi->pi_tuple_size != sizeof(struct t10_pi_tuple)) { | 166 | if (bi->pi_tuple_size != sizeof(struct t10_pi_tuple)) { |
| 168 | pr_warn("pi_tuple_size mismatch for T10 PI: expected \ | 167 | pr_warn("pi_tuple_size mismatch for T10 PI: expected %zu, got %u\n", |
| 169 | %zu, got %u\n", | ||
| 170 | sizeof(struct t10_pi_tuple), | 168 | sizeof(struct t10_pi_tuple), |
| 171 | bi->pi_tuple_size); | 169 | bi->pi_tuple_size); |
| 172 | return -EINVAL; | 170 | return -EINVAL; |
| @@ -174,8 +172,7 @@ static int blk_validate_integrity_limits(struct queue_limits *lim) · 1 unmodified line | |||
| 174 | break; | 172 | break; |
| 175 | case BLK_INTEGRITY_CSUM_CRC64: | 173 | case BLK_INTEGRITY_CSUM_CRC64: |
| 176 | if (bi->pi_tuple_size != sizeof(struct crc64_pi_tuple)) { | 174 | if (bi->pi_tuple_size != sizeof(struct crc64_pi_tuple)) { |
| 177 | pr_warn("pi_tuple_size mismatch for CRC64 PI: \ | 175 | pr_warn("pi_tuple_size mismatch for CRC64 PI: expected %zu, got %u\n", |
| 178 | expected %zu, got %u\n", | ||
| 179 | sizeof(struct crc64_pi_tuple), | 176 | sizeof(struct crc64_pi_tuple), |
| 180 | bi->pi_tuple_size); | 177 | bi->pi_tuple_size); |
| 181 | return -EINVAL; | 178 | return -EINVAL; |
| @@ -972,6 +969,8 @@ bool queue_limits_stack_integrity(struct queue_limits *t, · 790 unmodified lines | |||
| 972 | goto incompatible; | 969 | goto incompatible; |
| 973 | if (ti->csum_type != bi->csum_type) | 970 | if (ti->csum_type != bi->csum_type) |
| 974 | goto incompatible; | 971 | goto incompatible; |
| 972 | if (ti->pi_tuple_size != bi->pi_tuple_size) | ||
| 973 | goto incompatible; | ||
| 975 | if ((ti->flags & BLK_INTEGRITY_REF_TAG) != | 974 | if ((ti->flags & BLK_INTEGRITY_REF_TAG) != |
| 976 | (bi->flags & BLK_INTEGRITY_REF_TAG)) | 975 | (bi->flags & BLK_INTEGRITY_REF_TAG)) |
| 977 | goto incompatible; | 976 | goto incompatible; |
| @@ -980,6 +979,7 @@ bool queue_limits_stack_integrity(struct queue_limits *t, · 2 unmodified lines | |||
| 980 | ti->flags |= (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) | | 979 | ti->flags |= (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) | |
| 981 | (bi->flags & BLK_INTEGRITY_REF_TAG); | 980 | (bi->flags & BLK_INTEGRITY_REF_TAG); |
| 982 | ti->csum_type = bi->csum_type; | 981 | ti->csum_type = bi->csum_type; |
| 982 | ti->pi_tuple_size = bi->pi_tuple_size; | ||
| 983 | ti->metadata_size = bi->metadata_size; | 983 | ti->metadata_size = bi->metadata_size; |
| 984 | ti->pi_offset = bi->pi_offset; | 984 | ti->pi_offset = bi->pi_offset; |
| 985 | ti->interval_exp = bi->interval_exp; | 985 | ti->interval_exp = bi->interval_exp; |
| @@ -10437,7 +10437,7 @@ end: · 10436 unmodified lines | |||
| 10437 | (u64 *)(lin_dma_pkts_arr), DEBUGFS_WRITE64); | 10437 | (u64 *)(lin_dma_pkts_arr), DEBUGFS_WRITE64); |
| 10438 | WREG32(sob_addr, 0); | 10438 | WREG32(sob_addr, 0); |
| 10439 | 10439 | ||
| 10440 | kfree(lin_dma_pkts_arr); | 10440 | kvfree(lin_dma_pkts_arr); |
| 10441 | 10441 | ||
| 10442 | return rc; | 10442 | return rc; |
| 10443 | } | 10443 | } |
| @@ -315,7 +315,7 @@ static void __iomem *einj_get_parameter_address(void) · 314 unmodified lines | |||
| 315 | memcpy_fromio(&v5param, p, v5param_size); | 315 | memcpy_fromio(&v5param, p, v5param_size); |
| 316 | acpi5 = 1; | 316 | acpi5 = 1; |
| 317 | check_vendor_extension(pa_v5, &v5param); | 317 | check_vendor_extension(pa_v5, &v5param); |
| 318 | if (available_error_type & ACPI65_EINJV2_SUPP) { | 318 | if (is_v2 && available_error_type & ACPI65_EINJV2_SUPP) { |
| 319 | len = v5param.einjv2_struct.length; | 319 | len = v5param.einjv2_struct.length; |
| 320 | offset = offsetof(struct einjv2_extension_struct, component_arr); | 320 | offset = offsetof(struct einjv2_extension_struct, component_arr); |
| 321 | max_nr_components = (len - offset) / | 321 | max_nr_components = (len - offset) / |
| @@ -540,6 +540,9 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, · 218 unmodified lines | |||
| 540 | struct set_error_type_with_address *v5param; | 540 | struct set_error_type_with_address *v5param; |
| 541 | 541 | ||
| 542 | v5param = kmalloc(v5param_size, GFP_KERNEL); | 542 | v5param = kmalloc(v5param_size, GFP_KERNEL); |
| 543 | if (!v5param) | ||
| 544 | return -ENOMEM; | ||
| 545 | |||
| 543 | memcpy_fromio(v5param, einj_param, v5param_size); | 546 | memcpy_fromio(v5param, einj_param, v5param_size); |
| 544 | v5param->type = type; | 547 | v5param->type = type; |
| 545 | if (type & ACPI5_VENDOR_BIT) { | 548 | if (type & ACPI5_VENDOR_BIT) { |
| @@ -1091,7 +1094,7 @@ err_put_table: · 545 unmodified lines | |||
| 1091 | return rc; | 1094 | return rc; |
| 1092 | } | 1095 | } |
| 1093 | 1096 | ||
| 1094 | static void __exit einj_remove(struct faux_device *fdev) | 1097 | static void einj_remove(struct faux_device *fdev) |
| 1095 | { | 1098 | { |
| 1096 | struct apei_exec_context ctx; | 1099 | struct apei_exec_context ctx; |
| 1097 | 1100 | ||
| @@ -1114,15 +1117,9 @@ static void __exit einj_remove(struct faux_device *fdev) · 16 unmodified lines | |||
| 1114 | } | 1117 | } |
| 1115 | 1118 | ||
| 1116 | static struct faux_device *einj_dev; | 1119 | static struct faux_device *einj_dev; |
| 1117 | /* | 1120 | static struct faux_device_ops einj_device_ops = { |
| 1118 | * einj_remove() lives in .exit.text. For drivers registered via | ||
| 1119 | * platform_driver_probe() this is ok because they cannot get unbound at | ||
| 1120 | * runtime. So mark the driver struct with __refdata to prevent modpost | ||
| 1121 | * triggering a section mismatch warning. | ||
| 1122 | */ | ||
| 1123 | static struct faux_device_ops einj_device_ops __refdata = { | ||
| 1124 | .probe = einj_probe, | 1121 | .probe = einj_probe, |
| 1125 | .remove = __exit_p(einj_remove), | 1122 | .remove = einj_remove, |
| 1126 | }; | 1123 | }; |
| 1127 | 1124 | ||
| 1128 | static int __init einj_init(void) | 1125 | static int __init einj_init(void) |
| @@ -329,7 +329,7 @@ static bool applicable_image(const void *data, struct pfru_update_cap_info *cap, · 328 unmodified lines | |||
| 329 | if (type == PFRU_CODE_INJECT_TYPE) | 329 | if (type == PFRU_CODE_INJECT_TYPE) |
| 330 | return payload_hdr->rt_ver >= cap->code_rt_version; | 330 | return payload_hdr->rt_ver >= cap->code_rt_version; |
| 331 | 331 | ||
| 332 | return payload_hdr->rt_ver >= cap->drv_rt_version; | 332 | return payload_hdr->svn_ver >= cap->drv_svn; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | static void print_update_debug_info(struct pfru_updated_result *result, | 335 | static void print_update_debug_info(struct pfru_updated_result *result, |
| @@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci) · 278 unmodified lines | |||
| 279 | return NULL; | 279 | return NULL; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb) | ||
| 283 | { | ||
| 284 | struct atmtcp_hdr *hdr; | ||
| 285 | |||
| 286 | if (skb->len < sizeof(struct atmtcp_hdr)) | ||
| 287 | return -EINVAL; | ||
| 288 | |||
| 289 | hdr = (struct atmtcp_hdr *)skb->data; | ||
| 290 | if (hdr->length == ATMTCP_HDR_MAGIC) | ||
| 291 | return -EINVAL; | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 282 | 295 | ||
| 283 | static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) | 296 | static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) |
| 284 | { | 297 | { |
| @@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) · 3 unmodified lines | |||
| 288 | struct sk_buff *new_skb; | 301 | struct sk_buff *new_skb; |
| 289 | int result = 0; | 302 | int result = 0; |
| 290 | 303 | ||
| 291 | if (skb->len < sizeof(struct atmtcp_hdr)) | ||
| 292 | goto done; | ||
| 293 | |||
| 294 | dev = vcc->dev_data; | 304 | dev = vcc->dev_data; |
| 295 | hdr = (struct atmtcp_hdr *) skb->data; | 305 | hdr = (struct atmtcp_hdr *) skb->data; |
| 296 | if (hdr->length == ATMTCP_HDR_MAGIC) { | 306 | if (hdr->length == ATMTCP_HDR_MAGIC) { |
| @@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = { · 50 unmodified lines | |||
| 347 | 357 | ||
| 348 | static const struct atmdev_ops atmtcp_c_dev_ops = { | 358 | static const struct atmdev_ops atmtcp_c_dev_ops = { |
| 349 | .close = atmtcp_c_close, | 359 | .close = atmtcp_c_close, |
| 360 | .pre_send = atmtcp_c_pre_send, | ||
| 350 | .send = atmtcp_c_send | 361 | .send = atmtcp_c_send |
| 351 | }; | 362 | }; |
| 352 | 363 | ||
| @@ -675,7 +675,7 @@ static void dpm_async_resume_subordinate(struct device *dev, async_func_t func) · 674 unmodified lines | |||
| 675 | idx = device_links_read_lock(); | 675 | idx = device_links_read_lock(); |
| 676 | 676 | ||
| 677 | /* Start processing the device's "async" consumers. */ | 677 | /* Start processing the device's "async" consumers. */ |
| 678 | list_for_each_entry_rcu(link, &dev->links.consumers, s_node) | 678 | list_for_each_entry_rcu_locked(link, &dev->links.consumers, s_node) |
| 679 | if (READ_ONCE(link->status) != DL_STATE_DORMANT) | 679 | if (READ_ONCE(link->status) != DL_STATE_DORMANT) |
| 680 | dpm_async_with_cleanup(link->consumer, func); | 680 | dpm_async_with_cleanup(link->consumer, func); |
| 681 | 681 | ||
| @@ -1330,7 +1330,7 @@ static void dpm_async_suspend_superior(struct device *dev, async_func_t func) · 648 unmodified lines | |||
| 1330 | idx = device_links_read_lock(); | 1330 | idx = device_links_read_lock(); |
| 1331 | 1331 | ||
| 1332 | /* Start processing the device's "async" suppliers. */ | 1332 | /* Start processing the device's "async" suppliers. */ |
| 1333 | list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) | 1333 | list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) |
| 1334 | if (READ_ONCE(link->status) != DL_STATE_DORMANT) | 1334 | if (READ_ONCE(link->status) != DL_STATE_DORMANT) |
| 1335 | dpm_async_with_cleanup(link->supplier, func); | 1335 | dpm_async_with_cleanup(link->supplier, func); |
| 1336 | 1336 | ||
| @@ -137,20 +137,29 @@ static void loop_global_unlock(struct loop_device *lo, bool global) · 136 unmodified lines | |||
| 137 | static int max_part; | 137 | static int max_part; |
| 138 | static int part_shift; | 138 | static int part_shift; |
| 139 | 139 | ||
| 140 | static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file) | 140 | static loff_t lo_calculate_size(struct loop_device *lo, struct file *file) |
| 141 | { | 141 | { |
| 142 | struct kstat stat; | ||
| 142 | loff_t loopsize; | 143 | loff_t loopsize; |
| 144 | int ret; | ||
| 143 | 145 | ||
| 144 | /* Compute loopsize in bytes */ | 146 | /* |
| 145 | loopsize = i_size_read(file->f_mapping->host); | 147 | * Get the accurate file size. This provides better results than |
| 146 | if (offset > 0) | 148 | * cached inode data, particularly for network filesystems where |
| 147 | loopsize -= offset; | 149 | * metadata may be stale. |
| 150 | */ | ||
| 151 | ret = vfs_getattr_nosec(&file->f_path, &stat, STATX_SIZE, 0); | ||
| 152 | if (ret) | ||
| 153 | return 0; | ||
| 154 | |||
| 155 | loopsize = stat.size; | ||
| 156 | if (lo->lo_offset > 0) | ||
| 157 | loopsize -= lo->lo_offset; | ||
| 148 | /* offset is beyond i_size, weird but possible */ | 158 | /* offset is beyond i_size, weird but possible */ |
| 149 | if (loopsize < 0) | 159 | if (loopsize < 0) |
| 150 | return 0; | 160 | return 0; |
| 151 | 161 | if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) | |
| 152 | if (sizelimit > 0 && sizelimit < loopsize) | 162 | loopsize = lo->lo_sizelimit; |
| 153 | loopsize = sizelimit; | ||
| 154 | /* | 163 | /* |
| 155 | * Unfortunately, if we want to do I/O on the device, | 164 | * Unfortunately, if we want to do I/O on the device, |
| 156 | * the number of 512-byte sectors has to fit into a sector_t. | 165 | * the number of 512-byte sectors has to fit into a sector_t. |
| @@ -158,11 +167,6 @@ static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file) · 1 unmodified line | |||
| 158 | return loopsize >> 9; | 167 | return loopsize >> 9; |
| 159 | } | 168 | } |
| 160 | 169 | ||
| 161 | static loff_t get_loop_size(struct loop_device *lo, struct file *file) | ||
| 162 | { | ||
| 163 | return get_size(lo->lo_offset, lo->lo_sizelimit, file); | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | 170 | /* |
| 167 | * We support direct I/O only if lo_offset is aligned with the logical I/O size | 171 | * We support direct I/O only if lo_offset is aligned with the logical I/O size |
| 168 | * of backing device, and the logical block size of loop is bigger than that of | 172 | * of backing device, and the logical block size of loop is bigger than that of |
| @@ -569,7 +573,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, · 400 unmodified lines | |||
| 569 | error = -EINVAL; | 573 | error = -EINVAL; |
| 570 | 574 | ||
| 571 | /* size of the new backing store needs to be the same */ | 575 | /* size of the new backing store needs to be the same */ |
| 572 | if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) | 576 | if (lo_calculate_size(lo, file) != lo_calculate_size(lo, old_file)) |
| 573 | goto out_err; | 577 | goto out_err; |
| 574 | 578 | ||
| 575 | /* | 579 | /* |
| @@ -1063,7 +1067,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode, · 487 unmodified lines | |||
| 1063 | loop_update_dio(lo); | 1067 | loop_update_dio(lo); |
| 1064 | loop_sysfs_init(lo); | 1068 | loop_sysfs_init(lo); |
| 1065 | 1069 | ||
| 1066 | size = get_loop_size(lo, file); | 1070 | size = lo_calculate_size(lo, file); |
| 1067 | loop_set_size(lo, size); | 1071 | loop_set_size(lo, size); |
| 1068 | 1072 | ||
| 1069 | /* Order wrt reading lo_state in loop_validate_file(). */ | 1073 | /* Order wrt reading lo_state in loop_validate_file(). */ |
| @@ -1255,8 +1259,7 @@ out_unfreeze: · 185 unmodified lines | |||
| 1255 | if (partscan) | 1259 | if (partscan) |
| 1256 | clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); | 1260 | clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state); |
| 1257 | if (!err && size_changed) { | 1261 | if (!err && size_changed) { |
| 1258 | loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit, | 1262 | loff_t new_size = lo_calculate_size(lo, lo->lo_backing_file); |
| 1259 | lo->lo_backing_file); | ||
| 1260 | loop_set_size(lo, new_size); | 1263 | loop_set_size(lo, new_size); |
| 1261 | } | 1264 | } |
| 1262 | out_unlock: | 1265 | out_unlock: |
| @@ -1399,7 +1402,7 @@ static int loop_set_capacity(struct loop_device *lo) · 136 unmodified lines | |||
| 1399 | if (unlikely(lo->lo_state != Lo_bound)) | 1402 | if (unlikely(lo->lo_state != Lo_bound)) |
| 1400 | return -ENXIO; | 1403 | return -ENXIO; |
| 1401 | 1404 | ||
| 1402 | size = get_loop_size(lo, lo->lo_backing_file); | 1405 | size = lo_calculate_size(lo, lo->lo_backing_file); |
| 1403 | loop_set_size(lo, size); | 1406 | loop_set_size(lo, size); |
| 1404 | 1407 | ||
| 1405 | return 0; | 1408 | return 0; |
| @@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_device *rpdev) · 128 unmodified lines | |||
| 129 | 129 | ||
| 130 | chinfo.src = RPMSG_ADDR_ANY; | 130 | chinfo.src = RPMSG_ADDR_ANY; |
| 131 | chinfo.dst = rpdev->dst; | 131 | chinfo.dst = rpdev->dst; |
| 132 | strscpy(chinfo.name, cdx_rpmsg_id_table[0].name, | 132 | strscpy(chinfo.name, cdx_rpmsg_id_table[0].name, sizeof(chinfo.name)); |
| 133 | strlen(cdx_rpmsg_id_table[0].name)); | ||
| 134 | 133 | ||
| 135 | cdx_mcdi->ept = rpmsg_create_ept(rpdev, cdx_rpmsg_cb, NULL, chinfo); | 134 | cdx_mcdi->ept = rpmsg_create_ept(rpdev, cdx_rpmsg_cb, NULL, chinfo); |
| 136 | if (!cdx_mcdi->ept) { | 135 | if (!cdx_mcdi->ept) { |
| @@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct comedi_device *dev, · 1586 unmodified lines | |||
| 1587 | memset(&data[n], 0, (MIN_SAMPLES - n) * | 1587 | memset(&data[n], 0, (MIN_SAMPLES - n) * |
| 1588 | sizeof(unsigned int)); | 1588 | sizeof(unsigned int)); |
| 1589 | } | 1589 | } |
| 1590 | } else { | ||
| 1591 | memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) * | ||
| 1592 | sizeof(unsigned int)); | ||
| 1590 | } | 1593 | } |
| 1591 | ret = parse_insn(dev, insns + i, data, file); | 1594 | ret = parse_insn(dev, insns + i, data, file); |
| 1592 | if (ret < 0) | 1595 | if (ret < 0) |
| @@ -1670,6 +1673,8 @@ static int do_insn_ioctl(struct comedi_device *dev, · 77 unmodified lines | |||
| 1670 | memset(&data[insn->n], 0, | 1673 | memset(&data[insn->n], 0, |
| 1671 | (MIN_SAMPLES - insn->n) * sizeof(unsigned int)); | 1674 | (MIN_SAMPLES - insn->n) * sizeof(unsigned int)); |
| 1672 | } | 1675 | } |
| 1676 | } else { | ||
| 1677 | memset(data, 0, n_data * sizeof(unsigned int)); | ||
| 1673 | } | 1678 | } |
| 1674 | ret = parse_insn(dev, insn, data, file); | 1679 | ret = parse_insn(dev, insn, data, file); |
| 1675 | if (ret < 0) | 1680 | if (ret < 0) |
| @@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, · 619 unmodified lines | |||
| 620 | unsigned int chan = CR_CHAN(insn->chanspec); | 620 | unsigned int chan = CR_CHAN(insn->chanspec); |
| 621 | unsigned int base_chan = (chan < 32) ? 0 : chan; | 621 | unsigned int base_chan = (chan < 32) ? 0 : chan; |
| 622 | unsigned int _data[2]; | 622 | unsigned int _data[2]; |
| 623 | unsigned int i; | ||
| 623 | int ret; | 624 | int ret; |
| 624 | 625 | ||
| 625 | if (insn->n == 0) | ||
| 626 | return 0; | ||
| 627 | |||
| 628 | memset(_data, 0, sizeof(_data)); | 626 | memset(_data, 0, sizeof(_data)); |
| 629 | memset(&_insn, 0, sizeof(_insn)); | 627 | memset(&_insn, 0, sizeof(_insn)); |
| 630 | _insn.insn = INSN_BITS; | 628 | _insn.insn = INSN_BITS; |
| @@ -635,18 +633,21 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, · 4 unmodified lines | |||
| 635 | if (insn->insn == INSN_WRITE) { | 633 | if (insn->insn == INSN_WRITE) { |
| 636 | if (!(s->subdev_flags & SDF_WRITABLE)) | 634 | if (!(s->subdev_flags & SDF_WRITABLE)) |
| 637 | return -EINVAL; | 635 | return -EINVAL; |
| 638 | _data[0] = 1U << (chan - base_chan); /* mask */ | 636 | _data[0] = 1U << (chan - base_chan); /* mask */ |
| 639 | _data[1] = data[0] ? (1U << (chan - base_chan)) : 0; /* bits */ | ||
| 640 | } | 637 | } |
| 638 | for (i = 0; i < insn->n; i++) { | ||
| 639 | if (insn->insn == INSN_WRITE) | ||
| 640 | _data[1] = data[i] ? _data[0] : 0; /* bits */ | ||
| 641 | 641 | ||
| 642 | ret = s->insn_bits(dev, s, &_insn, _data); | 642 | ret = s->insn_bits(dev, s, &_insn, _data); |
| 643 | if (ret < 0) | 643 | if (ret < 0) |
| 644 | return ret; | 644 | return ret; |
| 645 | 645 | ||
| 646 | if (insn->insn == INSN_READ) | 646 | if (insn->insn == INSN_READ) |
| 647 | data[0] = (_data[1] >> (chan - base_chan)) & 1; | 647 | data[i] = (_data[1] >> (chan - base_chan)) & 1; |
| 648 | } | ||
| 648 | 649 | ||
| 649 | return 1; | 650 | return insn->n; |
| 650 | } | 651 | } |
| 651 | 652 | ||
| 652 | static int __comedi_device_postconfig_async(struct comedi_device *dev, | 653 | static int __comedi_device_postconfig_async(struct comedi_device *dev, |
| @@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_device *dev, · 327 unmodified lines | |||
| 328 | * Hook up the external trigger source interrupt only if the | 328 | * Hook up the external trigger source interrupt only if the |
| 329 | * user config option is valid and the board supports interrupts. | 329 | * user config option is valid and the board supports interrupts. |
| 330 | */ | 330 | */ |
| 331 | if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) { | 331 | if (it->options[1] > 0 && it->options[1] < 16 && |
| 332 | (board->irq_mask & (1U << it->options[1]))) { | ||
| 332 | ret = request_irq(it->options[1], pcl726_interrupt, 0, | 333 | ret = request_irq(it->options[1], pcl726_interrupt, 0, |
| 333 | dev->board_name, dev); | 334 | dev->board_name, dev); |
| 334 | if (ret == 0) { | 335 | if (ret == 0) { |
| @@ -287,20 +287,15 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, · 286 unmodified lines | |||
| 287 | return 0; | 287 | return 0; |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | if (tick_nohz_tick_stopped()) { | 290 | /* |
| 291 | /* | 291 | * If the tick is already stopped, the cost of possible short idle |
| 292 | * If the tick is already stopped, the cost of possible short | 292 | * duration misprediction is much higher, because the CPU may be stuck |
| 293 | * idle duration misprediction is much higher, because the CPU | 293 | * in a shallow idle state for a long time as a result of it. In that |
| 294 | * may be stuck in a shallow idle state for a long time as a | 294 | * case, say we might mispredict and use the known time till the closest |
| 295 | * result of it. In that case say we might mispredict and use | 295 | * timer event for the idle state selection. |
| 296 | * the known time till the closest timer event for the idle | 296 | */ |
| 297 | * state selection. | 297 | if (tick_nohz_tick_stopped() && predicted_ns < TICK_NSEC) |
| 298 | */ | 298 | predicted_ns = data->next_timer_ns; |
| 299 | if (predicted_ns < TICK_NSEC) | ||
| 300 | predicted_ns = data->next_timer_ns; | ||
| 301 | } else if (latency_req > predicted_ns) { | ||
| 302 | latency_req = predicted_ns; | ||
| 303 | } | ||
| 304 | 299 | ||
| 305 | /* | 300 | /* |
| 306 | * Find the idle state with the lowest power while satisfying | 301 | * Find the idle state with the lowest power while satisfying |
| @@ -316,13 +311,15 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, · 9 unmodified lines | |||
| 316 | if (idx == -1) | 311 | if (idx == -1) |
| 317 | idx = i; /* first enabled state */ | 312 | idx = i; /* first enabled state */ |
| 318 | 313 | ||
| 314 | if (s->exit_latency_ns > latency_req) | ||
| 315 | break; | ||
| 316 | |||
| 319 | if (s->target_residency_ns > predicted_ns) { | 317 | if (s->target_residency_ns > predicted_ns) { |
| 320 | /* | 318 | /* |
| 321 | * Use a physical idle state, not busy polling, unless | 319 | * Use a physical idle state, not busy polling, unless |
| 322 | * a timer is going to trigger soon enough. | 320 | * a timer is going to trigger soon enough. |
| 323 | */ | 321 | */ |
| 324 | if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && | 322 | if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && |
| 325 | s->exit_latency_ns <= latency_req && | ||
| 326 | s->target_residency_ns <= data->next_timer_ns) { | 323 | s->target_residency_ns <= data->next_timer_ns) { |
| 327 | predicted_ns = s->target_residency_ns; | 324 | predicted_ns = s->target_residency_ns; |
| 328 | idx = i; | 325 | idx = i; |
| @@ -354,8 +351,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, · 25 unmodified lines | |||
| 354 | 351 | ||
| 355 | return idx; | 352 | return idx; |
| 356 | } | 353 | } |
| 357 | if (s->exit_latency_ns > latency_req) | ||
| 358 | break; | ||
| 359 | 354 | ||
| 360 | idx = i; | 355 | idx = i; |
| 361 | } | 356 | } |
| @@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt) · 404 unmodified lines | |||
| 405 | } | 405 | } |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | priv->dma_nelms = | 408 | err = dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); |
| 409 | dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0); | 409 | if (err) { |
| 410 | if (priv->dma_nelms == 0) { | ||
| 411 | dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); | 410 | dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n"); |
| 412 | return -ENOMEM; | 411 | return err; |
| 413 | } | 412 | } |
| 413 | priv->dma_nelms = sgt->nents; | ||
| 414 | 414 | ||
| 415 | /* enable clock */ | 415 | /* enable clock */ |
| 416 | err = clk_enable(priv->clk); | 416 | err = clk_enable(priv->clk); |
| @@ -344,6 +344,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { · 343 unmodified lines | |||
| 344 | .ignore_interrupt = "AMDI0030:00@8", | 344 | .ignore_interrupt = "AMDI0030:00@8", |
| 345 | }, | 345 | }, |
| 346 | }, | 346 | }, |
| 347 | { | ||
| 348 | /* | ||
| 349 | * Spurious wakeups from TP_ATTN# pin | ||
| 350 | * Found in BIOS 5.35 | ||
| 351 | * https://gitlab.freedesktop.org/drm/amd/-/issues/4482 | ||
| 352 | */ | ||
| 353 | .matches = { | ||
| 354 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
| 355 | DMI_MATCH(DMI_PRODUCT_FAMILY, "ProArt PX13"), | ||
| 356 | }, | ||
| 357 | .driver_data = &(struct acpi_gpiolib_dmi_quirk) { | ||
| 358 | .ignore_wake = "ASCP1A00:00@8", | ||
| 359 | }, | ||
| 360 | }, | ||
| 347 | {} /* Terminating entry */ | 361 | {} /* Terminating entry */ |
| 348 | }; | 362 | }; |
| 349 | 363 | ||
| @@ -514,7 +514,7 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, · 513 unmodified lines | |||
| 514 | return false; | 514 | return false; |
| 515 | 515 | ||
| 516 | if (drm_gem_is_imported(obj)) { | 516 | if (drm_gem_is_imported(obj)) { |
| 517 | struct dma_buf *dma_buf = obj->dma_buf; | 517 | struct dma_buf *dma_buf = obj->import_attach->dmabuf; |
| 518 | 518 | ||
| 519 | if (dma_buf->ops != &amdgpu_dmabuf_ops) | 519 | if (dma_buf->ops != &amdgpu_dmabuf_ops) |
| 520 | /* No XGMI with non AMD GPUs */ | 520 | /* No XGMI with non AMD GPUs */ |
| @@ -317,7 +317,8 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, · 316 unmodified lines | |||
| 317 | */ | 317 | */ |
| 318 | if (!vm->is_compute_context || !vm->process_info) | 318 | if (!vm->is_compute_context || !vm->process_info) |
| 319 | return 0; | 319 | return 0; |
| 320 | if (!drm_gem_is_imported(obj) || !dma_buf_is_dynamic(obj->dma_buf)) | 320 | if (!drm_gem_is_imported(obj) || |
| 321 | !dma_buf_is_dynamic(obj->import_attach->dmabuf)) | ||
| 321 | return 0; | 322 | return 0; |
| 322 | mutex_lock_nested(&vm->process_info->lock, 1); | 323 | mutex_lock_nested(&vm->process_info->lock, 1); |
| 323 | if (!WARN_ON(!vm->process_info->eviction_fence)) { | 324 | if (!WARN_ON(!vm->process_info->eviction_fence)) { |
| @@ -1283,7 +1283,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, · 1282 unmodified lines | |||
| 1283 | struct drm_gem_object *obj = &bo->tbo.base; | 1283 | struct drm_gem_object *obj = &bo->tbo.base; |
| 1284 | 1284 | ||
| 1285 | if (drm_gem_is_imported(obj) && bo_va->is_xgmi) { | 1285 | if (drm_gem_is_imported(obj) && bo_va->is_xgmi) { |
| 1286 | struct dma_buf *dma_buf = obj->dma_buf; | 1286 | struct dma_buf *dma_buf = obj->import_attach->dmabuf; |
| 1287 | struct drm_gem_object *gobj = dma_buf->priv; | 1287 | struct drm_gem_object *gobj = dma_buf->priv; |
| 1288 | struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); | 1288 | struct amdgpu_bo *abo = gem_to_amdgpu_bo(gobj); |
| 1289 | 1289 | ||
| @@ -7792,6 +7792,9 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, · 7791 unmodified lines | |||
| 7792 | struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn); | 7792 | struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(conn); |
| 7793 | int ret; | 7793 | int ret; |
| 7794 | 7794 | ||
| 7795 | if (WARN_ON(unlikely(!old_con_state || !new_con_state))) | ||
| 7796 | return -EINVAL; | ||
| 7797 | |||
| 7795 | trace_amdgpu_dm_connector_atomic_check(new_con_state); | 7798 | trace_amdgpu_dm_connector_atomic_check(new_con_state); |
| 7796 | 7799 | ||
| 7797 | if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { | 7800 | if (conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { |
| @@ -299,6 +299,25 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable) · 298 unmodified lines | |||
| 299 | irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id); | 299 | irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id); |
| 300 | 300 | ||
| 301 | if (enable) { | 301 | if (enable) { |
| 302 | struct dc *dc = adev->dm.dc; | ||
| 303 | struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc); | ||
| 304 | struct psr_settings *psr = &acrtc_state->stream->link->psr_settings; | ||
| 305 | struct replay_settings *pr = &acrtc_state->stream->link->replay_settings; | ||
| 306 | bool sr_supported = (psr->psr_version != DC_PSR_VERSION_UNSUPPORTED) || | ||
| 307 | pr->config.replay_supported; | ||
| 308 | |||
| 309 | /* | ||
| 310 | * IPS & self-refresh feature can cause vblank counter resets between | ||
| 311 | * vblank disable and enable. | ||
| 312 | * It may cause system stuck due to waiting for the vblank counter. | ||
| 313 | * Call this function to estimate missed vblanks by using timestamps and | ||
| 314 | * update the vblank counter in DRM. | ||
| 315 | */ | ||
| 316 | if (dc->caps.ips_support && | ||
| 317 | dc->config.disable_ips != DMUB_IPS_DISABLE_ALL && | ||
| 318 | sr_supported && vblank->config.disable_immediate) | ||
| 319 | drm_crtc_vblank_restore(crtc); | ||
| 320 | |||
| 302 | /* vblank irq on -> Only need vupdate irq in vrr mode */ | 321 | /* vblank irq on -> Only need vupdate irq in vrr mode */ |
| 303 | if (amdgpu_dm_crtc_vrr_active(acrtc_state)) | 322 | if (amdgpu_dm_crtc_vrr_active(acrtc_state)) |
| 304 | rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true); | 323 | rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true); |
| @@ -174,11 +174,8 @@ static struct graphics_object_id bios_parser_get_connector_id( · 173 unmodified lines | |||
| 174 | return object_id; | 174 | return object_id; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | if (tbl->ucNumberOfObjects <= i) { | 177 | if (tbl->ucNumberOfObjects <= i) |
| 178 | dm_error("Can't find connector id %d in connector table of size %d.\n", | ||
| 179 | i, tbl->ucNumberOfObjects); | ||
| 180 | return object_id; | 178 | return object_id; |
| 181 | } | ||
| 182 | 179 | ||
| 183 | id = le16_to_cpu(tbl->asObjects[i].usObjectID); | 180 | id = le16_to_cpu(tbl->asObjects[i].usObjectID); |
| 184 | object_id = object_id_from_bios_object_id(id); | 181 | object_id = object_id_from_bios_object_id(id); |
| @@ -993,7 +993,7 @@ static enum bp_result set_pixel_clock_v3( · 992 unmodified lines | |||
| 993 | allocation.sPCLKInput.usFbDiv = | 993 | allocation.sPCLKInput.usFbDiv = |
| 994 | cpu_to_le16((uint16_t)bp_params->feedback_divider); | 994 | cpu_to_le16((uint16_t)bp_params->feedback_divider); |
| 995 | allocation.sPCLKInput.ucFracFbDiv = | 995 | allocation.sPCLKInput.ucFracFbDiv = |
| 996 | (uint8_t)bp_params->fractional_feedback_divider; | 996 | (uint8_t)(bp_params->fractional_feedback_divider / 100000); |
| 997 | allocation.sPCLKInput.ucPostDiv = | 997 | allocation.sPCLKInput.ucPostDiv = |
| 998 | (uint8_t)bp_params->pixel_clock_post_divider; | 998 | (uint8_t)bp_params->pixel_clock_post_divider; |
| 999 | 999 | ||
| @@ -72,9 +72,9 @@ static const struct state_dependent_clocks dce80_max_clks_by_state[] = { · 71 unmodified lines | |||
| 72 | /* ClocksStateLow */ | 72 | /* ClocksStateLow */ |
| 73 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, | 73 | { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, |
| 74 | /* ClocksStateNominal */ | 74 | /* ClocksStateNominal */ |
| 75 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, | 75 | { .display_clk_khz = 625000, .pixel_clk_khz = 400000 }, |
| 76 | /* ClocksStatePerformance */ | 76 | /* ClocksStatePerformance */ |
| 77 | { .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; | 77 | { .display_clk_khz = 625000, .pixel_clk_khz = 400000 } }; |
| 78 | 78 | ||
| 79 | int dentist_get_divider_from_did(int did) | 79 | int dentist_get_divider_from_did(int did) |
| 80 | { | 80 | { |
| @@ -391,8 +391,6 @@ static void dce_pplib_apply_display_requirements( · 310 unmodified lines | |||
| 391 | { | 391 | { |
| 392 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | 392 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; |
| 393 | 393 | ||
| 394 | pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); | ||
| 395 | |||
| 396 | dce110_fill_display_configs(context, pp_display_cfg); | 394 | dce110_fill_display_configs(context, pp_display_cfg); |
| 397 | 395 | ||
| 398 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) | 396 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) |
| @@ -405,11 +403,9 @@ static void dce_update_clocks(struct clk_mgr *clk_mgr_base, · 6 unmodified lines | |||
| 405 | { | 403 | { |
| 406 | struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); | 404 | struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); |
| 407 | struct dm_pp_power_level_change_request level_change_req; | 405 | struct dm_pp_power_level_change_request level_change_req; |
| 408 | int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; | 406 | const int max_disp_clk = |
| 409 | 407 | clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz; | |
| 410 | /*TODO: W/A for dal3 linux, investigate why this works */ | 408 | int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); |
| 411 | if (!clk_mgr_dce->dfs_bypass_active) | ||
| 412 | patched_disp_clk = patched_disp_clk * 115 / 100; | ||
| 413 | 409 | ||
| 414 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); | 410 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); |
| 415 | /* get max clock state from PPLIB */ | 411 | /* get max clock state from PPLIB */ |
| @@ -120,9 +120,15 @@ void dce110_fill_display_configs( · 119 unmodified lines | |||
| 120 | const struct dc_state *context, | 120 | const struct dc_state *context, |
| 121 | struct dm_pp_display_configuration *pp_display_cfg) | 121 | struct dm_pp_display_configuration *pp_display_cfg) |
| 122 | { | 122 | { |
| 123 | struct dc *dc = context->clk_mgr->ctx->dc; | ||
| 123 | int j; | 124 | int j; |
| 124 | int num_cfgs = 0; | 125 | int num_cfgs = 0; |
| 125 | 126 | ||
| 127 | pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); | ||
| 128 | pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; | ||
| 129 | pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; | ||
| 130 | pp_display_cfg->crtc_index = dc->res_pool->res_cap->num_timing_generator; | ||
| 131 | |||
| 126 | for (j = 0; j < context->stream_count; j++) { | 132 | for (j = 0; j < context->stream_count; j++) { |
| 127 | int k; | 133 | int k; |
| 128 | 134 | ||
| @@ -164,6 +170,23 @@ void dce110_fill_display_configs( · 35 unmodified lines | |||
| 164 | cfg->v_refresh /= stream->timing.h_total; | 170 | cfg->v_refresh /= stream->timing.h_total; |
| 165 | cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) | 171 | cfg->v_refresh = (cfg->v_refresh + stream->timing.v_total / 2) |
| 166 | / stream->timing.v_total; | 172 | / stream->timing.v_total; |
| 173 | |||
| 174 | /* Find first CRTC index and calculate its line time. | ||
| 175 | * This is necessary for DPM on SI GPUs. | ||
| 176 | */ | ||
| 177 | if (cfg->pipe_idx < pp_display_cfg->crtc_index) { | ||
| 178 | const struct dc_crtc_timing *timing = | ||
| 179 | &context->streams[0]->timing; | ||
| 180 | |||
| 181 | pp_display_cfg->crtc_index = cfg->pipe_idx; | ||
| 182 | pp_display_cfg->line_time_in_us = | ||
| 183 | timing->h_total * 10000 / timing->pix_clk_100hz; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | if (!num_cfgs) { | ||
| 188 | pp_display_cfg->crtc_index = 0; | ||
| 189 | pp_display_cfg->line_time_in_us = 0; | ||
| 167 | } | 190 | } |
| 168 | 191 | ||
| 169 | pp_display_cfg->display_count = num_cfgs; | 192 | pp_display_cfg->display_count = num_cfgs; |
| @@ -223,25 +246,8 @@ void dce11_pplib_apply_display_requirements( · 53 unmodified lines | |||
| 223 | pp_display_cfg->min_engine_clock_deep_sleep_khz | 246 | pp_display_cfg->min_engine_clock_deep_sleep_khz |
| 224 | = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; | 247 | = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; |
| 225 | 248 | ||
| 226 | pp_display_cfg->avail_mclk_switch_time_us = | ||
| 227 | dce110_get_min_vblank_time_us(context); | ||
| 228 | /* TODO: dce11.2*/ | ||
| 229 | pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0; | ||
| 230 | |||
| 231 | pp_display_cfg->disp_clk_khz = dc->clk_mgr->clks.dispclk_khz; | ||
| 232 | |||
| 233 | dce110_fill_display_configs(context, pp_display_cfg); | 249 | dce110_fill_display_configs(context, pp_display_cfg); |
| 234 | 250 | ||
| 235 | /* TODO: is this still applicable?*/ | ||
| 236 | if (pp_display_cfg->display_count == 1) { | ||
| 237 | const struct dc_crtc_timing *timing = | ||
| 238 | &context->streams[0]->timing; | ||
| 239 | |||
| 240 | pp_display_cfg->crtc_index = | ||
| 241 | pp_display_cfg->disp_configs[0].pipe_idx; | ||
| 242 | pp_display_cfg->line_time_in_us = timing->h_total * 10000 / timing->pix_clk_100hz; | ||
| 243 | } | ||
| 244 | |||
| 245 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) | 251 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) |
| 246 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); | 252 | dm_pp_apply_display_requirements(dc->ctx, pp_display_cfg); |
| 247 | } | 253 | } |
| @@ -83,22 +83,13 @@ static const struct state_dependent_clocks dce60_max_clks_by_state[] = { · 82 unmodified lines | |||
| 83 | static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base) | 83 | static int dce60_get_dp_ref_freq_khz(struct clk_mgr *clk_mgr_base) |
| 84 | { | 84 | { |
| 85 | struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | 85 | struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); |
| 86 | int dprefclk_wdivider; | 86 | struct dc_context *ctx = clk_mgr_base->ctx; |
| 87 | int dp_ref_clk_khz; | 87 | int dp_ref_clk_khz = 0; |
| 88 | int target_div; | ||
| 89 | 88 | ||
| 90 | /* DCE6 has no DPREFCLK_CNTL to read DP Reference Clock source */ | 89 | if (ASIC_REV_IS_TAHITI_P(ctx->asic_id.hw_internal_rev)) |
| 91 | 90 | dp_ref_clk_khz = ctx->dc_bios->fw_info.default_display_engine_pll_frequency; | |
| 92 | /* Read the mmDENTIST_DISPCLK_CNTL to get the currently | 91 | else |
| 93 | * programmed DID DENTIST_DPREFCLK_WDIVIDER*/ | 92 | dp_ref_clk_khz = clk_mgr_base->clks.dispclk_khz; |
| 94 | REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DPREFCLK_WDIVIDER, &dprefclk_wdivider); | ||
| 95 | |||
| 96 | /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/ | ||
| 97 | target_div = dentist_get_divider_from_did(dprefclk_wdivider); | ||
| 98 | |||
| 99 | /* Calculate the current DFS clock, in kHz.*/ | ||
| 100 | dp_ref_clk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR | ||
| 101 | * clk_mgr->base.dentist_vco_freq_khz) / target_div; | ||
| 102 | 93 | ||
| 103 | return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz); | 94 | return dce_adjust_dp_ref_freq_for_ss(clk_mgr, dp_ref_clk_khz); |
| 104 | } | 95 | } |
| @@ -109,8 +100,6 @@ static void dce60_pplib_apply_display_requirements( · 4 unmodified lines | |||
| 109 | { | 100 | { |
| 110 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; | 101 | struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; |
| 111 | 102 | ||
| 112 | pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); | ||
| 113 | |||
| 114 | dce110_fill_display_configs(context, pp_display_cfg); | 103 | dce110_fill_display_configs(context, pp_display_cfg); |
| 115 | 104 | ||
| 116 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) | 105 | if (memcmp(&dc->current_state->pp_display_cfg, pp_display_cfg, sizeof(*pp_display_cfg)) != 0) |
| @@ -123,11 +112,9 @@ static void dce60_update_clocks(struct clk_mgr *clk_mgr_base, · 6 unmodified lines | |||
| 123 | { | 112 | { |
| 124 | struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); | 113 | struct clk_mgr_internal *clk_mgr_dce = TO_CLK_MGR_INTERNAL(clk_mgr_base); |
| 125 | struct dm_pp_power_level_change_request level_change_req; | 114 | struct dm_pp_power_level_change_request level_change_req; |
| 126 | int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; | 115 | const int max_disp_clk = |
| 127 | 116 | clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE].display_clk_khz; | |
| 128 | /*TODO: W/A for dal3 linux, investigate why this works */ | 117 | int patched_disp_clk = MIN(max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); |
| 129 | if (!clk_mgr_dce->dfs_bypass_active) | ||
| 130 | patched_disp_clk = patched_disp_clk * 115 / 100; | ||
| 131 | 118 | ||
| 132 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); | 119 | level_change_req.power_level = dce_get_required_clocks_state(clk_mgr_base, context); |
| 133 | /* get max clock state from PPLIB */ | 120 | /* get max clock state from PPLIB */ |
| @@ -217,11 +217,24 @@ static bool create_links( · 216 unmodified lines | |||
| 217 | connectors_num, | 217 | connectors_num, |
| 218 | num_virtual_links); | 218 | num_virtual_links); |
| 219 | 219 | ||
| 220 | // condition loop on link_count to allow skipping invalid indices | 220 | /* When getting the number of connectors, the VBIOS reports the number of valid indices, |
| 221 | * but it doesn't say which indices are valid, and not every index has an actual connector. | ||
| 222 | * So, if we don't find a connector on an index, that is not an error. | ||
| 223 | * | ||
| 224 | * - There is no guarantee that the first N indices will be valid | ||
| 225 | * - VBIOS may report a higher amount of valid indices than there are actual connectors | ||
| 226 | * - Some VBIOS have valid configurations for more connectors than there actually are | ||
| 227 | * on the card. This may be because the manufacturer used the same VBIOS for different | ||
| 228 | * variants of the same card. | ||
| 229 | */ | ||
| 221 | for (i = 0; dc->link_count < connectors_num && i < MAX_LINKS; i++) { | 230 | for (i = 0; dc->link_count < connectors_num && i < MAX_LINKS; i++) { |
| 231 | struct graphics_object_id connector_id = bios->funcs->get_connector_id(bios, i); | ||
| 222 | struct link_init_data link_init_params = {0}; | 232 | struct link_init_data link_init_params = {0}; |
| 223 | struct dc_link *link; | 233 | struct dc_link *link; |
| 224 | 234 | ||
| 235 | if (connector_id.id == CONNECTOR_ID_UNKNOWN) | ||
| 236 | continue; | ||
| 237 | |||
| 225 | DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count); | 238 | DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count); |
| 226 | 239 | ||
| 227 | link_init_params.ctx = dc->ctx; | 240 | link_init_params.ctx = dc->ctx; |
| @@ -896,13 +896,13 @@ void dce110_link_encoder_construct( · 895 unmodified lines | |||
| 896 | enc110->base.id, &bp_cap_info); | 896 | enc110->base.id, &bp_cap_info); |
| 897 | 897 | ||
| 898 | /* Override features with DCE-specific values */ | 898 | /* Override features with DCE-specific values */ |
| 899 | if (BP_RESULT_OK == result) { | 899 | if (result == BP_RESULT_OK) { |
| 900 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = | 900 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = |
| 901 | bp_cap_info.DP_HBR2_EN; | 901 | bp_cap_info.DP_HBR2_EN; |
| 902 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = | 902 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = |
| 903 | bp_cap_info.DP_HBR3_EN; | 903 | bp_cap_info.DP_HBR3_EN; |
| 904 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | 904 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; |
| 905 | } else { | 905 | } else if (result != BP_RESULT_NORECORD) { |
| 906 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | 906 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", |
| 907 | __func__, | 907 | __func__, |
| 908 | result); | 908 | result); |
| @@ -1798,13 +1798,13 @@ void dce60_link_encoder_construct( · 889 unmodified lines | |||
| 1798 | enc110->base.id, &bp_cap_info); | 1798 | enc110->base.id, &bp_cap_info); |
| 1799 | 1799 | ||
| 1800 | /* Override features with DCE-specific values */ | 1800 | /* Override features with DCE-specific values */ |
| 1801 | if (BP_RESULT_OK == result) { | 1801 | if (result == BP_RESULT_OK) { |
| 1802 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = | 1802 | enc110->base.features.flags.bits.IS_HBR2_CAPABLE = |
| 1803 | bp_cap_info.DP_HBR2_EN; | 1803 | bp_cap_info.DP_HBR2_EN; |
| 1804 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = | 1804 | enc110->base.features.flags.bits.IS_HBR3_CAPABLE = |
| 1805 | bp_cap_info.DP_HBR3_EN; | 1805 | bp_cap_info.DP_HBR3_EN; |
| 1806 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; | 1806 | enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; |
| 1807 | } else { | 1807 | } else if (result != BP_RESULT_NORECORD) { |
| 1808 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", | 1808 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", |
| 1809 | __func__, | 1809 | __func__, |
| 1810 | result); | 1810 | result); |
| @@ -4,7 +4,6 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include "dc.h" | 5 | #include "dc.h" |
| 6 | #include "dc_dmub_srv.h" | 6 | #include "dc_dmub_srv.h" |
| 7 | #include "dc_dp_types.h" | ||
| 8 | #include "dmub/dmub_srv.h" | 7 | #include "dmub/dmub_srv.h" |
| 9 | #include "core_types.h" | 8 | #include "core_types.h" |
| 10 | #include "dmub_replay.h" | 9 | #include "dmub_replay.h" |
| @@ -44,45 +43,21 @@ static void dmub_replay_get_state(struct dmub_replay *dmub, enum replay_state *s · 33 unmodified lines | |||
| 44 | /* | 43 | /* |
| 45 | * Enable/Disable Replay. | 44 | * Enable/Disable Replay. |
| 46 | */ | 45 | */ |
| 47 | static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst, | 46 | static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait, uint8_t panel_inst) |
| 48 | struct dc_link *link) | ||
| 49 | { | 47 | { |
| 50 | union dmub_rb_cmd cmd; | 48 | union dmub_rb_cmd cmd; |
| 51 | struct dc_context *dc = dmub->ctx; | 49 | struct dc_context *dc = dmub->ctx; |
| 52 | uint32_t retry_count; | 50 | uint32_t retry_count; |
| 53 | enum replay_state state = REPLAY_STATE_0; | 51 | enum replay_state state = REPLAY_STATE_0; |
| 54 | struct pipe_ctx *pipe_ctx = NULL; | ||
| 55 | struct resource_context *res_ctx = &link->ctx->dc->current_state->res_ctx; | ||
| 56 | uint8_t i; | ||
| 57 | 52 | ||
| 58 | memset(&cmd, 0, sizeof(cmd)); | 53 | memset(&cmd, 0, sizeof(cmd)); |
| 59 | cmd.replay_enable.header.type = DMUB_CMD__REPLAY; | 54 | cmd.replay_enable.header.type = DMUB_CMD__REPLAY; |
| 60 | cmd.replay_enable.data.panel_inst = panel_inst; | 55 | cmd.replay_enable.data.panel_inst = panel_inst; |
| 61 | 56 | ||
| 62 | cmd.replay_enable.header.sub_type = DMUB_CMD__REPLAY_ENABLE; | 57 | cmd.replay_enable.header.sub_type = DMUB_CMD__REPLAY_ENABLE; |
| 63 | if (enable) { | 58 | if (enable) |
| 64 | cmd.replay_enable.data.enable = REPLAY_ENABLE; | 59 | cmd.replay_enable.data.enable = REPLAY_ENABLE; |
| 65 | // hpo stream/link encoder assignments are not static, need to update everytime we try to enable replay | 60 | else |
| 66 | if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) { | ||
| 67 | for (i = 0; i < MAX_PIPES; i++) { | ||
| 68 | if (res_ctx && | ||
| 69 | res_ctx->pipe_ctx[i].stream && | ||
| 70 | res_ctx->pipe_ctx[i].stream->link && | ||
| 71 | res_ctx->pipe_ctx[i].stream->link == link && | ||
| 72 | res_ctx->pipe_ctx[i].stream->link->connector_signal == SIGNAL_TYPE_EDP) { | ||
| 73 | pipe_ctx = &res_ctx->pipe_ctx[i]; | ||
| 74 | //TODO: refactor for multi edp support | ||
| 75 | break; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | if (!pipe_ctx) | ||
| 80 | return; | ||
| 81 | |||
| 82 | cmd.replay_enable.data.hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | ||
| 83 | cmd.replay_enable.data.hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst; | ||
| 84 | } | ||
| 85 | } else | ||
| 86 | cmd.replay_enable.data.enable = REPLAY_DISABLE; | 61 | cmd.replay_enable.data.enable = REPLAY_DISABLE; |
| 87 | 62 | ||
| 88 | cmd.replay_enable.header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_enable_data); | 63 | cmd.replay_enable.header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_enable_data); |
| @@ -174,17 +149,6 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub, · 85 unmodified lines | |||
| 174 | copy_settings_data->digbe_inst = replay_context->digbe_inst; | 149 | copy_settings_data->digbe_inst = replay_context->digbe_inst; |
| 175 | copy_settings_data->digfe_inst = replay_context->digfe_inst; | 150 | copy_settings_data->digfe_inst = replay_context->digfe_inst; |
| 176 | 151 | ||
| 177 | if (link->cur_link_settings.link_rate >= LINK_RATE_UHBR10) { | ||
| 178 | if (pipe_ctx->stream_res.hpo_dp_stream_enc) | ||
| 179 | copy_settings_data->hpo_stream_enc_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; | ||
| 180 | else | ||
| 181 | copy_settings_data->hpo_stream_enc_inst = 0; | ||
| 182 | if (pipe_ctx->link_res.hpo_dp_link_enc) | ||
| 183 | copy_settings_data->hpo_link_enc_inst = pipe_ctx->link_res.hpo_dp_link_enc->inst; | ||
| 184 | else | ||
| 185 | copy_settings_data->hpo_link_enc_inst = 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (pipe_ctx->plane_res.dpp) | 152 | if (pipe_ctx->plane_res.dpp) |
| 189 | copy_settings_data->dpp_inst = pipe_ctx->plane_res.dpp->inst; | 153 | copy_settings_data->dpp_inst = pipe_ctx->plane_res.dpp->inst; |
| 190 | else | 154 | else |
| @@ -247,7 +211,6 @@ static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub, · 56 unmodified lines | |||
| 247 | pCmd->header.type = DMUB_CMD__REPLAY; | 211 | pCmd->header.type = DMUB_CMD__REPLAY; |
| 248 | pCmd->header.sub_type = DMUB_CMD__REPLAY_SET_COASTING_VTOTAL; | 212 | pCmd->header.sub_type = DMUB_CMD__REPLAY_SET_COASTING_VTOTAL; |
| 249 | pCmd->header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data); | 213 | pCmd->header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data); |
| 250 | pCmd->replay_set_coasting_vtotal_data.panel_inst = panel_inst; | ||
| 251 | pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF); | 214 | pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF); |
| 252 | pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16; | 215 | pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16; |
| 253 | 216 | ||
| @@ -19,7 +19,7 @@ struct dmub_replay_funcs { · 18 unmodified lines | |||
| 19 | void (*replay_get_state)(struct dmub_replay *dmub, enum replay_state *state, | 19 | void (*replay_get_state)(struct dmub_replay *dmub, enum replay_state *state, |
| 20 | uint8_t panel_inst); | 20 | uint8_t panel_inst); |
| 21 | void (*replay_enable)(struct dmub_replay *dmub, bool enable, bool wait, | 21 | void (*replay_enable)(struct dmub_replay *dmub, bool enable, bool wait, |
| 22 | uint8_t panel_inst, struct dc_link *link); | 22 | uint8_t panel_inst); |
| 23 | bool (*replay_copy_settings)(struct dmub_replay *dmub, struct dc_link *link, | 23 | bool (*replay_copy_settings)(struct dmub_replay *dmub, struct dc_link *link, |
| 24 | struct replay_context *replay_context, uint8_t panel_inst); | 24 | struct replay_context *replay_context, uint8_t panel_inst); |
| 25 | void (*replay_set_power_opt)(struct dmub_replay *dmub, unsigned int power_opt, | 25 | void (*replay_set_power_opt)(struct dmub_replay *dmub, unsigned int power_opt, |
| @@ -944,7 +944,7 @@ bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active, · 943 unmodified lines | |||
| 944 | // TODO: Handle mux change case if force_static is set | 944 | // TODO: Handle mux change case if force_static is set |
| 945 | // If force_static is set, just change the replay_allow_active state directly | 945 | // If force_static is set, just change the replay_allow_active state directly |
| 946 | if (replay != NULL && link->replay_settings.replay_feature_enabled) | 946 | if (replay != NULL && link->replay_settings.replay_feature_enabled) |
| 947 | replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst, link); | 947 | replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst); |
| 948 | link->replay_settings.replay_allow_active = *allow_active; | 948 | link->replay_settings.replay_allow_active = *allow_active; |
| 949 | } | 949 | } |
| 950 | 950 | ||
| @@ -4047,14 +4047,6 @@ struct dmub_cmd_replay_copy_settings_data { · 4046 unmodified lines | |||
| 4047 | * DIG BE HW instance. | 4047 | * DIG BE HW instance. |
| 4048 | */ | 4048 | */ |
| 4049 | uint8_t digbe_inst; | 4049 | uint8_t digbe_inst; |
| 4050 | /** | ||
| 4051 | * @hpo_stream_enc_inst: HPO stream encoder instance | ||
| 4052 | */ | ||
| 4053 | uint8_t hpo_stream_enc_inst; | ||
| 4054 | /** | ||
| 4055 | * @hpo_link_enc_inst: HPO link encoder instance | ||
| 4056 | */ | ||
| 4057 | uint8_t hpo_link_enc_inst; | ||
| 4058 | /** | 4050 | /** |
| 4059 | * AUX HW instance. | 4051 | * AUX HW instance. |
| 4060 | */ | 4052 | */ |
| @@ -4159,18 +4151,6 @@ struct dmub_rb_cmd_replay_enable_data { · 98 unmodified lines | |||
| 4159 | * This does not support HDMI/DP2 for now. | 4151 | * This does not support HDMI/DP2 for now. |
| 4160 | */ | 4152 | */ |
| 4161 | uint8_t phy_rate; | 4153 | uint8_t phy_rate; |
| 4162 | /** | ||
| 4163 | * @hpo_stream_enc_inst: HPO stream encoder instance | ||
| 4164 | */ | ||
| 4165 | uint8_t hpo_stream_enc_inst; | ||
| 4166 | /** | ||
| 4167 | * @hpo_link_enc_inst: HPO link encoder instance | ||
| 4168 | */ | ||
| 4169 | uint8_t hpo_link_enc_inst; | ||
| 4170 | /** | ||
| 4171 | * @pad: Align structure to 4 byte boundary. | ||
| 4172 | */ | ||
| 4173 | uint8_t pad[2]; | ||
| 4174 | }; | 4154 | }; |
| 4175 | 4155 | ||
| 4176 | /** | 4156 | /** |
| @@ -260,6 +260,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp) · 259 unmodified lines | |||
| 260 | return MOD_HDCP_STATUS_FAILURE; | 260 | return MOD_HDCP_STATUS_FAILURE; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | if (!display) | ||
| 264 | return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; | ||
| 265 | |||
| 263 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; | 266 | hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; |
| 264 | 267 | ||
| 265 | mutex_lock(&psp->hdcp_context.mutex); | 268 | mutex_lock(&psp->hdcp_context.mutex); |
| @@ -1697,9 +1697,11 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu, · 1696 unmodified lines | |||
| 1697 | uint32_t *min_power_limit) | 1697 | uint32_t *min_power_limit) |
| 1698 | { | 1698 | { |
| 1699 | struct smu_table_context *table_context = &smu->smu_table; | 1699 | struct smu_table_context *table_context = &smu->smu_table; |
| 1700 | struct smu_14_0_2_powerplay_table *powerplay_table = | ||
| 1701 | table_context->power_play_table; | ||
| 1700 | PPTable_t *pptable = table_context->driver_pptable; | 1702 | PPTable_t *pptable = table_context->driver_pptable; |
| 1701 | CustomSkuTable_t *skutable = &pptable->CustomSkuTable; | 1703 | CustomSkuTable_t *skutable = &pptable->CustomSkuTable; |
| 1702 | uint32_t power_limit; | 1704 | uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; |
| 1703 | uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; | 1705 | uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; |
| 1704 | 1706 | ||
| 1705 | if (smu_v14_0_get_current_power_limit(smu, &power_limit)) | 1707 | if (smu_v14_0_get_current_power_limit(smu, &power_limit)) |
| @@ -1712,11 +1714,29 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu, · 6 unmodified lines | |||
| 1712 | if (default_power_limit) | 1714 | if (default_power_limit) |
| 1713 | *default_power_limit = power_limit; | 1715 | *default_power_limit = power_limit; |
| 1714 | 1716 | ||
| 1715 | if (max_power_limit) | 1717 | if (powerplay_table) { |
| 1716 | *max_power_limit = msg_limit; | 1718 | if (smu->od_enabled && |
| 1719 | smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { | ||
| 1720 | od_percent_upper = pptable->SkuTable.OverDriveLimitsBasicMax.Ppt; | ||
| 1721 | od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; | ||
| 1722 | } else if (smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { | ||
| 1723 | od_percent_upper = 0; | ||
| 1724 | od_percent_lower = pptable->SkuTable.OverDriveLimitsBasicMin.Ppt; | ||
| 1725 | } | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", | ||
| 1729 | od_percent_upper, od_percent_lower, power_limit); | ||
| 1730 | |||
| 1731 | if (max_power_limit) { | ||
| 1732 | *max_power_limit = msg_limit * (100 + od_percent_upper); | ||
| 1733 | *max_power_limit /= 100; | ||
| 1734 | } | ||
| 1717 | 1735 | ||
| 1718 | if (min_power_limit) | 1736 | if (min_power_limit) { |
| 1719 | *min_power_limit = 0; | 1737 | *min_power_limit = power_limit * (100 + od_percent_lower); |
| 1738 | *min_power_limit /= 100; | ||
| 1739 | } | ||
| 1720 | 1740 | ||
| 1721 | return 0; | 1741 | return 0; |
| 1722 | } | 1742 | } |
| @@ -1474,8 +1474,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) · 1473 unmodified lines | |||
| 1474 | 1474 | ||
| 1475 | dp = devm_drm_bridge_alloc(dev, struct analogix_dp_device, bridge, | 1475 | dp = devm_drm_bridge_alloc(dev, struct analogix_dp_device, bridge, |
| 1476 | &analogix_dp_bridge_funcs); | 1476 | &analogix_dp_bridge_funcs); |
| 1477 | if (!dp) | 1477 | if (IS_ERR(dp)) |
| 1478 | return ERR_PTR(-ENOMEM); | 1478 | return ERR_CAST(dp); |
| 1479 | 1479 | ||
| 1480 | dp->dev = &pdev->dev; | 1480 | dp->dev = &pdev->dev; |
| 1481 | dp->dpms_mode = DRM_MODE_DPMS_OFF; | 1481 | dp->dpms_mode = DRM_MODE_DPMS_OFF; |
| @@ -2432,6 +2432,8 @@ static const struct drm_gpuvm_ops lock_ops = { · 2431 unmodified lines | |||
| 2432 | * | 2432 | * |
| 2433 | * The expected usage is: | 2433 | * The expected usage is: |
| 2434 | * | 2434 | * |
| 2435 | * .. code-block:: c | ||
| 2436 | * | ||
| 2435 | * vm_bind { | 2437 | * vm_bind { |
| 2436 | * struct drm_exec exec; | 2438 | * struct drm_exec exec; |
| 2437 | * | 2439 | * |
| @@ -381,6 +381,26 @@ struct DecFifo { · 380 unmodified lines | |||
| 381 | len: usize, | 381 | len: usize, |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | // On arm32 architecture, dividing an `u64` by a constant will generate a call | ||
| 385 | // to `__aeabi_uldivmod` which is not present in the kernel. | ||
| 386 | // So use the multiply by inverse method for this architecture. | ||
| 387 | fn div10(val: u64) -> u64 { | ||
| 388 | if cfg!(target_arch = "arm") { | ||
| 389 | let val_h = val >> 32; | ||
| 390 | let val_l = val & 0xFFFFFFFF; | ||
| 391 | let b_h: u64 = 0x66666666; | ||
| 392 | let b_l: u64 = 0x66666667; | ||
| 393 | |||
| 394 | let tmp1 = val_h * b_l + ((val_l * b_l) >> 32); | ||
| 395 | let tmp2 = val_l * b_h + (tmp1 & 0xffffffff); | ||
| 396 | let tmp3 = val_h * b_h + (tmp1 >> 32) + (tmp2 >> 32); | ||
| 397 | |||
| 398 | tmp3 >> 2 | ||
| 399 | } else { | ||
| 400 | val / 10 | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 384 | impl DecFifo { | 404 | impl DecFifo { |
| 385 | fn push(&mut self, data: u64, len: usize) { | 405 | fn push(&mut self, data: u64, len: usize) { |
| 386 | let mut chunk = data; | 406 | let mut chunk = data; |
| @@ -389,7 +409,7 @@ impl DecFifo { · 2 unmodified lines | |||
| 389 | } | 409 | } |
| 390 | for i in 0..len { | 410 | for i in 0..len { |
| 391 | self.decimals[i] = (chunk % 10) as u8; | 411 | self.decimals[i] = (chunk % 10) as u8; |
| 392 | chunk /= 10; | 412 | chunk = div10(chunk); |
| 393 | } | 413 | } |
| 394 | self.len += len; | 414 | self.len += len; |
| 395 | } | 415 | } |
| @@ -325,6 +325,17 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp) · 324 unmodified lines | |||
| 325 | return hibmc_dp_link_reduce_rate(dp); | 325 | return hibmc_dp_link_reduce_rate(dp); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static void hibmc_dp_update_caps(struct hibmc_dp_dev *dp) | ||
| 329 | { | ||
| 330 | dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE]; | ||
| 331 | if (dp->link.cap.link_rate > DP_LINK_BW_8_1 || !dp->link.cap.link_rate) | ||
| 332 | dp->link.cap.link_rate = DP_LINK_BW_8_1; | ||
| 333 | |||
| 334 | dp->link.cap.lanes = dp->dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; | ||
| 335 | if (dp->link.cap.lanes > HIBMC_DP_LANE_NUM_MAX) | ||
| 336 | dp->link.cap.lanes = HIBMC_DP_LANE_NUM_MAX; | ||
| 337 | } | ||
| 338 | |||
| 328 | int hibmc_dp_link_training(struct hibmc_dp_dev *dp) | 339 | int hibmc_dp_link_training(struct hibmc_dp_dev *dp) |
| 329 | { | 340 | { |
| 330 | struct hibmc_dp_link *link = &dp->link; | 341 | struct hibmc_dp_link *link = &dp->link; |
| @@ -334,8 +345,7 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp) · 3 unmodified lines | |||
| 334 | if (ret) | 345 | if (ret) |
| 335 | drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); | 346 | drm_err(dp->dev, "dp aux read dpcd failed, ret: %d\n", ret); |
| 336 | 347 | ||
| 337 | dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE]; | 348 | hibmc_dp_update_caps(dp); |
| 338 | dp->link.cap.lanes = 0x2; | ||
| 339 | 349 | ||
| 340 | ret = hibmc_dp_get_serdes_rate_cfg(dp); | 350 | ret = hibmc_dp_get_serdes_rate_cfg(dp); |
| 341 | if (ret < 0) | 351 | if (ret < 0) |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | DEFINE_DRM_GEM_FOPS(hibmc_fops); | 33 | DEFINE_DRM_GEM_FOPS(hibmc_fops); |
| 34 | 34 | ||
| 35 | static const char *g_irqs_names_map[HIBMC_MAX_VECTORS] = { "vblank", "hpd" }; | 35 | static const char *g_irqs_names_map[HIBMC_MAX_VECTORS] = { "hibmc-vblank", "hibmc-hpd" }; |
| 36 | 36 | ||
| 37 | static irqreturn_t hibmc_interrupt(int irq, void *arg) | 37 | static irqreturn_t hibmc_interrupt(int irq, void *arg) |
| 38 | { | 38 | { |
| @@ -115,6 +115,8 @@ static const struct drm_mode_config_funcs hibmc_mode_funcs = { · 76 unmodified lines | |||
| 115 | static int hibmc_kms_init(struct hibmc_drm_private *priv) | 115 | static int hibmc_kms_init(struct hibmc_drm_private *priv) |
| 116 | { | 116 | { |
| 117 | struct drm_device *dev = &priv->dev; | 117 | struct drm_device *dev = &priv->dev; |
| 118 | struct drm_encoder *encoder; | ||
| 119 | u32 clone_mask = 0; | ||
| 118 | int ret; | 120 | int ret; |
| 119 | 121 | ||
| 120 | ret = drmm_mode_config_init(dev); | 122 | ret = drmm_mode_config_init(dev); |
| @@ -154,6 +156,12 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) · 33 unmodified lines | |||
| 154 | return ret; | 156 | return ret; |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 159 | drm_for_each_encoder(encoder, dev) | ||
| 160 | clone_mask |= drm_encoder_mask(encoder); | ||
| 161 | |||
| 162 | drm_for_each_encoder(encoder, dev) | ||
| 163 | encoder->possible_clones = clone_mask; | ||
| 164 | |||
| 157 | return 0; | 165 | return 0; |
| 158 | } | 166 | } |
| 159 | 167 | ||
| @@ -277,7 +285,6 @@ static void hibmc_unload(struct drm_device *dev) · 117 unmodified lines | |||
| 277 | static int hibmc_msi_init(struct drm_device *dev) | 285 | static int hibmc_msi_init(struct drm_device *dev) |
| 278 | { | 286 | { |
| 279 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 287 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
| 280 | char name[32] = {0}; | ||
| 281 | int valid_irq_num; | 288 | int valid_irq_num; |
| 282 | int irq; | 289 | int irq; |
| 283 | int ret; | 290 | int ret; |
| @@ -292,9 +299,6 @@ static int hibmc_msi_init(struct drm_device *dev) · 8 unmodified lines | |||
| 292 | valid_irq_num = ret; | 299 | valid_irq_num = ret; |
| 293 | 300 | ||
| 294 | for (int i = 0; i < valid_irq_num; i++) { | 301 | for (int i = 0; i < valid_irq_num; i++) { |
| 295 | snprintf(name, ARRAY_SIZE(name) - 1, "%s-%s-%s", | ||
| 296 | dev->driver->name, pci_name(pdev), g_irqs_names_map[i]); | ||
| 297 | |||
| 298 | irq = pci_irq_vector(pdev, i); | 302 | irq = pci_irq_vector(pdev, i); |
| 299 | 303 | ||
| 300 | if (i) | 304 | if (i) |
| @@ -302,10 +306,10 @@ static int hibmc_msi_init(struct drm_device *dev) · 1 unmodified line | |||
| 302 | ret = devm_request_threaded_irq(&pdev->dev, irq, | 306 | ret = devm_request_threaded_irq(&pdev->dev, irq, |
| 303 | hibmc_dp_interrupt, | 307 | hibmc_dp_interrupt, |
| 304 | hibmc_dp_hpd_isr, | 308 | hibmc_dp_hpd_isr, |
| 305 | IRQF_SHARED, name, dev); | 309 | IRQF_SHARED, g_irqs_names_map[i], dev); |
| 306 | else | 310 | else |
| 307 | ret = devm_request_irq(&pdev->dev, irq, hibmc_interrupt, | 311 | ret = devm_request_irq(&pdev->dev, irq, hibmc_interrupt, |
| 308 | IRQF_SHARED, name, dev); | 312 | IRQF_SHARED, g_irqs_names_map[i], dev); |
| 309 | if (ret) { | 313 | if (ret) { |
| 310 | drm_err(dev, "install irq failed: %d\n", ret); | 314 | drm_err(dev, "install irq failed: %d\n", ret); |
| 311 | return ret; | 315 | return ret; |
| @@ -323,13 +327,13 @@ static int hibmc_load(struct drm_device *dev) · 11 unmodified lines | |||
| 323 | 327 | ||
| 324 | ret = hibmc_hw_init(priv); | 328 | ret = hibmc_hw_init(priv); |
| 325 | if (ret) | 329 | if (ret) |
| 326 | goto err; | 330 | return ret; |
| 327 | 331 | ||
| 328 | ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), | 332 | ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), |
| 329 | pci_resource_len(pdev, 0)); | 333 | pci_resource_len(pdev, 0)); |
| 330 | if (ret) { | 334 | if (ret) { |
| 331 | drm_err(dev, "Error initializing VRAM MM; %d\n", ret); | 335 | drm_err(dev, "Error initializing VRAM MM; %d\n", ret); |
| 332 | goto err; | 336 | return ret; |
| 333 | } | 337 | } |
| 334 | 338 | ||
| 335 | ret = hibmc_kms_init(priv); | 339 | ret = hibmc_kms_init(priv); |
| @@ -69,6 +69,7 @@ int hibmc_de_init(struct hibmc_drm_private *priv); · 68 unmodified lines | |||
| 69 | int hibmc_vdac_init(struct hibmc_drm_private *priv); | 69 | int hibmc_vdac_init(struct hibmc_drm_private *priv); |
| 70 | 70 | ||
| 71 | int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connector); | 71 | int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connector); |
| 72 | void hibmc_ddc_del(struct hibmc_vdac *vdac); | ||
| 72 | 73 | ||
| 73 | int hibmc_dp_init(struct hibmc_drm_private *priv); | 74 | int hibmc_dp_init(struct hibmc_drm_private *priv); |
| 74 | 75 | ||
| @@ -95,3 +95,8 @@ int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac) · 94 unmodified lines | |||
| 95 | 95 | ||
| 96 | return i2c_bit_add_bus(&vdac->adapter); | 96 | return i2c_bit_add_bus(&vdac->adapter); |
| 97 | } | 97 | } |
| 98 | |||
| 99 | void hibmc_ddc_del(struct hibmc_vdac *vdac) | ||
| 100 | { | ||
| 101 | i2c_del_adapter(&vdac->adapter); | ||
| 102 | } | ||
| @@ -53,7 +53,7 @@ static void hibmc_connector_destroy(struct drm_connector *connector) · 52 unmodified lines | |||
| 53 | { | 53 | { |
| 54 | struct hibmc_vdac *vdac = to_hibmc_vdac(connector); | 54 | struct hibmc_vdac *vdac = to_hibmc_vdac(connector); |
| 55 | 55 | ||
| 56 | i2c_del_adapter(&vdac->adapter); | 56 | hibmc_ddc_del(vdac); |
| 57 | drm_connector_cleanup(connector); | 57 | drm_connector_cleanup(connector); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| @@ -110,7 +110,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) · 50 unmodified lines | |||
| 110 | ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_DAC, NULL); | 110 | ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_DAC, NULL); |
| 111 | if (ret) { | 111 | if (ret) { |
| 112 | drm_err(dev, "failed to init encoder: %d\n", ret); | 112 | drm_err(dev, "failed to init encoder: %d\n", ret); |
| 113 | return ret; | 113 | goto err; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); | 116 | drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); |
| @@ -121,7 +121,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) · 4 unmodified lines | |||
| 121 | &vdac->adapter); | 121 | &vdac->adapter); |
| 122 | if (ret) { | 122 | if (ret) { |
| 123 | drm_err(dev, "failed to init connector: %d\n", ret); | 123 | drm_err(dev, "failed to init connector: %d\n", ret); |
| 124 | return ret; | 124 | goto err; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | drm_connector_helper_add(connector, &hibmc_connector_helper_funcs); | 127 | drm_connector_helper_add(connector, &hibmc_connector_helper_funcs); |
| @@ -131,4 +131,9 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) · 3 unmodified lines | |||
| 131 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | 131 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
| 132 | 132 | ||
| 133 | return 0; | 133 | return 0; |
| 134 | |||
| 135 | err: | ||
| 136 | hibmc_ddc_del(vdac); | ||
| 137 | |||
| 138 | return ret; | ||
| 134 | } | 139 | } |
| @@ -1506,10 +1506,14 @@ u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl) · 1505 unmodified lines | |||
| 1506 | if (!(master_ctl & GEN11_GU_MISC_IRQ)) | 1506 | if (!(master_ctl & GEN11_GU_MISC_IRQ)) |
| 1507 | return 0; | 1507 | return 0; |
| 1508 | 1508 | ||
| 1509 | intel_display_rpm_assert_block(display); | ||
| 1510 | |||
| 1509 | iir = intel_de_read(display, GEN11_GU_MISC_IIR); | 1511 | iir = intel_de_read(display, GEN11_GU_MISC_IIR); |
| 1510 | if (likely(iir)) | 1512 | if (likely(iir)) |
| 1511 | intel_de_write(display, GEN11_GU_MISC_IIR, iir); | 1513 | intel_de_write(display, GEN11_GU_MISC_IIR, iir); |
| 1512 | 1514 | ||
| 1515 | intel_display_rpm_assert_unblock(display); | ||
| 1516 | |||
| 1513 | return iir; | 1517 | return iir; |
| 1514 | } | 1518 | } |
| 1515 | 1519 | ||
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #include "intel_modeset_lock.h" | 23 | #include "intel_modeset_lock.h" |
| 24 | #include "intel_tc.h" | 24 | #include "intel_tc.h" |
| 25 | 25 | ||
| 26 | #define DP_PIN_ASSIGNMENT_NONE 0x0 | ||
| 26 | #define DP_PIN_ASSIGNMENT_C 0x3 | 27 | #define DP_PIN_ASSIGNMENT_C 0x3 |
| 27 | #define DP_PIN_ASSIGNMENT_D 0x4 | 28 | #define DP_PIN_ASSIGNMENT_D 0x4 |
| 28 | #define DP_PIN_ASSIGNMENT_E 0x5 | 29 | #define DP_PIN_ASSIGNMENT_E 0x5 |
| @@ -66,6 +67,7 @@ struct intel_tc_port { · 37 unmodified lines | |||
| 66 | enum tc_port_mode init_mode; | 67 | enum tc_port_mode init_mode; |
| 67 | enum phy_fia phy_fia; | 68 | enum phy_fia phy_fia; |
| 68 | u8 phy_fia_idx; | 69 | u8 phy_fia_idx; |
| 70 | u8 max_lane_count; | ||
| 69 | }; | 71 | }; |
| 70 | 72 | ||
| 71 | static enum intel_display_power_domain | 73 | static enum intel_display_power_domain |
| @@ -307,6 +309,8 @@ static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) · 235 unmodified lines | |||
| 307 | REG_FIELD_GET(TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK, val); | 309 | REG_FIELD_GET(TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK, val); |
| 308 | 310 | ||
| 309 | switch (pin_assignment) { | 311 | switch (pin_assignment) { |
| 312 | case DP_PIN_ASSIGNMENT_NONE: | ||
| 313 | return 0; | ||
| 310 | default: | 314 | default: |
| 311 | MISSING_CASE(pin_assignment); | 315 | MISSING_CASE(pin_assignment); |
| 312 | fallthrough; | 316 | fallthrough; |
| @@ -365,12 +369,12 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) · 52 unmodified lines | |||
| 365 | } | 369 | } |
| 366 | } | 370 | } |
| 367 | 371 | ||
| 368 | int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) | 372 | static int get_max_lane_count(struct intel_tc_port *tc) |
| 369 | { | 373 | { |
| 370 | struct intel_display *display = to_intel_display(dig_port); | 374 | struct intel_display *display = to_intel_display(tc->dig_port); |
| 371 | struct intel_tc_port *tc = to_tc_port(dig_port); | 375 | struct intel_digital_port *dig_port = tc->dig_port; |
| 372 | 376 | ||
| 373 | if (!intel_encoder_is_tc(&dig_port->base) || tc->mode != TC_PORT_DP_ALT) | 377 | if (tc->mode != TC_PORT_DP_ALT) |
| 374 | return 4; | 378 | return 4; |
| 375 | 379 | ||
| 376 | assert_tc_cold_blocked(tc); | 380 | assert_tc_cold_blocked(tc); |
| @@ -384,6 +388,25 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) · 7 unmodified lines | |||
| 384 | return intel_tc_port_get_max_lane_count(dig_port); | 388 | return intel_tc_port_get_max_lane_count(dig_port); |
| 385 | } | 389 | } |
| 386 | 390 | ||
| 391 | static void read_pin_configuration(struct intel_tc_port *tc) | ||
| 392 | { | ||
| 393 | tc->max_lane_count = get_max_lane_count(tc); | ||
| 394 | } | ||
| 395 | |||
| 396 | int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) | ||
| 397 | { | ||
| 398 | struct intel_display *display = to_intel_display(dig_port); | ||
| 399 | struct intel_tc_port *tc = to_tc_port(dig_port); | ||
| 400 | |||
| 401 | if (!intel_encoder_is_tc(&dig_port->base)) | ||
| 402 | return 4; | ||
| 403 | |||
| 404 | if (DISPLAY_VER(display) < 20) | ||
| 405 | return get_max_lane_count(tc); | ||
| 406 | |||
| 407 | return tc->max_lane_count; | ||
| 408 | } | ||
| 409 | |||
| 387 | void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, | 410 | void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, |
| 388 | int required_lanes) | 411 | int required_lanes) |
| 389 | { | 412 | { |
| @@ -596,9 +619,12 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) · 206 unmodified lines | |||
| 596 | tc_cold_wref = __tc_cold_block(tc, &domain); | 619 | tc_cold_wref = __tc_cold_block(tc, &domain); |
| 597 | 620 | ||
| 598 | tc->mode = tc_phy_get_current_mode(tc); | 621 | tc->mode = tc_phy_get_current_mode(tc); |
| 599 | if (tc->mode != TC_PORT_DISCONNECTED) | 622 | if (tc->mode != TC_PORT_DISCONNECTED) { |
| 600 | tc->lock_wakeref = tc_cold_block(tc); | 623 | tc->lock_wakeref = tc_cold_block(tc); |
| 601 | 624 | ||
| 625 | read_pin_configuration(tc); | ||
| 626 | } | ||
| 627 | |||
| 602 | __tc_cold_unblock(tc, domain, tc_cold_wref); | 628 | __tc_cold_unblock(tc, domain, tc_cold_wref); |
| 603 | } | 629 | } |
| 604 | 630 | ||
| @@ -656,8 +682,11 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, · 51 unmodified lines | |||
| 656 | 682 | ||
| 657 | tc->lock_wakeref = tc_cold_block(tc); | 683 | tc->lock_wakeref = tc_cold_block(tc); |
| 658 | 684 | ||
| 659 | if (tc->mode == TC_PORT_TBT_ALT) | 685 | if (tc->mode == TC_PORT_TBT_ALT) { |
| 686 | read_pin_configuration(tc); | ||
| 687 | |||
| 660 | return true; | 688 | return true; |
| 689 | } | ||
| 661 | 690 | ||
| 662 | if ((!tc_phy_is_ready(tc) || | 691 | if ((!tc_phy_is_ready(tc) || |
| 663 | !icl_tc_phy_take_ownership(tc, true)) && | 692 | !icl_tc_phy_take_ownership(tc, true)) && |
| @@ -668,6 +697,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, · 4 unmodified lines | |||
| 668 | goto out_unblock_tc_cold; | 697 | goto out_unblock_tc_cold; |
| 669 | } | 698 | } |
| 670 | 699 | ||
| 700 | read_pin_configuration(tc); | ||
| 671 | 701 | ||
| 672 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) | 702 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) |
| 673 | goto out_release_phy; | 703 | goto out_release_phy; |
| @@ -858,9 +888,12 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc) · 184 unmodified lines | |||
| 858 | port_wakeref = intel_display_power_get(display, port_power_domain); | 888 | port_wakeref = intel_display_power_get(display, port_power_domain); |
| 859 | 889 | ||
| 860 | tc->mode = tc_phy_get_current_mode(tc); | 890 | tc->mode = tc_phy_get_current_mode(tc); |
| 861 | if (tc->mode != TC_PORT_DISCONNECTED) | 891 | if (tc->mode != TC_PORT_DISCONNECTED) { |
| 862 | tc->lock_wakeref = tc_cold_block(tc); | 892 | tc->lock_wakeref = tc_cold_block(tc); |
| 863 | 893 | ||
| 894 | read_pin_configuration(tc); | ||
| 895 | } | ||
| 896 | |||
| 864 | intel_display_power_put(display, port_power_domain, port_wakeref); | 897 | intel_display_power_put(display, port_power_domain, port_wakeref); |
| 865 | } | 898 | } |
| 866 | 899 | ||
| @@ -873,6 +906,9 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) · 6 unmodified lines | |||
| 873 | 906 | ||
| 874 | if (tc->mode == TC_PORT_TBT_ALT) { | 907 | if (tc->mode == TC_PORT_TBT_ALT) { |
| 875 | tc->lock_wakeref = tc_cold_block(tc); | 908 | tc->lock_wakeref = tc_cold_block(tc); |
| 909 | |||
| 910 | read_pin_configuration(tc); | ||
| 911 | |||
| 876 | return true; | 912 | return true; |
| 877 | } | 913 | } |
| 878 | 914 | ||
| @@ -894,6 +930,8 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) · 15 unmodified lines | |||
| 894 | 930 | ||
| 895 | tc->lock_wakeref = tc_cold_block(tc); | 931 | tc->lock_wakeref = tc_cold_block(tc); |
| 896 | 932 | ||
| 933 | read_pin_configuration(tc); | ||
| 934 | |||
| 897 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) | 935 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) |
| 898 | goto out_unblock_tc_cold; | 936 | goto out_unblock_tc_cold; |
| 899 | 937 | ||
| @@ -1124,9 +1162,18 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc) · 224 unmodified lines | |||
| 1124 | tc_cold_wref = __tc_cold_block(tc, &domain); | 1162 | tc_cold_wref = __tc_cold_block(tc, &domain); |
| 1125 | 1163 | ||
| 1126 | tc->mode = tc_phy_get_current_mode(tc); | 1164 | tc->mode = tc_phy_get_current_mode(tc); |
| 1127 | if (tc->mode != TC_PORT_DISCONNECTED) | 1165 | if (tc->mode != TC_PORT_DISCONNECTED) { |
| 1128 | tc->lock_wakeref = tc_cold_block(tc); | 1166 | tc->lock_wakeref = tc_cold_block(tc); |
| 1129 | 1167 | ||
| 1168 | read_pin_configuration(tc); | ||
| 1169 | /* | ||
| 1170 | * Set a valid lane count value for a DP-alt sink which got | ||
| 1171 | * disconnected. The driver can only disable the output on this PHY. | ||
| 1172 | */ | ||
| 1173 | if (tc->max_lane_count == 0) | ||
| 1174 | tc->max_lane_count = 4; | ||
| 1175 | } | ||
| 1176 | |||
| 1130 | drm_WARN_ON(display->drm, | 1177 | drm_WARN_ON(display->drm, |
| 1131 | (tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) && | 1178 | (tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) && |
| 1132 | !xelpdp_tc_phy_tcss_power_is_enabled(tc)); | 1179 | !xelpdp_tc_phy_tcss_power_is_enabled(tc)); |
| @@ -1138,14 +1185,19 @@ static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) · 5 unmodified lines | |||
| 1138 | { | 1185 | { |
| 1139 | tc->lock_wakeref = tc_cold_block(tc); | 1186 | tc->lock_wakeref = tc_cold_block(tc); |
| 1140 | 1187 | ||
| 1141 | if (tc->mode == TC_PORT_TBT_ALT) | 1188 | if (tc->mode == TC_PORT_TBT_ALT) { |
| 1189 | read_pin_configuration(tc); | ||
| 1190 | |||
| 1142 | return true; | 1191 | return true; |
| 1192 | } | ||
| 1143 | 1193 | ||
| 1144 | if (!xelpdp_tc_phy_enable_tcss_power(tc, true)) | 1194 | if (!xelpdp_tc_phy_enable_tcss_power(tc, true)) |
| 1145 | goto out_unblock_tccold; | 1195 | goto out_unblock_tccold; |
| 1146 | 1196 | ||
| 1147 | xelpdp_tc_phy_take_ownership(tc, true); | 1197 | xelpdp_tc_phy_take_ownership(tc, true); |
| 1148 | 1198 | ||
| 1199 | read_pin_configuration(tc); | ||
| 1200 | |||
| 1149 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) | 1201 | if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) |
| 1150 | goto out_release_phy; | 1202 | goto out_release_phy; |
| 1151 | 1203 | ||
| @@ -1226,14 +1278,19 @@ static void tc_phy_get_hw_state(struct intel_tc_port *tc) · 74 unmodified lines | |||
| 1226 | tc->phy_ops->get_hw_state(tc); | 1278 | tc->phy_ops->get_hw_state(tc); |
| 1227 | } | 1279 | } |
| 1228 | 1280 | ||
| 1229 | static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, | 1281 | /* Is the PHY owned by display i.e. is it in legacy or DP-alt mode? */ |
| 1230 | bool phy_is_ready, bool phy_is_owned) | 1282 | static bool tc_phy_owned_by_display(struct intel_tc_port *tc, |
| 1283 | bool phy_is_ready, bool phy_is_owned) | ||
| 1231 | { | 1284 | { |
| 1232 | struct intel_display *display = to_intel_display(tc->dig_port); | 1285 | struct intel_display *display = to_intel_display(tc->dig_port); |
| 1233 | 1286 | ||
| 1234 | drm_WARN_ON(display->drm, phy_is_owned && !phy_is_ready); | 1287 | if (DISPLAY_VER(display) < 20) { |
| 1288 | drm_WARN_ON(display->drm, phy_is_owned && !phy_is_ready); | ||
| 1235 | 1289 | ||
| 1236 | return phy_is_ready && phy_is_owned; | 1290 | return phy_is_ready && phy_is_owned; |
| 1291 | } else { | ||
| 1292 | return phy_is_owned; | ||
| 1293 | } | ||
| 1237 | } | 1294 | } |
| 1238 | 1295 | ||
| 1239 | static bool tc_phy_is_connected(struct intel_tc_port *tc, | 1296 | static bool tc_phy_is_connected(struct intel_tc_port *tc, |
| @@ -1244,7 +1301,7 @@ static bool tc_phy_is_connected(struct intel_tc_port *tc, · 4 unmodified lines | |||
| 1244 | bool phy_is_owned = tc_phy_is_owned(tc); | 1301 | bool phy_is_owned = tc_phy_is_owned(tc); |
| 1245 | bool is_connected; | 1302 | bool is_connected; |
| 1246 | 1303 | ||
| 1247 | if (tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) | 1304 | if (tc_phy_owned_by_display(tc, phy_is_ready, phy_is_owned)) |
| 1248 | is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY; | 1305 | is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY; |
| 1249 | else | 1306 | else |
| 1250 | is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT; | 1307 | is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT; |
| @@ -1352,7 +1409,7 @@ tc_phy_get_current_mode(struct intel_tc_port *tc) · 101 unmodified lines | |||
| 1352 | phy_is_ready = tc_phy_is_ready(tc); | 1409 | phy_is_ready = tc_phy_is_ready(tc); |
| 1353 | phy_is_owned = tc_phy_is_owned(tc); | 1410 | phy_is_owned = tc_phy_is_owned(tc); |
| 1354 | 1411 | ||
| 1355 | if (!tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) { | 1412 | if (!tc_phy_owned_by_display(tc, phy_is_ready, phy_is_owned)) { |
| 1356 | mode = get_tc_mode_in_phy_not_owned_state(tc, live_mode); | 1413 | mode = get_tc_mode_in_phy_not_owned_state(tc, live_mode); |
| 1357 | } else { | 1414 | } else { |
| 1358 | drm_WARN_ON(display->drm, live_mode == TC_PORT_TBT_ALT); | 1415 | drm_WARN_ON(display->drm, live_mode == TC_PORT_TBT_ALT); |
| @@ -1441,11 +1498,11 @@ static void intel_tc_port_reset_mode(struct intel_tc_port *tc, · 82 unmodified lines | |||
| 1441 | intel_display_power_flush_work(display); | 1498 | intel_display_power_flush_work(display); |
| 1442 | if (!intel_tc_cold_requires_aux_pw(dig_port)) { | 1499 | if (!intel_tc_cold_requires_aux_pw(dig_port)) { |
| 1443 | enum intel_display_power_domain aux_domain; | 1500 | enum intel_display_power_domain aux_domain; |
| 1444 | bool aux_powered; | ||
| 1445 | 1501 | ||
| 1446 | aux_domain = intel_aux_power_domain(dig_port); | 1502 | aux_domain = intel_aux_power_domain(dig_port); |
| 1447 | aux_powered = intel_display_power_is_enabled(display, aux_domain); | 1503 | if (intel_display_power_is_enabled(display, aux_domain)) |
| 1448 | drm_WARN_ON(display->drm, aux_powered); | 1504 | drm_dbg_kms(display->drm, "Port %s: AUX unexpectedly powered\n", |
| 1505 | tc->port_name); | ||
| 1449 | } | 1506 | } |
| 1450 | 1507 | ||
| 1451 | tc_phy_disconnect(tc); | 1508 | tc_phy_disconnect(tc); |
| @@ -634,6 +634,8 @@ static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine, · 633 unmodified lines | |||
| 634 | static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, | 634 | static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, |
| 635 | struct i915_wa_list *wal) | 635 | struct i915_wa_list *wal) |
| 636 | { | 636 | { |
| 637 | struct drm_i915_private *i915 = engine->i915; | ||
| 638 | |||
| 637 | /* Wa_1406697149 (WaDisableBankHangMode:icl) */ | 639 | /* Wa_1406697149 (WaDisableBankHangMode:icl) */ |
| 638 | wa_write(wal, GEN8_L3CNTLREG, GEN8_ERRDETBCTRL); | 640 | wa_write(wal, GEN8_L3CNTLREG, GEN8_ERRDETBCTRL); |
| 639 | 641 | ||
| @@ -669,6 +671,15 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, · 29 unmodified lines | |||
| 669 | 671 | ||
| 670 | /* Wa_1406306137:icl,ehl */ | 672 | /* Wa_1406306137:icl,ehl */ |
| 671 | wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, GEN11_DIS_PICK_2ND_EU); | 673 | wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, GEN11_DIS_PICK_2ND_EU); |
| 674 | |||
| 675 | if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) { | ||
| 676 | /* | ||
| 677 | * Disable Repacking for Compression (masked R/W access) | ||
| 678 | * before rendering compressed surfaces for display. | ||
| 679 | */ | ||
| 680 | wa_masked_en(wal, CACHE_MODE_0_GEN7, | ||
| 681 | DISABLE_REPACKING_FOR_COMPRESSION); | ||
| 682 | } | ||
| 672 | } | 683 | } |
| 673 | 684 | ||
| 674 | /* | 685 | /* |
| @@ -2306,15 +2317,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) · 1631 unmodified lines | |||
| 2306 | GEN8_RC_SEMA_IDLE_MSG_DISABLE); | 2317 | GEN8_RC_SEMA_IDLE_MSG_DISABLE); |
| 2307 | } | 2318 | } |
| 2308 | 2319 | ||
| 2309 | if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) { | ||
| 2310 | /* | ||
| 2311 | * "Disable Repacking for Compression (masked R/W access) | ||
| 2312 | * before rendering compressed surfaces for display." | ||
| 2313 | */ | ||
| 2314 | wa_masked_en(wal, CACHE_MODE_0_GEN7, | ||
| 2315 | DISABLE_REPACKING_FOR_COMPRESSION); | ||
| 2316 | } | ||
| 2317 | |||
| 2318 | if (GRAPHICS_VER(i915) == 11) { | 2320 | if (GRAPHICS_VER(i915) == 11) { |
| 2319 | /* This is not an Wa. Enable for better image quality */ | 2321 | /* This is not an Wa. Enable for better image quality */ |
| 2320 | wa_masked_en(wal, | 2322 | wa_masked_en(wal, |
| @@ -60,14 +60,14 @@ · 59 unmodified lines | |||
| 60 | * virtual address in the GPU's VA space there is no guarantee that the actual | 60 | * virtual address in the GPU's VA space there is no guarantee that the actual |
| 61 | * mappings are created in the GPU's MMU. If the given memory is swapped out | 61 | * mappings are created in the GPU's MMU. If the given memory is swapped out |
| 62 | * at the time the bind operation is executed the kernel will stash the mapping | 62 | * at the time the bind operation is executed the kernel will stash the mapping |
| 63 | * details into it's internal alloctor and create the actual MMU mappings once | 63 | * details into it's internal allocator and create the actual MMU mappings once |
| 64 | * the memory is swapped back in. While this is transparent for userspace, it is | 64 | * the memory is swapped back in. While this is transparent for userspace, it is |
| 65 | * guaranteed that all the backing memory is swapped back in and all the memory | 65 | * guaranteed that all the backing memory is swapped back in and all the memory |
| 66 | * mappings, as requested by userspace previously, are actually mapped once the | 66 | * mappings, as requested by userspace previously, are actually mapped once the |
| 67 | * DRM_NOUVEAU_EXEC ioctl is called to submit an exec job. | 67 | * DRM_NOUVEAU_EXEC ioctl is called to submit an exec job. |
| 68 | * | 68 | * |
| 69 | * A VM_BIND job can be executed either synchronously or asynchronously. If | 69 | * A VM_BIND job can be executed either synchronously or asynchronously. If |
| 70 | * exectued asynchronously, userspace may provide a list of syncobjs this job | 70 | * executed asynchronously, userspace may provide a list of syncobjs this job |
| 71 | * will wait for and/or a list of syncobj the kernel will signal once the | 71 | * will wait for and/or a list of syncobj the kernel will signal once the |
| 72 | * VM_BIND job finished execution. If executed synchronously the ioctl will | 72 | * VM_BIND job finished execution. If executed synchronously the ioctl will |
| 73 | * block until the bind job is finished. For synchronous jobs the kernel will | 73 | * block until the bind job is finished. For synchronous jobs the kernel will |
| @@ -82,7 +82,7 @@ · 8 unmodified lines | |||
| 82 | * Since VM_BIND jobs update the GPU's VA space on job submit, EXEC jobs do have | 82 | * Since VM_BIND jobs update the GPU's VA space on job submit, EXEC jobs do have |
| 83 | * an up to date view of the VA space. However, the actual mappings might still | 83 | * an up to date view of the VA space. However, the actual mappings might still |
| 84 | * be pending. Hence, EXEC jobs require to have the particular fences - of | 84 | * be pending. Hence, EXEC jobs require to have the particular fences - of |
| 85 | * the corresponding VM_BIND jobs they depent on - attached to them. | 85 | * the corresponding VM_BIND jobs they depend on - attached to them. |
| 86 | */ | 86 | */ |
| 87 | 87 | ||
| 88 | static int | 88 | static int |
| @@ -219,7 +219,8 @@ nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass, · 218 unmodified lines | |||
| 219 | case RAW: args->type = NVIF_VMM_V0_TYPE_RAW; break; | 219 | case RAW: args->type = NVIF_VMM_V0_TYPE_RAW; break; |
| 220 | default: | 220 | default: |
| 221 | WARN_ON(1); | 221 | WARN_ON(1); |
| 222 | return -EINVAL; | 222 | ret = -EINVAL; |
| 223 | goto done; | ||
| 223 | } | 224 | } |
| 224 | 225 | ||
| 225 | memcpy(args->data, argv, argc); | 226 | memcpy(args->data, argv, argc); |
| @@ -325,7 +325,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) · 324 unmodified lines | |||
| 325 | 325 | ||
| 326 | rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); | 326 | rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries); |
| 327 | if (IS_ERR_OR_NULL(rpc)) { | 327 | if (IS_ERR_OR_NULL(rpc)) { |
| 328 | kfree(buf); | 328 | kvfree(buf); |
| 329 | return rpc; | 329 | return rpc; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| @@ -334,7 +334,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries) · 2 unmodified lines | |||
| 334 | 334 | ||
| 335 | rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); | 335 | rpc = r535_gsp_msgq_recv_one_elem(gsp, &info); |
| 336 | if (IS_ERR_OR_NULL(rpc)) { | 336 | if (IS_ERR_OR_NULL(rpc)) { |
| 337 | kfree(buf); | 337 | kvfree(buf); |
| 338 | return rpc; | 338 | return rpc; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| @@ -39,7 +39,8 @@ impl File { · 38 unmodified lines | |||
| 39 | _ => return Err(EINVAL), | 39 | _ => return Err(EINVAL), |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | getparam.set_value(value); | 42 | #[allow(clippy::useless_conversion)] |
| 43 | getparam.set_value(value.into()); | ||
| 43 | 44 | ||
| 44 | Ok(0) | 45 | Ok(0) |
| 45 | } | 46 | } |
| @@ -53,6 +53,7 @@ config ROCKCHIP_CDN_DP · 52 unmodified lines | |||
| 53 | bool "Rockchip cdn DP" | 53 | bool "Rockchip cdn DP" |
| 54 | depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m) | 54 | depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m) |
| 55 | select DRM_DISPLAY_HELPER | 55 | select DRM_DISPLAY_HELPER |
| 56 | select DRM_BRIDGE_CONNECTOR | ||
| 56 | select DRM_DISPLAY_DP_HELPER | 57 | select DRM_DISPLAY_DP_HELPER |
| 57 | help | 58 | help |
| 58 | This selects support for Rockchip SoC specific extensions | 59 | This selects support for Rockchip SoC specific extensions |
| @@ -2579,12 +2579,13 @@ static int vop2_win_init(struct vop2 *vop2) · 2578 unmodified lines | |||
| 2579 | } | 2579 | } |
| 2580 | 2580 | ||
| 2581 | /* | 2581 | /* |
| 2582 | * The window registers are only updated when config done is written. | 2582 | * The window and video port registers are only updated when config |
| 2583 | * Until that they read back the old value. As we read-modify-write | 2583 | * done is written. Until that they read back the old value. As we |
| 2584 | * these registers mark them as non-volatile. This makes sure we read | 2584 | * read-modify-write these registers mark them as non-volatile. This |
| 2585 | * the new values from the regmap register cache. | 2585 | * makes sure we read the new values from the regmap register cache. |
| 2586 | */ | 2586 | */ |
| 2587 | static const struct regmap_range vop2_nonvolatile_range[] = { | 2587 | static const struct regmap_range vop2_nonvolatile_range[] = { |
| 2588 | regmap_reg_range(RK3568_VP0_CTRL_BASE, RK3588_VP3_CTRL_BASE + 255), | ||
| 2588 | regmap_reg_range(0x1000, 0x23ff), | 2589 | regmap_reg_range(0x1000, 0x23ff), |
| 2589 | }; | 2590 | }; |
| 2590 | 2591 | ||
| @@ -1033,13 +1033,14 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) · 1032 unmodified lines | |||
| 1033 | NULL : &result->dst_pitch; | 1033 | NULL : &result->dst_pitch; |
| 1034 | 1034 | ||
| 1035 | drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); | 1035 | drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); |
| 1036 | buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32)); | 1036 | buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); |
| 1037 | KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); | 1037 | KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); |
| 1038 | 1038 | ||
| 1039 | buf = dst.vaddr; /* restore original value of buf */ | 1039 | buf = dst.vaddr; /* restore original value of buf */ |
| 1040 | memset(buf, 0, dst_size); | 1040 | memset(buf, 0, dst_size); |
| 1041 | 1041 | ||
| 1042 | drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); | 1042 | drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); |
| 1043 | buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); | ||
| 1043 | KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); | 1044 | KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); |
| 1044 | } | 1045 | } |
| 1045 | 1046 | ||
| @@ -408,7 +408,7 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile) · 407 unmodified lines | |||
| 408 | 408 | ||
| 409 | /* Special layout, prepared below.. */ | 409 | /* Special layout, prepared below.. */ |
| 410 | vm = xe_vm_create(xe, XE_VM_FLAG_MIGRATION | | 410 | vm = xe_vm_create(xe, XE_VM_FLAG_MIGRATION | |
| 411 | XE_VM_FLAG_SET_TILE_ID(tile)); | 411 | XE_VM_FLAG_SET_TILE_ID(tile), NULL); |
| 412 | if (IS_ERR(vm)) | 412 | if (IS_ERR(vm)) |
| 413 | return ERR_CAST(vm); | 413 | return ERR_CAST(vm); |
| 414 | 414 | ||
| @@ -101,7 +101,7 @@ static int allocate_gsc_client_resources(struct xe_gt *gt, · 100 unmodified lines | |||
| 101 | xe_assert(xe, hwe); | 101 | xe_assert(xe, hwe); |
| 102 | 102 | ||
| 103 | /* PXP instructions must be issued from PPGTT */ | 103 | /* PXP instructions must be issued from PPGTT */ |
| 104 | vm = xe_vm_create(xe, XE_VM_FLAG_GSC); | 104 | vm = xe_vm_create(xe, XE_VM_FLAG_GSC, NULL); |
| 105 | if (IS_ERR(vm)) | 105 | if (IS_ERR(vm)) |
| 106 | return PTR_ERR(vm); | 106 | return PTR_ERR(vm); |
| 107 | 107 | ||
| @@ -1640,7 +1640,7 @@ static void xe_vm_free_scratch(struct xe_vm *vm) · 1639 unmodified lines | |||
| 1640 | } | 1640 | } |
| 1641 | } | 1641 | } |
| 1642 | 1642 | ||
| 1643 | struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) | 1643 | struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file *xef) |
| 1644 | { | 1644 | { |
| 1645 | struct drm_gem_object *vm_resv_obj; | 1645 | struct drm_gem_object *vm_resv_obj; |
| 1646 | struct xe_vm *vm; | 1646 | struct xe_vm *vm; |
| @@ -1661,9 +1661,10 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) · 14 unmodified lines | |||
| 1661 | vm->xe = xe; | 1661 | vm->xe = xe; |
| 1662 | 1662 | ||
| 1663 | vm->size = 1ull << xe->info.va_bits; | 1663 | vm->size = 1ull << xe->info.va_bits; |
| 1664 | |||
| 1665 | vm->flags = flags; | 1664 | vm->flags = flags; |
| 1666 | 1665 | ||
| 1666 | if (xef) | ||
| 1667 | vm->xef = xe_file_get(xef); | ||
| 1667 | /** | 1668 | /** |
| 1668 | * GSC VMs are kernel-owned, only used for PXP ops and can sometimes be | 1669 | * GSC VMs are kernel-owned, only used for PXP ops and can sometimes be |
| 1669 | * manipulated under the PXP mutex. However, the PXP mutex can be taken | 1670 | * manipulated under the PXP mutex. However, the PXP mutex can be taken |
| @@ -1794,6 +1795,20 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) · 124 unmodified lines | |||
| 1794 | if (number_tiles > 1) | 1795 | if (number_tiles > 1) |
| 1795 | vm->composite_fence_ctx = dma_fence_context_alloc(1); | 1796 | vm->composite_fence_ctx = dma_fence_context_alloc(1); |
| 1796 | 1797 | ||
| 1798 | if (xef && xe->info.has_asid) { | ||
| 1799 | u32 asid; | ||
| 1800 | |||
| 1801 | down_write(&xe->usm.lock); | ||
| 1802 | err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, | ||
| 1803 | XA_LIMIT(1, XE_MAX_ASID - 1), | ||
| 1804 | &xe->usm.next_asid, GFP_KERNEL); | ||
| 1805 | up_write(&xe->usm.lock); | ||
| 1806 | if (err < 0) | ||
| 1807 | goto err_unlock_close; | ||
| 1808 | |||
| 1809 | vm->usm.asid = asid; | ||
| 1810 | } | ||
| 1811 | |||
| 1797 | trace_xe_vm_create(vm); | 1812 | trace_xe_vm_create(vm); |
| 1798 | 1813 | ||
| 1799 | return vm; | 1814 | return vm; |
| @@ -1814,6 +1829,8 @@ err_no_resv: · 14 unmodified lines | |||
| 1814 | for_each_tile(tile, xe, id) | 1829 | for_each_tile(tile, xe, id) |
| 1815 | xe_range_fence_tree_fini(&vm->rftree[id]); | 1830 | xe_range_fence_tree_fini(&vm->rftree[id]); |
| 1816 | ttm_lru_bulk_move_fini(&xe->ttm, &vm->lru_bulk_move); | 1831 | ttm_lru_bulk_move_fini(&xe->ttm, &vm->lru_bulk_move); |
| 1832 | if (vm->xef) | ||
| 1833 | xe_file_put(vm->xef); | ||
| 1817 | kfree(vm); | 1834 | kfree(vm); |
| 1818 | if (flags & XE_VM_FLAG_LR_MODE) | 1835 | if (flags & XE_VM_FLAG_LR_MODE) |
| 1819 | xe_pm_runtime_put(xe); | 1836 | xe_pm_runtime_put(xe); |
| @@ -2059,9 +2076,8 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 239 unmodified lines | |||
| 2059 | struct xe_device *xe = to_xe_device(dev); | 2076 | struct xe_device *xe = to_xe_device(dev); |
| 2060 | struct xe_file *xef = to_xe_file(file); | 2077 | struct xe_file *xef = to_xe_file(file); |
| 2061 | struct drm_xe_vm_create *args = data; | 2078 | struct drm_xe_vm_create *args = data; |
| 2062 | struct xe_tile *tile; | ||
| 2063 | struct xe_vm *vm; | 2079 | struct xe_vm *vm; |
| 2064 | u32 id, asid; | 2080 | u32 id; |
| 2065 | int err; | 2081 | int err; |
| 2066 | u32 flags = 0; | 2082 | u32 flags = 0; |
| 2067 | 2083 | ||
| @@ -2097,29 +2113,10 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, · 29 unmodified lines | |||
| 2097 | if (args->flags & DRM_XE_VM_CREATE_FLAG_FAULT_MODE) | 2113 | if (args->flags & DRM_XE_VM_CREATE_FLAG_FAULT_MODE) |
| 2098 | flags |= XE_VM_FLAG_FAULT_MODE; | 2114 | flags |= XE_VM_FLAG_FAULT_MODE; |
| 2099 | 2115 | ||
| 2100 | vm = xe_vm_create(xe, flags); | 2116 | vm = xe_vm_create(xe, flags, xef); |
| 2101 | if (IS_ERR(vm)) | 2117 | if (IS_ERR(vm)) |
| 2102 | return PTR_ERR(vm); | 2118 | return PTR_ERR(vm); |
| 2103 | 2119 | ||
| 2104 | if (xe->info.has_asid) { | ||
| 2105 | down_write(&xe->usm.lock); | ||
| 2106 | err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm, | ||
| 2107 | XA_LIMIT(1, XE_MAX_ASID - 1), | ||
| 2108 | &xe->usm.next_asid, GFP_KERNEL); | ||
| 2109 | up_write(&xe->usm.lock); | ||
| 2110 | if (err < 0) | ||
| 2111 | goto err_close_and_put; | ||
| 2112 | |||
| 2113 | vm->usm.asid = asid; | ||
| 2114 | } | ||
| 2115 | |||
| 2116 | vm->xef = xe_file_get(xef); | ||
| 2117 | |||
| 2118 | /* Record BO memory for VM pagetable created against client */ | ||
| 2119 | for_each_tile(tile, xe, id) | ||
| 2120 | if (vm->pt_root[id]) | ||
| 2121 | xe_drm_client_add_bo(vm->xef->client, vm->pt_root[id]->bo); | ||
| 2122 | |||
| 2123 | #if IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEM) | 2120 | #if IS_ENABLED(CONFIG_DRM_XE_DEBUG_MEM) |
| 2124 | /* Warning: Security issue - never enable by default */ | 2121 | /* Warning: Security issue - never enable by default */ |
| 2125 | args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); | 2122 | args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE); |
| @@ -3421,6 +3418,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, · 1295 unmodified lines | |||
| 3421 | free_bind_ops: | 3418 | free_bind_ops: |
| 3422 | if (args->num_binds > 1) | 3419 | if (args->num_binds > 1) |
| 3423 | kvfree(*bind_ops); | 3420 | kvfree(*bind_ops); |
| 3421 | *bind_ops = NULL; | ||
| 3424 | return err; | 3422 | return err; |
| 3425 | } | 3423 | } |
| 3426 | 3424 | ||
| @@ -3527,7 +3525,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) · 100 unmodified lines | |||
| 3527 | struct xe_exec_queue *q = NULL; | 3525 | struct xe_exec_queue *q = NULL; |
| 3528 | u32 num_syncs, num_ufence = 0; | 3526 | u32 num_syncs, num_ufence = 0; |
| 3529 | struct xe_sync_entry *syncs = NULL; | 3527 | struct xe_sync_entry *syncs = NULL; |
| 3530 | struct drm_xe_vm_bind_op *bind_ops; | 3528 | struct drm_xe_vm_bind_op *bind_ops = NULL; |
| 3531 | struct xe_vma_ops vops; | 3529 | struct xe_vma_ops vops; |
| 3532 | struct dma_fence *fence; | 3530 | struct dma_fence *fence; |
| 3533 | int err; | 3531 | int err; |
| @@ -26,7 +26,7 @@ struct xe_sync_entry; · 25 unmodified lines | |||
| 26 | struct xe_svm_range; | 26 | struct xe_svm_range; |
| 27 | struct drm_exec; | 27 | struct drm_exec; |
| 28 | 28 | ||
| 29 | struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags); | 29 | struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct xe_file *xef); |
| 30 | 30 | ||
| 31 | struct xe_vm *xe_vm_lookup(struct xe_file *xef, u32 id); | 31 | struct xe_vm *xe_vm_lookup(struct xe_file *xef, u32 id); |
| 32 | int xe_vma_cmp_vma_cb(const void *key, const struct rb_node *node); | 32 | int xe_vma_cmp_vma_cb(const void *key, const struct rb_node *node); |
| @@ -143,10 +143,10 @@ static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len) · 142 unmodified lines | |||
| 143 | return -EIO; | 143 | return -EIO; |
| 144 | 144 | ||
| 145 | for (i = 0; i < len; i++) { | 145 | for (i = 0; i < len; i++) { |
| 146 | if (i % 4 == 0) | 146 | unsigned int shift = (i % 4) * 8; |
| 147 | vals[i/4] = 0; | 147 | unsigned int reg = i / 4; |
| 148 | vals[i/4] <<= 8; | 148 | |
| 149 | vals[i/4] |= buf[i]; | 149 | vals[reg] |= buf[i] << shift; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, | 152 | return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, |
| @@ -175,7 +175,7 @@ static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write, · 22 unmodified lines | |||
| 175 | return ret; | 175 | return ret; |
| 176 | 176 | ||
| 177 | ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, | 177 | ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, |
| 178 | val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 2000); | 178 | val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 100000); |
| 179 | if (ret) | 179 | if (ret) |
| 180 | return ret; | 180 | return ret; |
| 181 | 181 | ||
| @@ -281,15 +281,19 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s · 99 unmodified lines | |||
| 281 | ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); | 281 | ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); |
| 282 | if (ret) | 282 | if (ret) |
| 283 | goto out_unlock; | 283 | goto out_unlock; |
| 284 | ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]); | 284 | if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) { |
| 285 | ret = -EINVAL; | ||
| 286 | goto out_unlock; | ||
| 287 | } | ||
| 288 | ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0] + 1); | ||
| 285 | if (ret) | 289 | if (ret) |
| 286 | goto out_unlock; | 290 | goto out_unlock; |
| 287 | if (read_write == I2C_SMBUS_WRITE) { | 291 | if (read_write == I2C_SMBUS_WRITE) { |
| 288 | ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]); | 292 | ret = rtl9300_i2c_write(i2c, &data->block[0], data->block[0] + 1); |
| 289 | if (ret) | 293 | if (ret) |
| 290 | goto out_unlock; | 294 | goto out_unlock; |
| 291 | } | 295 | } |
| 292 | len = data->block[0]; | 296 | len = data->block[0] + 1; |
| 293 | break; | 297 | break; |
| 294 | 298 | ||
| 295 | default: | 299 | default: |
| @@ -477,7 +477,7 @@ static irqreturn_t sca3300_trigger_handler(int irq, void *p) · 476 unmodified lines | |||
| 477 | struct iio_dev *indio_dev = pf->indio_dev; | 477 | struct iio_dev *indio_dev = pf->indio_dev; |
| 478 | struct sca3300_data *data = iio_priv(indio_dev); | 478 | struct sca3300_data *data = iio_priv(indio_dev); |
| 479 | int bit, ret, val, i = 0; | 479 | int bit, ret, val, i = 0; |
| 480 | IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX); | 480 | IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { }; |
| 481 | 481 | ||
| 482 | iio_for_each_active_channel(indio_dev, bit) { | 482 | iio_for_each_active_channel(indio_dev, bit) { |
| 483 | ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val); | 483 | ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val); |
| @@ -1300,7 +1300,7 @@ config RN5T618_ADC · 1299 unmodified lines | |||
| 1300 | 1300 | ||
| 1301 | config ROHM_BD79124 | 1301 | config ROHM_BD79124 |
| 1302 | tristate "Rohm BD79124 ADC driver" | 1302 | tristate "Rohm BD79124 ADC driver" |
| 1303 | depends on I2C | 1303 | depends on I2C && GPIOLIB |
| 1304 | select REGMAP_I2C | 1304 | select REGMAP_I2C |
| 1305 | select IIO_ADC_HELPER | 1305 | select IIO_ADC_HELPER |
| 1306 | help | 1306 | help |
| @@ -849,7 +849,7 @@ enum { · 848 unmodified lines | |||
| 849 | static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan) | 849 | static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan) |
| 850 | { | 850 | { |
| 851 | struct device *dev = &st->sd.spi->dev; | 851 | struct device *dev = &st->sd.spi->dev; |
| 852 | struct ad7124_channel *ch = &st->channels[chan->channel]; | 852 | struct ad7124_channel *ch = &st->channels[chan->address]; |
| 853 | int ret; | 853 | int ret; |
| 854 | 854 | ||
| 855 | if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) { | 855 | if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) { |
| @@ -865,8 +865,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan · 9 unmodified lines | |||
| 865 | if (ret < 0) | 865 | if (ret < 0) |
| 866 | return ret; | 866 | return ret; |
| 867 | 867 | ||
| 868 | dev_dbg(dev, "offset for channel %d after zero-scale calibration: 0x%x\n", | 868 | dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n", |
| 869 | chan->channel, ch->cfg.calibration_offset); | 869 | chan->address, ch->cfg.calibration_offset); |
| 870 | } else { | 870 | } else { |
| 871 | ch->cfg.calibration_gain = st->gain_default; | 871 | ch->cfg.calibration_gain = st->gain_default; |
| 872 | 872 | ||
| @@ -880,8 +880,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan · 7 unmodified lines | |||
| 880 | if (ret < 0) | 880 | if (ret < 0) |
| 881 | return ret; | 881 | return ret; |
| 882 | 882 | ||
| 883 | dev_dbg(dev, "gain for channel %d after full-scale calibration: 0x%x\n", | 883 | dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n", |
| 884 | chan->channel, ch->cfg.calibration_gain); | 884 | chan->address, ch->cfg.calibration_gain); |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | return 0; | 887 | return 0; |
| @@ -924,7 +924,7 @@ static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev, · 36 unmodified lines | |||
| 924 | { | 924 | { |
| 925 | struct ad7124_state *st = iio_priv(indio_dev); | 925 | struct ad7124_state *st = iio_priv(indio_dev); |
| 926 | 926 | ||
| 927 | st->channels[chan->channel].syscalib_mode = mode; | 927 | st->channels[chan->address].syscalib_mode = mode; |
| 928 | 928 | ||
| 929 | return 0; | 929 | return 0; |
| 930 | } | 930 | } |
| @@ -934,7 +934,7 @@ static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev, · 3 unmodified lines | |||
| 934 | { | 934 | { |
| 935 | struct ad7124_state *st = iio_priv(indio_dev); | 935 | struct ad7124_state *st = iio_priv(indio_dev); |
| 936 | 936 | ||
| 937 | return st->channels[chan->channel].syscalib_mode; | 937 | return st->channels[chan->address].syscalib_mode; |
| 938 | } | 938 | } |
| 939 | 939 | ||
| 940 | static const struct iio_enum ad7124_syscalib_mode_enum = { | 940 | static const struct iio_enum ad7124_syscalib_mode_enum = { |
| @@ -200,7 +200,7 @@ struct ad7173_channel_config { · 199 unmodified lines | |||
| 200 | /* | 200 | /* |
| 201 | * Following fields are used to compare equality. If you | 201 | * Following fields are used to compare equality. If you |
| 202 | * make adaptations in it, you most likely also have to adapt | 202 | * make adaptations in it, you most likely also have to adapt |
| 203 | * ad7173_find_live_config(), too. | 203 | * ad7173_is_setup_equal(), too. |
| 204 | */ | 204 | */ |
| 205 | struct_group(config_props, | 205 | struct_group(config_props, |
| 206 | bool bipolar; | 206 | bool bipolar; |
| @@ -561,12 +561,19 @@ static void ad7173_reset_usage_cnts(struct ad7173_state *st) · 354 unmodified lines | |||
| 561 | st->config_usage_counter = 0; | 561 | st->config_usage_counter = 0; |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | static struct ad7173_channel_config * | 564 | /** |
| 565 | ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg) | 565 | * ad7173_is_setup_equal - Compare two channel setups |
| 566 | * @cfg1: First channel configuration | ||
| 567 | * @cfg2: Second channel configuration | ||
| 568 | * | ||
| 569 | * Compares all configuration options that affect the registers connected to | ||
| 570 | * SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx. | ||
| 571 | * | ||
| 572 | * Returns: true if the setups are identical, false otherwise | ||
| 573 | */ | ||
| 574 | static bool ad7173_is_setup_equal(const struct ad7173_channel_config *cfg1, | ||
| 575 | const struct ad7173_channel_config *cfg2) | ||
| 566 | { | 576 | { |
| 567 | struct ad7173_channel_config *cfg_aux; | ||
| 568 | int i; | ||
| 569 | |||
| 570 | /* | 577 | /* |
| 571 | * This is just to make sure that the comparison is adapted after | 578 | * This is just to make sure that the comparison is adapted after |
| 572 | * struct ad7173_channel_config was changed. | 579 | * struct ad7173_channel_config was changed. |
| @@ -579,14 +586,22 @@ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *c · 6 unmodified lines | |||
| 579 | u8 ref_sel; | 586 | u8 ref_sel; |
| 580 | })); | 587 | })); |
| 581 | 588 | ||
| 589 | return cfg1->bipolar == cfg2->bipolar && | ||
| 590 | cfg1->input_buf == cfg2->input_buf && | ||
| 591 | cfg1->odr == cfg2->odr && | ||
| 592 | cfg1->ref_sel == cfg2->ref_sel; | ||
| 593 | } | ||
| 594 | |||
| 595 | static struct ad7173_channel_config * | ||
| 596 | ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg) | ||
| 597 | { | ||
| 598 | struct ad7173_channel_config *cfg_aux; | ||
| 599 | int i; | ||
| 600 | |||
| 582 | for (i = 0; i < st->num_channels; i++) { | 601 | for (i = 0; i < st->num_channels; i++) { |
| 583 | cfg_aux = &st->channels[i].cfg; | 602 | cfg_aux = &st->channels[i].cfg; |
| 584 | 603 | ||
| 585 | if (cfg_aux->live && | 604 | if (cfg_aux->live && ad7173_is_setup_equal(cfg, cfg_aux)) |
| 586 | cfg->bipolar == cfg_aux->bipolar && | ||
| 587 | cfg->input_buf == cfg_aux->input_buf && | ||
| 588 | cfg->odr == cfg_aux->odr && | ||
| 589 | cfg->ref_sel == cfg_aux->ref_sel) | ||
| 590 | return cfg_aux; | 605 | return cfg_aux; |
| 591 | } | 606 | } |
| 592 | return NULL; | 607 | return NULL; |
| @@ -1228,7 +1243,7 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev, · 635 unmodified lines | |||
| 1228 | const unsigned long *scan_mask) | 1243 | const unsigned long *scan_mask) |
| 1229 | { | 1244 | { |
| 1230 | struct ad7173_state *st = iio_priv(indio_dev); | 1245 | struct ad7173_state *st = iio_priv(indio_dev); |
| 1231 | int i, ret; | 1246 | int i, j, k, ret; |
| 1232 | 1247 | ||
| 1233 | for (i = 0; i < indio_dev->num_channels; i++) { | 1248 | for (i = 0; i < indio_dev->num_channels; i++) { |
| 1234 | if (test_bit(i, scan_mask)) | 1249 | if (test_bit(i, scan_mask)) |
| @@ -1239,6 +1254,54 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev, · 4 unmodified lines | |||
| 1239 | return ret; | 1254 | return ret; |
| 1240 | } | 1255 | } |
| 1241 | 1256 | ||
| 1257 | /* | ||
| 1258 | * On some chips, there are more channels that setups, so if there were | ||
| 1259 | * more unique setups requested than the number of available slots, | ||
| 1260 | * ad7173_set_channel() will have written over some of the slots. We | ||
| 1261 | * can detect this by making sure each assigned cfg_slot matches the | ||
| 1262 | * requested configuration. If it doesn't, we know that the slot was | ||
| 1263 | * overwritten by a different channel. | ||
| 1264 | */ | ||
| 1265 | for_each_set_bit(i, scan_mask, indio_dev->num_channels) { | ||
| 1266 | const struct ad7173_channel_config *cfg1, *cfg2; | ||
| 1267 | |||
| 1268 | cfg1 = &st->channels[i].cfg; | ||
| 1269 | |||
| 1270 | for_each_set_bit(j, scan_mask, indio_dev->num_channels) { | ||
| 1271 | cfg2 = &st->channels[j].cfg; | ||
| 1272 | |||
| 1273 | /* | ||
| 1274 | * Only compare configs that are assigned to the same | ||
| 1275 | * SETUP_SEL slot and don't compare channel to itself. | ||
| 1276 | */ | ||
| 1277 | if (i == j || cfg1->cfg_slot != cfg2->cfg_slot) | ||
| 1278 | continue; | ||
| 1279 | |||
| 1280 | /* | ||
| 1281 | * If we find two different configs trying to use the | ||
| 1282 | * same SETUP_SEL slot, then we know that the that we | ||
| 1283 | * have too many unique configurations requested for | ||
| 1284 | * the available slots and at least one was overwritten. | ||
| 1285 | */ | ||
| 1286 | if (!ad7173_is_setup_equal(cfg1, cfg2)) { | ||
| 1287 | /* | ||
| 1288 | * At this point, there isn't a way to tell | ||
| 1289 | * which setups are actually programmed in the | ||
| 1290 | * ADC anymore, so we could read them back to | ||
| 1291 | * see, but it is simpler to just turn off all | ||
| 1292 | * of the live flags so that everything gets | ||
| 1293 | * reprogramed on the next attempt read a sample. | ||
| 1294 | */ | ||
| 1295 | for (k = 0; k < st->num_channels; k++) | ||
| 1296 | st->channels[k].cfg.live = false; | ||
| 1297 | |||
| 1298 | dev_err(&st->sd.spi->dev, | ||
| 1299 | "Too many unique channel configurations requested for scan\n"); | ||
| 1300 | return -EINVAL; | ||
| 1301 | } | ||
| 1302 | } | ||
| 1303 | } | ||
| 1304 | |||
| 1242 | return 0; | 1305 | return 0; |
| 1243 | } | 1306 | } |
| 1244 | 1307 | ||
| @@ -873,6 +873,7 @@ static const struct ad7380_chip_info adaq4381_4_chip_info = { · 872 unmodified lines | |||
| 873 | .has_hardware_gain = true, | 873 | .has_hardware_gain = true, |
| 874 | .available_scan_masks = ad7380_4_channel_scan_masks, | 874 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| 875 | .timing_specs = &ad7380_4_timing, | 875 | .timing_specs = &ad7380_4_timing, |
| 876 | .max_conversion_rate_hz = 4 * MEGA, | ||
| 876 | }; | 877 | }; |
| 877 | 878 | ||
| 878 | static const struct spi_offload_config ad7380_offload_config = { | 879 | static const struct spi_offload_config ad7380_offload_config = { |
| @@ -89,7 +89,6 @@ struct rzg2l_adc { · 88 unmodified lines | |||
| 89 | struct completion completion; | 89 | struct completion completion; |
| 90 | struct mutex lock; | 90 | struct mutex lock; |
| 91 | u16 last_val[RZG2L_ADC_MAX_CHANNELS]; | 91 | u16 last_val[RZG2L_ADC_MAX_CHANNELS]; |
| 92 | bool was_rpm_active; | ||
| 93 | }; | 92 | }; |
| 94 | 93 | ||
| 95 | /** | 94 | /** |
| @@ -428,6 +427,8 @@ static int rzg2l_adc_probe(struct platform_device *pdev) · 332 unmodified lines | |||
| 428 | if (!indio_dev) | 427 | if (!indio_dev) |
| 429 | return -ENOMEM; | 428 | return -ENOMEM; |
| 430 | 429 | ||
| 430 | platform_set_drvdata(pdev, indio_dev); | ||
| 431 | |||
| 431 | adc = iio_priv(indio_dev); | 432 | adc = iio_priv(indio_dev); |
| 432 | 433 | ||
| 433 | adc->hw_params = device_get_match_data(dev); | 434 | adc->hw_params = device_get_match_data(dev); |
| @@ -460,8 +461,6 @@ static int rzg2l_adc_probe(struct platform_device *pdev) · 26 unmodified lines | |||
| 460 | if (ret) | 461 | if (ret) |
| 461 | return ret; | 462 | return ret; |
| 462 | 463 | ||
| 463 | platform_set_drvdata(pdev, indio_dev); | ||
| 464 | |||
| 465 | ret = rzg2l_adc_hw_init(dev, adc); | 464 | ret = rzg2l_adc_hw_init(dev, adc); |
| 466 | if (ret) | 465 | if (ret) |
| 467 | return dev_err_probe(&pdev->dev, ret, | 466 | return dev_err_probe(&pdev->dev, ret, |
| @@ -541,14 +540,9 @@ static int rzg2l_adc_suspend(struct device *dev) · 73 unmodified lines | |||
| 541 | }; | 540 | }; |
| 542 | int ret; | 541 | int ret; |
| 543 | 542 | ||
| 544 | if (pm_runtime_suspended(dev)) { | 543 | ret = pm_runtime_force_suspend(dev); |
| 545 | adc->was_rpm_active = false; | 544 | if (ret) |
| 546 | } else { | 545 | return ret; |
| 547 | ret = pm_runtime_force_suspend(dev); | ||
| 548 | if (ret) | ||
| 549 | return ret; | ||
| 550 | adc->was_rpm_active = true; | ||
| 551 | } | ||
| 552 | 546 | ||
| 553 | ret = reset_control_bulk_assert(ARRAY_SIZE(resets), resets); | 547 | ret = reset_control_bulk_assert(ARRAY_SIZE(resets), resets); |
| 554 | if (ret) | 548 | if (ret) |
| @@ -557,9 +551,7 @@ static int rzg2l_adc_suspend(struct device *dev) · 2 unmodified lines | |||
| 557 | return 0; | 551 | return 0; |
| 558 | 552 | ||
| 559 | rpm_restore: | 553 | rpm_restore: |
| 560 | if (adc->was_rpm_active) | 554 | pm_runtime_force_resume(dev); |
| 561 | pm_runtime_force_resume(dev); | ||
| 562 | |||
| 563 | return ret; | 555 | return ret; |
| 564 | } | 556 | } |
| 565 | 557 | ||
| @@ -577,11 +569,9 @@ static int rzg2l_adc_resume(struct device *dev) · 11 unmodified lines | |||
| 577 | if (ret) | 569 | if (ret) |
| 578 | return ret; | 570 | return ret; |
| 579 | 571 | ||
| 580 | if (adc->was_rpm_active) { | 572 | ret = pm_runtime_force_resume(dev); |
| 581 | ret = pm_runtime_force_resume(dev); | 573 | if (ret) |
| 582 | if (ret) | 574 | goto resets_restore; |
| 583 | goto resets_restore; | ||
| 584 | } | ||
| 585 | 575 | ||
| 586 | ret = rzg2l_adc_hw_init(dev, adc); | 576 | ret = rzg2l_adc_hw_init(dev, adc); |
| 587 | if (ret) | 577 | if (ret) |
| @@ -590,10 +580,7 @@ static int rzg2l_adc_resume(struct device *dev) · 2 unmodified lines | |||
| 590 | return 0; | 580 | return 0; |
| 591 | 581 | ||
| 592 | rpm_restore: | 582 | rpm_restore: |
| 593 | if (adc->was_rpm_active) { | 583 | pm_runtime_force_suspend(dev); |
| 594 | pm_runtime_mark_last_busy(dev); | ||
| 595 | pm_runtime_put_autosuspend(dev); | ||
| 596 | } | ||
| 597 | resets_restore: | 584 | resets_restore: |
| 598 | reset_control_bulk_assert(ARRAY_SIZE(resets), resets); | 585 | reset_control_bulk_assert(ARRAY_SIZE(resets), resets); |
| 599 | return ret; | 586 | return ret; |
| @@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp) · 31 unmodified lines | |||
| 32 | goto exit; | 32 | goto exit; |
| 33 | 33 | ||
| 34 | *temp = (s16)be16_to_cpup(raw); | 34 | *temp = (s16)be16_to_cpup(raw); |
| 35 | /* | ||
| 36 | * Temperature data is invalid if both accel and gyro are off. | ||
| 37 | * Return -EBUSY in this case. | ||
| 38 | */ | ||
| 35 | if (*temp == INV_ICM42600_DATA_INVALID) | 39 | if (*temp == INV_ICM42600_DATA_INVALID) |
| 36 | ret = -EINVAL; | 40 | ret = -EBUSY; |
| 37 | 41 | ||
| 38 | exit: | 42 | exit: |
| 39 | mutex_unlock(&st->lock); | 43 | mutex_unlock(&st->lock); |
| @@ -639,7 +639,7 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) · 638 unmodified lines | |||
| 639 | struct { | 639 | struct { |
| 640 | __le16 chan[4]; | 640 | __le16 chan[4]; |
| 641 | aligned_s64 ts; | 641 | aligned_s64 ts; |
| 642 | } scan; | 642 | } scan = { }; |
| 643 | int data_result, ret; | 643 | int data_result, ret; |
| 644 | 644 | ||
| 645 | mutex_lock(&data->mutex); | 645 | mutex_lock(&data->mutex); |
| @@ -3213,11 +3213,12 @@ int bmp280_common_probe(struct device *dev, · 3212 unmodified lines | |||
| 3213 | 3213 | ||
| 3214 | /* Bring chip out of reset if there is an assigned GPIO line */ | 3214 | /* Bring chip out of reset if there is an assigned GPIO line */ |
| 3215 | gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); | 3215 | gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); |
| 3216 | if (IS_ERR(gpiod)) | ||
| 3217 | return dev_err_probe(dev, PTR_ERR(gpiod), "failed to get reset GPIO\n"); | ||
| 3218 | |||
| 3216 | /* Deassert the signal */ | 3219 | /* Deassert the signal */ |
| 3217 | if (gpiod) { | 3220 | dev_info(dev, "release reset\n"); |
| 3218 | dev_info(dev, "release reset\n"); | 3221 | gpiod_set_value(gpiod, 0); |
| 3219 | gpiod_set_value(gpiod, 0); | ||
| 3220 | } | ||
| 3221 | 3222 | ||
| 3222 | data->regmap = regmap; | 3223 | data->regmap = regmap; |
| 3223 | 3224 | ||
| @@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) · 937 unmodified lines | |||
| 938 | struct iio_dev *indio_dev = pf->indio_dev; | 938 | struct iio_dev *indio_dev = pf->indio_dev; |
| 939 | struct isl29501_private *isl29501 = iio_priv(indio_dev); | 939 | struct isl29501_private *isl29501 = iio_priv(indio_dev); |
| 940 | const unsigned long *active_mask = indio_dev->active_scan_mask; | 940 | const unsigned long *active_mask = indio_dev->active_scan_mask; |
| 941 | u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ | 941 | u32 value; |
| 942 | 942 | struct { | |
| 943 | if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) | 943 | u16 data; |
| 944 | isl29501_register_read(isl29501, REG_DISTANCE, buffer); | 944 | aligned_s64 ts; |
| 945 | } scan = { }; | ||
| 946 | |||
| 947 | if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) { | ||
| 948 | isl29501_register_read(isl29501, REG_DISTANCE, &value); | ||
| 949 | scan.data = value; | ||
| 950 | } | ||
| 945 | 951 | ||
| 946 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); | 952 | iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); |
| 947 | iio_trigger_notify_done(indio_dev->trig); | 953 | iio_trigger_notify_done(indio_dev->trig); |
| 948 | 954 | ||
| 949 | return IRQ_HANDLED; | 955 | return IRQ_HANDLED; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| 13 | #include <linux/spi/spi.h> | 13 | #include <linux/spi/spi.h> |
| 14 | #include <linux/types.h> | ||
| 14 | #include <linux/iio/iio.h> | 15 | #include <linux/iio/iio.h> |
| 15 | #include <linux/iio/sysfs.h> | 16 | #include <linux/iio/sysfs.h> |
| 16 | #include <linux/iio/trigger.h> | 17 | #include <linux/iio/trigger.h> |
| @@ -121,8 +122,15 @@ struct maxim_thermocouple_data { · 104 unmodified lines | |||
| 121 | struct spi_device *spi; | 122 | struct spi_device *spi; |
| 122 | const struct maxim_thermocouple_chip *chip; | 123 | const struct maxim_thermocouple_chip *chip; |
| 123 | char tc_type; | 124 | char tc_type; |
| 124 | 125 | /* Buffer for reading up to 2 hardware channels. */ | |
| 125 | u8 buffer[16] __aligned(IIO_DMA_MINALIGN); | 126 | struct { |
| 127 | union { | ||
| 128 | __be16 raw16; | ||
| 129 | __be32 raw32; | ||
| 130 | __be16 raw[2]; | ||
| 131 | }; | ||
| 132 | aligned_s64 timestamp; | ||
| 133 | } buffer __aligned(IIO_DMA_MINALIGN); | ||
| 126 | }; | 134 | }; |
| 127 | 135 | ||
| 128 | static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, | 136 | static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, |
| @@ -130,18 +138,16 @@ static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, · 1 unmodified line | |||
| 130 | { | 138 | { |
| 131 | unsigned int storage_bytes = data->chip->read_size; | 139 | unsigned int storage_bytes = data->chip->read_size; |
| 132 | unsigned int shift = chan->scan_type.shift + (chan->address * 8); | 140 | unsigned int shift = chan->scan_type.shift + (chan->address * 8); |
| 133 | __be16 buf16; | ||
| 134 | __be32 buf32; | ||
| 135 | int ret; | 141 | int ret; |
| 136 | 142 | ||
| 137 | switch (storage_bytes) { | 143 | switch (storage_bytes) { |
| 138 | case 2: | 144 | case 2: |
| 139 | ret = spi_read(data->spi, (void *)&buf16, storage_bytes); | 145 | ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes); |
| 140 | *val = be16_to_cpu(buf16); | 146 | *val = be16_to_cpu(data->buffer.raw16); |
| 141 | break; | 147 | break; |
| 142 | case 4: | 148 | case 4: |
| 143 | ret = spi_read(data->spi, (void *)&buf32, storage_bytes); | 149 | ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes); |
| 144 | *val = be32_to_cpu(buf32); | 150 | *val = be32_to_cpu(data->buffer.raw32); |
| 145 | break; | 151 | break; |
| 146 | default: | 152 | default: |
| 147 | ret = -EINVAL; | 153 | ret = -EINVAL; |
| @@ -166,9 +172,9 @@ static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private) · 18 unmodified lines | |||
| 166 | struct maxim_thermocouple_data *data = iio_priv(indio_dev); | 172 | struct maxim_thermocouple_data *data = iio_priv(indio_dev); |
| 167 | int ret; | 173 | int ret; |
| 168 | 174 | ||
| 169 | ret = spi_read(data->spi, data->buffer, data->chip->read_size); | 175 | ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size); |
| 170 | if (!ret) { | 176 | if (!ret) { |
| 171 | iio_push_to_buffers_with_ts(indio_dev, data->buffer, | 177 | iio_push_to_buffers_with_ts(indio_dev, &data->buffer, |
| 172 | sizeof(data->buffer), | 178 | sizeof(data->buffer), |
| 173 | iio_get_time_ns(indio_dev)); | 179 | iio_get_time_ns(indio_dev)); |
| 174 | } | 180 | } |
| @@ -115,7 +115,7 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp, · 114 unmodified lines | |||
| 115 | 115 | ||
| 116 | out_free_map: | 116 | out_free_map: |
| 117 | if (ib_uses_virt_dma(dev)) | 117 | if (ib_uses_virt_dma(dev)) |
| 118 | kfree(map->pfn_list); | 118 | kvfree(map->pfn_list); |
| 119 | else | 119 | else |
| 120 | hmm_dma_map_free(dev->dma_device, map); | 120 | hmm_dma_map_free(dev->dma_device, map); |
| 121 | return ret; | 121 | return ret; |
| @@ -287,7 +287,7 @@ static void ib_umem_odp_free(struct ib_umem_odp *umem_odp) · 165 unmodified lines | |||
| 287 | mutex_unlock(&umem_odp->umem_mutex); | 287 | mutex_unlock(&umem_odp->umem_mutex); |
| 288 | mmu_interval_notifier_remove(&umem_odp->notifier); | 288 | mmu_interval_notifier_remove(&umem_odp->notifier); |
| 289 | if (ib_uses_virt_dma(dev)) | 289 | if (ib_uses_virt_dma(dev)) |
| 290 | kfree(umem_odp->map.pfn_list); | 290 | kvfree(umem_odp->map.pfn_list); |
| 291 | else | 291 | else |
| 292 | hmm_dma_map_free(dev->dma_device, &umem_odp->map); | 292 | hmm_dma_map_free(dev->dma_device, &umem_odp->map); |
| 293 | } | 293 | } |
| @@ -1921,7 +1921,6 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, · 1920 unmodified lines | |||
| 1921 | struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq, | 1921 | struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq, |
| 1922 | ib_srq); | 1922 | ib_srq); |
| 1923 | struct bnxt_re_dev *rdev = srq->rdev; | 1923 | struct bnxt_re_dev *rdev = srq->rdev; |
| 1924 | int rc; | ||
| 1925 | 1924 | ||
| 1926 | switch (srq_attr_mask) { | 1925 | switch (srq_attr_mask) { |
| 1927 | case IB_SRQ_MAX_WR: | 1926 | case IB_SRQ_MAX_WR: |
| @@ -1933,11 +1932,8 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, · 5 unmodified lines | |||
| 1933 | return -EINVAL; | 1932 | return -EINVAL; |
| 1934 | 1933 | ||
| 1935 | srq->qplib_srq.threshold = srq_attr->srq_limit; | 1934 | srq->qplib_srq.threshold = srq_attr->srq_limit; |
| 1936 | rc = bnxt_qplib_modify_srq(&rdev->qplib_res, &srq->qplib_srq); | 1935 | bnxt_qplib_srq_arm_db(&srq->qplib_srq.dbinfo, srq->qplib_srq.threshold); |
| 1937 | if (rc) { | 1936 | |
| 1938 | ibdev_err(&rdev->ibdev, "Modify HW SRQ failed!"); | ||
| 1939 | return rc; | ||
| 1940 | } | ||
| 1941 | /* On success, update the shadow */ | 1937 | /* On success, update the shadow */ |
| 1942 | srq->srq_limit = srq_attr->srq_limit; | 1938 | srq->srq_limit = srq_attr->srq_limit; |
| 1943 | /* No need to Build and send response back to udata */ | 1939 | /* No need to Build and send response back to udata */ |
| @@ -2017,6 +2017,28 @@ static void bnxt_re_free_nqr_mem(struct bnxt_re_dev *rdev) · 2016 unmodified lines | |||
| 2017 | rdev->nqr = NULL; | 2017 | rdev->nqr = NULL; |
| 2018 | } | 2018 | } |
| 2019 | 2019 | ||
| 2020 | /* When DEL_GID fails, driver is not freeing GID ctx memory. | ||
| 2021 | * To avoid the memory leak, free the memory during unload | ||
| 2022 | */ | ||
| 2023 | static void bnxt_re_free_gid_ctx(struct bnxt_re_dev *rdev) | ||
| 2024 | { | ||
| 2025 | struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; | ||
| 2026 | struct bnxt_re_gid_ctx *ctx, **ctx_tbl; | ||
| 2027 | int i; | ||
| 2028 | |||
| 2029 | if (!sgid_tbl->active) | ||
| 2030 | return; | ||
| 2031 | |||
| 2032 | ctx_tbl = sgid_tbl->ctx; | ||
| 2033 | for (i = 0; i < sgid_tbl->max; i++) { | ||
| 2034 | if (sgid_tbl->hw_id[i] == 0xFFFF) | ||
| 2035 | continue; | ||
| 2036 | |||
| 2037 | ctx = ctx_tbl[i]; | ||
| 2038 | kfree(ctx); | ||
| 2039 | } | ||
| 2040 | } | ||
| 2041 | |||
| 2020 | static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type) | 2042 | static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type) |
| 2021 | { | 2043 | { |
| 2022 | u8 type; | 2044 | u8 type; |
| @@ -2030,6 +2052,7 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type) · 7 unmodified lines | |||
| 2030 | if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags)) | 2052 | if (test_and_clear_bit(BNXT_RE_FLAG_QOS_WORK_REG, &rdev->flags)) |
| 2031 | cancel_delayed_work_sync(&rdev->worker); | 2053 | cancel_delayed_work_sync(&rdev->worker); |
| 2032 | 2054 | ||
| 2055 | bnxt_re_free_gid_ctx(rdev); | ||
| 2033 | if (test_and_clear_bit(BNXT_RE_FLAG_RESOURCES_INITIALIZED, | 2056 | if (test_and_clear_bit(BNXT_RE_FLAG_RESOURCES_INITIALIZED, |
| 2034 | &rdev->flags)) | 2057 | &rdev->flags)) |
| 2035 | bnxt_re_cleanup_res(rdev); | 2058 | bnxt_re_cleanup_res(rdev); |
| @@ -705,9 +705,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, · 704 unmodified lines | |||
| 705 | srq->dbinfo.db = srq->dpi->dbr; | 705 | srq->dbinfo.db = srq->dpi->dbr; |
| 706 | srq->dbinfo.max_slot = 1; | 706 | srq->dbinfo.max_slot = 1; |
| 707 | srq->dbinfo.priv_db = res->dpi_tbl.priv_db; | 707 | srq->dbinfo.priv_db = res->dpi_tbl.priv_db; |
| 708 | if (srq->threshold) | 708 | bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA); |
| 709 | bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA); | ||
| 710 | srq->arm_req = false; | ||
| 711 | 709 | ||
| 712 | return 0; | 710 | return 0; |
| 713 | fail: | 711 | fail: |
| @@ -717,24 +715,6 @@ fail: · 3 unmodified lines | |||
| 717 | return rc; | 715 | return rc; |
| 718 | } | 716 | } |
| 719 | 717 | ||
| 720 | int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res, | ||
| 721 | struct bnxt_qplib_srq *srq) | ||
| 722 | { | ||
| 723 | struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; | ||
| 724 | u32 count; | ||
| 725 | |||
| 726 | count = __bnxt_qplib_get_avail(srq_hwq); | ||
| 727 | if (count > srq->threshold) { | ||
| 728 | srq->arm_req = false; | ||
| 729 | bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold); | ||
| 730 | } else { | ||
| 731 | /* Deferred arming */ | ||
| 732 | srq->arm_req = true; | ||
| 733 | } | ||
| 734 | |||
| 735 | return 0; | ||
| 736 | } | ||
| 737 | |||
| 738 | int bnxt_qplib_query_srq(struct bnxt_qplib_res *res, | 718 | int bnxt_qplib_query_srq(struct bnxt_qplib_res *res, |
| 739 | struct bnxt_qplib_srq *srq) | 719 | struct bnxt_qplib_srq *srq) |
| 740 | { | 720 | { |
| @@ -776,7 +756,6 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq, · 35 unmodified lines | |||
| 776 | struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; | 756 | struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; |
| 777 | struct rq_wqe *srqe; | 757 | struct rq_wqe *srqe; |
| 778 | struct sq_sge *hw_sge; | 758 | struct sq_sge *hw_sge; |
| 779 | u32 count = 0; | ||
| 780 | int i, next; | 759 | int i, next; |
| 781 | 760 | ||
| 782 | spin_lock(&srq_hwq->lock); | 761 | spin_lock(&srq_hwq->lock); |
| @@ -808,15 +787,8 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq, · 25 unmodified lines | |||
| 808 | 787 | ||
| 809 | bnxt_qplib_hwq_incr_prod(&srq->dbinfo, srq_hwq, srq->dbinfo.max_slot); | 788 | bnxt_qplib_hwq_incr_prod(&srq->dbinfo, srq_hwq, srq->dbinfo.max_slot); |
| 810 | 789 | ||
| 811 | spin_lock(&srq_hwq->lock); | ||
| 812 | count = __bnxt_qplib_get_avail(srq_hwq); | ||
| 813 | spin_unlock(&srq_hwq->lock); | ||
| 814 | /* Ring DB */ | 790 | /* Ring DB */ |
| 815 | bnxt_qplib_ring_prod_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ); | 791 | bnxt_qplib_ring_prod_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ); |
| 816 | if (srq->arm_req == true && count > srq->threshold) { | ||
| 817 | srq->arm_req = false; | ||
| 818 | bnxt_qplib_srq_arm_db(&srq->dbinfo, srq->threshold); | ||
| 819 | } | ||
| 820 | 792 | ||
| 821 | return 0; | 793 | return 0; |
| 822 | } | 794 | } |
| @@ -546,8 +546,6 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, · 545 unmodified lines | |||
| 546 | srqn_handler_t srq_handler); | 546 | srqn_handler_t srq_handler); |
| 547 | int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, | 547 | int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, |
| 548 | struct bnxt_qplib_srq *srq); | 548 | struct bnxt_qplib_srq *srq); |
| 549 | int bnxt_qplib_modify_srq(struct bnxt_qplib_res *res, | ||
| 550 | struct bnxt_qplib_srq *srq); | ||
| 551 | int bnxt_qplib_query_srq(struct bnxt_qplib_res *res, | 549 | int bnxt_qplib_query_srq(struct bnxt_qplib_res *res, |
| 552 | struct bnxt_qplib_srq *srq); | 550 | struct bnxt_qplib_srq *srq); |
| 553 | void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res, | 551 | void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res, |
| @@ -121,6 +121,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, · 120 unmodified lines | |||
| 121 | pbl->pg_arr = vmalloc_array(pages, sizeof(void *)); | 121 | pbl->pg_arr = vmalloc_array(pages, sizeof(void *)); |
| 122 | if (!pbl->pg_arr) | 122 | if (!pbl->pg_arr) |
| 123 | return -ENOMEM; | 123 | return -ENOMEM; |
| 124 | memset(pbl->pg_arr, 0, pages * sizeof(void *)); | ||
| 124 | 125 | ||
| 125 | pbl->pg_map_arr = vmalloc_array(pages, sizeof(dma_addr_t)); | 126 | pbl->pg_map_arr = vmalloc_array(pages, sizeof(dma_addr_t)); |
| 126 | if (!pbl->pg_map_arr) { | 127 | if (!pbl->pg_map_arr) { |
| @@ -128,6 +129,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, · 1 unmodified line | |||
| 128 | pbl->pg_arr = NULL; | 129 | pbl->pg_arr = NULL; |
| 129 | return -ENOMEM; | 130 | return -ENOMEM; |
| 130 | } | 131 | } |
| 132 | memset(pbl->pg_map_arr, 0, pages * sizeof(dma_addr_t)); | ||
| 131 | pbl->pg_count = 0; | 133 | pbl->pg_count = 0; |
| 132 | pbl->pg_size = sginfo->pgsize; | 134 | pbl->pg_size = sginfo->pgsize; |
| 133 | 135 | ||
| @@ -994,6 +994,8 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, · 993 unmodified lines | |||
| 994 | old_entry = xa_store(&dev->qp_xa, 1, qp, GFP_KERNEL); | 994 | old_entry = xa_store(&dev->qp_xa, 1, qp, GFP_KERNEL); |
| 995 | if (xa_is_err(old_entry)) | 995 | if (xa_is_err(old_entry)) |
| 996 | ret = xa_err(old_entry); | 996 | ret = xa_err(old_entry); |
| 997 | else | ||
| 998 | qp->ibqp.qp_num = 1; | ||
| 997 | } else { | 999 | } else { |
| 998 | ret = xa_alloc_cyclic(&dev->qp_xa, &qp->ibqp.qp_num, qp, | 1000 | ret = xa_alloc_cyclic(&dev->qp_xa, &qp->ibqp.qp_num, qp, |
| 999 | XA_LIMIT(1, dev->attrs.max_qp - 1), | 1001 | XA_LIMIT(1, dev->attrs.max_qp - 1), |
| @@ -1031,7 +1033,9 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, · 31 unmodified lines | |||
| 1031 | if (ret) | 1033 | if (ret) |
| 1032 | goto err_out_cmd; | 1034 | goto err_out_cmd; |
| 1033 | } else { | 1035 | } else { |
| 1034 | init_kernel_qp(dev, qp, attrs); | 1036 | ret = init_kernel_qp(dev, qp, attrs); |
| 1037 | if (ret) | ||
| 1038 | goto err_out_xa; | ||
| 1035 | } | 1039 | } |
| 1036 | 1040 | ||
| 1037 | qp->attrs.max_send_sge = attrs->cap.max_send_sge; | 1041 | qp->attrs.max_send_sge = attrs->cap.max_send_sge; |
| @@ -3043,7 +3043,7 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev) · 3042 unmodified lines | |||
| 3043 | if (!hr_dev->is_vf) | 3043 | if (!hr_dev->is_vf) |
| 3044 | hns_roce_free_link_table(hr_dev); | 3044 | hns_roce_free_link_table(hr_dev); |
| 3045 | 3045 | ||
| 3046 | if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP09) | 3046 | if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) |
| 3047 | free_dip_entry(hr_dev); | 3047 | free_dip_entry(hr_dev); |
| 3048 | } | 3048 | } |
| 3049 | 3049 | ||
| @@ -5476,7 +5476,7 @@ out: · 2426 unmodified lines | |||
| 5476 | return ret; | 5476 | return ret; |
| 5477 | } | 5477 | } |
| 5478 | 5478 | ||
| 5479 | static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 qpn, | 5479 | static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 sccn, |
| 5480 | void *buffer) | 5480 | void *buffer) |
| 5481 | { | 5481 | { |
| 5482 | struct hns_roce_v2_scc_context *context; | 5482 | struct hns_roce_v2_scc_context *context; |
| @@ -5488,7 +5488,7 @@ static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 qpn, · 5 unmodified lines | |||
| 5488 | return PTR_ERR(mailbox); | 5488 | return PTR_ERR(mailbox); |
| 5489 | 5489 | ||
| 5490 | ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_SCCC, | 5490 | ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_SCCC, |
| 5491 | qpn); | 5491 | sccn); |
| 5492 | if (ret) | 5492 | if (ret) |
| 5493 | goto out; | 5493 | goto out; |
| 5494 | 5494 | ||
| @@ -100,6 +100,7 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp) · 99 unmodified lines | |||
| 100 | struct hns_roce_v2_qp_context qpc; | 100 | struct hns_roce_v2_qp_context qpc; |
| 101 | struct hns_roce_v2_scc_context sccc; | 101 | struct hns_roce_v2_scc_context sccc; |
| 102 | } context = {}; | 102 | } context = {}; |
| 103 | u32 sccn = hr_qp->qpn; | ||
| 103 | int ret; | 104 | int ret; |
| 104 | 105 | ||
| 105 | if (!hr_dev->hw->query_qpc) | 106 | if (!hr_dev->hw->query_qpc) |
| @@ -116,7 +117,13 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp) · 10 unmodified lines | |||
| 116 | !hr_dev->hw->query_sccc) | 117 | !hr_dev->hw->query_sccc) |
| 117 | goto out; | 118 | goto out; |
| 118 | 119 | ||
| 119 | ret = hr_dev->hw->query_sccc(hr_dev, hr_qp->qpn, &context.sccc); | 120 | if (hr_qp->cong_type == CONG_TYPE_DIP) { |
| 121 | if (!hr_qp->dip) | ||
| 122 | goto out; | ||
| 123 | sccn = hr_qp->dip->dip_idx; | ||
| 124 | } | ||
| 125 | |||
| 126 | ret = hr_dev->hw->query_sccc(hr_dev, sccn, &context.sccc); | ||
| 120 | if (ret) | 127 | if (ret) |
| 121 | ibdev_warn_ratelimited(&hr_dev->ib_dev, | 128 | ibdev_warn_ratelimited(&hr_dev->ib_dev, |
| 122 | "failed to query SCCC, ret = %d.\n", | 129 | "failed to query SCCC, ret = %d.\n", |
| @@ -345,33 +345,15 @@ int rxe_prepare(struct rxe_av *av, struct rxe_pkt_info *pkt, · 344 unmodified lines | |||
| 345 | 345 | ||
| 346 | static void rxe_skb_tx_dtor(struct sk_buff *skb) | 346 | static void rxe_skb_tx_dtor(struct sk_buff *skb) |
| 347 | { | 347 | { |
| 348 | struct net_device *ndev = skb->dev; | 348 | struct rxe_qp *qp = skb->sk->sk_user_data; |
| 349 | struct rxe_dev *rxe; | ||
| 350 | unsigned int qp_index; | ||
| 351 | struct rxe_qp *qp; | ||
| 352 | int skb_out; | 349 | int skb_out; |
| 353 | 350 | ||
| 354 | rxe = rxe_get_dev_from_net(ndev); | ||
| 355 | if (!rxe && is_vlan_dev(ndev)) | ||
| 356 | rxe = rxe_get_dev_from_net(vlan_dev_real_dev(ndev)); | ||
| 357 | if (WARN_ON(!rxe)) | ||
| 358 | return; | ||
| 359 | |||
| 360 | qp_index = (int)(uintptr_t)skb->sk->sk_user_data; | ||
| 361 | if (!qp_index) | ||
| 362 | return; | ||
| 363 | |||
| 364 | qp = rxe_pool_get_index(&rxe->qp_pool, qp_index); | ||
| 365 | if (!qp) | ||
| 366 | goto put_dev; | ||
| 367 | |||
| 368 | skb_out = atomic_dec_return(&qp->skb_out); | 351 | skb_out = atomic_dec_return(&qp->skb_out); |
| 369 | if (qp->need_req_skb && skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW) | 352 | if (unlikely(qp->need_req_skb && |
| 353 | skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW)) | ||
| 370 | rxe_sched_task(&qp->send_task); | 354 | rxe_sched_task(&qp->send_task); |
| 371 | 355 | ||
| 372 | rxe_put(qp); | 356 | rxe_put(qp); |
| 373 | put_dev: | ||
| 374 | ib_device_put(&rxe->ib_dev); | ||
| 375 | sock_put(skb->sk); | 357 | sock_put(skb->sk); |
| 376 | } | 358 | } |
| 377 | 359 | ||
| @@ -383,6 +365,7 @@ static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 5 unmodified lines | |||
| 383 | sock_hold(sk); | 365 | sock_hold(sk); |
| 384 | skb->sk = sk; | 366 | skb->sk = sk; |
| 385 | skb->destructor = rxe_skb_tx_dtor; | 367 | skb->destructor = rxe_skb_tx_dtor; |
| 368 | rxe_get(pkt->qp); | ||
| 386 | atomic_inc(&pkt->qp->skb_out); | 369 | atomic_inc(&pkt->qp->skb_out); |
| 387 | 370 | ||
| 388 | if (skb->protocol == htons(ETH_P_IP)) | 371 | if (skb->protocol == htons(ETH_P_IP)) |
| @@ -405,6 +388,7 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt) · 16 unmodified lines | |||
| 405 | sock_hold(sk); | 388 | sock_hold(sk); |
| 406 | skb->sk = sk; | 389 | skb->sk = sk; |
| 407 | skb->destructor = rxe_skb_tx_dtor; | 390 | skb->destructor = rxe_skb_tx_dtor; |
| 391 | rxe_get(pkt->qp); | ||
| 408 | atomic_inc(&pkt->qp->skb_out); | 392 | atomic_inc(&pkt->qp->skb_out); |
| 409 | 393 | ||
| 410 | if (skb->protocol == htons(ETH_P_IP)) | 394 | if (skb->protocol == htons(ETH_P_IP)) |
| @@ -497,6 +481,9 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, · 86 unmodified lines | |||
| 497 | goto out; | 481 | goto out; |
| 498 | } | 482 | } |
| 499 | 483 | ||
| 484 | /* Add time stamp to skb. */ | ||
| 485 | skb->tstamp = ktime_get(); | ||
| 486 | |||
| 500 | skb_reserve(skb, hdr_len + LL_RESERVED_SPACE(ndev)); | 487 | skb_reserve(skb, hdr_len + LL_RESERVED_SPACE(ndev)); |
| 501 | 488 | ||
| 502 | /* FIXME: hold reference to this netdev until life of this skb. */ | 489 | /* FIXME: hold reference to this netdev until life of this skb. */ |
| @@ -244,7 +244,7 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, · 243 unmodified lines | |||
| 244 | err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &qp->sk); | 244 | err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &qp->sk); |
| 245 | if (err < 0) | 245 | if (err < 0) |
| 246 | return err; | 246 | return err; |
| 247 | qp->sk->sk->sk_user_data = (void *)(uintptr_t)qp->elem.index; | 247 | qp->sk->sk->sk_user_data = qp; |
| 248 | 248 | ||
| 249 | /* pick a source UDP port number for this QP based on | 249 | /* pick a source UDP port number for this QP based on |
| 250 | * the source QPN. this spreads traffic for different QPs | 250 | * the source QPN. this spreads traffic for different QPs |
| @@ -3638,7 +3638,7 @@ static int __init parse_ivrs_acpihid(char *str) · 3637 unmodified lines | |||
| 3638 | { | 3638 | { |
| 3639 | u32 seg = 0, bus, dev, fn; | 3639 | u32 seg = 0, bus, dev, fn; |
| 3640 | char *hid, *uid, *p, *addr; | 3640 | char *hid, *uid, *p, *addr; |
| 3641 | char acpiid[ACPIID_LEN] = {0}; | 3641 | char acpiid[ACPIID_LEN + 1] = { }; /* size with NULL terminator */ |
| 3642 | int i; | 3642 | int i; |
| 3643 | 3643 | ||
| 3644 | addr = strchr(str, '@'); | 3644 | addr = strchr(str, '@'); |
| @@ -3664,7 +3664,7 @@ static int __init parse_ivrs_acpihid(char *str) · 19 unmodified lines | |||
| 3664 | /* We have the '@', make it the terminator to get just the acpiid */ | 3664 | /* We have the '@', make it the terminator to get just the acpiid */ |
| 3665 | *addr++ = 0; | 3665 | *addr++ = 0; |
| 3666 | 3666 | ||
| 3667 | if (strlen(str) > ACPIID_LEN + 1) | 3667 | if (strlen(str) > ACPIID_LEN) |
| 3668 | goto not_found; | 3668 | goto not_found; |
| 3669 | 3669 | ||
| 3670 | if (sscanf(str, "=%s", acpiid) != 1) | 3670 | if (sscanf(str, "=%s", acpiid) != 1) |
| @@ -2997,9 +2997,9 @@ void arm_smmu_attach_commit(struct arm_smmu_attach_state *state) · 2996 unmodified lines | |||
| 2997 | /* ATS is being switched off, invalidate the entire ATC */ | 2997 | /* ATS is being switched off, invalidate the entire ATC */ |
| 2998 | arm_smmu_atc_inv_master(master, IOMMU_NO_PASID); | 2998 | arm_smmu_atc_inv_master(master, IOMMU_NO_PASID); |
| 2999 | } | 2999 | } |
| 3000 | master->ats_enabled = state->ats_enabled; | ||
| 3001 | 3000 | ||
| 3002 | arm_smmu_remove_master_domain(master, state->old_domain, state->ssid); | 3001 | arm_smmu_remove_master_domain(master, state->old_domain, state->ssid); |
| 3002 | master->ats_enabled = state->ats_enabled; | ||
| 3003 | } | 3003 | } |
| 3004 | 3004 | ||
| 3005 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 3005 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
| @@ -301,9 +301,11 @@ static void tegra241_vintf_user_handle_error(struct tegra241_vintf *vintf) · 300 unmodified lines | |||
| 301 | struct iommu_vevent_tegra241_cmdqv vevent_data; | 301 | struct iommu_vevent_tegra241_cmdqv vevent_data; |
| 302 | int i; | 302 | int i; |
| 303 | 303 | ||
| 304 | for (i = 0; i < LVCMDQ_ERR_MAP_NUM_64; i++) | 304 | for (i = 0; i < LVCMDQ_ERR_MAP_NUM_64; i++) { |
| 305 | vevent_data.lvcmdq_err_map[i] = | 305 | u64 err = readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i))); |
| 306 | readq_relaxed(REG_VINTF(vintf, LVCMDQ_ERR_MAP_64(i))); | 306 | |
| 307 | vevent_data.lvcmdq_err_map[i] = cpu_to_le64(err); | ||
| 308 | } | ||
| 307 | 309 | ||
| 308 | iommufd_viommu_report_event(viommu, IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV, | 310 | iommufd_viommu_report_event(viommu, IOMMU_VEVENTQ_TYPE_TEGRA241_CMDQV, |
| 309 | &vevent_data, sizeof(vevent_data)); | 311 | &vevent_data, sizeof(vevent_data)); |
| @@ -339,7 +339,7 @@ iommufd_hw_queue_alloc_phys(struct iommu_hw_queue_alloc *cmd, · 338 unmodified lines | |||
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | *base_pa = (page_to_pfn(pages[0]) << PAGE_SHIFT) + offset; | 341 | *base_pa = (page_to_pfn(pages[0]) << PAGE_SHIFT) + offset; |
| 342 | kfree(pages); | 342 | kvfree(pages); |
| 343 | return access; | 343 | return access; |
| 344 | 344 | ||
| 345 | out_unpin: | 345 | out_unpin: |
| @@ -349,7 +349,7 @@ out_detach: · 3 unmodified lines | |||
| 349 | out_destroy: | 349 | out_destroy: |
| 350 | iommufd_access_destroy_internal(viommu->ictx, access); | 350 | iommufd_access_destroy_internal(viommu->ictx, access); |
| 351 | out_free: | 351 | out_free: |
| 352 | kfree(pages); | 352 | kvfree(pages); |
| 353 | return ERR_PTR(rc); | 353 | return ERR_PTR(rc); |
| 354 | } | 354 | } |
| 355 | 355 | ||
| @@ -1283,7 +1283,7 @@ static phys_addr_t riscv_iommu_iova_to_phys(struct iommu_domain *iommu_domain, · 1282 unmodified lines | |||
| 1283 | unsigned long *ptr; | 1283 | unsigned long *ptr; |
| 1284 | 1284 | ||
| 1285 | ptr = riscv_iommu_pte_fetch(domain, iova, &pte_size); | 1285 | ptr = riscv_iommu_pte_fetch(domain, iova, &pte_size); |
| 1286 | if (_io_pte_none(*ptr) || !_io_pte_present(*ptr)) | 1286 | if (!ptr) |
| 1287 | return 0; | 1287 | return 0; |
| 1288 | 1288 | ||
| 1289 | return pfn_to_phys(__page_val_to_pfn(*ptr)) | (iova & (pte_size - 1)); | 1289 | return pfn_to_phys(__page_val_to_pfn(*ptr)) | (iova & (pte_size - 1)); |
| @@ -998,8 +998,7 @@ static void viommu_get_resv_regions(struct device *dev, struct list_head *head) · 997 unmodified lines | |||
| 998 | iommu_dma_get_resv_regions(dev, head); | 998 | iommu_dma_get_resv_regions(dev, head); |
| 999 | } | 999 | } |
| 1000 | 1000 | ||
| 1001 | static const struct iommu_ops viommu_ops; | 1001 | static const struct bus_type *virtio_bus_type; |
| 1002 | static struct virtio_driver virtio_iommu_drv; | ||
| 1003 | 1002 | ||
| 1004 | static int viommu_match_node(struct device *dev, const void *data) | 1003 | static int viommu_match_node(struct device *dev, const void *data) |
| 1005 | { | 1004 | { |
| @@ -1008,8 +1007,9 @@ static int viommu_match_node(struct device *dev, const void *data) · 2 unmodified lines | |||
| 1008 | 1007 | ||
| 1009 | static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode) | 1008 | static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode) |
| 1010 | { | 1009 | { |
| 1011 | struct device *dev = driver_find_device(&virtio_iommu_drv.driver, NULL, | 1010 | struct device *dev = bus_find_device(virtio_bus_type, NULL, fwnode, |
| 1012 | fwnode, viommu_match_node); | 1011 | viommu_match_node); |
| 1012 | |||
| 1013 | put_device(dev); | 1013 | put_device(dev); |
| 1014 | 1014 | ||
| 1015 | return dev ? dev_to_virtio(dev)->priv : NULL; | 1015 | return dev ? dev_to_virtio(dev)->priv : NULL; |
| @@ -1160,6 +1160,9 @@ static int viommu_probe(struct virtio_device *vdev) · 144 unmodified lines | |||
| 1160 | if (!viommu) | 1160 | if (!viommu) |
| 1161 | return -ENOMEM; | 1161 | return -ENOMEM; |
| 1162 | 1162 | ||
| 1163 | /* Borrow this for easy lookups later */ | ||
| 1164 | virtio_bus_type = dev->bus; | ||
| 1165 | |||
| 1163 | spin_lock_init(&viommu->request_lock); | 1166 | spin_lock_init(&viommu->request_lock); |
| 1164 | ida_init(&viommu->domain_ids); | 1167 | ida_init(&viommu->domain_ids); |
| 1165 | viommu->dev = dev; | 1168 | viommu->dev = dev; |
| @@ -1229,10 +1232,10 @@ static int viommu_probe(struct virtio_device *vdev) · 63 unmodified lines | |||
| 1229 | if (ret) | 1232 | if (ret) |
| 1230 | goto err_free_vqs; | 1233 | goto err_free_vqs; |
| 1231 | 1234 | ||
| 1232 | iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev); | ||
| 1233 | |||
| 1234 | vdev->priv = viommu; | 1235 | vdev->priv = viommu; |
| 1235 | 1236 | ||
| 1237 | iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev); | ||
| 1238 | |||
| 1236 | dev_info(dev, "input address: %u bits\n", | 1239 | dev_info(dev, "input address: %u bits\n", |
| 1237 | order_base_2(viommu->geometry.aperture_end)); | 1240 | order_base_2(viommu->geometry.aperture_end)); |
| 1238 | dev_info(dev, "page mask: %#llx\n", viommu->pgsize_bitmap); | 1241 | dev_info(dev, "page mask: %#llx\n", viommu->pgsize_bitmap); |
| @@ -39,12 +39,13 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #include "hfc_pci.h" | 40 | #include "hfc_pci.h" |
| 41 | 41 | ||
| 42 | static void hfcpci_softirq(struct timer_list *unused); | ||
| 42 | static const char *hfcpci_revision = "2.0"; | 43 | static const char *hfcpci_revision = "2.0"; |
| 43 | 44 | ||
| 44 | static int HFC_cnt; | 45 | static int HFC_cnt; |
| 45 | static uint debug; | 46 | static uint debug; |
| 46 | static uint poll, tics; | 47 | static uint poll, tics; |
| 47 | static struct timer_list hfc_tl; | 48 | static DEFINE_TIMER(hfc_tl, hfcpci_softirq); |
| 48 | static unsigned long hfc_jiffies; | 49 | static unsigned long hfc_jiffies; |
| 49 | 50 | ||
| 50 | MODULE_AUTHOR("Karsten Keil"); | 51 | MODULE_AUTHOR("Karsten Keil"); |
| @@ -2305,8 +2306,7 @@ hfcpci_softirq(struct timer_list *unused) · 2254 unmodified lines | |||
| 2305 | hfc_jiffies = jiffies + 1; | 2306 | hfc_jiffies = jiffies + 1; |
| 2306 | else | 2307 | else |
| 2307 | hfc_jiffies += tics; | 2308 | hfc_jiffies += tics; |
| 2308 | hfc_tl.expires = hfc_jiffies; | 2309 | mod_timer(&hfc_tl, hfc_jiffies); |
| 2309 | add_timer(&hfc_tl); | ||
| 2310 | } | 2310 | } |
| 2311 | 2311 | ||
| 2312 | static int __init | 2312 | static int __init |
| @@ -2332,10 +2332,8 @@ HFC_init(void) · 19 unmodified lines | |||
| 2332 | if (poll != HFCPCI_BTRANS_THRESHOLD) { | 2332 | if (poll != HFCPCI_BTRANS_THRESHOLD) { |
| 2333 | printk(KERN_INFO "%s: Using alternative poll value of %d\n", | 2333 | printk(KERN_INFO "%s: Using alternative poll value of %d\n", |
| 2334 | __func__, poll); | 2334 | __func__, poll); |
| 2335 | timer_setup(&hfc_tl, hfcpci_softirq, 0); | 2335 | hfc_jiffies = jiffies + tics; |
| 2336 | hfc_tl.expires = jiffies + tics; | 2336 | mod_timer(&hfc_tl, hfc_jiffies); |
| 2337 | hfc_jiffies = hfc_tl.expires; | ||
| 2338 | add_timer(&hfc_tl); | ||
| 2339 | } else | 2337 | } else |
| 2340 | tics = 0; /* indicate the use of controller's timer */ | 2338 | tics = 0; /* indicate the use of controller's timer */ |
| 2341 | 2339 | ||
| @@ -339,6 +339,7 @@ static int start_readonly; · 338 unmodified lines | |||
| 339 | * so all the races disappear. | 339 | * so all the races disappear. |
| 340 | */ | 340 | */ |
| 341 | static bool create_on_open = true; | 341 | static bool create_on_open = true; |
| 342 | static bool legacy_async_del_gendisk = true; | ||
| 342 | 343 | ||
| 343 | /* | 344 | /* |
| 344 | * We have a system wide 'event count' that is incremented | 345 | * We have a system wide 'event count' that is incremented |
| @@ -877,15 +878,18 @@ void mddev_unlock(struct mddev *mddev) · 532 unmodified lines | |||
| 877 | export_rdev(rdev, mddev); | 878 | export_rdev(rdev, mddev); |
| 878 | } | 879 | } |
| 879 | 880 | ||
| 880 | /* Call del_gendisk after release reconfig_mutex to avoid | 881 | if (!legacy_async_del_gendisk) { |
| 881 | * deadlock (e.g. call del_gendisk under the lock and an | 882 | /* |
| 882 | * access to sysfs files waits the lock) | 883 | * Call del_gendisk after release reconfig_mutex to avoid |
| 883 | * And MD_DELETED is only used for md raid which is set in | 884 | * deadlock (e.g. call del_gendisk under the lock and an |
| 884 | * do_md_stop. dm raid only uses md_stop to stop. So dm raid | 885 | * access to sysfs files waits the lock) |
| 885 | * doesn't need to check MD_DELETED when getting reconfig lock | 886 | * And MD_DELETED is only used for md raid which is set in |
| 886 | */ | 887 | * do_md_stop. dm raid only uses md_stop to stop. So dm raid |
| 887 | if (test_bit(MD_DELETED, &mddev->flags)) | 888 | * doesn't need to check MD_DELETED when getting reconfig lock |
| 888 | del_gendisk(mddev->gendisk); | 889 | */ |
| 890 | if (test_bit(MD_DELETED, &mddev->flags)) | ||
| 891 | del_gendisk(mddev->gendisk); | ||
| 892 | } | ||
| 889 | } | 893 | } |
| 890 | EXPORT_SYMBOL_GPL(mddev_unlock); | 894 | EXPORT_SYMBOL_GPL(mddev_unlock); |
| 891 | 895 | ||
| @@ -1419,7 +1423,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru · 527 unmodified lines | |||
| 1419 | else { | 1423 | else { |
| 1420 | if (sb->events_hi == sb->cp_events_hi && | 1424 | if (sb->events_hi == sb->cp_events_hi && |
| 1421 | sb->events_lo == sb->cp_events_lo) { | 1425 | sb->events_lo == sb->cp_events_lo) { |
| 1422 | mddev->resync_offset = sb->resync_offset; | 1426 | mddev->resync_offset = sb->recovery_cp; |
| 1423 | } else | 1427 | } else |
| 1424 | mddev->resync_offset = 0; | 1428 | mddev->resync_offset = 0; |
| 1425 | } | 1429 | } |
| @@ -1547,13 +1551,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev) · 121 unmodified lines | |||
| 1547 | mddev->minor_version = sb->minor_version; | 1551 | mddev->minor_version = sb->minor_version; |
| 1548 | if (mddev->in_sync) | 1552 | if (mddev->in_sync) |
| 1549 | { | 1553 | { |
| 1550 | sb->resync_offset = mddev->resync_offset; | 1554 | sb->recovery_cp = mddev->resync_offset; |
| 1551 | sb->cp_events_hi = (mddev->events>>32); | 1555 | sb->cp_events_hi = (mddev->events>>32); |
| 1552 | sb->cp_events_lo = (u32)mddev->events; | 1556 | sb->cp_events_lo = (u32)mddev->events; |
| 1553 | if (mddev->resync_offset == MaxSector) | 1557 | if (mddev->resync_offset == MaxSector) |
| 1554 | sb->state = (1<< MD_SB_CLEAN); | 1558 | sb->state = (1<< MD_SB_CLEAN); |
| 1555 | } else | 1559 | } else |
| 1556 | sb->resync_offset = 0; | 1560 | sb->recovery_cp = 0; |
| 1557 | 1561 | ||
| 1558 | sb->layout = mddev->layout; | 1562 | sb->layout = mddev->layout; |
| 1559 | sb->chunk_size = mddev->chunk_sectors << 9; | 1563 | sb->chunk_size = mddev->chunk_sectors << 9; |
| @@ -4835,9 +4839,42 @@ out_unlock: · 3275 unmodified lines | |||
| 4835 | static struct md_sysfs_entry md_metadata = | 4839 | static struct md_sysfs_entry md_metadata = |
| 4836 | __ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); | 4840 | __ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store); |
| 4837 | 4841 | ||
| 4842 | static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors) | ||
| 4843 | { | ||
| 4844 | return rdev->raid_disk >= 0 && | ||
| 4845 | !test_bit(Journal, &rdev->flags) && | ||
| 4846 | !test_bit(Faulty, &rdev->flags) && | ||
| 4847 | !test_bit(In_sync, &rdev->flags) && | ||
| 4848 | rdev->recovery_offset < sectors; | ||
| 4849 | } | ||
| 4850 | |||
| 4851 | static enum sync_action md_get_active_sync_action(struct mddev *mddev) | ||
| 4852 | { | ||
| 4853 | struct md_rdev *rdev; | ||
| 4854 | bool is_recover = false; | ||
| 4855 | |||
| 4856 | if (mddev->resync_offset < MaxSector) | ||
| 4857 | return ACTION_RESYNC; | ||
| 4858 | |||
| 4859 | if (mddev->reshape_position != MaxSector) | ||
| 4860 | return ACTION_RESHAPE; | ||
| 4861 | |||
| 4862 | rcu_read_lock(); | ||
| 4863 | rdev_for_each_rcu(rdev, mddev) { | ||
| 4864 | if (rdev_needs_recovery(rdev, MaxSector)) { | ||
| 4865 | is_recover = true; | ||
| 4866 | break; | ||
| 4867 | } | ||
| 4868 | } | ||
| 4869 | rcu_read_unlock(); | ||
| 4870 | |||
| 4871 | return is_recover ? ACTION_RECOVER : ACTION_IDLE; | ||
| 4872 | } | ||
| 4873 | |||
| 4838 | enum sync_action md_sync_action(struct mddev *mddev) | 4874 | enum sync_action md_sync_action(struct mddev *mddev) |
| 4839 | { | 4875 | { |
| 4840 | unsigned long recovery = mddev->recovery; | 4876 | unsigned long recovery = mddev->recovery; |
| 4877 | enum sync_action active_action; | ||
| 4841 | 4878 | ||
| 4842 | /* | 4879 | /* |
| 4843 | * frozen has the highest priority, means running sync_thread will be | 4880 | * frozen has the highest priority, means running sync_thread will be |
| @@ -4861,8 +4898,17 @@ enum sync_action md_sync_action(struct mddev *mddev) · 17 unmodified lines | |||
| 4861 | !test_bit(MD_RECOVERY_NEEDED, &recovery)) | 4898 | !test_bit(MD_RECOVERY_NEEDED, &recovery)) |
| 4862 | return ACTION_IDLE; | 4899 | return ACTION_IDLE; |
| 4863 | 4900 | ||
| 4864 | if (test_bit(MD_RECOVERY_RESHAPE, &recovery) || | 4901 | /* |
| 4865 | mddev->reshape_position != MaxSector) | 4902 | * Check if any sync operation (resync/recover/reshape) is |
| 4903 | * currently active. This ensures that only one sync operation | ||
| 4904 | * can run at a time. Returns the type of active operation, or | ||
| 4905 | * ACTION_IDLE if none are active. | ||
| 4906 | */ | ||
| 4907 | active_action = md_get_active_sync_action(mddev); | ||
| 4908 | if (active_action != ACTION_IDLE) | ||
| 4909 | return active_action; | ||
| 4910 | |||
| 4911 | if (test_bit(MD_RECOVERY_RESHAPE, &recovery)) | ||
| 4866 | return ACTION_RESHAPE; | 4912 | return ACTION_RESHAPE; |
| 4867 | 4913 | ||
| 4868 | if (test_bit(MD_RECOVERY_RECOVER, &recovery)) | 4914 | if (test_bit(MD_RECOVERY_RECOVER, &recovery)) |
| @@ -5818,6 +5864,13 @@ static void md_kobj_release(struct kobject *ko) · 949 unmodified lines | |||
| 5818 | { | 5864 | { |
| 5819 | struct mddev *mddev = container_of(ko, struct mddev, kobj); | 5865 | struct mddev *mddev = container_of(ko, struct mddev, kobj); |
| 5820 | 5866 | ||
| 5867 | if (legacy_async_del_gendisk) { | ||
| 5868 | if (mddev->sysfs_state) | ||
| 5869 | sysfs_put(mddev->sysfs_state); | ||
| 5870 | if (mddev->sysfs_level) | ||
| 5871 | sysfs_put(mddev->sysfs_level); | ||
| 5872 | del_gendisk(mddev->gendisk); | ||
| 5873 | } | ||
| 5821 | put_disk(mddev->gendisk); | 5874 | put_disk(mddev->gendisk); |
| 5822 | } | 5875 | } |
| 5823 | 5876 | ||
| @@ -6021,6 +6074,9 @@ static int md_alloc_and_put(dev_t dev, char *name) · 197 unmodified lines | |||
| 6021 | { | 6074 | { |
| 6022 | struct mddev *mddev = md_alloc(dev, name); | 6075 | struct mddev *mddev = md_alloc(dev, name); |
| 6023 | 6076 | ||
| 6077 | if (legacy_async_del_gendisk) | ||
| 6078 | pr_warn("md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+\n"); | ||
| 6079 | |||
| 6024 | if (IS_ERR(mddev)) | 6080 | if (IS_ERR(mddev)) |
| 6025 | return PTR_ERR(mddev); | 6081 | return PTR_ERR(mddev); |
| 6026 | mddev_put(mddev); | 6082 | mddev_put(mddev); |
| @@ -6431,10 +6487,22 @@ static void md_clean(struct mddev *mddev) · 404 unmodified lines | |||
| 6431 | mddev->persistent = 0; | 6487 | mddev->persistent = 0; |
| 6432 | mddev->level = LEVEL_NONE; | 6488 | mddev->level = LEVEL_NONE; |
| 6433 | mddev->clevel[0] = 0; | 6489 | mddev->clevel[0] = 0; |
| 6434 | /* if UNTIL_STOP is set, it's cleared here */ | 6490 | |
| 6435 | mddev->hold_active = 0; | 6491 | /* |
| 6436 | /* Don't clear MD_CLOSING, or mddev can be opened again. */ | 6492 | * For legacy_async_del_gendisk mode, it can stop the array in the |
| 6437 | mddev->flags &= BIT_ULL_MASK(MD_CLOSING); | 6493 | * middle of assembling it, then it still can access the array. So |
| 6494 | * it needs to clear MD_CLOSING. If not legacy_async_del_gendisk, | ||
| 6495 | * it can't open the array again after stopping it. So it doesn't | ||
| 6496 | * clear MD_CLOSING. | ||
| 6497 | */ | ||
| 6498 | if (legacy_async_del_gendisk && mddev->hold_active) { | ||
| 6499 | clear_bit(MD_CLOSING, &mddev->flags); | ||
| 6500 | } else { | ||
| 6501 | /* if UNTIL_STOP is set, it's cleared here */ | ||
| 6502 | mddev->hold_active = 0; | ||
| 6503 | /* Don't clear MD_CLOSING, or mddev can be opened again. */ | ||
| 6504 | mddev->flags &= BIT_ULL_MASK(MD_CLOSING); | ||
| 6505 | } | ||
| 6438 | mddev->sb_flags = 0; | 6506 | mddev->sb_flags = 0; |
| 6439 | mddev->ro = MD_RDWR; | 6507 | mddev->ro = MD_RDWR; |
| 6440 | mddev->metadata_type[0] = 0; | 6508 | mddev->metadata_type[0] = 0; |
| @@ -6658,7 +6726,8 @@ static int do_md_stop(struct mddev *mddev, int mode) · 217 unmodified lines | |||
| 6658 | 6726 | ||
| 6659 | export_array(mddev); | 6727 | export_array(mddev); |
| 6660 | md_clean(mddev); | 6728 | md_clean(mddev); |
| 6661 | set_bit(MD_DELETED, &mddev->flags); | 6729 | if (!legacy_async_del_gendisk) |
| 6730 | set_bit(MD_DELETED, &mddev->flags); | ||
| 6662 | } | 6731 | } |
| 6663 | md_new_event(); | 6732 | md_new_event(); |
| 6664 | sysfs_notify_dirent_safe(mddev->sysfs_state); | 6733 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
| @@ -8968,11 +9037,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action) · 2303 unmodified lines | |||
| 8968 | start = MaxSector; | 9037 | start = MaxSector; |
| 8969 | rcu_read_lock(); | 9038 | rcu_read_lock(); |
| 8970 | rdev_for_each_rcu(rdev, mddev) | 9039 | rdev_for_each_rcu(rdev, mddev) |
| 8971 | if (rdev->raid_disk >= 0 && | 9040 | if (rdev_needs_recovery(rdev, start)) |
| 8972 | !test_bit(Journal, &rdev->flags) && | ||
| 8973 | !test_bit(Faulty, &rdev->flags) && | ||
| 8974 | !test_bit(In_sync, &rdev->flags) && | ||
| 8975 | rdev->recovery_offset < start) | ||
| 8976 | start = rdev->recovery_offset; | 9041 | start = rdev->recovery_offset; |
| 8977 | rcu_read_unlock(); | 9042 | rcu_read_unlock(); |
| 8978 | 9043 | ||
| @@ -9331,12 +9396,8 @@ void md_do_sync(struct md_thread *thread) · 352 unmodified lines | |||
| 9331 | test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) { | 9396 | test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) { |
| 9332 | rcu_read_lock(); | 9397 | rcu_read_lock(); |
| 9333 | rdev_for_each_rcu(rdev, mddev) | 9398 | rdev_for_each_rcu(rdev, mddev) |
| 9334 | if (rdev->raid_disk >= 0 && | 9399 | if (mddev->delta_disks >= 0 && |
| 9335 | mddev->delta_disks >= 0 && | 9400 | rdev_needs_recovery(rdev, mddev->curr_resync)) |
| 9336 | !test_bit(Journal, &rdev->flags) && | ||
| 9337 | !test_bit(Faulty, &rdev->flags) && | ||
| 9338 | !test_bit(In_sync, &rdev->flags) && | ||
| 9339 | rdev->recovery_offset < mddev->curr_resync) | ||
| 9340 | rdev->recovery_offset = mddev->curr_resync; | 9401 | rdev->recovery_offset = mddev->curr_resync; |
| 9341 | rcu_read_unlock(); | 9402 | rcu_read_unlock(); |
| 9342 | } | 9403 | } |
| @@ -10392,6 +10453,7 @@ module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR); · 1049 unmodified lines | |||
| 10392 | module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR); | 10453 | module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR); |
| 10393 | module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR); | 10454 | module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR); |
| 10394 | module_param(create_on_open, bool, S_IRUSR|S_IWUSR); | 10455 | module_param(create_on_open, bool, S_IRUSR|S_IWUSR); |
| 10456 | module_param(legacy_async_del_gendisk, bool, 0600); | ||
| 10395 | 10457 | ||
| 10396 | MODULE_LICENSE("GPL"); | 10458 | MODULE_LICENSE("GPL"); |
| 10397 | MODULE_DESCRIPTION("MD RAID framework"); | 10459 | MODULE_DESCRIPTION("MD RAID framework"); |
| @@ -1841,7 +1841,6 @@ static int alvium_s_stream(struct v4l2_subdev *sd, int enable) · 1840 unmodified lines | |||
| 1841 | 1841 | ||
| 1842 | } else { | 1842 | } else { |
| 1843 | alvium_set_stream_mipi(alvium, enable); | 1843 | alvium_set_stream_mipi(alvium, enable); |
| 1844 | pm_runtime_mark_last_busy(&client->dev); | ||
| 1845 | pm_runtime_put_autosuspend(&client->dev); | 1844 | pm_runtime_put_autosuspend(&client->dev); |
| 1846 | } | 1845 | } |
| 1847 | 1846 | ||
| @@ -787,10 +787,8 @@ static int ccs_set_ctrl(struct v4l2_ctrl *ctrl) · 786 unmodified lines | |||
| 787 | rval = -EINVAL; | 787 | rval = -EINVAL; |
| 788 | } | 788 | } |
| 789 | 789 | ||
| 790 | if (pm_status > 0) { | 790 | if (pm_status > 0) |
| 791 | pm_runtime_mark_last_busy(&client->dev); | ||
| 792 | pm_runtime_put_autosuspend(&client->dev); | 791 | pm_runtime_put_autosuspend(&client->dev); |
| 793 | } | ||
| 794 | 792 | ||
| 795 | return rval; | 793 | return rval; |
| 796 | } | 794 | } |
| @@ -1914,7 +1912,6 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) · 1117 unmodified lines | |||
| 1914 | if (!enable) { | 1912 | if (!enable) { |
| 1915 | ccs_stop_streaming(sensor); | 1913 | ccs_stop_streaming(sensor); |
| 1916 | sensor->streaming = false; | 1914 | sensor->streaming = false; |
| 1917 | pm_runtime_mark_last_busy(&client->dev); | ||
| 1918 | pm_runtime_put_autosuspend(&client->dev); | 1915 | pm_runtime_put_autosuspend(&client->dev); |
| 1919 | 1916 | ||
| 1920 | return 0; | 1917 | return 0; |
| @@ -1929,7 +1926,6 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) · 8 unmodified lines | |||
| 1929 | rval = ccs_start_streaming(sensor); | 1926 | rval = ccs_start_streaming(sensor); |
| 1930 | if (rval < 0) { | 1927 | if (rval < 0) { |
| 1931 | sensor->streaming = false; | 1928 | sensor->streaming = false; |
| 1932 | pm_runtime_mark_last_busy(&client->dev); | ||
| 1933 | pm_runtime_put_autosuspend(&client->dev); | 1929 | pm_runtime_put_autosuspend(&client->dev); |
| 1934 | } | 1930 | } |
| 1935 | 1931 | ||
| @@ -2677,7 +2673,6 @@ nvm_show(struct device *dev, struct device_attribute *attr, char *buf) · 741 unmodified lines | |||
| 2677 | return -ENODEV; | 2673 | return -ENODEV; |
| 2678 | } | 2674 | } |
| 2679 | 2675 | ||
| 2680 | pm_runtime_mark_last_busy(&client->dev); | ||
| 2681 | pm_runtime_put_autosuspend(&client->dev); | 2676 | pm_runtime_put_autosuspend(&client->dev); |
| 2682 | 2677 | ||
| 2683 | /* | 2678 | /* |
| @@ -374,7 +374,6 @@ static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) · 373 unmodified lines | |||
| 374 | 374 | ||
| 375 | static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 375 | static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
| 376 | { | 376 | { |
| 377 | pm_runtime_mark_last_busy(sd->dev); | ||
| 378 | pm_runtime_put_autosuspend(sd->dev); | 377 | pm_runtime_put_autosuspend(sd->dev); |
| 379 | 378 | ||
| 380 | return 0; | 379 | return 0; |
| @@ -974,7 +974,6 @@ static int gc0308_s_ctrl(struct v4l2_ctrl *ctrl) · 973 unmodified lines | |||
| 974 | if (ret) | 974 | if (ret) |
| 975 | dev_err(gc0308->dev, "failed to set control: %d\n", ret); | 975 | dev_err(gc0308->dev, "failed to set control: %d\n", ret); |
| 976 | 976 | ||
| 977 | pm_runtime_mark_last_busy(gc0308->dev); | ||
| 978 | pm_runtime_put_autosuspend(gc0308->dev); | 977 | pm_runtime_put_autosuspend(gc0308->dev); |
| 979 | 978 | ||
| 980 | return ret; | 979 | return ret; |
| @@ -1157,14 +1156,12 @@ static int gc0308_start_stream(struct gc0308 *gc0308) · 176 unmodified lines | |||
| 1157 | return 0; | 1156 | return 0; |
| 1158 | 1157 | ||
| 1159 | disable_pm: | 1158 | disable_pm: |
| 1160 | pm_runtime_mark_last_busy(gc0308->dev); | ||
| 1161 | pm_runtime_put_autosuspend(gc0308->dev); | 1159 | pm_runtime_put_autosuspend(gc0308->dev); |
| 1162 | return ret; | 1160 | return ret; |
| 1163 | } | 1161 | } |
| 1164 | 1162 | ||
| 1165 | static int gc0308_stop_stream(struct gc0308 *gc0308) | 1163 | static int gc0308_stop_stream(struct gc0308 *gc0308) |
| 1166 | { | 1164 | { |
| 1167 | pm_runtime_mark_last_busy(gc0308->dev); | ||
| 1168 | pm_runtime_put_autosuspend(gc0308->dev); | 1165 | pm_runtime_put_autosuspend(gc0308->dev); |
| 1169 | return 0; | 1166 | return 0; |
| 1170 | } | 1167 | } |
| @@ -963,7 +963,6 @@ static int gc2145_enable_streams(struct v4l2_subdev *sd, · 962 unmodified lines | |||
| 963 | return 0; | 963 | return 0; |
| 964 | 964 | ||
| 965 | err_rpm_put: | 965 | err_rpm_put: |
| 966 | pm_runtime_mark_last_busy(&client->dev); | ||
| 967 | pm_runtime_put_autosuspend(&client->dev); | 966 | pm_runtime_put_autosuspend(&client->dev); |
| 968 | return ret; | 967 | return ret; |
| 969 | } | 968 | } |
| @@ -985,7 +984,6 @@ static int gc2145_disable_streams(struct v4l2_subdev *sd, · 15 unmodified lines | |||
| 985 | if (ret) | 984 | if (ret) |
| 986 | dev_err(&client->dev, "%s failed to write regs\n", __func__); | 985 | dev_err(&client->dev, "%s failed to write regs\n", __func__); |
| 987 | 986 | ||
| 988 | pm_runtime_mark_last_busy(&client->dev); | ||
| 989 | pm_runtime_put_autosuspend(&client->dev); | 987 | pm_runtime_put_autosuspend(&client->dev); |
| 990 | 988 | ||
| 991 | return ret; | 989 | return ret; |
| @@ -1193,7 +1191,6 @@ static int gc2145_s_ctrl(struct v4l2_ctrl *ctrl) · 201 unmodified lines | |||
| 1193 | break; | 1191 | break; |
| 1194 | } | 1192 | } |
| 1195 | 1193 | ||
| 1196 | pm_runtime_mark_last_busy(&client->dev); | ||
| 1197 | pm_runtime_put_autosuspend(&client->dev); | 1194 | pm_runtime_put_autosuspend(&client->dev); |
| 1198 | 1195 | ||
| 1199 | return ret; | 1196 | return ret; |
| @@ -771,7 +771,6 @@ static int imx219_enable_streams(struct v4l2_subdev *sd, · 770 unmodified lines | |||
| 771 | return 0; | 771 | return 0; |
| 772 | 772 | ||
| 773 | err_rpm_put: | 773 | err_rpm_put: |
| 774 | pm_runtime_mark_last_busy(&client->dev); | ||
| 775 | pm_runtime_put_autosuspend(&client->dev); | 774 | pm_runtime_put_autosuspend(&client->dev); |
| 776 | return ret; | 775 | return ret; |
| 777 | } | 776 | } |
| @@ -793,7 +792,6 @@ static int imx219_disable_streams(struct v4l2_subdev *sd, · 15 unmodified lines | |||
| 793 | __v4l2_ctrl_grab(imx219->vflip, false); | 792 | __v4l2_ctrl_grab(imx219->vflip, false); |
| 794 | __v4l2_ctrl_grab(imx219->hflip, false); | 793 | __v4l2_ctrl_grab(imx219->hflip, false); |
| 795 | 794 | ||
| 796 | pm_runtime_mark_last_busy(&client->dev); | ||
| 797 | pm_runtime_put_autosuspend(&client->dev); | 795 | pm_runtime_put_autosuspend(&client->dev); |
| 798 | 796 | ||
| 799 | return ret; | 797 | return ret; |
| @@ -1143,7 +1143,6 @@ static int imx283_enable_streams(struct v4l2_subdev *sd, · 1142 unmodified lines | |||
| 1143 | return 0; | 1143 | return 0; |
| 1144 | 1144 | ||
| 1145 | err_rpm_put: | 1145 | err_rpm_put: |
| 1146 | pm_runtime_mark_last_busy(imx283->dev); | ||
| 1147 | pm_runtime_put_autosuspend(imx283->dev); | 1146 | pm_runtime_put_autosuspend(imx283->dev); |
| 1148 | 1147 | ||
| 1149 | return ret; | 1148 | return ret; |
| @@ -1163,7 +1162,6 @@ static int imx283_disable_streams(struct v4l2_subdev *sd, · 13 unmodified lines | |||
| 1163 | if (ret) | 1162 | if (ret) |
| 1164 | dev_err(imx283->dev, "Failed to stop stream\n"); | 1163 | dev_err(imx283->dev, "Failed to stop stream\n"); |
| 1165 | 1164 | ||
| 1166 | pm_runtime_mark_last_busy(imx283->dev); | ||
| 1167 | pm_runtime_put_autosuspend(imx283->dev); | 1165 | pm_runtime_put_autosuspend(imx283->dev); |
| 1168 | 1166 | ||
| 1169 | return ret; | 1167 | return ret; |
| @@ -1558,7 +1556,6 @@ static int imx283_probe(struct i2c_client *client) · 388 unmodified lines | |||
| 1558 | * Decrease the PM usage count. The device will get suspended after the | 1556 | * Decrease the PM usage count. The device will get suspended after the |
| 1559 | * autosuspend delay, turning the power off. | 1557 | * autosuspend delay, turning the power off. |
| 1560 | */ | 1558 | */ |
| 1561 | pm_runtime_mark_last_busy(imx283->dev); | ||
| 1562 | pm_runtime_put_autosuspend(imx283->dev); | 1559 | pm_runtime_put_autosuspend(imx283->dev); |
| 1563 | 1560 | ||
| 1564 | return 0; | 1561 | return 0; |
| @@ -869,7 +869,6 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl) · 868 unmodified lines | |||
| 869 | break; | 869 | break; |
| 870 | } | 870 | } |
| 871 | 871 | ||
| 872 | pm_runtime_mark_last_busy(imx290->dev); | ||
| 873 | pm_runtime_put_autosuspend(imx290->dev); | 872 | pm_runtime_put_autosuspend(imx290->dev); |
| 874 | 873 | ||
| 875 | return ret; | 874 | return ret; |
| @@ -1099,7 +1098,6 @@ static int imx290_set_stream(struct v4l2_subdev *sd, int enable) · 223 unmodified lines | |||
| 1099 | } | 1098 | } |
| 1100 | } else { | 1099 | } else { |
| 1101 | imx290_stop_streaming(imx290); | 1100 | imx290_stop_streaming(imx290); |
| 1102 | pm_runtime_mark_last_busy(imx290->dev); | ||
| 1103 | pm_runtime_put_autosuspend(imx290->dev); | 1101 | pm_runtime_put_autosuspend(imx290->dev); |
| 1104 | } | 1102 | } |
| 1105 | 1103 | ||
| @@ -1294,7 +1292,6 @@ static int imx290_subdev_init(struct imx290 *imx290) · 188 unmodified lines | |||
| 1294 | * will already be prevented even before the delay. | 1292 | * will already be prevented even before the delay. |
| 1295 | */ | 1293 | */ |
| 1296 | v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops); | 1294 | v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops); |
| 1297 | pm_runtime_mark_last_busy(imx290->dev); | ||
| 1298 | pm_runtime_put_autosuspend(imx290->dev); | 1295 | pm_runtime_put_autosuspend(imx290->dev); |
| 1299 | 1296 | ||
| 1300 | imx290->sd.internal_ops = &imx290_internal_ops; | 1297 | imx290->sd.internal_ops = &imx290_internal_ops; |
| @@ -604,7 +604,6 @@ static int imx296_s_stream(struct v4l2_subdev *sd, int enable) · 603 unmodified lines | |||
| 604 | if (!enable) { | 604 | if (!enable) { |
| 605 | ret = imx296_stream_off(sensor); | 605 | ret = imx296_stream_off(sensor); |
| 606 | 606 | ||
| 607 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 608 | pm_runtime_put_autosuspend(sensor->dev); | 607 | pm_runtime_put_autosuspend(sensor->dev); |
| 609 | 608 | ||
| 610 | goto unlock; | 609 | goto unlock; |
| @@ -952,7 +952,6 @@ static int imx415_s_stream(struct v4l2_subdev *sd, int enable) · 951 unmodified lines | |||
| 952 | if (!enable) { | 952 | if (!enable) { |
| 953 | ret = imx415_stream_off(sensor); | 953 | ret = imx415_stream_off(sensor); |
| 954 | 954 | ||
| 955 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 956 | pm_runtime_put_autosuspend(sensor->dev); | 955 | pm_runtime_put_autosuspend(sensor->dev); |
| 957 | 956 | ||
| 958 | goto unlock; | 957 | goto unlock; |
| @@ -974,7 +974,6 @@ static int mt9m114_start_streaming(struct mt9m114 *sensor, · 973 unmodified lines | |||
| 974 | return 0; | 974 | return 0; |
| 975 | 975 | ||
| 976 | error: | 976 | error: |
| 977 | pm_runtime_mark_last_busy(&sensor->client->dev); | ||
| 978 | pm_runtime_put_autosuspend(&sensor->client->dev); | 977 | pm_runtime_put_autosuspend(&sensor->client->dev); |
| 979 | 978 | ||
| 980 | return ret; | 979 | return ret; |
| @@ -988,7 +987,6 @@ static int mt9m114_stop_streaming(struct mt9m114 *sensor) · 7 unmodified lines | |||
| 988 | 987 | ||
| 989 | ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); | 988 | ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); |
| 990 | 989 | ||
| 991 | pm_runtime_mark_last_busy(&sensor->client->dev); | ||
| 992 | pm_runtime_put_autosuspend(&sensor->client->dev); | 990 | pm_runtime_put_autosuspend(&sensor->client->dev); |
| 993 | 991 | ||
| 994 | return ret; | 992 | return ret; |
| @@ -1046,7 +1044,6 @@ static int mt9m114_pa_g_ctrl(struct v4l2_ctrl *ctrl) · 51 unmodified lines | |||
| 1046 | break; | 1044 | break; |
| 1047 | } | 1045 | } |
| 1048 | 1046 | ||
| 1049 | pm_runtime_mark_last_busy(&sensor->client->dev); | ||
| 1050 | pm_runtime_put_autosuspend(&sensor->client->dev); | 1047 | pm_runtime_put_autosuspend(&sensor->client->dev); |
| 1051 | 1048 | ||
| 1052 | return ret; | 1049 | return ret; |
| @@ -1113,7 +1110,6 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl) · 60 unmodified lines | |||
| 1113 | break; | 1110 | break; |
| 1114 | } | 1111 | } |
| 1115 | 1112 | ||
| 1116 | pm_runtime_mark_last_busy(&sensor->client->dev); | ||
| 1117 | pm_runtime_put_autosuspend(&sensor->client->dev); | 1113 | pm_runtime_put_autosuspend(&sensor->client->dev); |
| 1118 | 1114 | ||
| 1119 | return ret; | 1115 | return ret; |
| @@ -1565,7 +1561,6 @@ static int mt9m114_ifp_s_ctrl(struct v4l2_ctrl *ctrl) · 445 unmodified lines | |||
| 1565 | break; | 1561 | break; |
| 1566 | } | 1562 | } |
| 1567 | 1563 | ||
| 1568 | pm_runtime_mark_last_busy(&sensor->client->dev); | ||
| 1569 | pm_runtime_put_autosuspend(&sensor->client->dev); | 1564 | pm_runtime_put_autosuspend(&sensor->client->dev); |
| 1570 | 1565 | ||
| 1571 | return ret; | 1566 | return ret; |
| @@ -2472,7 +2467,6 @@ static int mt9m114_probe(struct i2c_client *client) · 900 unmodified lines | |||
| 2472 | * Decrease the PM usage count. The device will get suspended after the | 2467 | * Decrease the PM usage count. The device will get suspended after the |
| 2473 | * autosuspend delay, turning the power off. | 2468 | * autosuspend delay, turning the power off. |
| 2474 | */ | 2469 | */ |
| 2475 | pm_runtime_mark_last_busy(dev); | ||
| 2476 | pm_runtime_put_autosuspend(dev); | 2470 | pm_runtime_put_autosuspend(dev); |
| 2477 | 2471 | ||
| 2478 | return 0; | 2472 | return 0; |
| @@ -497,7 +497,6 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) · 496 unmodified lines | |||
| 497 | } else { | 497 | } else { |
| 498 | cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, | 498 | cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, |
| 499 | OV4689_MODE_SW_STANDBY, NULL); | 499 | OV4689_MODE_SW_STANDBY, NULL); |
| 500 | pm_runtime_mark_last_busy(dev); | ||
| 501 | pm_runtime_put_autosuspend(dev); | 500 | pm_runtime_put_autosuspend(dev); |
| 502 | } | 501 | } |
| 503 | 502 | ||
| @@ -702,7 +701,6 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl) · 198 unmodified lines | |||
| 702 | break; | 701 | break; |
| 703 | } | 702 | } |
| 704 | 703 | ||
| 705 | pm_runtime_mark_last_busy(dev); | ||
| 706 | pm_runtime_put_autosuspend(dev); | 704 | pm_runtime_put_autosuspend(dev); |
| 707 | 705 | ||
| 708 | return ret; | 706 | return ret; |
| @@ -999,7 +997,6 @@ static int ov4689_probe(struct i2c_client *client) · 290 unmodified lines | |||
| 999 | goto err_clean_subdev_pm; | 997 | goto err_clean_subdev_pm; |
| 1000 | } | 998 | } |
| 1001 | 999 | ||
| 1002 | pm_runtime_mark_last_busy(dev); | ||
| 1003 | pm_runtime_put_autosuspend(dev); | 1000 | pm_runtime_put_autosuspend(dev); |
| 1004 | 1001 | ||
| 1005 | return 0; | 1002 | return 0; |
| @@ -3341,7 +3341,6 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl) · 3340 unmodified lines | |||
| 3341 | break; | 3341 | break; |
| 3342 | } | 3342 | } |
| 3343 | 3343 | ||
| 3344 | pm_runtime_mark_last_busy(&sensor->i2c_client->dev); | ||
| 3345 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); | 3344 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); |
| 3346 | 3345 | ||
| 3347 | return 0; | 3346 | return 0; |
| @@ -3417,7 +3416,6 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl) · 69 unmodified lines | |||
| 3417 | break; | 3416 | break; |
| 3418 | } | 3417 | } |
| 3419 | 3418 | ||
| 3420 | pm_runtime_mark_last_busy(&sensor->i2c_client->dev); | ||
| 3421 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); | 3419 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); |
| 3422 | 3420 | ||
| 3423 | return ret; | 3421 | return ret; |
| @@ -3754,7 +3752,6 @@ out: · 330 unmodified lines | |||
| 3754 | mutex_unlock(&sensor->lock); | 3752 | mutex_unlock(&sensor->lock); |
| 3755 | 3753 | ||
| 3756 | if (!enable || ret) { | 3754 | if (!enable || ret) { |
| 3757 | pm_runtime_mark_last_busy(&sensor->i2c_client->dev); | ||
| 3758 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); | 3755 | pm_runtime_put_autosuspend(&sensor->i2c_client->dev); |
| 3759 | } | 3756 | } |
| 3760 | 3757 | ||
| @@ -3965,7 +3962,6 @@ static int ov5640_probe(struct i2c_client *client) · 204 unmodified lines | |||
| 3965 | 3962 | ||
| 3966 | pm_runtime_set_autosuspend_delay(dev, 1000); | 3963 | pm_runtime_set_autosuspend_delay(dev, 1000); |
| 3967 | pm_runtime_use_autosuspend(dev); | 3964 | pm_runtime_use_autosuspend(dev); |
| 3968 | pm_runtime_mark_last_busy(dev); | ||
| 3969 | pm_runtime_put_autosuspend(dev); | 3965 | pm_runtime_put_autosuspend(dev); |
| 3970 | 3966 | ||
| 3971 | return 0; | 3967 | return 0; |
| @@ -808,7 +808,6 @@ static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl) · 807 unmodified lines | |||
| 808 | break; | 808 | break; |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | pm_runtime_mark_last_busy(ov5645->dev); | ||
| 812 | pm_runtime_put_autosuspend(ov5645->dev); | 811 | pm_runtime_put_autosuspend(ov5645->dev); |
| 813 | 812 | ||
| 814 | return ret; | 813 | return ret; |
| @@ -979,7 +978,6 @@ static int ov5645_disable_streams(struct v4l2_subdev *sd, · 164 unmodified lines | |||
| 979 | OV5645_SYSTEM_CTRL0_STOP); | 978 | OV5645_SYSTEM_CTRL0_STOP); |
| 980 | 979 | ||
| 981 | rpm_put: | 980 | rpm_put: |
| 982 | pm_runtime_mark_last_busy(ov5645->dev); | ||
| 983 | pm_runtime_put_autosuspend(ov5645->dev); | 981 | pm_runtime_put_autosuspend(ov5645->dev); |
| 984 | 982 | ||
| 985 | return ret; | 983 | return ret; |
| @@ -1196,7 +1194,6 @@ static int ov5645_probe(struct i2c_client *client) · 210 unmodified lines | |||
| 1196 | 1194 | ||
| 1197 | pm_runtime_set_autosuspend_delay(dev, 1000); | 1195 | pm_runtime_set_autosuspend_delay(dev, 1000); |
| 1198 | pm_runtime_use_autosuspend(dev); | 1196 | pm_runtime_use_autosuspend(dev); |
| 1199 | pm_runtime_mark_last_busy(dev); | ||
| 1200 | pm_runtime_put_autosuspend(dev); | 1197 | pm_runtime_put_autosuspend(dev); |
| 1201 | 1198 | ||
| 1202 | return 0; | 1199 | return 0; |
| @@ -2990,7 +2990,6 @@ static int ov64a40_start_streaming(struct ov64a40 *ov64a40, · 2989 unmodified lines | |||
| 2990 | return 0; | 2990 | return 0; |
| 2991 | 2991 | ||
| 2992 | error_power_off: | 2992 | error_power_off: |
| 2993 | pm_runtime_mark_last_busy(ov64a40->dev); | ||
| 2994 | pm_runtime_put_autosuspend(ov64a40->dev); | 2993 | pm_runtime_put_autosuspend(ov64a40->dev); |
| 2995 | 2994 | ||
| 2996 | return ret; | 2995 | return ret; |
| @@ -3000,7 +2999,6 @@ static int ov64a40_stop_streaming(struct ov64a40 *ov64a40, · 3 unmodified lines | |||
| 3000 | struct v4l2_subdev_state *state) | 2999 | struct v4l2_subdev_state *state) |
| 3001 | { | 3000 | { |
| 3002 | cci_update_bits(ov64a40->cci, OV64A40_REG_SMIA, BIT(0), 0, NULL); | 3001 | cci_update_bits(ov64a40->cci, OV64A40_REG_SMIA, BIT(0), 0, NULL); |
| 3003 | pm_runtime_mark_last_busy(ov64a40->dev); | ||
| 3004 | pm_runtime_put_autosuspend(ov64a40->dev); | 3002 | pm_runtime_put_autosuspend(ov64a40->dev); |
| 3005 | 3003 | ||
| 3006 | __v4l2_ctrl_grab(ov64a40->link_freq, false); | 3004 | __v4l2_ctrl_grab(ov64a40->link_freq, false); |
| @@ -3329,10 +3327,8 @@ static int ov64a40_set_ctrl(struct v4l2_ctrl *ctrl) · 322 unmodified lines | |||
| 3329 | break; | 3327 | break; |
| 3330 | } | 3328 | } |
| 3331 | 3329 | ||
| 3332 | if (pm_status > 0) { | 3330 | if (pm_status > 0) |
| 3333 | pm_runtime_mark_last_busy(ov64a40->dev); | ||
| 3334 | pm_runtime_put_autosuspend(ov64a40->dev); | 3331 | pm_runtime_put_autosuspend(ov64a40->dev); |
| 3335 | } | ||
| 3336 | 3332 | ||
| 3337 | return ret; | 3333 | return ret; |
| 3338 | } | 3334 | } |
| @@ -3622,7 +3618,6 @@ static int ov64a40_probe(struct i2c_client *client) · 283 unmodified lines | |||
| 3622 | goto error_subdev_cleanup; | 3618 | goto error_subdev_cleanup; |
| 3623 | } | 3619 | } |
| 3624 | 3620 | ||
| 3625 | pm_runtime_mark_last_busy(&client->dev); | ||
| 3626 | pm_runtime_put_autosuspend(&client->dev); | 3621 | pm_runtime_put_autosuspend(&client->dev); |
| 3627 | 3622 | ||
| 3628 | return 0; | 3623 | return 0; |
| @@ -1391,7 +1391,6 @@ static int ov8858_s_stream(struct v4l2_subdev *sd, int on) · 1390 unmodified lines | |||
| 1391 | } | 1391 | } |
| 1392 | } else { | 1392 | } else { |
| 1393 | ov8858_stop_stream(ov8858); | 1393 | ov8858_stop_stream(ov8858); |
| 1394 | pm_runtime_mark_last_busy(&client->dev); | ||
| 1395 | pm_runtime_put_autosuspend(&client->dev); | 1394 | pm_runtime_put_autosuspend(&client->dev); |
| 1396 | } | 1395 | } |
| 1397 | 1396 | ||
| @@ -1945,7 +1944,6 @@ static int ov8858_probe(struct i2c_client *client) · 547 unmodified lines | |||
| 1945 | goto err_power_off; | 1944 | goto err_power_off; |
| 1946 | } | 1945 | } |
| 1947 | 1946 | ||
| 1948 | pm_runtime_mark_last_busy(dev); | ||
| 1949 | pm_runtime_put_autosuspend(dev); | 1947 | pm_runtime_put_autosuspend(dev); |
| 1950 | 1948 | ||
| 1951 | return 0; | 1949 | return 0; |
| @@ -465,7 +465,6 @@ static int mipid02_disable_streams(struct v4l2_subdev *sd, · 464 unmodified lines | |||
| 465 | if (ret) | 465 | if (ret) |
| 466 | goto error; | 466 | goto error; |
| 467 | 467 | ||
| 468 | pm_runtime_mark_last_busy(&client->dev); | ||
| 469 | pm_runtime_put_autosuspend(&client->dev); | 468 | pm_runtime_put_autosuspend(&client->dev); |
| 470 | 469 | ||
| 471 | error: | 470 | error: |
| @@ -542,7 +541,6 @@ error: · 70 unmodified lines | |||
| 542 | cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret); | 541 | cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret); |
| 543 | cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret); | 542 | cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret); |
| 544 | 543 | ||
| 545 | pm_runtime_mark_last_busy(&client->dev); | ||
| 546 | pm_runtime_put_autosuspend(&client->dev); | 544 | pm_runtime_put_autosuspend(&client->dev); |
| 547 | return ret; | 545 | return ret; |
| 548 | } | 546 | } |
| @@ -816,7 +816,6 @@ static int tc358746_s_stream(struct v4l2_subdev *sd, int enable) · 815 unmodified lines | |||
| 816 | return 0; | 816 | return 0; |
| 817 | 817 | ||
| 818 | err_out: | 818 | err_out: |
| 819 | pm_runtime_mark_last_busy(sd->dev); | ||
| 820 | pm_runtime_put_sync_autosuspend(sd->dev); | 819 | pm_runtime_put_sync_autosuspend(sd->dev); |
| 821 | 820 | ||
| 822 | return err; | 821 | return err; |
| @@ -838,7 +837,6 @@ err_out: · 15 unmodified lines | |||
| 838 | if (err) | 837 | if (err) |
| 839 | return err; | 838 | return err; |
| 840 | 839 | ||
| 841 | pm_runtime_mark_last_busy(sd->dev); | ||
| 842 | pm_runtime_put_sync_autosuspend(sd->dev); | 840 | pm_runtime_put_sync_autosuspend(sd->dev); |
| 843 | 841 | ||
| 844 | return v4l2_subdev_call(src, video, s_stream, 0); | 842 | return v4l2_subdev_call(src, video, s_stream, 0); |
| @@ -1016,7 +1014,6 @@ tc358746_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) · 171 unmodified lines | |||
| 1016 | err = tc358746_read(tc358746, reg->reg, &val); | 1014 | err = tc358746_read(tc358746, reg->reg, &val); |
| 1017 | reg->val = val; | 1015 | reg->val = val; |
| 1018 | 1016 | ||
| 1019 | pm_runtime_mark_last_busy(sd->dev); | ||
| 1020 | pm_runtime_put_sync_autosuspend(sd->dev); | 1017 | pm_runtime_put_sync_autosuspend(sd->dev); |
| 1021 | 1018 | ||
| 1022 | return err; | 1019 | return err; |
| @@ -1032,7 +1029,6 @@ tc358746_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) · 9 unmodified lines | |||
| 1032 | 1029 | ||
| 1033 | tc358746_write(tc358746, (u32)reg->reg, (u32)reg->val); | 1030 | tc358746_write(tc358746, (u32)reg->reg, (u32)reg->val); |
| 1034 | 1031 | ||
| 1035 | pm_runtime_mark_last_busy(sd->dev); | ||
| 1036 | pm_runtime_put_sync_autosuspend(sd->dev); | 1032 | pm_runtime_put_sync_autosuspend(sd->dev); |
| 1037 | 1033 | ||
| 1038 | return 0; | 1034 | return 0; |
| @@ -1395,7 +1391,6 @@ static int tc358746_init_hw(struct tc358746 *tc358746) · 356 unmodified lines | |||
| 1395 | } | 1391 | } |
| 1396 | 1392 | ||
| 1397 | err = tc358746_read(tc358746, CHIPID_REG, &val); | 1393 | err = tc358746_read(tc358746, CHIPID_REG, &val); |
| 1398 | pm_runtime_mark_last_busy(dev); | ||
| 1399 | pm_runtime_put_sync_autosuspend(dev); | 1394 | pm_runtime_put_sync_autosuspend(dev); |
| 1400 | if (err) | 1395 | if (err) |
| 1401 | return -ENODEV; | 1396 | return -ENODEV; |
| @@ -808,7 +808,6 @@ static int thp7312_s_stream(struct v4l2_subdev *sd, int enable) · 807 unmodified lines | |||
| 808 | if (!enable) { | 808 | if (!enable) { |
| 809 | thp7312_stream_enable(thp7312, false); | 809 | thp7312_stream_enable(thp7312, false); |
| 810 | 810 | ||
| 811 | pm_runtime_mark_last_busy(thp7312->dev); | ||
| 812 | pm_runtime_put_autosuspend(thp7312->dev); | 811 | pm_runtime_put_autosuspend(thp7312->dev); |
| 813 | 812 | ||
| 814 | v4l2_subdev_unlock_state(sd_state); | 813 | v4l2_subdev_unlock_state(sd_state); |
| @@ -839,7 +838,6 @@ static int thp7312_s_stream(struct v4l2_subdev *sd, int enable) · 24 unmodified lines | |||
| 839 | goto finish_unlock; | 838 | goto finish_unlock; |
| 840 | 839 | ||
| 841 | finish_pm: | 840 | finish_pm: |
| 842 | pm_runtime_mark_last_busy(thp7312->dev); | ||
| 843 | pm_runtime_put_autosuspend(thp7312->dev); | 841 | pm_runtime_put_autosuspend(thp7312->dev); |
| 844 | finish_unlock: | 842 | finish_unlock: |
| 845 | v4l2_subdev_unlock_state(sd_state); | 843 | v4l2_subdev_unlock_state(sd_state); |
| @@ -1147,7 +1145,6 @@ static int thp7312_s_ctrl(struct v4l2_ctrl *ctrl) · 301 unmodified lines | |||
| 1147 | break; | 1145 | break; |
| 1148 | } | 1146 | } |
| 1149 | 1147 | ||
| 1150 | pm_runtime_mark_last_busy(thp7312->dev); | ||
| 1151 | pm_runtime_put_autosuspend(thp7312->dev); | 1148 | pm_runtime_put_autosuspend(thp7312->dev); |
| 1152 | 1149 | ||
| 1153 | return ret; | 1150 | return ret; |
| @@ -2183,7 +2180,6 @@ static int thp7312_probe(struct i2c_client *client) · 1029 unmodified lines | |||
| 2183 | * Decrease the PM usage count. The device will get suspended after the | 2180 | * Decrease the PM usage count. The device will get suspended after the |
| 2184 | * autosuspend delay, turning the power off. | 2181 | * autosuspend delay, turning the power off. |
| 2185 | */ | 2182 | */ |
| 2186 | pm_runtime_mark_last_busy(dev); | ||
| 2187 | pm_runtime_put_autosuspend(dev); | 2183 | pm_runtime_put_autosuspend(dev); |
| 2188 | 2184 | ||
| 2189 | dev_info(dev, "THP7312 firmware version %02u.%02u\n", | 2185 | dev_info(dev, "THP7312 firmware version %02u.%02u\n", |
| @@ -1104,7 +1104,6 @@ static int vd55g1_disable_streams(struct v4l2_subdev *sd, · 1103 unmodified lines | |||
| 1104 | 1104 | ||
| 1105 | vd55g1_grab_ctrls(sensor, false); | 1105 | vd55g1_grab_ctrls(sensor, false); |
| 1106 | 1106 | ||
| 1107 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 1108 | pm_runtime_put_autosuspend(sensor->dev); | 1107 | pm_runtime_put_autosuspend(sensor->dev); |
| 1109 | 1108 | ||
| 1110 | return ret; | 1109 | return ret; |
| @@ -1338,7 +1337,6 @@ static int vd55g1_g_volatile_ctrl(struct v4l2_ctrl *ctrl) · 227 unmodified lines | |||
| 1338 | break; | 1337 | break; |
| 1339 | } | 1338 | } |
| 1340 | 1339 | ||
| 1341 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 1342 | pm_runtime_put_autosuspend(sensor->dev); | 1340 | pm_runtime_put_autosuspend(sensor->dev); |
| 1343 | 1341 | ||
| 1344 | return ret; | 1342 | return ret; |
| @@ -1433,7 +1431,6 @@ static int vd55g1_s_ctrl(struct v4l2_ctrl *ctrl) · 88 unmodified lines | |||
| 1433 | break; | 1431 | break; |
| 1434 | } | 1432 | } |
| 1435 | 1433 | ||
| 1436 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 1437 | pm_runtime_put_autosuspend(sensor->dev); | 1434 | pm_runtime_put_autosuspend(sensor->dev); |
| 1438 | 1435 | ||
| 1439 | return ret; | 1436 | return ret; |
| @@ -1895,7 +1892,6 @@ static int vd55g1_probe(struct i2c_client *client) · 455 unmodified lines | |||
| 1895 | pm_runtime_enable(dev); | 1892 | pm_runtime_enable(dev); |
| 1896 | pm_runtime_set_autosuspend_delay(dev, 4000); | 1893 | pm_runtime_set_autosuspend_delay(dev, 4000); |
| 1897 | pm_runtime_use_autosuspend(dev); | 1894 | pm_runtime_use_autosuspend(dev); |
| 1898 | pm_runtime_mark_last_busy(dev); | ||
| 1899 | pm_runtime_put_autosuspend(dev); | 1895 | pm_runtime_put_autosuspend(dev); |
| 1900 | 1896 | ||
| 1901 | ret = vd55g1_subdev_init(sensor); | 1897 | ret = vd55g1_subdev_init(sensor); |
| @@ -493,7 +493,6 @@ static int vd56g3_g_volatile_ctrl(struct v4l2_ctrl *ctrl) · 492 unmodified lines | |||
| 493 | break; | 493 | break; |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 497 | pm_runtime_put_autosuspend(sensor->dev); | 496 | pm_runtime_put_autosuspend(sensor->dev); |
| 498 | 497 | ||
| 499 | return ret; | 498 | return ret; |
| @@ -577,7 +576,6 @@ static int vd56g3_s_ctrl(struct v4l2_ctrl *ctrl) · 77 unmodified lines | |||
| 577 | break; | 576 | break; |
| 578 | } | 577 | } |
| 579 | 578 | ||
| 580 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 581 | pm_runtime_put_autosuspend(sensor->dev); | 579 | pm_runtime_put_autosuspend(sensor->dev); |
| 582 | 580 | ||
| 583 | return ret; | 581 | return ret; |
| @@ -1021,7 +1019,6 @@ static int vd56g3_disable_streams(struct v4l2_subdev *sd, · 437 unmodified lines | |||
| 1021 | __v4l2_ctrl_grab(sensor->vflip_ctrl, false); | 1019 | __v4l2_ctrl_grab(sensor->vflip_ctrl, false); |
| 1022 | __v4l2_ctrl_grab(sensor->patgen_ctrl, false); | 1020 | __v4l2_ctrl_grab(sensor->patgen_ctrl, false); |
| 1023 | 1021 | ||
| 1024 | pm_runtime_mark_last_busy(sensor->dev); | ||
| 1025 | pm_runtime_put_autosuspend(sensor->dev); | 1022 | pm_runtime_put_autosuspend(sensor->dev); |
| 1026 | 1023 | ||
| 1027 | return ret; | 1024 | return ret; |
| @@ -1527,7 +1524,6 @@ static int vd56g3_probe(struct i2c_client *client) · 499 unmodified lines | |||
| 1527 | } | 1524 | } |
| 1528 | 1525 | ||
| 1529 | /* Sensor could now be powered off (after the autosuspend delay) */ | 1526 | /* Sensor could now be powered off (after the autosuspend delay) */ |
| 1530 | pm_runtime_mark_last_busy(dev); | ||
| 1531 | pm_runtime_put_autosuspend(dev); | 1527 | pm_runtime_put_autosuspend(dev); |
| 1532 | 1528 | ||
| 1533 | dev_dbg(dev, "Successfully probe %s sensor\n", | 1529 | dev_dbg(dev, "Successfully probe %s sensor\n", |
| @@ -288,7 +288,6 @@ static int amg88xx_read(struct device *dev, enum hwmon_sensor_types type, · 287 unmodified lines | |||
| 288 | return tmp; | 288 | return tmp; |
| 289 | 289 | ||
| 290 | tmp = regmap_bulk_read(data->regmap, AMG88XX_REG_TTHL, &buf, 2); | 290 | tmp = regmap_bulk_read(data->regmap, AMG88XX_REG_TTHL, &buf, 2); |
| 291 | pm_runtime_mark_last_busy(regmap_get_device(data->regmap)); | ||
| 292 | pm_runtime_put_autosuspend(regmap_get_device(data->regmap)); | 291 | pm_runtime_put_autosuspend(regmap_get_device(data->regmap)); |
| 293 | if (tmp) | 292 | if (tmp) |
| 294 | return tmp; | 293 | return tmp; |
| @@ -527,7 +526,6 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) · 232 unmodified lines | |||
| 527 | return 0; | 526 | return 0; |
| 528 | 527 | ||
| 529 | error_rpm_put: | 528 | error_rpm_put: |
| 530 | pm_runtime_mark_last_busy(dev); | ||
| 531 | pm_runtime_put_autosuspend(dev); | 529 | pm_runtime_put_autosuspend(dev); |
| 532 | error_del_list: | 530 | error_del_list: |
| 533 | video_i2c_del_list(vq, VB2_BUF_STATE_QUEUED); | 531 | video_i2c_del_list(vq, VB2_BUF_STATE_QUEUED); |
| @@ -544,7 +542,6 @@ static void stop_streaming(struct vb2_queue *vq) · 10 unmodified lines | |||
| 544 | 542 | ||
| 545 | kthread_stop(data->kthread_vid_cap); | 543 | kthread_stop(data->kthread_vid_cap); |
| 546 | data->kthread_vid_cap = NULL; | 544 | data->kthread_vid_cap = NULL; |
| 547 | pm_runtime_mark_last_busy(regmap_get_device(data->regmap)); | ||
| 548 | pm_runtime_put_autosuspend(regmap_get_device(data->regmap)); | 545 | pm_runtime_put_autosuspend(regmap_get_device(data->regmap)); |
| 549 | 546 | ||
| 550 | video_i2c_del_list(vq, VB2_BUF_STATE_ERROR); | 547 | video_i2c_del_list(vq, VB2_BUF_STATE_ERROR); |
| @@ -853,7 +850,6 @@ static int video_i2c_probe(struct i2c_client *client) · 302 unmodified lines | |||
| 853 | if (ret < 0) | 850 | if (ret < 0) |
| 854 | goto error_pm_disable; | 851 | goto error_pm_disable; |
| 855 | 852 | ||
| 856 | pm_runtime_mark_last_busy(&client->dev); | ||
| 857 | pm_runtime_put_autosuspend(&client->dev); | 853 | pm_runtime_put_autosuspend(&client->dev); |
| 858 | 854 | ||
| 859 | return 0; | 855 | return 0; |
| @@ -451,7 +451,6 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst) · 450 unmodified lines | |||
| 451 | if (q_status.report_queue_count == 0 && | 451 | if (q_status.report_queue_count == 0 && |
| 452 | (q_status.instance_queue_count == 0 || dec_info.sequence_changed)) { | 452 | (q_status.instance_queue_count == 0 || dec_info.sequence_changed)) { |
| 453 | dev_dbg(inst->dev->dev, "%s: finishing job.\n", __func__); | 453 | dev_dbg(inst->dev->dev, "%s: finishing job.\n", __func__); |
| 454 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 455 | pm_runtime_put_autosuspend(inst->dev->dev); | 454 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 456 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); | 455 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); |
| 457 | } | 456 | } |
| @@ -1364,7 +1363,6 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count · 906 unmodified lines | |||
| 1364 | } | 1363 | } |
| 1365 | 1364 | ||
| 1366 | } | 1365 | } |
| 1367 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1368 | pm_runtime_put_autosuspend(inst->dev->dev); | 1366 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1369 | return ret; | 1367 | return ret; |
| 1370 | 1368 | ||
| @@ -1498,7 +1496,6 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q) · 127 unmodified lines | |||
| 1498 | else | 1496 | else |
| 1499 | streamoff_capture(q); | 1497 | streamoff_capture(q); |
| 1500 | 1498 | ||
| 1501 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1502 | pm_runtime_put_autosuspend(inst->dev->dev); | 1499 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1503 | } | 1500 | } |
| 1504 | 1501 | ||
| @@ -1662,7 +1659,6 @@ static void wave5_vpu_dec_device_run(void *priv) · 157 unmodified lines | |||
| 1662 | 1659 | ||
| 1663 | finish_job_and_return: | 1660 | finish_job_and_return: |
| 1664 | dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__); | 1661 | dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__); |
| 1665 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1666 | pm_runtime_put_autosuspend(inst->dev->dev); | 1662 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1667 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); | 1663 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); |
| 1668 | } | 1664 | } |
| @@ -1391,12 +1391,10 @@ static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count · 1390 unmodified lines | |||
| 1391 | if (ret) | 1391 | if (ret) |
| 1392 | goto return_buffers; | 1392 | goto return_buffers; |
| 1393 | 1393 | ||
| 1394 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1395 | pm_runtime_put_autosuspend(inst->dev->dev); | 1394 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1396 | return 0; | 1395 | return 0; |
| 1397 | return_buffers: | 1396 | return_buffers: |
| 1398 | wave5_return_bufs(q, VB2_BUF_STATE_QUEUED); | 1397 | wave5_return_bufs(q, VB2_BUF_STATE_QUEUED); |
| 1399 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1400 | pm_runtime_put_autosuspend(inst->dev->dev); | 1398 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1401 | return ret; | 1399 | return ret; |
| 1402 | } | 1400 | } |
| @@ -1465,7 +1463,6 @@ static void wave5_vpu_enc_stop_streaming(struct vb2_queue *q) · 62 unmodified lines | |||
| 1465 | else | 1463 | else |
| 1466 | streamoff_capture(inst, q); | 1464 | streamoff_capture(inst, q); |
| 1467 | 1465 | ||
| 1468 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1469 | pm_runtime_put_autosuspend(inst->dev->dev); | 1466 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1470 | } | 1467 | } |
| 1471 | 1468 | ||
| @@ -1520,7 +1517,6 @@ static void wave5_vpu_enc_device_run(void *priv) · 48 unmodified lines | |||
| 1520 | break; | 1517 | break; |
| 1521 | } | 1518 | } |
| 1522 | dev_dbg(inst->dev->dev, "%s: leave with active job", __func__); | 1519 | dev_dbg(inst->dev->dev, "%s: leave with active job", __func__); |
| 1523 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1524 | pm_runtime_put_autosuspend(inst->dev->dev); | 1520 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1525 | return; | 1521 | return; |
| 1526 | default: | 1522 | default: |
| @@ -1529,7 +1525,6 @@ static void wave5_vpu_enc_device_run(void *priv) · 2 unmodified lines | |||
| 1529 | break; | 1525 | break; |
| 1530 | } | 1526 | } |
| 1531 | dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__); | 1527 | dev_dbg(inst->dev->dev, "%s: leave and finish job", __func__); |
| 1532 | pm_runtime_mark_last_busy(inst->dev->dev); | ||
| 1533 | pm_runtime_put_autosuspend(inst->dev->dev); | 1528 | pm_runtime_put_autosuspend(inst->dev->dev); |
| 1534 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); | 1529 | v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx); |
| 1535 | } | 1530 | } |
| @@ -585,7 +585,6 @@ static int tegra_vde_decode_begin(struct tegra_vde *vde, · 584 unmodified lines | |||
| 585 | return 0; | 585 | return 0; |
| 586 | 586 | ||
| 587 | put_runtime_pm: | 587 | put_runtime_pm: |
| 588 | pm_runtime_mark_last_busy(dev); | ||
| 589 | pm_runtime_put_autosuspend(dev); | 588 | pm_runtime_put_autosuspend(dev); |
| 590 | 589 | ||
| 591 | unlock: | 590 | unlock: |
| @@ -612,7 +611,6 @@ static void tegra_vde_decode_abort(struct tegra_vde *vde) · 20 unmodified lines | |||
| 612 | if (err) | 611 | if (err) |
| 613 | dev_err(dev, "DEC end: Failed to assert HW reset: %d\n", err); | 612 | dev_err(dev, "DEC end: Failed to assert HW reset: %d\n", err); |
| 614 | 613 | ||
| 615 | pm_runtime_mark_last_busy(dev); | ||
| 616 | pm_runtime_put_autosuspend(dev); | 614 | pm_runtime_put_autosuspend(dev); |
| 617 | 615 | ||
| 618 | mutex_unlock(&vde->lock); | 616 | mutex_unlock(&vde->lock); |
| @@ -142,7 +142,6 @@ int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_size) · 141 unmodified lines | |||
| 142 | } | 142 | } |
| 143 | mutex_unlock(&core->lock); | 143 | mutex_unlock(&core->lock); |
| 144 | 144 | ||
| 145 | pm_runtime_mark_last_busy(core->dev); | ||
| 146 | pm_runtime_put_autosuspend(core->dev); | 145 | pm_runtime_put_autosuspend(core->dev); |
| 147 | 146 | ||
| 148 | return 0; | 147 | return 0; |
| @@ -950,7 +950,6 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q) · 949 unmodified lines | |||
| 950 | kfree(job); | 950 | kfree(job); |
| 951 | } | 951 | } |
| 952 | 952 | ||
| 953 | pm_runtime_mark_last_busy(pispbe->dev); | ||
| 954 | pm_runtime_put_autosuspend(pispbe->dev); | 953 | pm_runtime_put_autosuspend(pispbe->dev); |
| 955 | 954 | ||
| 956 | dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", | 955 | dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n", |
| @@ -1742,7 +1741,6 @@ static int pispbe_probe(struct platform_device *pdev) · 785 unmodified lines | |||
| 1742 | if (ret) | 1741 | if (ret) |
| 1743 | goto disable_devs_err; | 1742 | goto disable_devs_err; |
| 1744 | 1743 | ||
| 1745 | pm_runtime_mark_last_busy(pispbe->dev); | ||
| 1746 | pm_runtime_put_autosuspend(pispbe->dev); | 1744 | pm_runtime_put_autosuspend(pispbe->dev); |
| 1747 | 1745 | ||
| 1748 | return 0; | 1746 | return 0; |
| @@ -765,7 +765,6 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx, · 764 unmodified lines | |||
| 765 | { | 765 | { |
| 766 | struct rkvdec_dev *rkvdec = ctx->dev; | 766 | struct rkvdec_dev *rkvdec = ctx->dev; |
| 767 | 767 | ||
| 768 | pm_runtime_mark_last_busy(rkvdec->dev); | ||
| 769 | pm_runtime_put_autosuspend(rkvdec->dev); | 768 | pm_runtime_put_autosuspend(rkvdec->dev); |
| 770 | rkvdec_job_finish_no_pm(ctx, result); | 769 | rkvdec_job_finish_no_pm(ctx, result); |
| 771 | } | 770 | } |
| @@ -1159,13 +1158,6 @@ static int rkvdec_probe(struct platform_device *pdev) · 387 unmodified lines | |||
| 1159 | return ret; | 1158 | return ret; |
| 1160 | } | 1159 | } |
| 1161 | 1160 | ||
| 1162 | if (iommu_get_domain_for_dev(&pdev->dev)) { | ||
| 1163 | rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev); | ||
| 1164 | |||
| 1165 | if (!rkvdec->empty_domain) | ||
| 1166 | dev_warn(rkvdec->dev, "cannot alloc new empty domain\n"); | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); | 1161 | vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); |
| 1170 | 1162 | ||
| 1171 | irq = platform_get_irq(pdev, 0); | 1163 | irq = platform_get_irq(pdev, 0); |
| @@ -1188,6 +1180,15 @@ static int rkvdec_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 1188 | if (ret) | 1180 | if (ret) |
| 1189 | goto err_disable_runtime_pm; | 1181 | goto err_disable_runtime_pm; |
| 1190 | 1182 | ||
| 1183 | if (iommu_get_domain_for_dev(&pdev->dev)) { | ||
| 1184 | rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev); | ||
| 1185 | |||
| 1186 | if (IS_ERR(rkvdec->empty_domain)) { | ||
| 1187 | rkvdec->empty_domain = NULL; | ||
| 1188 | dev_warn(rkvdec->dev, "cannot alloc new empty domain\n"); | ||
| 1189 | } | ||
| 1190 | } | ||
| 1191 | |||
| 1191 | return 0; | 1192 | return 0; |
| 1192 | 1193 | ||
| 1193 | err_disable_runtime_pm: | 1194 | err_disable_runtime_pm: |
| @@ -89,7 +89,6 @@ static void hantro_job_finish(struct hantro_dev *vpu, · 88 unmodified lines | |||
| 89 | struct hantro_ctx *ctx, | 89 | struct hantro_ctx *ctx, |
| 90 | enum vb2_buffer_state result) | 90 | enum vb2_buffer_state result) |
| 91 | { | 91 | { |
| 92 | pm_runtime_mark_last_busy(vpu->dev); | ||
| 93 | pm_runtime_put_autosuspend(vpu->dev); | 92 | pm_runtime_put_autosuspend(vpu->dev); |
| 94 | 93 | ||
| 95 | clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); | 94 | clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); |
| @@ -48,10 +48,8 @@ static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) · 47 unmodified lines | |||
| 48 | if (val >= 0) | 48 | if (val >= 0) |
| 49 | ir_raw_event_store_edge(gpio_dev->rcdev, val == 1); | 49 | ir_raw_event_store_edge(gpio_dev->rcdev, val == 1); |
| 50 | 50 | ||
| 51 | if (pmdev) { | 51 | if (pmdev) |
| 52 | pm_runtime_mark_last_busy(pmdev); | ||
| 53 | pm_runtime_put_autosuspend(pmdev); | 52 | pm_runtime_put_autosuspend(pmdev); |
| 54 | } | ||
| 55 | 53 | ||
| 56 | return IRQ_HANDLED; | 54 | return IRQ_HANDLED; |
| 57 | } | 55 | } |
| @@ -555,7 +555,6 @@ EXPORT_SYMBOL(memstick_add_host); · 554 unmodified lines | |||
| 555 | */ | 555 | */ |
| 556 | void memstick_remove_host(struct memstick_host *host) | 556 | void memstick_remove_host(struct memstick_host *host) |
| 557 | { | 557 | { |
| 558 | host->removing = 1; | ||
| 559 | flush_workqueue(workqueue); | 558 | flush_workqueue(workqueue); |
| 560 | mutex_lock(&host->lock); | 559 | mutex_lock(&host->lock); |
| 561 | if (host->card) | 560 | if (host->card) |
| @@ -812,6 +812,7 @@ static void rtsx_usb_ms_drv_remove(struct platform_device *pdev) · 811 unmodified lines | |||
| 812 | int err; | 812 | int err; |
| 813 | 813 | ||
| 814 | host->eject = true; | 814 | host->eject = true; |
| 815 | msh->removing = true; | ||
| 815 | cancel_work_sync(&host->handle_req); | 816 | cancel_work_sync(&host->handle_req); |
| 816 | cancel_delayed_work_sync(&host->poll_card); | 817 | cancel_delayed_work_sync(&host->poll_card); |
| 817 | 818 | ||
| @@ -99,6 +99,9 @@ · 98 unmodified lines | |||
| 99 | #define HIWORD_UPDATE(val, mask, shift) \ | 99 | #define HIWORD_UPDATE(val, mask, shift) \ |
| 100 | ((val) << (shift) | (mask) << ((shift) + 16)) | 100 | ((val) << (shift) | (mask) << ((shift) + 16)) |
| 101 | 101 | ||
| 102 | #define CD_STABLE_TIMEOUT_US 1000000 | ||
| 103 | #define CD_STABLE_MAX_SLEEP_US 10 | ||
| 104 | |||
| 102 | /** | 105 | /** |
| 103 | * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map | 106 | * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map |
| 104 | * | 107 | * |
| @@ -206,12 +209,15 @@ struct sdhci_arasan_data { · 101 unmodified lines | |||
| 206 | * 19MHz instead | 209 | * 19MHz instead |
| 207 | */ | 210 | */ |
| 208 | #define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) | 211 | #define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) |
| 212 | /* Enable CD stable check before power-up */ | ||
| 213 | #define SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE BIT(3) | ||
| 209 | }; | 214 | }; |
| 210 | 215 | ||
| 211 | struct sdhci_arasan_of_data { | 216 | struct sdhci_arasan_of_data { |
| 212 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; | 217 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; |
| 213 | const struct sdhci_pltfm_data *pdata; | 218 | const struct sdhci_pltfm_data *pdata; |
| 214 | const struct sdhci_arasan_clk_ops *clk_ops; | 219 | const struct sdhci_arasan_clk_ops *clk_ops; |
| 220 | u32 quirks; | ||
| 215 | }; | 221 | }; |
| 216 | 222 | ||
| 217 | static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = { | 223 | static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = { |
| @@ -514,6 +520,24 @@ static int sdhci_arasan_voltage_switch(struct mmc_host *mmc, · 296 unmodified lines | |||
| 514 | return -EINVAL; | 520 | return -EINVAL; |
| 515 | } | 521 | } |
| 516 | 522 | ||
| 523 | static void sdhci_arasan_set_power_and_bus_voltage(struct sdhci_host *host, unsigned char mode, | ||
| 524 | unsigned short vdd) | ||
| 525 | { | ||
| 526 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 527 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | ||
| 528 | u32 reg; | ||
| 529 | |||
| 530 | /* | ||
| 531 | * Ensure that the card detect logic has stabilized before powering up, this is | ||
| 532 | * necessary after a host controller reset. | ||
| 533 | */ | ||
| 534 | if (mode == MMC_POWER_UP && sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE) | ||
| 535 | read_poll_timeout(sdhci_readl, reg, reg & SDHCI_CD_STABLE, CD_STABLE_MAX_SLEEP_US, | ||
| 536 | CD_STABLE_TIMEOUT_US, false, host, SDHCI_PRESENT_STATE); | ||
| 537 | |||
| 538 | sdhci_set_power_and_bus_voltage(host, mode, vdd); | ||
| 539 | } | ||
| 540 | |||
| 517 | static const struct sdhci_ops sdhci_arasan_ops = { | 541 | static const struct sdhci_ops sdhci_arasan_ops = { |
| 518 | .set_clock = sdhci_arasan_set_clock, | 542 | .set_clock = sdhci_arasan_set_clock, |
| 519 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, | 543 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, |
| @@ -521,7 +545,7 @@ static const struct sdhci_ops sdhci_arasan_ops = { · 1 unmodified line | |||
| 521 | .set_bus_width = sdhci_set_bus_width, | 545 | .set_bus_width = sdhci_set_bus_width, |
| 522 | .reset = sdhci_arasan_reset, | 546 | .reset = sdhci_arasan_reset, |
| 523 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 547 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 524 | .set_power = sdhci_set_power_and_bus_voltage, | 548 | .set_power = sdhci_arasan_set_power_and_bus_voltage, |
| 525 | .hw_reset = sdhci_arasan_hw_reset, | 549 | .hw_reset = sdhci_arasan_hw_reset, |
| 526 | }; | 550 | }; |
| 527 | 551 | ||
| @@ -570,7 +594,7 @@ static const struct sdhci_ops sdhci_arasan_cqe_ops = { · 42 unmodified lines | |||
| 570 | .set_bus_width = sdhci_set_bus_width, | 594 | .set_bus_width = sdhci_set_bus_width, |
| 571 | .reset = sdhci_arasan_reset, | 595 | .reset = sdhci_arasan_reset, |
| 572 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 596 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 573 | .set_power = sdhci_set_power_and_bus_voltage, | 597 | .set_power = sdhci_arasan_set_power_and_bus_voltage, |
| 574 | .irq = sdhci_arasan_cqhci_irq, | 598 | .irq = sdhci_arasan_cqhci_irq, |
| 575 | }; | 599 | }; |
| 576 | 600 | ||
| @@ -1447,6 +1471,7 @@ static const struct sdhci_arasan_clk_ops zynqmp_clk_ops = { · 870 unmodified lines | |||
| 1447 | static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = { | 1471 | static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = { |
| 1448 | .pdata = &sdhci_arasan_zynqmp_pdata, | 1472 | .pdata = &sdhci_arasan_zynqmp_pdata, |
| 1449 | .clk_ops = &zynqmp_clk_ops, | 1473 | .clk_ops = &zynqmp_clk_ops, |
| 1474 | .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE, | ||
| 1450 | }; | 1475 | }; |
| 1451 | 1476 | ||
| 1452 | static const struct sdhci_arasan_clk_ops versal_clk_ops = { | 1477 | static const struct sdhci_arasan_clk_ops versal_clk_ops = { |
| @@ -1457,6 +1482,7 @@ static const struct sdhci_arasan_clk_ops versal_clk_ops = { · 4 unmodified lines | |||
| 1457 | static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { | 1482 | static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { |
| 1458 | .pdata = &sdhci_arasan_zynqmp_pdata, | 1483 | .pdata = &sdhci_arasan_zynqmp_pdata, |
| 1459 | .clk_ops = &versal_clk_ops, | 1484 | .clk_ops = &versal_clk_ops, |
| 1485 | .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE, | ||
| 1460 | }; | 1486 | }; |
| 1461 | 1487 | ||
| 1462 | static const struct sdhci_arasan_clk_ops versal_net_clk_ops = { | 1488 | static const struct sdhci_arasan_clk_ops versal_net_clk_ops = { |
| @@ -1467,6 +1493,7 @@ static const struct sdhci_arasan_clk_ops versal_net_clk_ops = { · 4 unmodified lines | |||
| 1467 | static struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = { | 1493 | static struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = { |
| 1468 | .pdata = &sdhci_arasan_versal_net_pdata, | 1494 | .pdata = &sdhci_arasan_versal_net_pdata, |
| 1469 | .clk_ops = &versal_net_clk_ops, | 1495 | .clk_ops = &versal_net_clk_ops, |
| 1496 | .quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE, | ||
| 1470 | }; | 1497 | }; |
| 1471 | 1498 | ||
| 1472 | static struct sdhci_arasan_of_data intel_keembay_emmc_data = { | 1499 | static struct sdhci_arasan_of_data intel_keembay_emmc_data = { |
| @@ -1937,6 +1964,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev) · 464 unmodified lines | |||
| 1937 | if (of_device_is_compatible(np, "rockchip,rk3399-sdhci-5.1")) | 1964 | if (of_device_is_compatible(np, "rockchip,rk3399-sdhci-5.1")) |
| 1938 | sdhci_arasan_update_clockmultiplier(host, 0x0); | 1965 | sdhci_arasan_update_clockmultiplier(host, 0x0); |
| 1939 | 1966 | ||
| 1967 | sdhci_arasan->quirks |= data->quirks; | ||
| 1968 | |||
| 1940 | if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") || | 1969 | if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") || |
| 1941 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || | 1970 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || |
| 1942 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) { | 1971 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) { |
| @@ -287,6 +287,20 @@ · 286 unmodified lines | |||
| 287 | #define GLI_MAX_TUNING_LOOP 40 | 287 | #define GLI_MAX_TUNING_LOOP 40 |
| 288 | 288 | ||
| 289 | /* Genesys Logic chipset */ | 289 | /* Genesys Logic chipset */ |
| 290 | static void sdhci_gli_mask_replay_timer_timeout(struct pci_dev *pdev) | ||
| 291 | { | ||
| 292 | int aer; | ||
| 293 | u32 value; | ||
| 294 | |||
| 295 | /* mask the replay timer timeout of AER */ | ||
| 296 | aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); | ||
| 297 | if (aer) { | ||
| 298 | pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value); | ||
| 299 | value |= PCI_ERR_COR_REP_TIMER; | ||
| 300 | pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value); | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 290 | static inline void gl9750_wt_on(struct sdhci_host *host) | 304 | static inline void gl9750_wt_on(struct sdhci_host *host) |
| 291 | { | 305 | { |
| 292 | u32 wt_value; | 306 | u32 wt_value; |
| @@ -607,7 +621,6 @@ static void gl9750_hw_setting(struct sdhci_host *host) · 314 unmodified lines | |||
| 607 | { | 621 | { |
| 608 | struct sdhci_pci_slot *slot = sdhci_priv(host); | 622 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 609 | struct pci_dev *pdev; | 623 | struct pci_dev *pdev; |
| 610 | int aer; | ||
| 611 | u32 value; | 624 | u32 value; |
| 612 | 625 | ||
| 613 | pdev = slot->chip->pdev; | 626 | pdev = slot->chip->pdev; |
| @@ -626,12 +639,7 @@ static void gl9750_hw_setting(struct sdhci_host *host) · 12 unmodified lines | |||
| 626 | pci_set_power_state(pdev, PCI_D0); | 639 | pci_set_power_state(pdev, PCI_D0); |
| 627 | 640 | ||
| 628 | /* mask the replay timer timeout of AER */ | 641 | /* mask the replay timer timeout of AER */ |
| 629 | aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); | 642 | sdhci_gli_mask_replay_timer_timeout(pdev); |
| 630 | if (aer) { | ||
| 631 | pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value); | ||
| 632 | value |= PCI_ERR_COR_REP_TIMER; | ||
| 633 | pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value); | ||
| 634 | } | ||
| 635 | 643 | ||
| 636 | gl9750_wt_off(host); | 644 | gl9750_wt_off(host); |
| 637 | } | 645 | } |
| @@ -806,7 +814,6 @@ static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock) · 168 unmodified lines | |||
| 806 | static void gl9755_hw_setting(struct sdhci_pci_slot *slot) | 814 | static void gl9755_hw_setting(struct sdhci_pci_slot *slot) |
| 807 | { | 815 | { |
| 808 | struct pci_dev *pdev = slot->chip->pdev; | 816 | struct pci_dev *pdev = slot->chip->pdev; |
| 809 | int aer; | ||
| 810 | u32 value; | 817 | u32 value; |
| 811 | 818 | ||
| 812 | gl9755_wt_on(pdev); | 819 | gl9755_wt_on(pdev); |
| @@ -841,12 +848,7 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot) · 28 unmodified lines | |||
| 841 | pci_set_power_state(pdev, PCI_D0); | 848 | pci_set_power_state(pdev, PCI_D0); |
| 842 | 849 | ||
| 843 | /* mask the replay timer timeout of AER */ | 850 | /* mask the replay timer timeout of AER */ |
| 844 | aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); | 851 | sdhci_gli_mask_replay_timer_timeout(pdev); |
| 845 | if (aer) { | ||
| 846 | pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value); | ||
| 847 | value |= PCI_ERR_COR_REP_TIMER; | ||
| 848 | pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value); | ||
| 849 | } | ||
| 850 | 852 | ||
| 851 | gl9755_wt_off(pdev); | 853 | gl9755_wt_off(pdev); |
| 852 | } | 854 | } |
| @@ -1751,7 +1753,7 @@ cleanup: · 898 unmodified lines | |||
| 1751 | return ret; | 1753 | return ret; |
| 1752 | } | 1754 | } |
| 1753 | 1755 | ||
| 1754 | static void gli_set_gl9763e(struct sdhci_pci_slot *slot) | 1756 | static void gl9763e_hw_setting(struct sdhci_pci_slot *slot) |
| 1755 | { | 1757 | { |
| 1756 | struct pci_dev *pdev = slot->chip->pdev; | 1758 | struct pci_dev *pdev = slot->chip->pdev; |
| 1757 | u32 value; | 1759 | u32 value; |
| @@ -1780,6 +1782,9 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot) · 22 unmodified lines | |||
| 1780 | value |= FIELD_PREP(GLI_9763E_HS400_RXDLY, GLI_9763E_HS400_RXDLY_5); | 1782 | value |= FIELD_PREP(GLI_9763E_HS400_RXDLY, GLI_9763E_HS400_RXDLY_5); |
| 1781 | pci_write_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, value); | 1783 | pci_write_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, value); |
| 1782 | 1784 | ||
| 1785 | /* mask the replay timer timeout of AER */ | ||
| 1786 | sdhci_gli_mask_replay_timer_timeout(pdev); | ||
| 1787 | |||
| 1783 | pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); | 1788 | pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); |
| 1784 | value &= ~GLI_9763E_VHS_REV; | 1789 | value &= ~GLI_9763E_VHS_REV; |
| 1785 | value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); | 1790 | value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); |
| @@ -1923,7 +1928,7 @@ static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) · 137 unmodified lines | |||
| 1923 | gli_pcie_enable_msi(slot); | 1928 | gli_pcie_enable_msi(slot); |
| 1924 | host->mmc_host_ops.hs400_enhanced_strobe = | 1929 | host->mmc_host_ops.hs400_enhanced_strobe = |
| 1925 | gl9763e_hs400_enhanced_strobe; | 1930 | gl9763e_hs400_enhanced_strobe; |
| 1926 | gli_set_gl9763e(slot); | 1931 | gl9763e_hw_setting(slot); |
| 1927 | sdhci_enable_v4_mode(host); | 1932 | sdhci_enable_v4_mode(host); |
| 1928 | 1933 | ||
| 1929 | return 0; | 1934 | return 0; |
| @@ -156,6 +156,7 @@ struct sdhci_am654_data { · 155 unmodified lines | |||
| 156 | 156 | ||
| 157 | #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) | 157 | #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) |
| 158 | #define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1) | 158 | #define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1) |
| 159 | #define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(2) | ||
| 159 | }; | 160 | }; |
| 160 | 161 | ||
| 161 | struct window { | 162 | struct window { |
| @@ -765,6 +766,7 @@ static int sdhci_am654_init(struct sdhci_host *host) · 603 unmodified lines | |||
| 765 | { | 766 | { |
| 766 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 767 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 767 | struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); | 768 | struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); |
| 769 | struct device *dev = mmc_dev(host->mmc); | ||
| 768 | u32 ctl_cfg_2 = 0; | 770 | u32 ctl_cfg_2 = 0; |
| 769 | u32 mask; | 771 | u32 mask; |
| 770 | u32 val; | 772 | u32 val; |
| @@ -820,6 +822,12 @@ static int sdhci_am654_init(struct sdhci_host *host) · 49 unmodified lines | |||
| 820 | if (ret) | 822 | if (ret) |
| 821 | goto err_cleanup_host; | 823 | goto err_cleanup_host; |
| 822 | 824 | ||
| 825 | if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_DISABLE_HS400 && | ||
| 826 | host->mmc->caps2 & (MMC_CAP2_HS400 | MMC_CAP2_HS400_ES)) { | ||
| 827 | dev_info(dev, "HS400 mode not supported on this silicon revision, disabling it\n"); | ||
| 828 | host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES); | ||
| 829 | } | ||
| 830 | |||
| 823 | ret = __sdhci_add_host(host); | 831 | ret = __sdhci_add_host(host); |
| 824 | if (ret) | 832 | if (ret) |
| 825 | goto err_cleanup_host; | 833 | goto err_cleanup_host; |
| @@ -883,6 +891,12 @@ static int sdhci_am654_get_of_property(struct platform_device *pdev, · 57 unmodified lines | |||
| 883 | return 0; | 891 | return 0; |
| 884 | } | 892 | } |
| 885 | 893 | ||
| 894 | static const struct soc_device_attribute sdhci_am654_descope_hs400[] = { | ||
| 895 | { .family = "AM62PX", .revision = "SR1.0" }, | ||
| 896 | { .family = "AM62PX", .revision = "SR1.1" }, | ||
| 897 | { /* sentinel */ } | ||
| 898 | }; | ||
| 899 | |||
| 886 | static const struct of_device_id sdhci_am654_of_match[] = { | 900 | static const struct of_device_id sdhci_am654_of_match[] = { |
| 887 | { | 901 | { |
| 888 | .compatible = "ti,am654-sdhci-5.1", | 902 | .compatible = "ti,am654-sdhci-5.1", |
| @@ -970,6 +984,10 @@ static int sdhci_am654_probe(struct platform_device *pdev) · 81 unmodified lines | |||
| 970 | if (ret) | 984 | if (ret) |
| 971 | return dev_err_probe(dev, ret, "parsing dt failed\n"); | 985 | return dev_err_probe(dev, ret, "parsing dt failed\n"); |
| 972 | 986 | ||
| 987 | soc = soc_device_match(sdhci_am654_descope_hs400); | ||
| 988 | if (soc) | ||
| 989 | sdhci_am654->quirks |= SDHCI_AM654_QUIRK_DISABLE_HS400; | ||
| 990 | |||
| 973 | host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch; | 991 | host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch; |
| 974 | host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning; | 992 | host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning; |
| 975 | 993 | ||
| @@ -538,8 +538,8 @@ static struct most_channel *get_channel(char *mdev, char *mdev_ch) · 537 unmodified lines | |||
| 538 | dev = bus_find_device_by_name(&mostbus, NULL, mdev); | 538 | dev = bus_find_device_by_name(&mostbus, NULL, mdev); |
| 539 | if (!dev) | 539 | if (!dev) |
| 540 | return NULL; | 540 | return NULL; |
| 541 | put_device(dev); | ||
| 542 | iface = dev_get_drvdata(dev); | 541 | iface = dev_get_drvdata(dev); |
| 542 | put_device(dev); | ||
| 543 | list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { | 543 | list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { |
| 544 | if (!strcmp(dev_name(&c->dev), mdev_ch)) | 544 | if (!strcmp(dev_name(&c->dev), mdev_ch)) |
| 545 | return c; | 545 | return c; |
| @@ -8022,7 +8022,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp) · 8021 unmodified lines | |||
| 8022 | } | 8022 | } |
| 8023 | rx_rings = min_t(int, rx_rings, hwr.grp); | 8023 | rx_rings = min_t(int, rx_rings, hwr.grp); |
| 8024 | hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings); | 8024 | hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings); |
| 8025 | if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp)) | 8025 | if (bnxt_ulp_registered(bp->edev) && |
| 8026 | hwr.stat > bnxt_get_ulp_stat_ctxs(bp)) | ||
| 8026 | hwr.stat -= bnxt_get_ulp_stat_ctxs(bp); | 8027 | hwr.stat -= bnxt_get_ulp_stat_ctxs(bp); |
| 8027 | hwr.cp = min_t(int, hwr.cp, hwr.stat); | 8028 | hwr.cp = min_t(int, hwr.cp, hwr.stat); |
| 8028 | rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh); | 8029 | rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh); |
| @@ -8030,6 +8031,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp) · 1 unmodified line | |||
| 8030 | hwr.rx = rx_rings << 1; | 8031 | hwr.rx = rx_rings << 1; |
| 8031 | tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx); | 8032 | tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx); |
| 8032 | hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings; | 8033 | hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings; |
| 8034 | if (hwr.tx != bp->tx_nr_rings) { | ||
| 8035 | netdev_warn(bp->dev, | ||
| 8036 | "Able to reserve only %d out of %d requested TX rings\n", | ||
| 8037 | hwr.tx, bp->tx_nr_rings); | ||
| 8038 | } | ||
| 8033 | bp->tx_nr_rings = hwr.tx; | 8039 | bp->tx_nr_rings = hwr.tx; |
| 8034 | 8040 | ||
| 8035 | /* If we cannot reserve all the RX rings, reset the RSS map only | 8041 | /* If we cannot reserve all the RX rings, reset the RSS map only |
| @@ -12857,6 +12863,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp) · 4821 unmodified lines | |||
| 12857 | return rc; | 12863 | return rc; |
| 12858 | } | 12864 | } |
| 12859 | 12865 | ||
| 12866 | static int bnxt_tx_nr_rings(struct bnxt *bp) | ||
| 12867 | { | ||
| 12868 | return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc : | ||
| 12869 | bp->tx_nr_rings_per_tc; | ||
| 12870 | } | ||
| 12871 | |||
| 12872 | static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp) | ||
| 12873 | { | ||
| 12874 | return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings; | ||
| 12875 | } | ||
| 12876 | |||
| 12860 | static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) | 12877 | static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) |
| 12861 | { | 12878 | { |
| 12862 | int rc = 0; | 12879 | int rc = 0; |
| @@ -12874,6 +12891,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) · 11 unmodified lines | |||
| 12874 | if (rc) | 12891 | if (rc) |
| 12875 | return rc; | 12892 | return rc; |
| 12876 | 12893 | ||
| 12894 | /* Make adjustments if reserved TX rings are less than requested */ | ||
| 12895 | bp->tx_nr_rings -= bp->tx_nr_rings_xdp; | ||
| 12896 | bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); | ||
| 12897 | if (bp->tx_nr_rings_xdp) { | ||
| 12898 | bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc; | ||
| 12899 | bp->tx_nr_rings += bp->tx_nr_rings_xdp; | ||
| 12900 | } | ||
| 12877 | rc = bnxt_alloc_mem(bp, irq_re_init); | 12901 | rc = bnxt_alloc_mem(bp, irq_re_init); |
| 12878 | if (rc) { | 12902 | if (rc) { |
| 12879 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); | 12903 | netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); |
| @@ -16329,7 +16353,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp) · 3449 unmodified lines | |||
| 16329 | bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings); | 16353 | bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings); |
| 16330 | bp->rx_nr_rings = bp->cp_nr_rings; | 16354 | bp->rx_nr_rings = bp->cp_nr_rings; |
| 16331 | bp->tx_nr_rings_per_tc = bp->cp_nr_rings; | 16355 | bp->tx_nr_rings_per_tc = bp->cp_nr_rings; |
| 16332 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc; | 16356 | bp->tx_nr_rings = bnxt_tx_nr_rings(bp); |
| 16333 | } | 16357 | } |
| 16334 | 16358 | ||
| 16335 | static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) | 16359 | static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) |
| @@ -16361,7 +16385,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) · 25 unmodified lines | |||
| 16361 | bnxt_trim_dflt_sh_rings(bp); | 16385 | bnxt_trim_dflt_sh_rings(bp); |
| 16362 | else | 16386 | else |
| 16363 | bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings; | 16387 | bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings; |
| 16364 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc; | 16388 | bp->tx_nr_rings = bnxt_tx_nr_rings(bp); |
| 16365 | 16389 | ||
| 16366 | avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings; | 16390 | avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings; |
| 16367 | if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) { | 16391 | if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) { |
| @@ -16374,7 +16398,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) · 6 unmodified lines | |||
| 16374 | rc = __bnxt_reserve_rings(bp); | 16398 | rc = __bnxt_reserve_rings(bp); |
| 16375 | if (rc && rc != -ENODEV) | 16399 | if (rc && rc != -ENODEV) |
| 16376 | netdev_warn(bp->dev, "Unable to reserve tx rings\n"); | 16400 | netdev_warn(bp->dev, "Unable to reserve tx rings\n"); |
| 16377 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | 16401 | bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); |
| 16378 | if (sh) | 16402 | if (sh) |
| 16379 | bnxt_trim_dflt_sh_rings(bp); | 16403 | bnxt_trim_dflt_sh_rings(bp); |
| 16380 | 16404 | ||
| @@ -16383,7 +16407,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) · 2 unmodified lines | |||
| 16383 | rc = __bnxt_reserve_rings(bp); | 16407 | rc = __bnxt_reserve_rings(bp); |
| 16384 | if (rc && rc != -ENODEV) | 16408 | if (rc && rc != -ENODEV) |
| 16385 | netdev_warn(bp->dev, "2nd rings reservation failed.\n"); | 16409 | netdev_warn(bp->dev, "2nd rings reservation failed.\n"); |
| 16386 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | 16410 | bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); |
| 16387 | } | 16411 | } |
| 16388 | if (BNXT_CHIP_TYPE_NITRO_A0(bp)) { | 16412 | if (BNXT_CHIP_TYPE_NITRO_A0(bp)) { |
| 16389 | bp->rx_nr_rings++; | 16413 | bp->rx_nr_rings++; |
| @@ -16417,7 +16441,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp) · 27 unmodified lines | |||
| 16417 | if (rc) | 16441 | if (rc) |
| 16418 | goto init_dflt_ring_err; | 16442 | goto init_dflt_ring_err; |
| 16419 | 16443 | ||
| 16420 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | 16444 | bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp); |
| 16421 | 16445 | ||
| 16422 | bnxt_set_dflt_rfs(bp); | 16446 | bnxt_set_dflt_rfs(bp); |
| 16423 | 16447 | ||
| @@ -3091,7 +3091,7 @@ static void gem_update_stats(struct macb *bp) · 3090 unmodified lines | |||
| 3091 | /* Add GEM_OCTTXH, GEM_OCTRXH */ | 3091 | /* Add GEM_OCTTXH, GEM_OCTRXH */ |
| 3092 | val = bp->macb_reg_readl(bp, offset + 4); | 3092 | val = bp->macb_reg_readl(bp, offset + 4); |
| 3093 | bp->ethtool_stats[i] += ((u64)val) << 32; | 3093 | bp->ethtool_stats[i] += ((u64)val) << 32; |
| 3094 | *(p++) += ((u64)val) << 32; | 3094 | *p += ((u64)val) << 32; |
| 3095 | } | 3095 | } |
| 3096 | } | 3096 | } |
| 3097 | 3097 | ||
| @@ -5636,19 +5636,16 @@ static void macb_remove(struct platform_device *pdev) · 2538 unmodified lines | |||
| 5636 | 5636 | ||
| 5637 | if (dev) { | 5637 | if (dev) { |
| 5638 | bp = netdev_priv(dev); | 5638 | bp = netdev_priv(dev); |
| 5639 | unregister_netdev(dev); | ||
| 5639 | phy_exit(bp->sgmii_phy); | 5640 | phy_exit(bp->sgmii_phy); |
| 5640 | mdiobus_unregister(bp->mii_bus); | 5641 | mdiobus_unregister(bp->mii_bus); |
| 5641 | mdiobus_free(bp->mii_bus); | 5642 | mdiobus_free(bp->mii_bus); |
| 5642 | 5643 | ||
| 5643 | unregister_netdev(dev); | 5644 | device_set_wakeup_enable(&bp->pdev->dev, 0); |
| 5644 | cancel_work_sync(&bp->hresp_err_bh_work); | 5645 | cancel_work_sync(&bp->hresp_err_bh_work); |
| 5645 | pm_runtime_disable(&pdev->dev); | 5646 | pm_runtime_disable(&pdev->dev); |
| 5646 | pm_runtime_dont_use_autosuspend(&pdev->dev); | 5647 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
| 5647 | if (!pm_runtime_suspended(&pdev->dev)) { | 5648 | pm_runtime_set_suspended(&pdev->dev); |
| 5648 | macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk, | ||
| 5649 | bp->rx_clk, bp->tsu_clk); | ||
| 5650 | pm_runtime_set_suspended(&pdev->dev); | ||
| 5651 | } | ||
| 5652 | phylink_destroy(bp->phylink); | 5649 | phylink_destroy(bp->phylink); |
| 5653 | free_netdev(dev); | 5650 | free_netdev(dev); |
| 5654 | } | 5651 | } |
| @@ -1099,7 +1099,7 @@ get_stats (struct net_device *dev) · 1098 unmodified lines | |||
| 1099 | dev->stats.rx_bytes += dr32(OctetRcvOk); | 1099 | dev->stats.rx_bytes += dr32(OctetRcvOk); |
| 1100 | dev->stats.tx_bytes += dr32(OctetXmtOk); | 1100 | dev->stats.tx_bytes += dr32(OctetXmtOk); |
| 1101 | 1101 | ||
| 1102 | dev->stats.multicast = dr32(McstFramesRcvdOk); | 1102 | dev->stats.multicast += dr32(McstFramesRcvdOk); |
| 1103 | dev->stats.collisions += dr32(SingleColFrames) | 1103 | dev->stats.collisions += dr32(SingleColFrames) |
| 1104 | + dr32(MultiColFrames); | 1104 | + dr32(MultiColFrames); |
| 1105 | 1105 | ||
| @@ -511,6 +511,7 @@ enum ice_pf_flags { · 510 unmodified lines | |||
| 511 | ICE_FLAG_LINK_LENIENT_MODE_ENA, | 511 | ICE_FLAG_LINK_LENIENT_MODE_ENA, |
| 512 | ICE_FLAG_PLUG_AUX_DEV, | 512 | ICE_FLAG_PLUG_AUX_DEV, |
| 513 | ICE_FLAG_UNPLUG_AUX_DEV, | 513 | ICE_FLAG_UNPLUG_AUX_DEV, |
| 514 | ICE_FLAG_AUX_DEV_CREATED, | ||
| 514 | ICE_FLAG_MTU_CHANGED, | 515 | ICE_FLAG_MTU_CHANGED, |
| 515 | ICE_FLAG_GNSS, /* GNSS successfully initialized */ | 516 | ICE_FLAG_GNSS, /* GNSS successfully initialized */ |
| 516 | ICE_FLAG_DPLL, /* SyncE/PTP dplls initialized */ | 517 | ICE_FLAG_DPLL, /* SyncE/PTP dplls initialized */ |
| @@ -13,16 +13,45 @@ · 12 unmodified lines | |||
| 13 | static DEFINE_XARRAY(ice_adapters); | 13 | static DEFINE_XARRAY(ice_adapters); |
| 14 | static DEFINE_MUTEX(ice_adapters_mutex); | 14 | static DEFINE_MUTEX(ice_adapters_mutex); |
| 15 | 15 | ||
| 16 | static unsigned long ice_adapter_index(u64 dsn) | 16 | #define ICE_ADAPTER_FIXED_INDEX BIT_ULL(63) |
| 17 | |||
| 18 | #define ICE_ADAPTER_INDEX_E825C \ | ||
| 19 | (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX) | ||
| 20 | |||
| 21 | static u64 ice_adapter_index(struct pci_dev *pdev) | ||
| 17 | { | 22 | { |
| 23 | switch (pdev->device) { | ||
| 24 | case ICE_DEV_ID_E825C_BACKPLANE: | ||
| 25 | case ICE_DEV_ID_E825C_QSFP: | ||
| 26 | case ICE_DEV_ID_E825C_SFP: | ||
| 27 | case ICE_DEV_ID_E825C_SGMII: | ||
| 28 | /* E825C devices have multiple NACs which are connected to the | ||
| 29 | * same clock source, and which must share the same | ||
| 30 | * ice_adapter structure. We can't use the serial number since | ||
| 31 | * each NAC has its own NVM generated with its own unique | ||
| 32 | * Device Serial Number. Instead, rely on the embedded nature | ||
| 33 | * of the E825C devices, and use a fixed index. This relies on | ||
| 34 | * the fact that all E825C physical functions in a given | ||
| 35 | * system are part of the same overall device. | ||
| 36 | */ | ||
| 37 | return ICE_ADAPTER_INDEX_E825C; | ||
| 38 | default: | ||
| 39 | return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | static unsigned long ice_adapter_xa_index(struct pci_dev *pdev) | ||
| 44 | { | ||
| 45 | u64 index = ice_adapter_index(pdev); | ||
| 46 | |||
| 18 | #if BITS_PER_LONG == 64 | 47 | #if BITS_PER_LONG == 64 |
| 19 | return dsn; | 48 | return index; |
| 20 | #else | 49 | #else |
| 21 | return (u32)dsn ^ (u32)(dsn >> 32); | 50 | return (u32)index ^ (u32)(index >> 32); |
| 22 | #endif | 51 | #endif |
| 23 | } | 52 | } |
| 24 | 53 | ||
| 25 | static struct ice_adapter *ice_adapter_new(u64 dsn) | 54 | static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev) |
| 26 | { | 55 | { |
| 27 | struct ice_adapter *adapter; | 56 | struct ice_adapter *adapter; |
| 28 | 57 | ||
| @@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn) · 1 unmodified line | |||
| 30 | if (!adapter) | 59 | if (!adapter) |
| 31 | return NULL; | 60 | return NULL; |
| 32 | 61 | ||
| 33 | adapter->device_serial_number = dsn; | 62 | adapter->index = ice_adapter_index(pdev); |
| 34 | spin_lock_init(&adapter->ptp_gltsyn_time_lock); | 63 | spin_lock_init(&adapter->ptp_gltsyn_time_lock); |
| 35 | spin_lock_init(&adapter->txq_ctx_lock); | 64 | spin_lock_init(&adapter->txq_ctx_lock); |
| 36 | refcount_set(&adapter->refcount, 1); | 65 | refcount_set(&adapter->refcount, 1); |
| @@ -64,24 +93,23 @@ static void ice_adapter_free(struct ice_adapter *adapter) · 27 unmodified lines | |||
| 64 | */ | 93 | */ |
| 65 | struct ice_adapter *ice_adapter_get(struct pci_dev *pdev) | 94 | struct ice_adapter *ice_adapter_get(struct pci_dev *pdev) |
| 66 | { | 95 | { |
| 67 | u64 dsn = pci_get_dsn(pdev); | ||
| 68 | struct ice_adapter *adapter; | 96 | struct ice_adapter *adapter; |
| 69 | unsigned long index; | 97 | unsigned long index; |
| 70 | int err; | 98 | int err; |
| 71 | 99 | ||
| 72 | index = ice_adapter_index(dsn); | 100 | index = ice_adapter_xa_index(pdev); |
| 73 | scoped_guard(mutex, &ice_adapters_mutex) { | 101 | scoped_guard(mutex, &ice_adapters_mutex) { |
| 74 | err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL); | 102 | err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL); |
| 75 | if (err == -EBUSY) { | 103 | if (err == -EBUSY) { |
| 76 | adapter = xa_load(&ice_adapters, index); | 104 | adapter = xa_load(&ice_adapters, index); |
| 77 | refcount_inc(&adapter->refcount); | 105 | refcount_inc(&adapter->refcount); |
| 78 | WARN_ON_ONCE(adapter->device_serial_number != dsn); | 106 | WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev)); |
| 79 | return adapter; | 107 | return adapter; |
| 80 | } | 108 | } |
| 81 | if (err) | 109 | if (err) |
| 82 | return ERR_PTR(err); | 110 | return ERR_PTR(err); |
| 83 | 111 | ||
| 84 | adapter = ice_adapter_new(dsn); | 112 | adapter = ice_adapter_new(pdev); |
| 85 | if (!adapter) | 113 | if (!adapter) |
| 86 | return ERR_PTR(-ENOMEM); | 114 | return ERR_PTR(-ENOMEM); |
| 87 | xa_store(&ice_adapters, index, adapter, GFP_KERNEL); | 115 | xa_store(&ice_adapters, index, adapter, GFP_KERNEL); |
| @@ -100,11 +128,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev) · 12 unmodified lines | |||
| 100 | */ | 128 | */ |
| 101 | void ice_adapter_put(struct pci_dev *pdev) | 129 | void ice_adapter_put(struct pci_dev *pdev) |
| 102 | { | 130 | { |
| 103 | u64 dsn = pci_get_dsn(pdev); | ||
| 104 | struct ice_adapter *adapter; | 131 | struct ice_adapter *adapter; |
| 105 | unsigned long index; | 132 | unsigned long index; |
| 106 | 133 | ||
| 107 | index = ice_adapter_index(dsn); | 134 | index = ice_adapter_xa_index(pdev); |
| 108 | scoped_guard(mutex, &ice_adapters_mutex) { | 135 | scoped_guard(mutex, &ice_adapters_mutex) { |
| 109 | adapter = xa_load(&ice_adapters, index); | 136 | adapter = xa_load(&ice_adapters, index); |
| 110 | if (WARN_ON(!adapter)) | 137 | if (WARN_ON(!adapter)) |
| @@ -33,7 +33,7 @@ struct ice_port_list { · 32 unmodified lines | |||
| 33 | * @txq_ctx_lock: Spinlock protecting access to the GLCOMM_QTX_CNTX_CTL register | 33 | * @txq_ctx_lock: Spinlock protecting access to the GLCOMM_QTX_CNTX_CTL register |
| 34 | * @ctrl_pf: Control PF of the adapter | 34 | * @ctrl_pf: Control PF of the adapter |
| 35 | * @ports: Ports list | 35 | * @ports: Ports list |
| 36 | * @device_serial_number: DSN cached for collision detection on 32bit systems | 36 | * @index: 64-bit index cached for collision detection on 32bit systems |
| 37 | */ | 37 | */ |
| 38 | struct ice_adapter { | 38 | struct ice_adapter { |
| 39 | refcount_t refcount; | 39 | refcount_t refcount; |
| @@ -44,7 +44,7 @@ struct ice_adapter { · 4 unmodified lines | |||
| 44 | 44 | ||
| 45 | struct ice_pf *ctrl_pf; | 45 | struct ice_pf *ctrl_pf; |
| 46 | struct ice_port_list ports; | 46 | struct ice_port_list ports; |
| 47 | u64 device_serial_number; | 47 | u64 index; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | struct ice_adapter *ice_adapter_get(struct pci_dev *pdev); | 50 | struct ice_adapter *ice_adapter_get(struct pci_dev *pdev); |
| @@ -2377,7 +2377,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size, · 2376 unmodified lines | |||
| 2377 | * The function will apply the new Tx topology from the package buffer | 2377 | * The function will apply the new Tx topology from the package buffer |
| 2378 | * if available. | 2378 | * if available. |
| 2379 | * | 2379 | * |
| 2380 | * Return: zero when update was successful, negative values otherwise. | 2380 | * Return: |
| 2381 | * * 0 - Successfully applied topology configuration. | ||
| 2382 | * * -EBUSY - Failed to acquire global configuration lock. | ||
| 2383 | * * -EEXIST - Topology configuration has already been applied. | ||
| 2384 | * * -EIO - Unable to apply topology configuration. | ||
| 2385 | * * -ENODEV - Failed to re-initialize device after applying configuration. | ||
| 2386 | * * Other negative error codes indicate unexpected failures. | ||
| 2381 | */ | 2387 | */ |
| 2382 | int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) | 2388 | int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) |
| 2383 | { | 2389 | { |
| @@ -2410,7 +2416,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) · 26 unmodified lines | |||
| 2410 | 2416 | ||
| 2411 | if (status) { | 2417 | if (status) { |
| 2412 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); | 2418 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); |
| 2413 | return status; | 2419 | return -EIO; |
| 2414 | } | 2420 | } |
| 2415 | 2421 | ||
| 2416 | /* Is default topology already applied ? */ | 2422 | /* Is default topology already applied ? */ |
| @@ -2497,31 +2503,45 @@ update_topo: · 80 unmodified lines | |||
| 2497 | ICE_GLOBAL_CFG_LOCK_TIMEOUT); | 2503 | ICE_GLOBAL_CFG_LOCK_TIMEOUT); |
| 2498 | if (status) { | 2504 | if (status) { |
| 2499 | ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n"); | 2505 | ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n"); |
| 2500 | return status; | 2506 | return -EBUSY; |
| 2501 | } | 2507 | } |
| 2502 | 2508 | ||
| 2503 | /* Check if reset was triggered already. */ | 2509 | /* Check if reset was triggered already. */ |
| 2504 | reg = rd32(hw, GLGEN_RSTAT); | 2510 | reg = rd32(hw, GLGEN_RSTAT); |
| 2505 | if (reg & GLGEN_RSTAT_DEVSTATE_M) { | 2511 | if (reg & GLGEN_RSTAT_DEVSTATE_M) { |
| 2506 | /* Reset is in progress, re-init the HW again */ | ||
| 2507 | ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n"); | 2512 | ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n"); |
| 2508 | ice_check_reset(hw); | 2513 | ice_check_reset(hw); |
| 2509 | return 0; | 2514 | /* Reset is in progress, re-init the HW again */ |
| 2515 | goto reinit_hw; | ||
| 2510 | } | 2516 | } |
| 2511 | 2517 | ||
| 2512 | /* Set new topology */ | 2518 | /* Set new topology */ |
| 2513 | status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true); | 2519 | status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true); |
| 2514 | if (status) { | 2520 | if (status) { |
| 2515 | ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n"); | 2521 | ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n", |
| 2516 | return status; | 2522 | ERR_PTR(status)); |
| 2523 | /* only report -EIO here as the caller checks the error value | ||
| 2524 | * and reports an informational error message informing that | ||
| 2525 | * the driver failed to program Tx topology. | ||
| 2526 | */ | ||
| 2527 | status = -EIO; | ||
| 2517 | } | 2528 | } |
| 2518 | 2529 | ||
| 2519 | /* New topology is updated, delay 1 second before issuing the CORER */ | 2530 | /* Even if Tx topology config failed, we need to CORE reset here to |
| 2531 | * clear the global configuration lock. Delay 1 second to allow | ||
| 2532 | * hardware to settle then issue a CORER | ||
| 2533 | */ | ||
| 2520 | msleep(1000); | 2534 | msleep(1000); |
| 2521 | ice_reset(hw, ICE_RESET_CORER); | 2535 | ice_reset(hw, ICE_RESET_CORER); |
| 2522 | /* CORER will clear the global lock, so no explicit call | 2536 | ice_check_reset(hw); |
| 2523 | * required for release. | 2537 | |
| 2524 | */ | 2538 | reinit_hw: |
| 2539 | /* Since we triggered a CORER, re-initialize hardware */ | ||
| 2540 | ice_deinit_hw(hw); | ||
| 2541 | if (ice_init_hw(hw)) { | ||
| 2542 | ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n"); | ||
| 2543 | return -ENODEV; | ||
| 2544 | } | ||
| 2525 | 2545 | ||
| 2526 | return 0; | 2546 | return status; |
| 2527 | } | 2547 | } |
| @@ -336,6 +336,7 @@ int ice_plug_aux_dev(struct ice_pf *pf) · 335 unmodified lines | |||
| 336 | mutex_lock(&pf->adev_mutex); | 336 | mutex_lock(&pf->adev_mutex); |
| 337 | cdev->adev = adev; | 337 | cdev->adev = adev; |
| 338 | mutex_unlock(&pf->adev_mutex); | 338 | mutex_unlock(&pf->adev_mutex); |
| 339 | set_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags); | ||
| 339 | 340 | ||
| 340 | return 0; | 341 | return 0; |
| 341 | } | 342 | } |
| @@ -347,15 +348,16 @@ void ice_unplug_aux_dev(struct ice_pf *pf) · 5 unmodified lines | |||
| 347 | { | 348 | { |
| 348 | struct auxiliary_device *adev; | 349 | struct auxiliary_device *adev; |
| 349 | 350 | ||
| 351 | if (!test_and_clear_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags)) | ||
| 352 | return; | ||
| 353 | |||
| 350 | mutex_lock(&pf->adev_mutex); | 354 | mutex_lock(&pf->adev_mutex); |
| 351 | adev = pf->cdev_info->adev; | 355 | adev = pf->cdev_info->adev; |
| 352 | pf->cdev_info->adev = NULL; | 356 | pf->cdev_info->adev = NULL; |
| 353 | mutex_unlock(&pf->adev_mutex); | 357 | mutex_unlock(&pf->adev_mutex); |
| 354 | 358 | ||
| 355 | if (adev) { | 359 | auxiliary_device_delete(adev); |
| 356 | auxiliary_device_delete(adev); | 360 | auxiliary_device_uninit(adev); |
| 357 | auxiliary_device_uninit(adev); | ||
| 358 | } | ||
| 359 | } | 361 | } |
| 360 | 362 | ||
| 361 | /** | 363 | /** |
| @@ -4536,17 +4536,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware) · 4535 unmodified lines | |||
| 4536 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); | 4536 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); |
| 4537 | else | 4537 | else |
| 4538 | dev_info(dev, "Tx scheduling layers switching feature enabled\n"); | 4538 | dev_info(dev, "Tx scheduling layers switching feature enabled\n"); |
| 4539 | /* if there was a change in topology ice_cfg_tx_topo triggered | 4539 | return 0; |
| 4540 | * a CORER and we need to re-init hw | 4540 | } else if (err == -ENODEV) { |
| 4541 | /* If we failed to re-initialize the device, we can no longer | ||
| 4542 | * continue loading. | ||
| 4541 | */ | 4543 | */ |
| 4542 | ice_deinit_hw(hw); | 4544 | dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n"); |
| 4543 | err = ice_init_hw(hw); | ||
| 4544 | |||
| 4545 | return err; | 4545 | return err; |
| 4546 | } else if (err == -EIO) { | 4546 | } else if (err == -EIO) { |
| 4547 | dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n"); | 4547 | dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n"); |
| 4548 | return 0; | ||
| 4549 | } else if (err == -EEXIST) { | ||
| 4550 | return 0; | ||
| 4548 | } | 4551 | } |
| 4549 | 4552 | ||
| 4553 | /* Do not treat this as a fatal error. */ | ||
| 4554 | dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n", | ||
| 4555 | ERR_PTR(err)); | ||
| 4550 | return 0; | 4556 | return 0; |
| 4551 | } | 4557 | } |
| 4552 | 4558 | ||
| @@ -1352,7 +1352,7 @@ construct_skb: · 1351 unmodified lines | |||
| 1352 | skb = ice_construct_skb(rx_ring, xdp); | 1352 | skb = ice_construct_skb(rx_ring, xdp); |
| 1353 | /* exit if we failed to retrieve a buffer */ | 1353 | /* exit if we failed to retrieve a buffer */ |
| 1354 | if (!skb) { | 1354 | if (!skb) { |
| 1355 | rx_ring->ring_stats->rx_stats.alloc_page_failed++; | 1355 | rx_ring->ring_stats->rx_stats.alloc_buf_failed++; |
| 1356 | xdp_verdict = ICE_XDP_CONSUMED; | 1356 | xdp_verdict = ICE_XDP_CONSUMED; |
| 1357 | } | 1357 | } |
| 1358 | ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict); | 1358 | ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict); |
| @@ -179,6 +179,58 @@ static int idpf_tx_singleq_csum(struct sk_buff *skb, · 178 unmodified lines | |||
| 179 | return 1; | 179 | return 1; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | /** | ||
| 183 | * idpf_tx_singleq_dma_map_error - handle TX DMA map errors | ||
| 184 | * @txq: queue to send buffer on | ||
| 185 | * @skb: send buffer | ||
| 186 | * @first: original first buffer info buffer for packet | ||
| 187 | * @idx: starting point on ring to unwind | ||
| 188 | */ | ||
| 189 | static void idpf_tx_singleq_dma_map_error(struct idpf_tx_queue *txq, | ||
| 190 | struct sk_buff *skb, | ||
| 191 | struct idpf_tx_buf *first, u16 idx) | ||
| 192 | { | ||
| 193 | struct libeth_sq_napi_stats ss = { }; | ||
| 194 | struct libeth_cq_pp cp = { | ||
| 195 | .dev = txq->dev, | ||
| 196 | .ss = &ss, | ||
| 197 | }; | ||
| 198 | |||
| 199 | u64_stats_update_begin(&txq->stats_sync); | ||
| 200 | u64_stats_inc(&txq->q_stats.dma_map_errs); | ||
| 201 | u64_stats_update_end(&txq->stats_sync); | ||
| 202 | |||
| 203 | /* clear dma mappings for failed tx_buf map */ | ||
| 204 | for (;;) { | ||
| 205 | struct idpf_tx_buf *tx_buf; | ||
| 206 | |||
| 207 | tx_buf = &txq->tx_buf[idx]; | ||
| 208 | libeth_tx_complete(tx_buf, &cp); | ||
| 209 | if (tx_buf == first) | ||
| 210 | break; | ||
| 211 | if (idx == 0) | ||
| 212 | idx = txq->desc_count; | ||
| 213 | idx--; | ||
| 214 | } | ||
| 215 | |||
| 216 | if (skb_is_gso(skb)) { | ||
| 217 | union idpf_tx_flex_desc *tx_desc; | ||
| 218 | |||
| 219 | /* If we failed a DMA mapping for a TSO packet, we will have | ||
| 220 | * used one additional descriptor for a context | ||
| 221 | * descriptor. Reset that here. | ||
| 222 | */ | ||
| 223 | tx_desc = &txq->flex_tx[idx]; | ||
| 224 | memset(tx_desc, 0, sizeof(*tx_desc)); | ||
| 225 | if (idx == 0) | ||
| 226 | idx = txq->desc_count; | ||
| 227 | idx--; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* Update tail in case netdev_xmit_more was previously true */ | ||
| 231 | idpf_tx_buf_hw_update(txq, idx, false); | ||
| 232 | } | ||
| 233 | |||
| 182 | /** | 234 | /** |
| 183 | * idpf_tx_singleq_map - Build the Tx base descriptor | 235 | * idpf_tx_singleq_map - Build the Tx base descriptor |
| 184 | * @tx_q: queue to send buffer on | 236 | * @tx_q: queue to send buffer on |
| @@ -219,8 +271,9 @@ static void idpf_tx_singleq_map(struct idpf_tx_queue *tx_q, · 34 unmodified lines | |||
| 219 | for (frag = &skb_shinfo(skb)->frags[0];; frag++) { | 271 | for (frag = &skb_shinfo(skb)->frags[0];; frag++) { |
| 220 | unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED; | 272 | unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED; |
| 221 | 273 | ||
| 222 | if (dma_mapping_error(tx_q->dev, dma)) | 274 | if (unlikely(dma_mapping_error(tx_q->dev, dma))) |
| 223 | return idpf_tx_dma_map_error(tx_q, skb, first, i); | 275 | return idpf_tx_singleq_dma_map_error(tx_q, skb, |
| 276 | first, i); | ||
| 224 | 277 | ||
| 225 | /* record length, and DMA address */ | 278 | /* record length, and DMA address */ |
| 226 | dma_unmap_len_set(tx_buf, len, size); | 279 | dma_unmap_len_set(tx_buf, len, size); |
| @@ -362,11 +415,11 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb, · 135 unmodified lines | |||
| 362 | { | 415 | { |
| 363 | struct idpf_tx_offload_params offload = { }; | 416 | struct idpf_tx_offload_params offload = { }; |
| 364 | struct idpf_tx_buf *first; | 417 | struct idpf_tx_buf *first; |
| 418 | u32 count, buf_count = 1; | ||
| 365 | int csum, tso, needed; | 419 | int csum, tso, needed; |
| 366 | unsigned int count; | ||
| 367 | __be16 protocol; | 420 | __be16 protocol; |
| 368 | 421 | ||
| 369 | count = idpf_tx_desc_count_required(tx_q, skb); | 422 | count = idpf_tx_res_count_required(tx_q, skb, &buf_count); |
| 370 | if (unlikely(!count)) | 423 | if (unlikely(!count)) |
| 371 | return idpf_tx_drop_skb(tx_q, skb); | 424 | return idpf_tx_drop_skb(tx_q, skb); |
| 372 | 425 | ||
| @@ -8,12 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include "idpf_ptp.h" | 8 | #include "idpf_ptp.h" |
| 9 | #include "idpf_virtchnl.h" | 9 | #include "idpf_virtchnl.h" |
| 10 | 10 | ||
| 11 | struct idpf_tx_stash { | 11 | #define idpf_tx_buf_next(buf) (*(u32 *)&(buf)->priv) |
| 12 | struct hlist_node hlist; | ||
| 13 | struct libeth_sqe buf; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define idpf_tx_buf_compl_tag(buf) (*(u32 *)&(buf)->priv) | ||
| 17 | LIBETH_SQE_CHECK_PRIV(u32); | 12 | LIBETH_SQE_CHECK_PRIV(u32); |
| 18 | 13 | ||
| 19 | /** | 14 | /** |
| @@ -39,36 +34,6 @@ static bool idpf_chk_linearize(const struct sk_buff *skb, · 19 unmodified lines | |||
| 39 | return true; | 34 | return true; |
| 40 | } | 35 | } |
| 41 | 36 | ||
| 42 | /** | ||
| 43 | * idpf_buf_lifo_push - push a buffer pointer onto stack | ||
| 44 | * @stack: pointer to stack struct | ||
| 45 | * @buf: pointer to buf to push | ||
| 46 | * | ||
| 47 | * Returns 0 on success, negative on failure | ||
| 48 | **/ | ||
| 49 | static int idpf_buf_lifo_push(struct idpf_buf_lifo *stack, | ||
| 50 | struct idpf_tx_stash *buf) | ||
| 51 | { | ||
| 52 | if (unlikely(stack->top == stack->size)) | ||
| 53 | return -ENOSPC; | ||
| 54 | |||
| 55 | stack->bufs[stack->top++] = buf; | ||
| 56 | |||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * idpf_buf_lifo_pop - pop a buffer pointer from stack | ||
| 62 | * @stack: pointer to stack struct | ||
| 63 | **/ | ||
| 64 | static struct idpf_tx_stash *idpf_buf_lifo_pop(struct idpf_buf_lifo *stack) | ||
| 65 | { | ||
| 66 | if (unlikely(!stack->top)) | ||
| 67 | return NULL; | ||
| 68 | |||
| 69 | return stack->bufs[--stack->top]; | ||
| 70 | } | ||
| 71 | |||
| 72 | /** | 37 | /** |
| 73 | * idpf_tx_timeout - Respond to a Tx Hang | 38 | * idpf_tx_timeout - Respond to a Tx Hang |
| 74 | * @netdev: network interface device structure | 39 | * @netdev: network interface device structure |
| @@ -97,52 +62,22 @@ void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue) · 22 unmodified lines | |||
| 97 | static void idpf_tx_buf_rel_all(struct idpf_tx_queue *txq) | 62 | static void idpf_tx_buf_rel_all(struct idpf_tx_queue *txq) |
| 98 | { | 63 | { |
| 99 | struct libeth_sq_napi_stats ss = { }; | 64 | struct libeth_sq_napi_stats ss = { }; |
| 100 | struct idpf_buf_lifo *buf_stack; | ||
| 101 | struct idpf_tx_stash *stash; | ||
| 102 | struct libeth_cq_pp cp = { | 65 | struct libeth_cq_pp cp = { |
| 103 | .dev = txq->dev, | 66 | .dev = txq->dev, |
| 104 | .ss = &ss, | 67 | .ss = &ss, |
| 105 | }; | 68 | }; |
| 106 | struct hlist_node *tmp; | 69 | u32 i; |
| 107 | u32 i, tag; | ||
| 108 | 70 | ||
| 109 | /* Buffers already cleared, nothing to do */ | 71 | /* Buffers already cleared, nothing to do */ |
| 110 | if (!txq->tx_buf) | 72 | if (!txq->tx_buf) |
| 111 | return; | 73 | return; |
| 112 | 74 | ||
| 113 | /* Free all the Tx buffer sk_buffs */ | 75 | /* Free all the Tx buffer sk_buffs */ |
| 114 | for (i = 0; i < txq->desc_count; i++) | 76 | for (i = 0; i < txq->buf_pool_size; i++) |
| 115 | libeth_tx_complete(&txq->tx_buf[i], &cp); | 77 | libeth_tx_complete(&txq->tx_buf[i], &cp); |
| 116 | 78 | ||
| 117 | kfree(txq->tx_buf); | 79 | kfree(txq->tx_buf); |
| 118 | txq->tx_buf = NULL; | 80 | txq->tx_buf = NULL; |
| 119 | |||
| 120 | if (!idpf_queue_has(FLOW_SCH_EN, txq)) | ||
| 121 | return; | ||
| 122 | |||
| 123 | buf_stack = &txq->stash->buf_stack; | ||
| 124 | if (!buf_stack->bufs) | ||
| 125 | return; | ||
| 126 | |||
| 127 | /* | ||
| 128 | * If a Tx timeout occurred, there are potentially still bufs in the | ||
| 129 | * hash table, free them here. | ||
| 130 | */ | ||
| 131 | hash_for_each_safe(txq->stash->sched_buf_hash, tag, tmp, stash, | ||
| 132 | hlist) { | ||
| 133 | if (!stash) | ||
| 134 | continue; | ||
| 135 | |||
| 136 | libeth_tx_complete(&stash->buf, &cp); | ||
| 137 | hash_del(&stash->hlist); | ||
| 138 | idpf_buf_lifo_push(buf_stack, stash); | ||
| 139 | } | ||
| 140 | |||
| 141 | for (i = 0; i < buf_stack->size; i++) | ||
| 142 | kfree(buf_stack->bufs[i]); | ||
| 143 | |||
| 144 | kfree(buf_stack->bufs); | ||
| 145 | buf_stack->bufs = NULL; | ||
| 146 | } | 81 | } |
| 147 | 82 | ||
| 148 | /** | 83 | /** |
| @@ -159,6 +94,9 @@ static void idpf_tx_desc_rel(struct idpf_tx_queue *txq) · 10 unmodified lines | |||
| 159 | if (!txq->desc_ring) | 94 | if (!txq->desc_ring) |
| 160 | return; | 95 | return; |
| 161 | 96 | ||
| 97 | if (txq->refillq) | ||
| 98 | kfree(txq->refillq->ring); | ||
| 99 | |||
| 162 | dmam_free_coherent(txq->dev, txq->size, txq->desc_ring, txq->dma); | 100 | dmam_free_coherent(txq->dev, txq->size, txq->desc_ring, txq->dma); |
| 163 | txq->desc_ring = NULL; | 101 | txq->desc_ring = NULL; |
| 164 | txq->next_to_use = 0; | 102 | txq->next_to_use = 0; |
| @@ -215,41 +153,18 @@ static void idpf_tx_desc_rel_all(struct idpf_vport *vport) · 50 unmodified lines | |||
| 215 | */ | 153 | */ |
| 216 | static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q) | 154 | static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q) |
| 217 | { | 155 | { |
| 218 | struct idpf_buf_lifo *buf_stack; | ||
| 219 | int buf_size; | ||
| 220 | int i; | ||
| 221 | |||
| 222 | /* Allocate book keeping buffers only. Buffers to be supplied to HW | 156 | /* Allocate book keeping buffers only. Buffers to be supplied to HW |
| 223 | * are allocated by kernel network stack and received as part of skb | 157 | * are allocated by kernel network stack and received as part of skb |
| 224 | */ | 158 | */ |
| 225 | buf_size = sizeof(struct idpf_tx_buf) * tx_q->desc_count; | 159 | if (idpf_queue_has(FLOW_SCH_EN, tx_q)) |
| 226 | tx_q->tx_buf = kzalloc(buf_size, GFP_KERNEL); | 160 | tx_q->buf_pool_size = U16_MAX; |
| 161 | else | ||
| 162 | tx_q->buf_pool_size = tx_q->desc_count; | ||
| 163 | tx_q->tx_buf = kcalloc(tx_q->buf_pool_size, sizeof(*tx_q->tx_buf), | ||
| 164 | GFP_KERNEL); | ||
| 227 | if (!tx_q->tx_buf) | 165 | if (!tx_q->tx_buf) |
| 228 | return -ENOMEM; | 166 | return -ENOMEM; |
| 229 | 167 | ||
| 230 | if (!idpf_queue_has(FLOW_SCH_EN, tx_q)) | ||
| 231 | return 0; | ||
| 232 | |||
| 233 | buf_stack = &tx_q->stash->buf_stack; | ||
| 234 | |||
| 235 | /* Initialize tx buf stack for out-of-order completions if | ||
| 236 | * flow scheduling offload is enabled | ||
| 237 | */ | ||
| 238 | buf_stack->bufs = kcalloc(tx_q->desc_count, sizeof(*buf_stack->bufs), | ||
| 239 | GFP_KERNEL); | ||
| 240 | if (!buf_stack->bufs) | ||
| 241 | return -ENOMEM; | ||
| 242 | |||
| 243 | buf_stack->size = tx_q->desc_count; | ||
| 244 | buf_stack->top = tx_q->desc_count; | ||
| 245 | |||
| 246 | for (i = 0; i < tx_q->desc_count; i++) { | ||
| 247 | buf_stack->bufs[i] = kzalloc(sizeof(*buf_stack->bufs[i]), | ||
| 248 | GFP_KERNEL); | ||
| 249 | if (!buf_stack->bufs[i]) | ||
| 250 | return -ENOMEM; | ||
| 251 | } | ||
| 252 | |||
| 253 | return 0; | 168 | return 0; |
| 254 | } | 169 | } |
| 255 | 170 | ||
| @@ -264,6 +179,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport, · 8 unmodified lines | |||
| 264 | struct idpf_tx_queue *tx_q) | 179 | struct idpf_tx_queue *tx_q) |
| 265 | { | 180 | { |
| 266 | struct device *dev = tx_q->dev; | 181 | struct device *dev = tx_q->dev; |
| 182 | struct idpf_sw_queue *refillq; | ||
| 267 | int err; | 183 | int err; |
| 268 | 184 | ||
| 269 | err = idpf_tx_buf_alloc_all(tx_q); | 185 | err = idpf_tx_buf_alloc_all(tx_q); |
| @@ -287,6 +203,31 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport, · 17 unmodified lines | |||
| 287 | tx_q->next_to_clean = 0; | 203 | tx_q->next_to_clean = 0; |
| 288 | idpf_queue_set(GEN_CHK, tx_q); | 204 | idpf_queue_set(GEN_CHK, tx_q); |
| 289 | 205 | ||
| 206 | if (!idpf_queue_has(FLOW_SCH_EN, tx_q)) | ||
| 207 | return 0; | ||
| 208 | |||
| 209 | refillq = tx_q->refillq; | ||
| 210 | refillq->desc_count = tx_q->buf_pool_size; | ||
| 211 | refillq->ring = kcalloc(refillq->desc_count, sizeof(u32), | ||
| 212 | GFP_KERNEL); | ||
| 213 | if (!refillq->ring) { | ||
| 214 | err = -ENOMEM; | ||
| 215 | goto err_alloc; | ||
| 216 | } | ||
| 217 | |||
| 218 | for (unsigned int i = 0; i < refillq->desc_count; i++) | ||
| 219 | refillq->ring[i] = | ||
| 220 | FIELD_PREP(IDPF_RFL_BI_BUFID_M, i) | | ||
| 221 | FIELD_PREP(IDPF_RFL_BI_GEN_M, | ||
| 222 | idpf_queue_has(GEN_CHK, refillq)); | ||
| 223 | |||
| 224 | /* Go ahead and flip the GEN bit since this counts as filling | ||
| 225 | * up the ring, i.e. we already ring wrapped. | ||
| 226 | */ | ||
| 227 | idpf_queue_change(GEN_CHK, refillq); | ||
| 228 | |||
| 229 | tx_q->last_re = tx_q->desc_count - IDPF_TX_SPLITQ_RE_MIN_GAP; | ||
| 230 | |||
| 290 | return 0; | 231 | return 0; |
| 291 | 232 | ||
| 292 | err_alloc: | 233 | err_alloc: |
| @@ -337,8 +278,6 @@ static int idpf_tx_desc_alloc_all(struct idpf_vport *vport) · 44 unmodified lines | |||
| 337 | for (i = 0; i < vport->num_txq_grp; i++) { | 278 | for (i = 0; i < vport->num_txq_grp; i++) { |
| 338 | for (j = 0; j < vport->txq_grps[i].num_txq; j++) { | 279 | for (j = 0; j < vport->txq_grps[i].num_txq; j++) { |
| 339 | struct idpf_tx_queue *txq = vport->txq_grps[i].txqs[j]; | 280 | struct idpf_tx_queue *txq = vport->txq_grps[i].txqs[j]; |
| 340 | u8 gen_bits = 0; | ||
| 341 | u16 bufidx_mask; | ||
| 342 | 281 | ||
| 343 | err = idpf_tx_desc_alloc(vport, txq); | 282 | err = idpf_tx_desc_alloc(vport, txq); |
| 344 | if (err) { | 283 | if (err) { |
| @@ -347,34 +286,6 @@ static int idpf_tx_desc_alloc_all(struct idpf_vport *vport) · 2 unmodified lines | |||
| 347 | i); | 286 | i); |
| 348 | goto err_out; | 287 | goto err_out; |
| 349 | } | 288 | } |
| 350 | |||
| 351 | if (!idpf_is_queue_model_split(vport->txq_model)) | ||
| 352 | continue; | ||
| 353 | |||
| 354 | txq->compl_tag_cur_gen = 0; | ||
| 355 | |||
| 356 | /* Determine the number of bits in the bufid | ||
| 357 | * mask and add one to get the start of the | ||
| 358 | * generation bits | ||
| 359 | */ | ||
| 360 | bufidx_mask = txq->desc_count - 1; | ||
| 361 | while (bufidx_mask >> 1) { | ||
| 362 | txq->compl_tag_gen_s++; | ||
| 363 | bufidx_mask = bufidx_mask >> 1; | ||
| 364 | } | ||
| 365 | txq->compl_tag_gen_s++; | ||
| 366 | |||
| 367 | gen_bits = IDPF_TX_SPLITQ_COMPL_TAG_WIDTH - | ||
| 368 | txq->compl_tag_gen_s; | ||
| 369 | txq->compl_tag_gen_max = GETMAXVAL(gen_bits); | ||
| 370 | |||
| 371 | /* Set bufid mask based on location of first | ||
| 372 | * gen bit; it cannot simply be the descriptor | ||
| 373 | * ring size-1 since we can have size values | ||
| 374 | * where not all of those bits are set. | ||
| 375 | */ | ||
| 376 | txq->compl_tag_bufid_m = | ||
| 377 | GETMAXVAL(txq->compl_tag_gen_s); | ||
| 378 | } | 289 | } |
| 379 | 290 | ||
| 380 | if (!idpf_is_queue_model_split(vport->txq_model)) | 291 | if (!idpf_is_queue_model_split(vport->txq_model)) |
| @@ -623,18 +534,18 @@ static int idpf_rx_hdr_buf_alloc_all(struct idpf_buf_queue *bufq) · 242 unmodified lines | |||
| 623 | } | 534 | } |
| 624 | 535 | ||
| 625 | /** | 536 | /** |
| 626 | * idpf_rx_post_buf_refill - Post buffer id to refill queue | 537 | * idpf_post_buf_refill - Post buffer id to refill queue |
| 627 | * @refillq: refill queue to post to | 538 | * @refillq: refill queue to post to |
| 628 | * @buf_id: buffer id to post | 539 | * @buf_id: buffer id to post |
| 629 | */ | 540 | */ |
| 630 | static void idpf_rx_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id) | 541 | static void idpf_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id) |
| 631 | { | 542 | { |
| 632 | u32 nta = refillq->next_to_use; | 543 | u32 nta = refillq->next_to_use; |
| 633 | 544 | ||
| 634 | /* store the buffer ID and the SW maintained GEN bit to the refillq */ | 545 | /* store the buffer ID and the SW maintained GEN bit to the refillq */ |
| 635 | refillq->ring[nta] = | 546 | refillq->ring[nta] = |
| 636 | FIELD_PREP(IDPF_RX_BI_BUFID_M, buf_id) | | 547 | FIELD_PREP(IDPF_RFL_BI_BUFID_M, buf_id) | |
| 637 | FIELD_PREP(IDPF_RX_BI_GEN_M, | 548 | FIELD_PREP(IDPF_RFL_BI_GEN_M, |
| 638 | idpf_queue_has(GEN_CHK, refillq)); | 549 | idpf_queue_has(GEN_CHK, refillq)); |
| 639 | 550 | ||
| 640 | if (unlikely(++nta == refillq->desc_count)) { | 551 | if (unlikely(++nta == refillq->desc_count)) { |
| @@ -1015,6 +926,11 @@ static void idpf_txq_group_rel(struct idpf_vport *vport) · 374 unmodified lines | |||
| 1015 | struct idpf_txq_group *txq_grp = &vport->txq_grps[i]; | 926 | struct idpf_txq_group *txq_grp = &vport->txq_grps[i]; |
| 1016 | 927 | ||
| 1017 | for (j = 0; j < txq_grp->num_txq; j++) { | 928 | for (j = 0; j < txq_grp->num_txq; j++) { |
| 929 | if (flow_sch_en) { | ||
| 930 | kfree(txq_grp->txqs[j]->refillq); | ||
| 931 | txq_grp->txqs[j]->refillq = NULL; | ||
| 932 | } | ||
| 933 | |||
| 1018 | kfree(txq_grp->txqs[j]); | 934 | kfree(txq_grp->txqs[j]); |
| 1019 | txq_grp->txqs[j] = NULL; | 935 | txq_grp->txqs[j] = NULL; |
| 1020 | } | 936 | } |
| @@ -1024,9 +940,6 @@ static void idpf_txq_group_rel(struct idpf_vport *vport) · 3 unmodified lines | |||
| 1024 | 940 | ||
| 1025 | kfree(txq_grp->complq); | 941 | kfree(txq_grp->complq); |
| 1026 | txq_grp->complq = NULL; | 942 | txq_grp->complq = NULL; |
| 1027 | |||
| 1028 | if (flow_sch_en) | ||
| 1029 | kfree(txq_grp->stashes); | ||
| 1030 | } | 943 | } |
| 1031 | kfree(vport->txq_grps); | 944 | kfree(vport->txq_grps); |
| 1032 | vport->txq_grps = NULL; | 945 | vport->txq_grps = NULL; |
| @@ -1387,7 +1300,6 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq) · 354 unmodified lines | |||
| 1387 | for (i = 0; i < vport->num_txq_grp; i++) { | 1300 | for (i = 0; i < vport->num_txq_grp; i++) { |
| 1388 | struct idpf_txq_group *tx_qgrp = &vport->txq_grps[i]; | 1301 | struct idpf_txq_group *tx_qgrp = &vport->txq_grps[i]; |
| 1389 | struct idpf_adapter *adapter = vport->adapter; | 1302 | struct idpf_adapter *adapter = vport->adapter; |
| 1390 | struct idpf_txq_stash *stashes; | ||
| 1391 | int j; | 1303 | int j; |
| 1392 | 1304 | ||
| 1393 | tx_qgrp->vport = vport; | 1305 | tx_qgrp->vport = vport; |
| @@ -1400,15 +1312,6 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq) · 6 unmodified lines | |||
| 1400 | goto err_alloc; | 1312 | goto err_alloc; |
| 1401 | } | 1313 | } |
| 1402 | 1314 | ||
| 1403 | if (split && flow_sch_en) { | ||
| 1404 | stashes = kcalloc(num_txq, sizeof(*stashes), | ||
| 1405 | GFP_KERNEL); | ||
| 1406 | if (!stashes) | ||
| 1407 | goto err_alloc; | ||
| 1408 | |||
| 1409 | tx_qgrp->stashes = stashes; | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | for (j = 0; j < tx_qgrp->num_txq; j++) { | 1315 | for (j = 0; j < tx_qgrp->num_txq; j++) { |
| 1413 | struct idpf_tx_queue *q = tx_qgrp->txqs[j]; | 1316 | struct idpf_tx_queue *q = tx_qgrp->txqs[j]; |
| 1414 | 1317 | ||
| @@ -1428,12 +1331,14 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq) · 13 unmodified lines | |||
| 1428 | if (!flow_sch_en) | 1331 | if (!flow_sch_en) |
| 1429 | continue; | 1332 | continue; |
| 1430 | 1333 | ||
| 1431 | if (split) { | ||
| 1432 | q->stash = &stashes[j]; | ||
| 1433 | hash_init(q->stash->sched_buf_hash); | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | idpf_queue_set(FLOW_SCH_EN, q); | 1334 | idpf_queue_set(FLOW_SCH_EN, q); |
| 1335 | |||
| 1336 | q->refillq = kzalloc(sizeof(*q->refillq), GFP_KERNEL); | ||
| 1337 | if (!q->refillq) | ||
| 1338 | goto err_alloc; | ||
| 1339 | |||
| 1340 | idpf_queue_set(GEN_CHK, q->refillq); | ||
| 1341 | idpf_queue_set(RFL_GEN_CHK, q->refillq); | ||
| 1437 | } | 1342 | } |
| 1438 | 1343 | ||
| 1439 | if (!split) | 1344 | if (!split) |
| @@ -1717,87 +1622,6 @@ static void idpf_tx_read_tstamp(struct idpf_tx_queue *txq, struct sk_buff *skb) · 277 unmodified lines | |||
| 1717 | spin_unlock_bh(&tx_tstamp_caps->status_lock); | 1622 | spin_unlock_bh(&tx_tstamp_caps->status_lock); |
| 1718 | } | 1623 | } |
| 1719 | 1624 | ||
| 1720 | /** | ||
| 1721 | * idpf_tx_clean_stashed_bufs - clean bufs that were stored for | ||
| 1722 | * out of order completions | ||
| 1723 | * @txq: queue to clean | ||
| 1724 | * @compl_tag: completion tag of packet to clean (from completion descriptor) | ||
| 1725 | * @cleaned: pointer to stats struct to track cleaned packets/bytes | ||
| 1726 | * @budget: Used to determine if we are in netpoll | ||
| 1727 | */ | ||
| 1728 | static void idpf_tx_clean_stashed_bufs(struct idpf_tx_queue *txq, | ||
| 1729 | u16 compl_tag, | ||
| 1730 | struct libeth_sq_napi_stats *cleaned, | ||
| 1731 | int budget) | ||
| 1732 | { | ||
| 1733 | struct idpf_tx_stash *stash; | ||
| 1734 | struct hlist_node *tmp_buf; | ||
| 1735 | struct libeth_cq_pp cp = { | ||
| 1736 | .dev = txq->dev, | ||
| 1737 | .ss = cleaned, | ||
| 1738 | .napi = budget, | ||
| 1739 | }; | ||
| 1740 | |||
| 1741 | /* Buffer completion */ | ||
| 1742 | hash_for_each_possible_safe(txq->stash->sched_buf_hash, stash, tmp_buf, | ||
| 1743 | hlist, compl_tag) { | ||
| 1744 | if (unlikely(idpf_tx_buf_compl_tag(&stash->buf) != compl_tag)) | ||
| 1745 | continue; | ||
| 1746 | |||
| 1747 | hash_del(&stash->hlist); | ||
| 1748 | |||
| 1749 | if (stash->buf.type == LIBETH_SQE_SKB && | ||
| 1750 | (skb_shinfo(stash->buf.skb)->tx_flags & SKBTX_IN_PROGRESS)) | ||
| 1751 | idpf_tx_read_tstamp(txq, stash->buf.skb); | ||
| 1752 | |||
| 1753 | libeth_tx_complete(&stash->buf, &cp); | ||
| 1754 | |||
| 1755 | /* Push shadow buf back onto stack */ | ||
| 1756 | idpf_buf_lifo_push(&txq->stash->buf_stack, stash); | ||
| 1757 | } | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | /** | ||
| 1761 | * idpf_stash_flow_sch_buffers - store buffer parameters info to be freed at a | ||
| 1762 | * later time (only relevant for flow scheduling mode) | ||
| 1763 | * @txq: Tx queue to clean | ||
| 1764 | * @tx_buf: buffer to store | ||
| 1765 | */ | ||
| 1766 | static int idpf_stash_flow_sch_buffers(struct idpf_tx_queue *txq, | ||
| 1767 | struct idpf_tx_buf *tx_buf) | ||
| 1768 | { | ||
| 1769 | struct idpf_tx_stash *stash; | ||
| 1770 | |||
| 1771 | if (unlikely(tx_buf->type <= LIBETH_SQE_CTX)) | ||
| 1772 | return 0; | ||
| 1773 | |||
| 1774 | stash = idpf_buf_lifo_pop(&txq->stash->buf_stack); | ||
| 1775 | if (unlikely(!stash)) { | ||
| 1776 | net_err_ratelimited("%s: No out-of-order TX buffers left!\n", | ||
| 1777 | netdev_name(txq->netdev)); | ||
| 1778 | |||
| 1779 | return -ENOMEM; | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | /* Store buffer params in shadow buffer */ | ||
| 1783 | stash->buf.skb = tx_buf->skb; | ||
| 1784 | stash->buf.bytes = tx_buf->bytes; | ||
| 1785 | stash->buf.packets = tx_buf->packets; | ||
| 1786 | stash->buf.type = tx_buf->type; | ||
| 1787 | stash->buf.nr_frags = tx_buf->nr_frags; | ||
| 1788 | dma_unmap_addr_set(&stash->buf, dma, dma_unmap_addr(tx_buf, dma)); | ||
| 1789 | dma_unmap_len_set(&stash->buf, len, dma_unmap_len(tx_buf, len)); | ||
| 1790 | idpf_tx_buf_compl_tag(&stash->buf) = idpf_tx_buf_compl_tag(tx_buf); | ||
| 1791 | |||
| 1792 | /* Add buffer to buf_hash table to be freed later */ | ||
| 1793 | hash_add(txq->stash->sched_buf_hash, &stash->hlist, | ||
| 1794 | idpf_tx_buf_compl_tag(&stash->buf)); | ||
| 1795 | |||
| 1796 | tx_buf->type = LIBETH_SQE_EMPTY; | ||
| 1797 | |||
| 1798 | return 0; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | #define idpf_tx_splitq_clean_bump_ntc(txq, ntc, desc, buf) \ | 1625 | #define idpf_tx_splitq_clean_bump_ntc(txq, ntc, desc, buf) \ |
| 1802 | do { \ | 1626 | do { \ |
| 1803 | if (unlikely(++(ntc) == (txq)->desc_count)) { \ | 1627 | if (unlikely(++(ntc) == (txq)->desc_count)) { \ |
| @@ -1825,14 +1649,8 @@ do { \ · 21 unmodified lines | |||
| 1825 | * Separate packet completion events will be reported on the completion queue, | 1649 | * Separate packet completion events will be reported on the completion queue, |
| 1826 | * and the buffers will be cleaned separately. The stats are not updated from | 1650 | * and the buffers will be cleaned separately. The stats are not updated from |
| 1827 | * this function when using flow-based scheduling. | 1651 | * this function when using flow-based scheduling. |
| 1828 | * | ||
| 1829 | * Furthermore, in flow scheduling mode, check to make sure there are enough | ||
| 1830 | * reserve buffers to stash the packet. If there are not, return early, which | ||
| 1831 | * will leave next_to_clean pointing to the packet that failed to be stashed. | ||
| 1832 | * | ||
| 1833 | * Return: false in the scenario above, true otherwise. | ||
| 1834 | */ | 1652 | */ |
| 1835 | static bool idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end, | 1653 | static void idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end, |
| 1836 | int napi_budget, | 1654 | int napi_budget, |
| 1837 | struct libeth_sq_napi_stats *cleaned, | 1655 | struct libeth_sq_napi_stats *cleaned, |
| 1838 | bool descs_only) | 1656 | bool descs_only) |
| @@ -1846,7 +1664,12 @@ static bool idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end, · 7 unmodified lines | |||
| 1846 | .napi = napi_budget, | 1664 | .napi = napi_budget, |
| 1847 | }; | 1665 | }; |
| 1848 | struct idpf_tx_buf *tx_buf; | 1666 | struct idpf_tx_buf *tx_buf; |
| 1849 | bool clean_complete = true; | 1667 | |
| 1668 | if (descs_only) { | ||
| 1669 | /* Bump ring index to mark as cleaned. */ | ||
| 1670 | tx_q->next_to_clean = end; | ||
| 1671 | return; | ||
| 1672 | } | ||
| 1850 | 1673 | ||
| 1851 | tx_desc = &tx_q->flex_tx[ntc]; | 1674 | tx_desc = &tx_q->flex_tx[ntc]; |
| 1852 | next_pending_desc = &tx_q->flex_tx[end]; | 1675 | next_pending_desc = &tx_q->flex_tx[end]; |
| @@ -1866,136 +1689,61 @@ static bool idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end, · 13 unmodified lines | |||
| 1866 | break; | 1689 | break; |
| 1867 | 1690 | ||
| 1868 | eop_idx = tx_buf->rs_idx; | 1691 | eop_idx = tx_buf->rs_idx; |
| 1692 | libeth_tx_complete(tx_buf, &cp); | ||
| 1869 | 1693 | ||
| 1870 | if (descs_only) { | 1694 | /* unmap remaining buffers */ |
| 1871 | if (IDPF_TX_BUF_RSV_UNUSED(tx_q) < tx_buf->nr_frags) { | 1695 | while (ntc != eop_idx) { |
| 1872 | clean_complete = false; | 1696 | idpf_tx_splitq_clean_bump_ntc(tx_q, ntc, |
| 1873 | goto tx_splitq_clean_out; | 1697 | tx_desc, tx_buf); |
| 1874 | } | ||
| 1875 | |||
| 1876 | idpf_stash_flow_sch_buffers(tx_q, tx_buf); | ||
| 1877 | 1698 | ||
| 1878 | while (ntc != eop_idx) { | 1699 | /* unmap any remaining paged data */ |
| 1879 | idpf_tx_splitq_clean_bump_ntc(tx_q, ntc, | ||
| 1880 | tx_desc, tx_buf); | ||
| 1881 | idpf_stash_flow_sch_buffers(tx_q, tx_buf); | ||
| 1882 | } | ||
| 1883 | } else { | ||
| 1884 | libeth_tx_complete(tx_buf, &cp); | 1700 | libeth_tx_complete(tx_buf, &cp); |
| 1885 | |||
| 1886 | /* unmap remaining buffers */ | ||
| 1887 | while (ntc != eop_idx) { | ||
| 1888 | idpf_tx_splitq_clean_bump_ntc(tx_q, ntc, | ||
| 1889 | tx_desc, tx_buf); | ||
| 1890 | |||
| 1891 | /* unmap any remaining paged data */ | ||
| 1892 | libeth_tx_complete(tx_buf, &cp); | ||
| 1893 | } | ||
| 1894 | } | 1701 | } |
| 1895 | 1702 | ||
| 1896 | fetch_next_txq_desc: | 1703 | fetch_next_txq_desc: |
| 1897 | idpf_tx_splitq_clean_bump_ntc(tx_q, ntc, tx_desc, tx_buf); | 1704 | idpf_tx_splitq_clean_bump_ntc(tx_q, ntc, tx_desc, tx_buf); |
| 1898 | } | 1705 | } |
| 1899 | 1706 | ||
| 1900 | tx_splitq_clean_out: | ||
| 1901 | tx_q->next_to_clean = ntc; | 1707 | tx_q->next_to_clean = ntc; |
| 1902 | |||
| 1903 | return clean_complete; | ||
| 1904 | } | 1708 | } |
| 1905 | 1709 | ||
| 1906 | #define idpf_tx_clean_buf_ring_bump_ntc(txq, ntc, buf) \ | ||
| 1907 | do { \ | ||
| 1908 | (buf)++; \ | ||
| 1909 | (ntc)++; \ | ||
| 1910 | if (unlikely((ntc) == (txq)->desc_count)) { \ | ||
| 1911 | buf = (txq)->tx_buf; \ | ||
| 1912 | ntc = 0; \ | ||
| 1913 | } \ | ||
| 1914 | } while (0) | ||
| 1915 | |||
| 1916 | /** | 1710 | /** |
| 1917 | * idpf_tx_clean_buf_ring - clean flow scheduling TX queue buffers | 1711 | * idpf_tx_clean_bufs - clean flow scheduling TX queue buffers |
| 1918 | * @txq: queue to clean | 1712 | * @txq: queue to clean |
| 1919 | * @compl_tag: completion tag of packet to clean (from completion descriptor) | 1713 | * @buf_id: packet's starting buffer ID, from completion descriptor |
| 1920 | * @cleaned: pointer to stats struct to track cleaned packets/bytes | 1714 | * @cleaned: pointer to stats struct to track cleaned packets/bytes |
| 1921 | * @budget: Used to determine if we are in netpoll | 1715 | * @budget: Used to determine if we are in netpoll |
| 1922 | * | 1716 | * |
| 1923 | * Cleans all buffers associated with the input completion tag either from the | 1717 | * Clean all buffers associated with the packet starting at buf_id. Returns the |
| 1924 | * TX buffer ring or from the hash table if the buffers were previously | 1718 | * byte/segment count for the cleaned packet. |
| 1925 | * stashed. Returns the byte/segment count for the cleaned packet associated | ||
| 1926 | * this completion tag. | ||
| 1927 | */ | 1719 | */ |
| 1928 | static bool idpf_tx_clean_buf_ring(struct idpf_tx_queue *txq, u16 compl_tag, | 1720 | static void idpf_tx_clean_bufs(struct idpf_tx_queue *txq, u32 buf_id, |
| 1929 | struct libeth_sq_napi_stats *cleaned, | 1721 | struct libeth_sq_napi_stats *cleaned, |
| 1930 | int budget) | 1722 | int budget) |
| 1931 | { | 1723 | { |
| 1932 | u16 idx = compl_tag & txq->compl_tag_bufid_m; | ||
| 1933 | struct idpf_tx_buf *tx_buf = NULL; | 1724 | struct idpf_tx_buf *tx_buf = NULL; |
| 1934 | struct libeth_cq_pp cp = { | 1725 | struct libeth_cq_pp cp = { |
| 1935 | .dev = txq->dev, | 1726 | .dev = txq->dev, |
| 1936 | .ss = cleaned, | 1727 | .ss = cleaned, |
| 1937 | .napi = budget, | 1728 | .napi = budget, |
| 1938 | }; | 1729 | }; |
| 1939 | u16 ntc, orig_idx = idx; | ||
| 1940 | |||
| 1941 | tx_buf = &txq->tx_buf[idx]; | ||
| 1942 | |||
| 1943 | if (unlikely(tx_buf->type <= LIBETH_SQE_CTX || | ||
| 1944 | idpf_tx_buf_compl_tag(tx_buf) != compl_tag)) | ||
| 1945 | return false; | ||
| 1946 | 1730 | ||
| 1731 | tx_buf = &txq->tx_buf[buf_id]; | ||
| 1947 | if (tx_buf->type == LIBETH_SQE_SKB) { | 1732 | if (tx_buf->type == LIBETH_SQE_SKB) { |
| 1948 | if (skb_shinfo(tx_buf->skb)->tx_flags & SKBTX_IN_PROGRESS) | 1733 | if (skb_shinfo(tx_buf->skb)->tx_flags & SKBTX_IN_PROGRESS) |
| 1949 | idpf_tx_read_tstamp(txq, tx_buf->skb); | 1734 | idpf_tx_read_tstamp(txq, tx_buf->skb); |
| 1950 | 1735 | ||
| 1951 | libeth_tx_complete(tx_buf, &cp); | 1736 | libeth_tx_complete(tx_buf, &cp); |
| 1737 | idpf_post_buf_refill(txq->refillq, buf_id); | ||
| 1952 | } | 1738 | } |
| 1953 | 1739 | ||
| 1954 | idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf); | 1740 | while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) { |
| 1741 | buf_id = idpf_tx_buf_next(tx_buf); | ||
| 1955 | 1742 | ||
| 1956 | while (idpf_tx_buf_compl_tag(tx_buf) == compl_tag) { | 1743 | tx_buf = &txq->tx_buf[buf_id]; |
| 1957 | libeth_tx_complete(tx_buf, &cp); | 1744 | libeth_tx_complete(tx_buf, &cp); |
| 1958 | idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf); | 1745 | idpf_post_buf_refill(txq->refillq, buf_id); |
| 1959 | } | 1746 | } |
| 1960 | |||
| 1961 | /* | ||
| 1962 | * It's possible the packet we just cleaned was an out of order | ||
| 1963 | * completion, which means we can stash the buffers starting from | ||
| 1964 | * the original next_to_clean and reuse the descriptors. We need | ||
| 1965 | * to compare the descriptor ring next_to_clean packet's "first" buffer | ||
| 1966 | * to the "first" buffer of the packet we just cleaned to determine if | ||
| 1967 | * this is the case. Howevever, next_to_clean can point to either a | ||
| 1968 | * reserved buffer that corresponds to a context descriptor used for the | ||
| 1969 | * next_to_clean packet (TSO packet) or the "first" buffer (single | ||
| 1970 | * packet). The orig_idx from the packet we just cleaned will always | ||
| 1971 | * point to the "first" buffer. If next_to_clean points to a reserved | ||
| 1972 | * buffer, let's bump ntc once and start the comparison from there. | ||
| 1973 | */ | ||
| 1974 | ntc = txq->next_to_clean; | ||
| 1975 | tx_buf = &txq->tx_buf[ntc]; | ||
| 1976 | |||
| 1977 | if (tx_buf->type == LIBETH_SQE_CTX) | ||
| 1978 | idpf_tx_clean_buf_ring_bump_ntc(txq, ntc, tx_buf); | ||
| 1979 | |||
| 1980 | /* | ||
| 1981 | * If ntc still points to a different "first" buffer, clean the | ||
| 1982 | * descriptor ring and stash all of the buffers for later cleaning. If | ||
| 1983 | * we cannot stash all of the buffers, next_to_clean will point to the | ||
| 1984 | * "first" buffer of the packet that could not be stashed and cleaning | ||
| 1985 | * will start there next time. | ||
| 1986 | */ | ||
| 1987 | if (unlikely(tx_buf != &txq->tx_buf[orig_idx] && | ||
| 1988 | !idpf_tx_splitq_clean(txq, orig_idx, budget, cleaned, | ||
| 1989 | true))) | ||
| 1990 | return true; | ||
| 1991 | |||
| 1992 | /* | ||
| 1993 | * Otherwise, update next_to_clean to reflect the cleaning that was | ||
| 1994 | * done above. | ||
| 1995 | */ | ||
| 1996 | txq->next_to_clean = idx; | ||
| 1997 | |||
| 1998 | return true; | ||
| 1999 | } | 1747 | } |
| 2000 | 1748 | ||
| 2001 | /** | 1749 | /** |
| @@ -2014,22 +1762,17 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq, · 12 unmodified lines | |||
| 2014 | struct libeth_sq_napi_stats *cleaned, | 1762 | struct libeth_sq_napi_stats *cleaned, |
| 2015 | int budget) | 1763 | int budget) |
| 2016 | { | 1764 | { |
| 2017 | u16 compl_tag; | 1765 | /* RS completion contains queue head for queue based scheduling or |
| 1766 | * completion tag for flow based scheduling. | ||
| 1767 | */ | ||
| 1768 | u16 rs_compl_val = le16_to_cpu(desc->q_head_compl_tag.q_head); | ||
| 2018 | 1769 | ||
| 2019 | if (!idpf_queue_has(FLOW_SCH_EN, txq)) { | 1770 | if (!idpf_queue_has(FLOW_SCH_EN, txq)) { |
| 2020 | u16 head = le16_to_cpu(desc->q_head_compl_tag.q_head); | 1771 | idpf_tx_splitq_clean(txq, rs_compl_val, budget, cleaned, false); |
| 2021 | |||
| 2022 | idpf_tx_splitq_clean(txq, head, budget, cleaned, false); | ||
| 2023 | return; | 1772 | return; |
| 2024 | } | 1773 | } |
| 2025 | 1774 | ||
| 2026 | compl_tag = le16_to_cpu(desc->q_head_compl_tag.compl_tag); | 1775 | idpf_tx_clean_bufs(txq, rs_compl_val, cleaned, budget); |
| 2027 | |||
| 2028 | /* If we didn't clean anything on the ring, this packet must be | ||
| 2029 | * in the hash table. Go clean it there. | ||
| 2030 | */ | ||
| 2031 | if (!idpf_tx_clean_buf_ring(txq, compl_tag, cleaned, budget)) | ||
| 2032 | idpf_tx_clean_stashed_bufs(txq, compl_tag, cleaned, budget); | ||
| 2033 | } | 1776 | } |
| 2034 | 1777 | ||
| 2035 | /** | 1778 | /** |
| @@ -2146,8 +1889,7 @@ fetch_next_desc: · 110 unmodified lines | |||
| 2146 | /* Update BQL */ | 1889 | /* Update BQL */ |
| 2147 | nq = netdev_get_tx_queue(tx_q->netdev, tx_q->idx); | 1890 | nq = netdev_get_tx_queue(tx_q->netdev, tx_q->idx); |
| 2148 | 1891 | ||
| 2149 | dont_wake = !complq_ok || IDPF_TX_BUF_RSV_LOW(tx_q) || | 1892 | dont_wake = !complq_ok || np->state != __IDPF_VPORT_UP || |
| 2150 | np->state != __IDPF_VPORT_UP || | ||
| 2151 | !netif_carrier_ok(tx_q->netdev); | 1893 | !netif_carrier_ok(tx_q->netdev); |
| 2152 | /* Check if the TXQ needs to and can be restarted */ | 1894 | /* Check if the TXQ needs to and can be restarted */ |
| 2153 | __netif_txq_completed_wake(nq, tx_q->cleaned_pkts, tx_q->cleaned_bytes, | 1895 | __netif_txq_completed_wake(nq, tx_q->cleaned_pkts, tx_q->cleaned_bytes, |
| @@ -2204,15 +1946,21 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc, · 50 unmodified lines | |||
| 2204 | desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag); | 1946 | desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag); |
| 2205 | } | 1947 | } |
| 2206 | 1948 | ||
| 2207 | /* Global conditions to tell whether the txq (and related resources) | 1949 | /** |
| 2208 | * has room to allow the use of "size" descriptors. | 1950 | * idpf_tx_splitq_has_room - check if enough Tx splitq resources are available |
| 1951 | * @tx_q: the queue to be checked | ||
| 1952 | * @descs_needed: number of descriptors required for this packet | ||
| 1953 | * @bufs_needed: number of Tx buffers required for this packet | ||
| 1954 | * | ||
| 1955 | * Return: 0 if no room available, 1 otherwise | ||
| 2209 | */ | 1956 | */ |
| 2210 | static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size) | 1957 | static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 descs_needed, |
| 1958 | u32 bufs_needed) | ||
| 2211 | { | 1959 | { |
| 2212 | if (IDPF_DESC_UNUSED(tx_q) < size || | 1960 | if (IDPF_DESC_UNUSED(tx_q) < descs_needed || |
| 2213 | IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) > | 1961 | IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) > |
| 2214 | IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) || | 1962 | IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) || |
| 2215 | IDPF_TX_BUF_RSV_LOW(tx_q)) | 1963 | idpf_tx_splitq_get_free_bufs(tx_q->refillq) < bufs_needed) |
| 2216 | return 0; | 1964 | return 0; |
| 2217 | return 1; | 1965 | return 1; |
| 2218 | } | 1966 | } |
| @@ -2221,14 +1969,21 @@ static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size) · 2 unmodified lines | |||
| 2221 | * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions | 1969 | * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions |
| 2222 | * @tx_q: the queue to be checked | 1970 | * @tx_q: the queue to be checked |
| 2223 | * @descs_needed: number of descriptors required for this packet | 1971 | * @descs_needed: number of descriptors required for this packet |
| 1972 | * @bufs_needed: number of buffers needed for this packet | ||
| 2224 | * | 1973 | * |
| 2225 | * Returns 0 if stop is not needed | 1974 | * Return: 0 if stop is not needed |
| 2226 | */ | 1975 | */ |
| 2227 | static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q, | 1976 | static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q, |
| 2228 | unsigned int descs_needed) | 1977 | u32 descs_needed, |
| 1978 | u32 bufs_needed) | ||
| 2229 | { | 1979 | { |
| 1980 | /* Since we have multiple resources to check for splitq, our | ||
| 1981 | * start,stop_thrs becomes a boolean check instead of a count | ||
| 1982 | * threshold. | ||
| 1983 | */ | ||
| 2230 | if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx, | 1984 | if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx, |
| 2231 | idpf_txq_has_room(tx_q, descs_needed), | 1985 | idpf_txq_has_room(tx_q, descs_needed, |
| 1986 | bufs_needed), | ||
| 2232 | 1, 1)) | 1987 | 1, 1)) |
| 2233 | return 0; | 1988 | return 0; |
| 2234 | 1989 | ||
| @@ -2270,14 +2025,16 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val, · 35 unmodified lines | |||
| 2270 | } | 2025 | } |
| 2271 | 2026 | ||
| 2272 | /** | 2027 | /** |
| 2273 | * idpf_tx_desc_count_required - calculate number of Tx descriptors needed | 2028 | * idpf_tx_res_count_required - get number of Tx resources needed for this pkt |
| 2274 | * @txq: queue to send buffer on | 2029 | * @txq: queue to send buffer on |
| 2275 | * @skb: send buffer | 2030 | * @skb: send buffer |
| 2031 | * @bufs_needed: (output) number of buffers needed for this skb. | ||
| 2276 | * | 2032 | * |
| 2277 | * Returns number of data descriptors needed for this skb. | 2033 | * Return: number of data descriptors and buffers needed for this skb. |
| 2278 | */ | 2034 | */ |
| 2279 | unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq, | 2035 | unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq, |
| 2280 | struct sk_buff *skb) | 2036 | struct sk_buff *skb, |
| 2037 | u32 *bufs_needed) | ||
| 2281 | { | 2038 | { |
| 2282 | const struct skb_shared_info *shinfo; | 2039 | const struct skb_shared_info *shinfo; |
| 2283 | unsigned int count = 0, i; | 2040 | unsigned int count = 0, i; |
| @@ -2288,6 +2045,7 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq, · 4 unmodified lines | |||
| 2288 | return count; | 2045 | return count; |
| 2289 | 2046 | ||
| 2290 | shinfo = skb_shinfo(skb); | 2047 | shinfo = skb_shinfo(skb); |
| 2048 | *bufs_needed += shinfo->nr_frags; | ||
| 2291 | for (i = 0; i < shinfo->nr_frags; i++) { | 2049 | for (i = 0; i < shinfo->nr_frags; i++) { |
| 2292 | unsigned int size; | 2050 | unsigned int size; |
| 2293 | 2051 | ||
| @@ -2317,71 +2075,89 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq, · 23 unmodified lines | |||
| 2317 | } | 2075 | } |
| 2318 | 2076 | ||
| 2319 | /** | 2077 | /** |
| 2320 | * idpf_tx_dma_map_error - handle TX DMA map errors | 2078 | * idpf_tx_splitq_bump_ntu - adjust NTU and generation |
| 2321 | * @txq: queue to send buffer on | 2079 | * @txq: the tx ring to wrap |
| 2322 | * @skb: send buffer | 2080 | * @ntu: ring index to bump |
| 2323 | * @first: original first buffer info buffer for packet | ||
| 2324 | * @idx: starting point on ring to unwind | ||
| 2325 | */ | 2081 | */ |
| 2326 | void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb, | 2082 | static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu) |
| 2327 | struct idpf_tx_buf *first, u16 idx) | ||
| 2328 | { | 2083 | { |
| 2329 | struct libeth_sq_napi_stats ss = { }; | 2084 | ntu++; |
| 2330 | struct libeth_cq_pp cp = { | ||
| 2331 | .dev = txq->dev, | ||
| 2332 | .ss = &ss, | ||
| 2333 | }; | ||
| 2334 | 2085 | ||
| 2335 | u64_stats_update_begin(&txq->stats_sync); | 2086 | if (ntu == txq->desc_count) |
| 2336 | u64_stats_inc(&txq->q_stats.dma_map_errs); | 2087 | ntu = 0; |
| 2337 | u64_stats_update_end(&txq->stats_sync); | ||
| 2338 | 2088 | ||
| 2339 | /* clear dma mappings for failed tx_buf map */ | 2089 | return ntu; |
| 2340 | for (;;) { | 2090 | } |
| 2341 | struct idpf_tx_buf *tx_buf; | ||
| 2342 | 2091 | ||
| 2343 | tx_buf = &txq->tx_buf[idx]; | 2092 | /** |
| 2344 | libeth_tx_complete(tx_buf, &cp); | 2093 | * idpf_tx_get_free_buf_id - get a free buffer ID from the refill queue |
| 2345 | if (tx_buf == first) | 2094 | * @refillq: refill queue to get buffer ID from |
| 2346 | break; | 2095 | * @buf_id: return buffer ID |
| 2347 | if (idx == 0) | 2096 | * |
| 2348 | idx = txq->desc_count; | 2097 | * Return: true if a buffer ID was found, false if not |
| 2349 | idx--; | 2098 | */ |
| 2350 | } | 2099 | static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq, |
| 2100 | u32 *buf_id) | ||
| 2101 | { | ||
| 2102 | u32 ntc = refillq->next_to_clean; | ||
| 2103 | u32 refill_desc; | ||
| 2351 | 2104 | ||
| 2352 | if (skb_is_gso(skb)) { | 2105 | refill_desc = refillq->ring[ntc]; |
| 2353 | union idpf_tx_flex_desc *tx_desc; | ||
| 2354 | 2106 | ||
| 2355 | /* If we failed a DMA mapping for a TSO packet, we will have | 2107 | if (unlikely(idpf_queue_has(RFL_GEN_CHK, refillq) != |
| 2356 | * used one additional descriptor for a context | 2108 | !!(refill_desc & IDPF_RFL_BI_GEN_M))) |
| 2357 | * descriptor. Reset that here. | 2109 | return false; |
| 2358 | */ | 2110 | |
| 2359 | tx_desc = &txq->flex_tx[idx]; | 2111 | *buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc); |
| 2360 | memset(tx_desc, 0, sizeof(*tx_desc)); | 2112 | |
| 2361 | if (idx == 0) | 2113 | if (unlikely(++ntc == refillq->desc_count)) { |
| 2362 | idx = txq->desc_count; | 2114 | idpf_queue_change(RFL_GEN_CHK, refillq); |
| 2363 | idx--; | 2115 | ntc = 0; |
| 2364 | } | 2116 | } |
| 2365 | 2117 | ||
| 2366 | /* Update tail in case netdev_xmit_more was previously true */ | 2118 | refillq->next_to_clean = ntc; |
| 2367 | idpf_tx_buf_hw_update(txq, idx, false); | 2119 | |
| 2120 | return true; | ||
| 2368 | } | 2121 | } |
| 2369 | 2122 | ||
| 2370 | /** | 2123 | /** |
| 2371 | * idpf_tx_splitq_bump_ntu - adjust NTU and generation | 2124 | * idpf_tx_splitq_pkt_err_unmap - Unmap buffers and bump tail in case of error |
| 2372 | * @txq: the tx ring to wrap | 2125 | * @txq: Tx queue to unwind |
| 2373 | * @ntu: ring index to bump | 2126 | * @params: pointer to splitq params struct |
| 2127 | * @first: starting buffer for packet to unmap | ||
| 2374 | */ | 2128 | */ |
| 2375 | static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu) | 2129 | static void idpf_tx_splitq_pkt_err_unmap(struct idpf_tx_queue *txq, |
| 2130 | struct idpf_tx_splitq_params *params, | ||
| 2131 | struct idpf_tx_buf *first) | ||
| 2376 | { | 2132 | { |
| 2377 | ntu++; | 2133 | struct idpf_sw_queue *refillq = txq->refillq; |
| 2134 | struct libeth_sq_napi_stats ss = { }; | ||
| 2135 | struct idpf_tx_buf *tx_buf = first; | ||
| 2136 | struct libeth_cq_pp cp = { | ||
| 2137 | .dev = txq->dev, | ||
| 2138 | .ss = &ss, | ||
| 2139 | }; | ||
| 2378 | 2140 | ||
| 2379 | if (ntu == txq->desc_count) { | 2141 | u64_stats_update_begin(&txq->stats_sync); |
| 2380 | ntu = 0; | 2142 | u64_stats_inc(&txq->q_stats.dma_map_errs); |
| 2381 | txq->compl_tag_cur_gen = IDPF_TX_ADJ_COMPL_TAG_GEN(txq); | 2143 | u64_stats_update_end(&txq->stats_sync); |
| 2144 | |||
| 2145 | libeth_tx_complete(tx_buf, &cp); | ||
| 2146 | while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) { | ||
| 2147 | tx_buf = &txq->tx_buf[idpf_tx_buf_next(tx_buf)]; | ||
| 2148 | libeth_tx_complete(tx_buf, &cp); | ||
| 2382 | } | 2149 | } |
| 2383 | 2150 | ||
| 2384 | return ntu; | 2151 | /* Update tail in case netdev_xmit_more was previously true. */ |
| 2152 | idpf_tx_buf_hw_update(txq, params->prev_ntu, false); | ||
| 2153 | |||
| 2154 | if (!refillq) | ||
| 2155 | return; | ||
| 2156 | |||
| 2157 | /* Restore refillq state to avoid leaking tags. */ | ||
| 2158 | if (params->prev_refill_gen != idpf_queue_has(RFL_GEN_CHK, refillq)) | ||
| 2159 | idpf_queue_change(RFL_GEN_CHK, refillq); | ||
| 2160 | refillq->next_to_clean = params->prev_refill_ntc; | ||
| 2385 | } | 2161 | } |
| 2386 | 2162 | ||
| 2387 | /** | 2163 | /** |
| @@ -2405,6 +2181,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, · 17 unmodified lines | |||
| 2405 | struct netdev_queue *nq; | 2181 | struct netdev_queue *nq; |
| 2406 | struct sk_buff *skb; | 2182 | struct sk_buff *skb; |
| 2407 | skb_frag_t *frag; | 2183 | skb_frag_t *frag; |
| 2184 | u32 next_buf_id; | ||
| 2408 | u16 td_cmd = 0; | 2185 | u16 td_cmd = 0; |
| 2409 | dma_addr_t dma; | 2186 | dma_addr_t dma; |
| 2410 | 2187 | ||
| @@ -2422,17 +2199,16 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, · 11 unmodified lines | |||
| 2422 | tx_buf = first; | 2199 | tx_buf = first; |
| 2423 | first->nr_frags = 0; | 2200 | first->nr_frags = 0; |
| 2424 | 2201 | ||
| 2425 | params->compl_tag = | ||
| 2426 | (tx_q->compl_tag_cur_gen << tx_q->compl_tag_gen_s) | i; | ||
| 2427 | |||
| 2428 | for (frag = &skb_shinfo(skb)->frags[0];; frag++) { | 2202 | for (frag = &skb_shinfo(skb)->frags[0];; frag++) { |
| 2429 | unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED; | 2203 | unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED; |
| 2430 | 2204 | ||
| 2431 | if (dma_mapping_error(tx_q->dev, dma)) | 2205 | if (unlikely(dma_mapping_error(tx_q->dev, dma))) { |
| 2432 | return idpf_tx_dma_map_error(tx_q, skb, first, i); | 2206 | idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL; |
| 2207 | return idpf_tx_splitq_pkt_err_unmap(tx_q, params, | ||
| 2208 | first); | ||
| 2209 | } | ||
| 2433 | 2210 | ||
| 2434 | first->nr_frags++; | 2211 | first->nr_frags++; |
| 2435 | idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag; | ||
| 2436 | tx_buf->type = LIBETH_SQE_FRAG; | 2212 | tx_buf->type = LIBETH_SQE_FRAG; |
| 2437 | 2213 | ||
| 2438 | /* record length, and DMA address */ | 2214 | /* record length, and DMA address */ |
| @@ -2488,29 +2264,12 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, · 49 unmodified lines | |||
| 2488 | max_data); | 2264 | max_data); |
| 2489 | 2265 | ||
| 2490 | if (unlikely(++i == tx_q->desc_count)) { | 2266 | if (unlikely(++i == tx_q->desc_count)) { |
| 2491 | tx_buf = tx_q->tx_buf; | ||
| 2492 | tx_desc = &tx_q->flex_tx[0]; | 2267 | tx_desc = &tx_q->flex_tx[0]; |
| 2493 | i = 0; | 2268 | i = 0; |
| 2494 | tx_q->compl_tag_cur_gen = | ||
| 2495 | IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q); | ||
| 2496 | } else { | 2269 | } else { |
| 2497 | tx_buf++; | ||
| 2498 | tx_desc++; | 2270 | tx_desc++; |
| 2499 | } | 2271 | } |
| 2500 | 2272 | ||
| 2501 | /* Since this packet has a buffer that is going to span | ||
| 2502 | * multiple descriptors, it's going to leave holes in | ||
| 2503 | * to the TX buffer ring. To ensure these holes do not | ||
| 2504 | * cause issues in the cleaning routines, we will clear | ||
| 2505 | * them of any stale data and assign them the same | ||
| 2506 | * completion tag as the current packet. Then when the | ||
| 2507 | * packet is being cleaned, the cleaning routines will | ||
| 2508 | * simply pass over these holes and finish cleaning the | ||
| 2509 | * rest of the packet. | ||
| 2510 | */ | ||
| 2511 | tx_buf->type = LIBETH_SQE_EMPTY; | ||
| 2512 | idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag; | ||
| 2513 | |||
| 2514 | /* Adjust the DMA offset and the remaining size of the | 2273 | /* Adjust the DMA offset and the remaining size of the |
| 2515 | * fragment. On the first iteration of this loop, | 2274 | * fragment. On the first iteration of this loop, |
| 2516 | * max_data will be >= 12K and <= 16K-1. On any | 2275 | * max_data will be >= 12K and <= 16K-1. On any |
| @@ -2535,15 +2294,25 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, · 18 unmodified lines | |||
| 2535 | idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size); | 2294 | idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size); |
| 2536 | 2295 | ||
| 2537 | if (unlikely(++i == tx_q->desc_count)) { | 2296 | if (unlikely(++i == tx_q->desc_count)) { |
| 2538 | tx_buf = tx_q->tx_buf; | ||
| 2539 | tx_desc = &tx_q->flex_tx[0]; | 2297 | tx_desc = &tx_q->flex_tx[0]; |
| 2540 | i = 0; | 2298 | i = 0; |
| 2541 | tx_q->compl_tag_cur_gen = IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q); | ||
| 2542 | } else { | 2299 | } else { |
| 2543 | tx_buf++; | ||
| 2544 | tx_desc++; | 2300 | tx_desc++; |
| 2545 | } | 2301 | } |
| 2546 | 2302 | ||
| 2303 | if (idpf_queue_has(FLOW_SCH_EN, tx_q)) { | ||
| 2304 | if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq, | ||
| 2305 | &next_buf_id))) { | ||
| 2306 | idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL; | ||
| 2307 | return idpf_tx_splitq_pkt_err_unmap(tx_q, params, | ||
| 2308 | first); | ||
| 2309 | } | ||
| 2310 | } else { | ||
| 2311 | next_buf_id = i; | ||
| 2312 | } | ||
| 2313 | idpf_tx_buf_next(tx_buf) = next_buf_id; | ||
| 2314 | tx_buf = &tx_q->tx_buf[next_buf_id]; | ||
| 2315 | |||
| 2547 | size = skb_frag_size(frag); | 2316 | size = skb_frag_size(frag); |
| 2548 | data_len -= size; | 2317 | data_len -= size; |
| 2549 | 2318 | ||
| @@ -2558,6 +2327,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q, · 8 unmodified lines | |||
| 2558 | 2327 | ||
| 2559 | /* write last descriptor with RS and EOP bits */ | 2328 | /* write last descriptor with RS and EOP bits */ |
| 2560 | first->rs_idx = i; | 2329 | first->rs_idx = i; |
| 2330 | idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL; | ||
| 2561 | td_cmd |= params->eop_cmd; | 2331 | td_cmd |= params->eop_cmd; |
| 2562 | idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size); | 2332 | idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size); |
| 2563 | i = idpf_tx_splitq_bump_ntu(tx_q, i); | 2333 | i = idpf_tx_splitq_bump_ntu(tx_q, i); |
| @@ -2661,8 +2431,6 @@ idpf_tx_splitq_get_ctx_desc(struct idpf_tx_queue *txq) · 97 unmodified lines | |||
| 2661 | union idpf_flex_tx_ctx_desc *desc; | 2431 | union idpf_flex_tx_ctx_desc *desc; |
| 2662 | int i = txq->next_to_use; | 2432 | int i = txq->next_to_use; |
| 2663 | 2433 | ||
| 2664 | txq->tx_buf[i].type = LIBETH_SQE_CTX; | ||
| 2665 | |||
| 2666 | /* grab the next descriptor */ | 2434 | /* grab the next descriptor */ |
| 2667 | desc = &txq->flex_ctx[i]; | 2435 | desc = &txq->flex_ctx[i]; |
| 2668 | txq->next_to_use = idpf_tx_splitq_bump_ntu(txq, i); | 2436 | txq->next_to_use = idpf_tx_splitq_bump_ntu(txq, i); |
| @@ -2755,6 +2523,21 @@ static void idpf_tx_set_tstamp_desc(union idpf_flex_tx_ctx_desc *ctx_desc, · 86 unmodified lines | |||
| 2755 | { } | 2523 | { } |
| 2756 | #endif /* CONFIG_PTP_1588_CLOCK */ | 2524 | #endif /* CONFIG_PTP_1588_CLOCK */ |
| 2757 | 2525 | ||
| 2526 | /** | ||
| 2527 | * idpf_tx_splitq_need_re - check whether RE bit needs to be set | ||
| 2528 | * @tx_q: pointer to Tx queue | ||
| 2529 | * | ||
| 2530 | * Return: true if RE bit needs to be set, false otherwise | ||
| 2531 | */ | ||
| 2532 | static bool idpf_tx_splitq_need_re(struct idpf_tx_queue *tx_q) | ||
| 2533 | { | ||
| 2534 | int gap = tx_q->next_to_use - tx_q->last_re; | ||
| 2535 | |||
| 2536 | gap += (gap < 0) ? tx_q->desc_count : 0; | ||
| 2537 | |||
| 2538 | return gap >= IDPF_TX_SPLITQ_RE_MIN_GAP; | ||
| 2539 | } | ||
| 2540 | |||
| 2758 | /** | 2541 | /** |
| 2759 | * idpf_tx_splitq_frame - Sends buffer on Tx ring using flex descriptors | 2542 | * idpf_tx_splitq_frame - Sends buffer on Tx ring using flex descriptors |
| 2760 | * @skb: send buffer | 2543 | * @skb: send buffer |
| @@ -2765,13 +2548,16 @@ static void idpf_tx_set_tstamp_desc(union idpf_flex_tx_ctx_desc *ctx_desc, · 4 unmodified lines | |||
| 2765 | static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, | 2548 | static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, |
| 2766 | struct idpf_tx_queue *tx_q) | 2549 | struct idpf_tx_queue *tx_q) |
| 2767 | { | 2550 | { |
| 2768 | struct idpf_tx_splitq_params tx_params = { }; | 2551 | struct idpf_tx_splitq_params tx_params = { |
| 2552 | .prev_ntu = tx_q->next_to_use, | ||
| 2553 | }; | ||
| 2769 | union idpf_flex_tx_ctx_desc *ctx_desc; | 2554 | union idpf_flex_tx_ctx_desc *ctx_desc; |
| 2770 | struct idpf_tx_buf *first; | 2555 | struct idpf_tx_buf *first; |
| 2771 | unsigned int count; | 2556 | u32 count, buf_count = 1; |
| 2772 | int tso, idx; | 2557 | int tso, idx; |
| 2558 | u32 buf_id; | ||
| 2773 | 2559 | ||
| 2774 | count = idpf_tx_desc_count_required(tx_q, skb); | 2560 | count = idpf_tx_res_count_required(tx_q, skb, &buf_count); |
| 2775 | if (unlikely(!count)) | 2561 | if (unlikely(!count)) |
| 2776 | return idpf_tx_drop_skb(tx_q, skb); | 2562 | return idpf_tx_drop_skb(tx_q, skb); |
| 2777 | 2563 | ||
| @@ -2781,7 +2567,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, · 3 unmodified lines | |||
| 2781 | 2567 | ||
| 2782 | /* Check for splitq specific TX resources */ | 2568 | /* Check for splitq specific TX resources */ |
| 2783 | count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso); | 2569 | count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso); |
| 2784 | if (idpf_tx_maybe_stop_splitq(tx_q, count)) { | 2570 | if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count)) { |
| 2785 | idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false); | 2571 | idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false); |
| 2786 | 2572 | ||
| 2787 | return NETDEV_TX_BUSY; | 2573 | return NETDEV_TX_BUSY; |
| @@ -2813,36 +2599,47 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, · 25 unmodified lines | |||
| 2813 | idpf_tx_set_tstamp_desc(ctx_desc, idx); | 2599 | idpf_tx_set_tstamp_desc(ctx_desc, idx); |
| 2814 | } | 2600 | } |
| 2815 | 2601 | ||
| 2816 | /* record the location of the first descriptor for this packet */ | 2602 | if (idpf_queue_has(FLOW_SCH_EN, tx_q)) { |
| 2817 | first = &tx_q->tx_buf[tx_q->next_to_use]; | 2603 | struct idpf_sw_queue *refillq = tx_q->refillq; |
| 2818 | first->skb = skb; | ||
| 2819 | 2604 | ||
| 2820 | if (tso) { | 2605 | /* Save refillq state in case of a packet rollback. Otherwise, |
| 2821 | first->packets = tx_params.offload.tso_segs; | 2606 | * the tags will be leaked since they will be popped from the |
| 2822 | first->bytes = skb->len + | 2607 | * refillq but never reposted during cleaning. |
| 2823 | ((first->packets - 1) * tx_params.offload.tso_hdr_len); | 2608 | */ |
| 2824 | } else { | 2609 | tx_params.prev_refill_gen = |
| 2825 | first->packets = 1; | 2610 | idpf_queue_has(RFL_GEN_CHK, refillq); |
| 2826 | first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN); | 2611 | tx_params.prev_refill_ntc = refillq->next_to_clean; |
| 2827 | } | 2612 | |
| 2613 | if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq, | ||
| 2614 | &buf_id))) { | ||
| 2615 | if (tx_params.prev_refill_gen != | ||
| 2616 | idpf_queue_has(RFL_GEN_CHK, refillq)) | ||
| 2617 | idpf_queue_change(RFL_GEN_CHK, refillq); | ||
| 2618 | refillq->next_to_clean = tx_params.prev_refill_ntc; | ||
| 2619 | |||
| 2620 | tx_q->next_to_use = tx_params.prev_ntu; | ||
| 2621 | return idpf_tx_drop_skb(tx_q, skb); | ||
| 2622 | } | ||
| 2623 | tx_params.compl_tag = buf_id; | ||
| 2828 | 2624 | ||
| 2829 | if (idpf_queue_has(FLOW_SCH_EN, tx_q)) { | ||
| 2830 | tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE; | 2625 | tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE; |
| 2831 | tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP; | 2626 | tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP; |
| 2832 | /* Set the RE bit to catch any packets that may have not been | 2627 | /* Set the RE bit to periodically "clean" the descriptor ring. |
| 2833 | * stashed during RS completion cleaning. MIN_GAP is set to | 2628 | * MIN_GAP is set to MIN_RING size to ensure it will be set at |
| 2834 | * MIN_RING size to ensure it will be set at least once each | 2629 | * least once each time around the ring. |
| 2835 | * time around the ring. | ||
| 2836 | */ | 2630 | */ |
| 2837 | if (!(tx_q->next_to_use % IDPF_TX_SPLITQ_RE_MIN_GAP)) { | 2631 | if (idpf_tx_splitq_need_re(tx_q)) { |
| 2838 | tx_params.eop_cmd |= IDPF_TXD_FLEX_FLOW_CMD_RE; | 2632 | tx_params.eop_cmd |= IDPF_TXD_FLEX_FLOW_CMD_RE; |
| 2839 | tx_q->txq_grp->num_completions_pending++; | 2633 | tx_q->txq_grp->num_completions_pending++; |
| 2634 | tx_q->last_re = tx_q->next_to_use; | ||
| 2840 | } | 2635 | } |
| 2841 | 2636 | ||
| 2842 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 2637 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
| 2843 | tx_params.offload.td_cmd |= IDPF_TXD_FLEX_FLOW_CMD_CS_EN; | 2638 | tx_params.offload.td_cmd |= IDPF_TXD_FLEX_FLOW_CMD_CS_EN; |
| 2844 | 2639 | ||
| 2845 | } else { | 2640 | } else { |
| 2641 | buf_id = tx_q->next_to_use; | ||
| 2642 | |||
| 2846 | tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_L2TAG1_L2TAG2; | 2643 | tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_L2TAG1_L2TAG2; |
| 2847 | tx_params.eop_cmd = IDPF_TXD_LAST_DESC_CMD; | 2644 | tx_params.eop_cmd = IDPF_TXD_LAST_DESC_CMD; |
| 2848 | 2645 | ||
| @@ -2850,6 +2647,18 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb, · 1 unmodified line | |||
| 2850 | tx_params.offload.td_cmd |= IDPF_TX_FLEX_DESC_CMD_CS_EN; | 2647 | tx_params.offload.td_cmd |= IDPF_TX_FLEX_DESC_CMD_CS_EN; |
| 2851 | } | 2648 | } |
| 2852 | 2649 | ||
| 2650 | first = &tx_q->tx_buf[buf_id]; | ||
| 2651 | first->skb = skb; | ||
| 2652 | |||
| 2653 | if (tso) { | ||
| 2654 | first->packets = tx_params.offload.tso_segs; | ||
| 2655 | first->bytes = skb->len + | ||
| 2656 | ((first->packets - 1) * tx_params.offload.tso_hdr_len); | ||
| 2657 | } else { | ||
| 2658 | first->packets = 1; | ||
| 2659 | first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN); | ||
| 2660 | } | ||
| 2661 | |||
| 2853 | idpf_tx_splitq_map(tx_q, &tx_params, first); | 2662 | idpf_tx_splitq_map(tx_q, &tx_params, first); |
| 2854 | 2663 | ||
| 2855 | return NETDEV_TX_OK; | 2664 | return NETDEV_TX_OK; |
| @@ -3387,7 +3196,7 @@ payload: · 531 unmodified lines | |||
| 3387 | skip_data: | 3196 | skip_data: |
| 3388 | rx_buf->netmem = 0; | 3197 | rx_buf->netmem = 0; |
| 3389 | 3198 | ||
| 3390 | idpf_rx_post_buf_refill(refillq, buf_id); | 3199 | idpf_post_buf_refill(refillq, buf_id); |
| 3391 | IDPF_RX_BUMP_NTC(rxq, ntc); | 3200 | IDPF_RX_BUMP_NTC(rxq, ntc); |
| 3392 | 3201 | ||
| 3393 | /* skip if it is non EOP desc */ | 3202 | /* skip if it is non EOP desc */ |
| @@ -3495,10 +3304,10 @@ static void idpf_rx_clean_refillq(struct idpf_buf_queue *bufq, · 101 unmodified lines | |||
| 3495 | bool failure; | 3304 | bool failure; |
| 3496 | 3305 | ||
| 3497 | if (idpf_queue_has(RFL_GEN_CHK, refillq) != | 3306 | if (idpf_queue_has(RFL_GEN_CHK, refillq) != |
| 3498 | !!(refill_desc & IDPF_RX_BI_GEN_M)) | 3307 | !!(refill_desc & IDPF_RFL_BI_GEN_M)) |
| 3499 | break; | 3308 | break; |
| 3500 | 3309 | ||
| 3501 | buf_id = FIELD_GET(IDPF_RX_BI_BUFID_M, refill_desc); | 3310 | buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc); |
| 3502 | failure = idpf_rx_update_bufq_desc(bufq, buf_id, buf_desc); | 3311 | failure = idpf_rx_update_bufq_desc(bufq, buf_id, buf_desc); |
| 3503 | if (failure) | 3312 | if (failure) |
| 3504 | break; | 3313 | break; |
| @@ -108,8 +108,8 @@ do { \ · 107 unmodified lines | |||
| 108 | */ | 108 | */ |
| 109 | #define IDPF_TX_SPLITQ_RE_MIN_GAP 64 | 109 | #define IDPF_TX_SPLITQ_RE_MIN_GAP 64 |
| 110 | 110 | ||
| 111 | #define IDPF_RX_BI_GEN_M BIT(16) | 111 | #define IDPF_RFL_BI_GEN_M BIT(16) |
| 112 | #define IDPF_RX_BI_BUFID_M GENMASK(15, 0) | 112 | #define IDPF_RFL_BI_BUFID_M GENMASK(15, 0) |
| 113 | 113 | ||
| 114 | #define IDPF_RXD_EOF_SPLITQ VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M | 114 | #define IDPF_RXD_EOF_SPLITQ VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M |
| 115 | #define IDPF_RXD_EOF_SINGLEQ VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M | 115 | #define IDPF_RXD_EOF_SINGLEQ VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M |
| @@ -118,10 +118,6 @@ do { \ · 2 unmodified lines | |||
| 118 | ((((txq)->next_to_clean > (txq)->next_to_use) ? 0 : (txq)->desc_count) + \ | 118 | ((((txq)->next_to_clean > (txq)->next_to_use) ? 0 : (txq)->desc_count) + \ |
| 119 | (txq)->next_to_clean - (txq)->next_to_use - 1) | 119 | (txq)->next_to_clean - (txq)->next_to_use - 1) |
| 120 | 120 | ||
| 121 | #define IDPF_TX_BUF_RSV_UNUSED(txq) ((txq)->stash->buf_stack.top) | ||
| 122 | #define IDPF_TX_BUF_RSV_LOW(txq) (IDPF_TX_BUF_RSV_UNUSED(txq) < \ | ||
| 123 | (txq)->desc_count >> 2) | ||
| 124 | |||
| 125 | #define IDPF_TX_COMPLQ_OVERFLOW_THRESH(txcq) ((txcq)->desc_count >> 1) | 121 | #define IDPF_TX_COMPLQ_OVERFLOW_THRESH(txcq) ((txcq)->desc_count >> 1) |
| 126 | /* Determine the absolute number of completions pending, i.e. the number of | 122 | /* Determine the absolute number of completions pending, i.e. the number of |
| 127 | * completions that are expected to arrive on the TX completion queue. | 123 | * completions that are expected to arrive on the TX completion queue. |
| @@ -131,11 +127,7 @@ do { \ · 3 unmodified lines | |||
| 131 | 0 : U32_MAX) + \ | 127 | 0 : U32_MAX) + \ |
| 132 | (txq)->num_completions_pending - (txq)->complq->num_completions) | 128 | (txq)->num_completions_pending - (txq)->complq->num_completions) |
| 133 | 129 | ||
| 134 | #define IDPF_TX_SPLITQ_COMPL_TAG_WIDTH 16 | 130 | #define IDPF_TXBUF_NULL U32_MAX |
| 135 | /* Adjust the generation for the completion tag and wrap if necessary */ | ||
| 136 | #define IDPF_TX_ADJ_COMPL_TAG_GEN(txq) \ | ||
| 137 | ((++(txq)->compl_tag_cur_gen) >= (txq)->compl_tag_gen_max ? \ | ||
| 138 | 0 : (txq)->compl_tag_cur_gen) | ||
| 139 | 131 | ||
| 140 | #define IDPF_TXD_LAST_DESC_CMD (IDPF_TX_DESC_CMD_EOP | IDPF_TX_DESC_CMD_RS) | 132 | #define IDPF_TXD_LAST_DESC_CMD (IDPF_TX_DESC_CMD_EOP | IDPF_TX_DESC_CMD_RS) |
| 141 | 133 | ||
| @@ -152,18 +144,6 @@ union idpf_tx_flex_desc { · 10 unmodified lines | |||
| 152 | 144 | ||
| 153 | #define idpf_tx_buf libeth_sqe | 145 | #define idpf_tx_buf libeth_sqe |
| 154 | 146 | ||
| 155 | /** | ||
| 156 | * struct idpf_buf_lifo - LIFO for managing OOO completions | ||
| 157 | * @top: Used to know how many buffers are left | ||
| 158 | * @size: Total size of LIFO | ||
| 159 | * @bufs: Backing array | ||
| 160 | */ | ||
| 161 | struct idpf_buf_lifo { | ||
| 162 | u16 top; | ||
| 163 | u16 size; | ||
| 164 | struct idpf_tx_stash **bufs; | ||
| 165 | }; | ||
| 166 | |||
| 167 | /** | 147 | /** |
| 168 | * struct idpf_tx_offload_params - Offload parameters for a given packet | 148 | * struct idpf_tx_offload_params - Offload parameters for a given packet |
| 169 | * @tx_flags: Feature flags enabled for this packet | 149 | * @tx_flags: Feature flags enabled for this packet |
| @@ -196,6 +176,9 @@ struct idpf_tx_offload_params { · 26 unmodified lines | |||
| 196 | * @compl_tag: Associated tag for completion | 176 | * @compl_tag: Associated tag for completion |
| 197 | * @td_tag: Descriptor tunneling tag | 177 | * @td_tag: Descriptor tunneling tag |
| 198 | * @offload: Offload parameters | 178 | * @offload: Offload parameters |
| 179 | * @prev_ntu: stored TxQ next_to_use in case of rollback | ||
| 180 | * @prev_refill_ntc: stored refillq next_to_clean in case of packet rollback | ||
| 181 | * @prev_refill_gen: stored refillq generation bit in case of packet rollback | ||
| 199 | */ | 182 | */ |
| 200 | struct idpf_tx_splitq_params { | 183 | struct idpf_tx_splitq_params { |
| 201 | enum idpf_tx_desc_dtype_value dtype; | 184 | enum idpf_tx_desc_dtype_value dtype; |
| @@ -206,6 +189,10 @@ struct idpf_tx_splitq_params { · 4 unmodified lines | |||
| 206 | }; | 189 | }; |
| 207 | 190 | ||
| 208 | struct idpf_tx_offload_params offload; | 191 | struct idpf_tx_offload_params offload; |
| 192 | |||
| 193 | u16 prev_ntu; | ||
| 194 | u16 prev_refill_ntc; | ||
| 195 | bool prev_refill_gen; | ||
| 209 | }; | 196 | }; |
| 210 | 197 | ||
| 211 | enum idpf_tx_ctx_desc_eipt_offload { | 198 | enum idpf_tx_ctx_desc_eipt_offload { |
| @@ -467,17 +454,6 @@ struct idpf_tx_queue_stats { · 255 unmodified lines | |||
| 467 | #define IDPF_ITR_IDX_SPACING(spacing, dflt) (spacing ? spacing : dflt) | 454 | #define IDPF_ITR_IDX_SPACING(spacing, dflt) (spacing ? spacing : dflt) |
| 468 | #define IDPF_DIM_DEFAULT_PROFILE_IX 1 | 455 | #define IDPF_DIM_DEFAULT_PROFILE_IX 1 |
| 469 | 456 | ||
| 470 | /** | ||
| 471 | * struct idpf_txq_stash - Tx buffer stash for Flow-based scheduling mode | ||
| 472 | * @buf_stack: Stack of empty buffers to store buffer info for out of order | ||
| 473 | * buffer completions. See struct idpf_buf_lifo | ||
| 474 | * @sched_buf_hash: Hash table to store buffers | ||
| 475 | */ | ||
| 476 | struct idpf_txq_stash { | ||
| 477 | struct idpf_buf_lifo buf_stack; | ||
| 478 | DECLARE_HASHTABLE(sched_buf_hash, 12); | ||
| 479 | } ____cacheline_aligned; | ||
| 480 | |||
| 481 | /** | 457 | /** |
| 482 | * struct idpf_rx_queue - software structure representing a receive queue | 458 | * struct idpf_rx_queue - software structure representing a receive queue |
| 483 | * @rx: universal receive descriptor array | 459 | * @rx: universal receive descriptor array |
| @@ -610,6 +586,8 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64, · 126 unmodified lines | |||
| 610 | * @netdev: &net_device corresponding to this queue | 586 | * @netdev: &net_device corresponding to this queue |
| 611 | * @next_to_use: Next descriptor to use | 587 | * @next_to_use: Next descriptor to use |
| 612 | * @next_to_clean: Next descriptor to clean | 588 | * @next_to_clean: Next descriptor to clean |
| 589 | * @last_re: last descriptor index that RE bit was set | ||
| 590 | * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather | ||
| 613 | * @cleaned_bytes: Splitq only, TXQ only: When a TX completion is received on | 591 | * @cleaned_bytes: Splitq only, TXQ only: When a TX completion is received on |
| 614 | * the TX completion queue, it can be for any TXQ associated | 592 | * the TX completion queue, it can be for any TXQ associated |
| 615 | * with that completion queue. This means we can clean up to | 593 | * with that completion queue. This means we can clean up to |
| @@ -620,11 +598,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64, · 4 unmodified lines | |||
| 620 | * only once at the end of the cleaning routine. | 598 | * only once at the end of the cleaning routine. |
| 621 | * @clean_budget: singleq only, queue cleaning budget | 599 | * @clean_budget: singleq only, queue cleaning budget |
| 622 | * @cleaned_pkts: Number of packets cleaned for the above said case | 600 | * @cleaned_pkts: Number of packets cleaned for the above said case |
| 623 | * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather | 601 | * @refillq: Pointer to refill queue |
| 624 | * @stash: Tx buffer stash for Flow-based scheduling mode | ||
| 625 | * @compl_tag_bufid_m: Completion tag buffer id mask | ||
| 626 | * @compl_tag_cur_gen: Used to keep track of current completion tag generation | ||
| 627 | * @compl_tag_gen_max: To determine when compl_tag_cur_gen should be reset | ||
| 628 | * @cached_tstamp_caps: Tx timestamp capabilities negotiated with the CP | 602 | * @cached_tstamp_caps: Tx timestamp capabilities negotiated with the CP |
| 629 | * @tstamp_task: Work that handles Tx timestamp read | 603 | * @tstamp_task: Work that handles Tx timestamp read |
| 630 | * @stats_sync: See struct u64_stats_sync | 604 | * @stats_sync: See struct u64_stats_sync |
| @@ -633,6 +607,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64, · 2 unmodified lines | |||
| 633 | * @size: Length of descriptor ring in bytes | 607 | * @size: Length of descriptor ring in bytes |
| 634 | * @dma: Physical address of ring | 608 | * @dma: Physical address of ring |
| 635 | * @q_vector: Backreference to associated vector | 609 | * @q_vector: Backreference to associated vector |
| 610 | * @buf_pool_size: Total number of idpf_tx_buf | ||
| 636 | */ | 611 | */ |
| 637 | struct idpf_tx_queue { | 612 | struct idpf_tx_queue { |
| 638 | __cacheline_group_begin_aligned(read_mostly); | 613 | __cacheline_group_begin_aligned(read_mostly); |
| @@ -654,7 +629,6 @@ struct idpf_tx_queue { · 15 unmodified lines | |||
| 654 | u16 desc_count; | 629 | u16 desc_count; |
| 655 | 630 | ||
| 656 | u16 tx_min_pkt_len; | 631 | u16 tx_min_pkt_len; |
| 657 | u16 compl_tag_gen_s; | ||
| 658 | 632 | ||
| 659 | struct net_device *netdev; | 633 | struct net_device *netdev; |
| 660 | __cacheline_group_end_aligned(read_mostly); | 634 | __cacheline_group_end_aligned(read_mostly); |
| @@ -662,6 +636,8 @@ struct idpf_tx_queue { · 1 unmodified line | |||
| 662 | __cacheline_group_begin_aligned(read_write); | 636 | __cacheline_group_begin_aligned(read_write); |
| 663 | u16 next_to_use; | 637 | u16 next_to_use; |
| 664 | u16 next_to_clean; | 638 | u16 next_to_clean; |
| 639 | u16 last_re; | ||
| 640 | u16 tx_max_bufs; | ||
| 665 | 641 | ||
| 666 | union { | 642 | union { |
| 667 | u32 cleaned_bytes; | 643 | u32 cleaned_bytes; |
| @@ -669,12 +645,7 @@ struct idpf_tx_queue { · 1 unmodified line | |||
| 669 | }; | 645 | }; |
| 670 | u16 cleaned_pkts; | 646 | u16 cleaned_pkts; |
| 671 | 647 | ||
| 672 | u16 tx_max_bufs; | 648 | struct idpf_sw_queue *refillq; |
| 673 | struct idpf_txq_stash *stash; | ||
| 674 | |||
| 675 | u16 compl_tag_bufid_m; | ||
| 676 | u16 compl_tag_cur_gen; | ||
| 677 | u16 compl_tag_gen_max; | ||
| 678 | 649 | ||
| 679 | struct idpf_ptp_vport_tx_tstamp_caps *cached_tstamp_caps; | 650 | struct idpf_ptp_vport_tx_tstamp_caps *cached_tstamp_caps; |
| 680 | struct work_struct *tstamp_task; | 651 | struct work_struct *tstamp_task; |
| @@ -689,11 +660,12 @@ struct idpf_tx_queue { · 8 unmodified lines | |||
| 689 | dma_addr_t dma; | 660 | dma_addr_t dma; |
| 690 | 661 | ||
| 691 | struct idpf_q_vector *q_vector; | 662 | struct idpf_q_vector *q_vector; |
| 663 | u32 buf_pool_size; | ||
| 692 | __cacheline_group_end_aligned(cold); | 664 | __cacheline_group_end_aligned(cold); |
| 693 | }; | 665 | }; |
| 694 | libeth_cacheline_set_assert(struct idpf_tx_queue, 64, | 666 | libeth_cacheline_set_assert(struct idpf_tx_queue, 64, |
| 695 | 112 + sizeof(struct u64_stats_sync), | 667 | 104 + sizeof(struct u64_stats_sync), |
| 696 | 24); | 668 | 32); |
| 697 | 669 | ||
| 698 | /** | 670 | /** |
| 699 | * struct idpf_buf_queue - software structure representing a buffer queue | 671 | * struct idpf_buf_queue - software structure representing a buffer queue |
| @@ -903,7 +875,6 @@ struct idpf_rxq_group { · 203 unmodified lines | |||
| 903 | * @vport: Vport back pointer | 875 | * @vport: Vport back pointer |
| 904 | * @num_txq: Number of TX queues associated | 876 | * @num_txq: Number of TX queues associated |
| 905 | * @txqs: Array of TX queue pointers | 877 | * @txqs: Array of TX queue pointers |
| 906 | * @stashes: array of OOO stashes for the queues | ||
| 907 | * @complq: Associated completion queue pointer, split queue only | 878 | * @complq: Associated completion queue pointer, split queue only |
| 908 | * @num_completions_pending: Total number of completions pending for the | 879 | * @num_completions_pending: Total number of completions pending for the |
| 909 | * completion queue, acculumated for all TX queues | 880 | * completion queue, acculumated for all TX queues |
| @@ -918,7 +889,6 @@ struct idpf_txq_group { · 8 unmodified lines | |||
| 918 | 889 | ||
| 919 | u16 num_txq; | 890 | u16 num_txq; |
| 920 | struct idpf_tx_queue *txqs[IDPF_LARGE_MAX_Q]; | 891 | struct idpf_tx_queue *txqs[IDPF_LARGE_MAX_Q]; |
| 921 | struct idpf_txq_stash *stashes; | ||
| 922 | 892 | ||
| 923 | struct idpf_compl_queue *complq; | 893 | struct idpf_compl_queue *complq; |
| 924 | 894 | ||
| @@ -1011,6 +981,17 @@ static inline void idpf_vport_intr_set_wb_on_itr(struct idpf_q_vector *q_vector) · 86 unmodified lines | |||
| 1011 | reg->dyn_ctl); | 981 | reg->dyn_ctl); |
| 1012 | } | 982 | } |
| 1013 | 983 | ||
| 984 | /** | ||
| 985 | * idpf_tx_splitq_get_free_bufs - get number of free buf_ids in refillq | ||
| 986 | * @refillq: pointer to refillq containing buf_ids | ||
| 987 | */ | ||
| 988 | static inline u32 idpf_tx_splitq_get_free_bufs(struct idpf_sw_queue *refillq) | ||
| 989 | { | ||
| 990 | return (refillq->next_to_use > refillq->next_to_clean ? | ||
| 991 | 0 : refillq->desc_count) + | ||
| 992 | refillq->next_to_use - refillq->next_to_clean - 1; | ||
| 993 | } | ||
| 994 | |||
| 1014 | int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget); | 995 | int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget); |
| 1015 | void idpf_vport_init_num_qs(struct idpf_vport *vport, | 996 | void idpf_vport_init_num_qs(struct idpf_vport *vport, |
| 1016 | struct virtchnl2_create_vport *vport_msg); | 997 | struct virtchnl2_create_vport *vport_msg); |
| @@ -1038,10 +1019,8 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val, · 21 unmodified lines | |||
| 1038 | bool xmit_more); | 1019 | bool xmit_more); |
| 1039 | unsigned int idpf_size_to_txd_count(unsigned int size); | 1020 | unsigned int idpf_size_to_txd_count(unsigned int size); |
| 1040 | netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb); | 1021 | netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb); |
| 1041 | void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb, | 1022 | unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq, |
| 1042 | struct idpf_tx_buf *first, u16 ring_idx); | 1023 | struct sk_buff *skb, u32 *buf_count); |
| 1043 | unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq, | ||
| 1044 | struct sk_buff *skb); | ||
| 1045 | void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue); | 1024 | void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue); |
| 1046 | netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb, | 1025 | netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb, |
| 1047 | struct idpf_tx_queue *tx_q); | 1026 | struct idpf_tx_queue *tx_q); |
| @@ -3125,7 +3125,7 @@ static int ixgbe_get_orom_ver_info(struct ixgbe_hw *hw, · 3124 unmodified lines | |||
| 3125 | if (err) | 3125 | if (err) |
| 3126 | return err; | 3126 | return err; |
| 3127 | 3127 | ||
| 3128 | combo_ver = le32_to_cpu(civd.combo_ver); | 3128 | combo_ver = get_unaligned_le32(&civd.combo_ver); |
| 3129 | 3129 | ||
| 3130 | orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver); | 3130 | orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver); |
| 3131 | orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver); | 3131 | orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver); |
| @@ -932,7 +932,7 @@ struct ixgbe_orom_civd_info { · 931 unmodified lines | |||
| 932 | __le32 combo_ver; /* Combo Image Version number */ | 932 | __le32 combo_ver; /* Combo Image Version number */ |
| 933 | u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */ | 933 | u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */ |
| 934 | __le16 combo_name[32]; /* Unicode string representing the Combo Image version */ | 934 | __le16 combo_name[32]; /* Unicode string representing the Combo Image version */ |
| 935 | }; | 935 | } __packed; |
| 936 | 936 | ||
| 937 | /* Function specific capabilities */ | 937 | /* Function specific capabilities */ |
| 938 | struct ixgbe_hw_func_caps { | 938 | struct ixgbe_hw_func_caps { |
| @@ -1978,6 +1978,13 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 1977 unmodified lines | |||
| 1978 | goto err_release_regions; | 1978 | goto err_release_regions; |
| 1979 | } | 1979 | } |
| 1980 | 1980 | ||
| 1981 | if (!is_cn20k(pdev) && | ||
| 1982 | !is_cgx_mapped_to_nix(pdev->subsystem_device, cgx->cgx_id)) { | ||
| 1983 | dev_notice(dev, "CGX %d not mapped to NIX, skipping probe\n", | ||
| 1984 | cgx->cgx_id); | ||
| 1985 | goto err_release_regions; | ||
| 1986 | } | ||
| 1987 | |||
| 1981 | cgx->lmac_count = cgx->mac_ops->get_nr_lmacs(cgx); | 1988 | cgx->lmac_count = cgx->mac_ops->get_nr_lmacs(cgx); |
| 1982 | if (!cgx->lmac_count) { | 1989 | if (!cgx->lmac_count) { |
| 1983 | dev_notice(dev, "CGX %d LMAC count is zero, skipping probe\n", cgx->cgx_id); | 1990 | dev_notice(dev, "CGX %d LMAC count is zero, skipping probe\n", cgx->cgx_id); |
| @@ -783,6 +783,20 @@ static inline bool is_cn10kb(struct rvu *rvu) · 782 unmodified lines | |||
| 783 | return false; | 783 | return false; |
| 784 | } | 784 | } |
| 785 | 785 | ||
| 786 | static inline bool is_cgx_mapped_to_nix(unsigned short id, u8 cgx_id) | ||
| 787 | { | ||
| 788 | /* On CNF10KA and CNF10KB silicons only two CGX blocks are connected | ||
| 789 | * to NIX. | ||
| 790 | */ | ||
| 791 | if (id == PCI_SUBSYS_DEVID_CNF10K_A || id == PCI_SUBSYS_DEVID_CNF10K_B) | ||
| 792 | return cgx_id <= 1; | ||
| 793 | |||
| 794 | return !(cgx_id && !(id == PCI_SUBSYS_DEVID_96XX || | ||
| 795 | id == PCI_SUBSYS_DEVID_98XX || | ||
| 796 | id == PCI_SUBSYS_DEVID_CN10K_A || | ||
| 797 | id == PCI_SUBSYS_DEVID_CN10K_B)); | ||
| 798 | } | ||
| 799 | |||
| 786 | static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu) | 800 | static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu) |
| 787 | { | 801 | { |
| 788 | u64 npc_const3; | 802 | u64 npc_const3; |
| @@ -124,7 +124,9 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf) · 123 unmodified lines | |||
| 124 | dev_stats->rx_ucast_frames; | 124 | dev_stats->rx_ucast_frames; |
| 125 | 125 | ||
| 126 | dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); | 126 | dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); |
| 127 | dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP); | 127 | dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP) + |
| 128 | (unsigned long)atomic_long_read(&dev_stats->tx_discards); | ||
| 129 | |||
| 128 | dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST); | 130 | dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST); |
| 129 | dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST); | 131 | dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST); |
| 130 | dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST); | 132 | dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST); |
| @@ -153,6 +153,7 @@ struct otx2_dev_stats { · 152 unmodified lines | |||
| 153 | u64 tx_bcast_frames; | 153 | u64 tx_bcast_frames; |
| 154 | u64 tx_mcast_frames; | 154 | u64 tx_mcast_frames; |
| 155 | u64 tx_drops; | 155 | u64 tx_drops; |
| 156 | atomic_long_t tx_discards; | ||
| 156 | }; | 157 | }; |
| 157 | 158 | ||
| 158 | /* Driver counted stats */ | 159 | /* Driver counted stats */ |
| @@ -2220,6 +2220,7 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev) · 2219 unmodified lines | |||
| 2220 | { | 2220 | { |
| 2221 | struct otx2_nic *pf = netdev_priv(netdev); | 2221 | struct otx2_nic *pf = netdev_priv(netdev); |
| 2222 | int qidx = skb_get_queue_mapping(skb); | 2222 | int qidx = skb_get_queue_mapping(skb); |
| 2223 | struct otx2_dev_stats *dev_stats; | ||
| 2223 | struct otx2_snd_queue *sq; | 2224 | struct otx2_snd_queue *sq; |
| 2224 | struct netdev_queue *txq; | 2225 | struct netdev_queue *txq; |
| 2225 | int sq_idx; | 2226 | int sq_idx; |
| @@ -2232,6 +2233,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev) · 6 unmodified lines | |||
| 2232 | /* Check for minimum and maximum packet length */ | 2233 | /* Check for minimum and maximum packet length */ |
| 2233 | if (skb->len <= ETH_HLEN || | 2234 | if (skb->len <= ETH_HLEN || |
| 2234 | (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) { | 2235 | (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) { |
| 2236 | dev_stats = &pf->hw.dev_stats; | ||
| 2237 | atomic_long_inc(&dev_stats->tx_discards); | ||
| 2235 | dev_kfree_skb(skb); | 2238 | dev_kfree_skb(skb); |
| 2236 | return NETDEV_TX_OK; | 2239 | return NETDEV_TX_OK; |
| 2237 | } | 2240 | } |
| @@ -417,9 +417,19 @@ static netdev_tx_t otx2vf_xmit(struct sk_buff *skb, struct net_device *netdev) · 416 unmodified lines | |||
| 417 | { | 417 | { |
| 418 | struct otx2_nic *vf = netdev_priv(netdev); | 418 | struct otx2_nic *vf = netdev_priv(netdev); |
| 419 | int qidx = skb_get_queue_mapping(skb); | 419 | int qidx = skb_get_queue_mapping(skb); |
| 420 | struct otx2_dev_stats *dev_stats; | ||
| 420 | struct otx2_snd_queue *sq; | 421 | struct otx2_snd_queue *sq; |
| 421 | struct netdev_queue *txq; | 422 | struct netdev_queue *txq; |
| 422 | 423 | ||
| 424 | /* Check for minimum and maximum packet length */ | ||
| 425 | if (skb->len <= ETH_HLEN || | ||
| 426 | (!skb_shinfo(skb)->gso_size && skb->len > vf->tx_max_pktlen)) { | ||
| 427 | dev_stats = &vf->hw.dev_stats; | ||
| 428 | atomic_long_inc(&dev_stats->tx_discards); | ||
| 429 | dev_kfree_skb(skb); | ||
| 430 | return NETDEV_TX_OK; | ||
| 431 | } | ||
| 432 | |||
| 423 | sq = &vf->qset.sq[qidx]; | 433 | sq = &vf->qset.sq[qidx]; |
| 424 | txq = netdev_get_tx_queue(netdev, qidx); | 434 | txq = netdev_get_tx_queue(netdev, qidx); |
| 425 | 435 | ||
| @@ -371,7 +371,8 @@ static void rvu_rep_get_stats(struct work_struct *work) · 370 unmodified lines | |||
| 371 | stats->rx_mcast_frames = rsp->rx.mcast; | 371 | stats->rx_mcast_frames = rsp->rx.mcast; |
| 372 | stats->tx_bytes = rsp->tx.octs; | 372 | stats->tx_bytes = rsp->tx.octs; |
| 373 | stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast; | 373 | stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast; |
| 374 | stats->tx_drops = rsp->tx.drop; | 374 | stats->tx_drops = rsp->tx.drop + |
| 375 | (unsigned long)atomic_long_read(&stats->tx_discards); | ||
| 375 | exit: | 376 | exit: |
| 376 | mutex_unlock(&priv->mbox.lock); | 377 | mutex_unlock(&priv->mbox.lock); |
| 377 | } | 378 | } |
| @@ -418,6 +419,16 @@ static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev) · 40 unmodified lines | |||
| 418 | struct otx2_nic *pf = rep->mdev; | 419 | struct otx2_nic *pf = rep->mdev; |
| 419 | struct otx2_snd_queue *sq; | 420 | struct otx2_snd_queue *sq; |
| 420 | struct netdev_queue *txq; | 421 | struct netdev_queue *txq; |
| 422 | struct rep_stats *stats; | ||
| 423 | |||
| 424 | /* Check for minimum and maximum packet length */ | ||
| 425 | if (skb->len <= ETH_HLEN || | ||
| 426 | (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) { | ||
| 427 | stats = &rep->stats; | ||
| 428 | atomic_long_inc(&stats->tx_discards); | ||
| 429 | dev_kfree_skb(skb); | ||
| 430 | return NETDEV_TX_OK; | ||
| 431 | } | ||
| 421 | 432 | ||
| 422 | sq = &pf->qset.sq[rep->rep_id]; | 433 | sq = &pf->qset.sq[rep->rep_id]; |
| 423 | txq = netdev_get_tx_queue(dev, 0); | 434 | txq = netdev_get_tx_queue(dev, 0); |
| @@ -27,6 +27,7 @@ struct rep_stats { · 26 unmodified lines | |||
| 27 | u64 tx_bytes; | 27 | u64 tx_bytes; |
| 28 | u64 tx_frames; | 28 | u64 tx_frames; |
| 29 | u64 tx_drops; | 29 | u64 tx_drops; |
| 30 | atomic_long_t tx_discards; | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | struct rep_dev { | 33 | struct rep_dev { |
| @@ -160,7 +160,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli · 159 unmodified lines | |||
| 160 | if (err) | 160 | if (err) |
| 161 | return err; | 161 | return err; |
| 162 | 162 | ||
| 163 | mlx5_unload_one_devl_locked(dev, true); | 163 | mlx5_sync_reset_unload_flow(dev, true); |
| 164 | err = mlx5_health_wait_pci_up(dev); | 164 | err = mlx5_health_wait_pci_up(dev); |
| 165 | if (err) | 165 | if (err) |
| 166 | NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset"); | 166 | NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset"); |
| @@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 574 unmodified lines | |||
| 575 | if (err) | 575 | if (err) |
| 576 | return err; | 576 | return err; |
| 577 | } | 577 | } |
| 578 | priv->dcbx.xoff = xoff; | ||
| 579 | 578 | ||
| 580 | /* Apply the settings */ | 579 | /* Apply the settings */ |
| 581 | if (update_buffer) { | 580 | if (update_buffer) { |
| @@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 2 unmodified lines | |||
| 584 | return err; | 583 | return err; |
| 585 | } | 584 | } |
| 586 | 585 | ||
| 586 | priv->dcbx.xoff = xoff; | ||
| 587 | |||
| 587 | if (update_prio2buffer) | 588 | if (update_prio2buffer) |
| 588 | err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer); | 589 | err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer); |
| 589 | 590 | ||
| @@ -66,11 +66,23 @@ struct mlx5e_port_buffer { · 65 unmodified lines | |||
| 66 | struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER]; | 66 | struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER]; |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | #ifdef CONFIG_MLX5_CORE_EN_DCB | ||
| 69 | int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, | 70 | int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, |
| 70 | u32 change, unsigned int mtu, | 71 | u32 change, unsigned int mtu, |
| 71 | struct ieee_pfc *pfc, | 72 | struct ieee_pfc *pfc, |
| 72 | u32 *buffer_size, | 73 | u32 *buffer_size, |
| 73 | u8 *prio2buffer); | 74 | u8 *prio2buffer); |
| 75 | #else | ||
| 76 | static inline int | ||
| 77 | mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, | ||
| 78 | u32 change, unsigned int mtu, | ||
| 79 | void *pfc, | ||
| 80 | u32 *buffer_size, | ||
| 81 | u8 *prio2buffer) | ||
| 82 | { | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | #endif | ||
| 74 | 86 | ||
| 75 | int mlx5e_port_query_buffer(struct mlx5e_priv *priv, | 87 | int mlx5e_port_query_buffer(struct mlx5e_priv *priv, |
| 76 | struct mlx5e_port_buffer *port_buffer); | 88 | struct mlx5e_port_buffer *port_buffer); |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | #include "en.h" | 49 | #include "en.h" |
| 50 | #include "en/dim.h" | 50 | #include "en/dim.h" |
| 51 | #include "en/txrx.h" | 51 | #include "en/txrx.h" |
| 52 | #include "en/port_buffer.h" | ||
| 52 | #include "en_tc.h" | 53 | #include "en_tc.h" |
| 53 | #include "en_rep.h" | 54 | #include "en_rep.h" |
| 54 | #include "en_accel/ipsec.h" | 55 | #include "en_accel/ipsec.h" |
| @@ -138,6 +139,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv) · 83 unmodified lines | |||
| 138 | if (up) { | 139 | if (up) { |
| 139 | netdev_info(priv->netdev, "Link up\n"); | 140 | netdev_info(priv->netdev, "Link up\n"); |
| 140 | netif_carrier_on(priv->netdev); | 141 | netif_carrier_on(priv->netdev); |
| 142 | mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu, | ||
| 143 | NULL, NULL, NULL); | ||
| 141 | } else { | 144 | } else { |
| 142 | netdev_info(priv->netdev, "Link down\n"); | 145 | netdev_info(priv->netdev, "Link down\n"); |
| 143 | netif_carrier_off(priv->netdev); | 146 | netif_carrier_off(priv->netdev); |
| @@ -3040,9 +3043,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) · 2896 unmodified lines | |||
| 3040 | struct mlx5e_params *params = &priv->channels.params; | 3043 | struct mlx5e_params *params = &priv->channels.params; |
| 3041 | struct net_device *netdev = priv->netdev; | 3044 | struct net_device *netdev = priv->netdev; |
| 3042 | struct mlx5_core_dev *mdev = priv->mdev; | 3045 | struct mlx5_core_dev *mdev = priv->mdev; |
| 3043 | u16 mtu; | 3046 | u16 mtu, prev_mtu; |
| 3044 | int err; | 3047 | int err; |
| 3045 | 3048 | ||
| 3049 | mlx5e_query_mtu(mdev, params, &prev_mtu); | ||
| 3050 | |||
| 3046 | err = mlx5e_set_mtu(mdev, params, params->sw_mtu); | 3051 | err = mlx5e_set_mtu(mdev, params, params->sw_mtu); |
| 3047 | if (err) | 3052 | if (err) |
| 3048 | return err; | 3053 | return err; |
| @@ -3052,6 +3057,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv) · 3 unmodified lines | |||
| 3052 | netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", | 3057 | netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n", |
| 3053 | __func__, mtu, params->sw_mtu); | 3058 | __func__, mtu, params->sw_mtu); |
| 3054 | 3059 | ||
| 3060 | if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) { | ||
| 3061 | err = mlx5e_port_manual_buffer_config(priv, 0, mtu, | ||
| 3062 | NULL, NULL, NULL); | ||
| 3063 | if (err) { | ||
| 3064 | netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n", | ||
| 3065 | __func__, mtu, err, prev_mtu); | ||
| 3066 | |||
| 3067 | mlx5e_set_mtu(mdev, params, prev_mtu); | ||
| 3068 | return err; | ||
| 3069 | } | ||
| 3070 | } | ||
| 3071 | |||
| 3055 | params->sw_mtu = mtu; | 3072 | params->sw_mtu = mtu; |
| 3056 | return 0; | 3073 | return 0; |
| 3057 | } | 3074 | } |
| @@ -3734,6 +3734,13 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id, · 3733 unmodified lines | |||
| 3734 | char *value = val.vstr; | 3734 | char *value = val.vstr; |
| 3735 | u8 eswitch_mode; | 3735 | u8 eswitch_mode; |
| 3736 | 3736 | ||
| 3737 | eswitch_mode = mlx5_eswitch_mode(dev); | ||
| 3738 | if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) { | ||
| 3739 | NL_SET_ERR_MSG_FMT_MOD(extack, | ||
| 3740 | "Changing fs mode is not supported when eswitch offloads enabled."); | ||
| 3741 | return -EOPNOTSUPP; | ||
| 3742 | } | ||
| 3743 | |||
| 3737 | if (!strcmp(value, "dmfs")) | 3744 | if (!strcmp(value, "dmfs")) |
| 3738 | return 0; | 3745 | return 0; |
| 3739 | 3746 | ||
| @@ -3759,14 +3766,6 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id, · 19 unmodified lines | |||
| 3759 | return -EINVAL; | 3766 | return -EINVAL; |
| 3760 | } | 3767 | } |
| 3761 | 3768 | ||
| 3762 | eswitch_mode = mlx5_eswitch_mode(dev); | ||
| 3763 | if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) { | ||
| 3764 | NL_SET_ERR_MSG_FMT_MOD(extack, | ||
| 3765 | "Moving to %s is not supported when eswitch offloads enabled.", | ||
| 3766 | value); | ||
| 3767 | return -EOPNOTSUPP; | ||
| 3768 | } | ||
| 3769 | |||
| 3770 | return 0; | 3769 | return 0; |
| 3771 | } | 3770 | } |
| 3772 | 3771 | ||
| @@ -6,13 +6,15 @@ · 5 unmodified lines | |||
| 6 | #include "fw_reset.h" | 6 | #include "fw_reset.h" |
| 7 | #include "diag/fw_tracer.h" | 7 | #include "diag/fw_tracer.h" |
| 8 | #include "lib/tout.h" | 8 | #include "lib/tout.h" |
| 9 | #include "sf/sf.h" | ||
| 9 | 10 | ||
| 10 | enum { | 11 | enum { |
| 11 | MLX5_FW_RESET_FLAGS_RESET_REQUESTED, | 12 | MLX5_FW_RESET_FLAGS_RESET_REQUESTED, |
| 12 | MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, | 13 | MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, |
| 13 | MLX5_FW_RESET_FLAGS_PENDING_COMP, | 14 | MLX5_FW_RESET_FLAGS_PENDING_COMP, |
| 14 | MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, | 15 | MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS, |
| 15 | MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED | 16 | MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, |
| 17 | MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, | ||
| 16 | }; | 18 | }; |
| 17 | 19 | ||
| 18 | struct mlx5_fw_reset { | 20 | struct mlx5_fw_reset { |
| @@ -219,7 +221,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev) · 200 unmodified lines | |||
| 219 | return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false); | 221 | return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false); |
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded) | 224 | static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) |
| 223 | { | 225 | { |
| 224 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | 226 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; |
| 225 | struct devlink *devlink = priv_to_devlink(dev); | 227 | struct devlink *devlink = priv_to_devlink(dev); |
| @@ -228,8 +230,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload · 2 unmodified lines | |||
| 228 | if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { | 230 | if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { |
| 229 | complete(&fw_reset->done); | 231 | complete(&fw_reset->done); |
| 230 | } else { | 232 | } else { |
| 231 | if (!unloaded) | 233 | mlx5_sync_reset_unload_flow(dev, false); |
| 232 | mlx5_unload_one(dev, false); | ||
| 233 | if (mlx5_health_wait_pci_up(dev)) | 234 | if (mlx5_health_wait_pci_up(dev)) |
| 234 | mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); | 235 | mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); |
| 235 | else | 236 | else |
| @@ -272,7 +273,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work) · 36 unmodified lines | |||
| 272 | 273 | ||
| 273 | mlx5_sync_reset_clear_reset_requested(dev, false); | 274 | mlx5_sync_reset_clear_reset_requested(dev, false); |
| 274 | mlx5_enter_error_state(dev, true); | 275 | mlx5_enter_error_state(dev, true); |
| 275 | mlx5_fw_reset_complete_reload(dev, false); | 276 | mlx5_fw_reset_complete_reload(dev); |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | #define MLX5_RESET_POLL_INTERVAL (HZ / 10) | 279 | #define MLX5_RESET_POLL_INTERVAL (HZ / 10) |
| @@ -428,6 +429,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev, · 149 unmodified lines | |||
| 428 | return false; | 429 | return false; |
| 429 | } | 430 | } |
| 430 | 431 | ||
| 432 | if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) { | ||
| 433 | mlx5_core_warn(dev, "SFs should be removed before reset\n"); | ||
| 434 | return false; | ||
| 435 | } | ||
| 436 | |||
| 431 | #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE) | 437 | #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE) |
| 432 | if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) { | 438 | if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) { |
| 433 | err = mlx5_check_hotplug_interrupt(dev, bridge); | 439 | err = mlx5_check_hotplug_interrupt(dev, bridge); |
| @@ -586,6 +592,65 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method) · 152 unmodified lines | |||
| 586 | return err; | 592 | return err; |
| 587 | } | 593 | } |
| 588 | 594 | ||
| 595 | void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked) | ||
| 596 | { | ||
| 597 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | ||
| 598 | unsigned long timeout; | ||
| 599 | int poll_freq = 20; | ||
| 600 | bool reset_action; | ||
| 601 | u8 rst_state; | ||
| 602 | int err; | ||
| 603 | |||
| 604 | if (locked) | ||
| 605 | mlx5_unload_one_devl_locked(dev, false); | ||
| 606 | else | ||
| 607 | mlx5_unload_one(dev, false); | ||
| 608 | |||
| 609 | if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags)) | ||
| 610 | return; | ||
| 611 | |||
| 612 | mlx5_set_fw_rst_ack(dev); | ||
| 613 | mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n"); | ||
| 614 | |||
| 615 | reset_action = false; | ||
| 616 | timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD)); | ||
| 617 | do { | ||
| 618 | rst_state = mlx5_get_fw_rst_state(dev); | ||
| 619 | if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ || | ||
| 620 | rst_state == MLX5_FW_RST_STATE_IDLE) { | ||
| 621 | reset_action = true; | ||
| 622 | break; | ||
| 623 | } | ||
| 624 | if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) { | ||
| 625 | mlx5_core_info(dev, "Sync Reset Drop mode ack\n"); | ||
| 626 | mlx5_set_fw_rst_ack(dev); | ||
| 627 | poll_freq = 1000; | ||
| 628 | } | ||
| 629 | msleep(poll_freq); | ||
| 630 | } while (!time_after(jiffies, timeout)); | ||
| 631 | |||
| 632 | if (!reset_action) { | ||
| 633 | mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n", | ||
| 634 | rst_state); | ||
| 635 | fw_reset->ret = -ETIMEDOUT; | ||
| 636 | goto done; | ||
| 637 | } | ||
| 638 | |||
| 639 | mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", | ||
| 640 | rst_state); | ||
| 641 | if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) { | ||
| 642 | err = mlx5_sync_pci_reset(dev, fw_reset->reset_method); | ||
| 643 | if (err) { | ||
| 644 | mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", | ||
| 645 | err); | ||
| 646 | fw_reset->ret = err; | ||
| 647 | } | ||
| 648 | } | ||
| 649 | |||
| 650 | done: | ||
| 651 | clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags); | ||
| 652 | } | ||
| 653 | |||
| 589 | static void mlx5_sync_reset_now_event(struct work_struct *work) | 654 | static void mlx5_sync_reset_now_event(struct work_struct *work) |
| 590 | { | 655 | { |
| 591 | struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, | 656 | struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, |
| @@ -613,17 +678,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work) · 21 unmodified lines | |||
| 613 | mlx5_enter_error_state(dev, true); | 678 | mlx5_enter_error_state(dev, true); |
| 614 | done: | 679 | done: |
| 615 | fw_reset->ret = err; | 680 | fw_reset->ret = err; |
| 616 | mlx5_fw_reset_complete_reload(dev, false); | 681 | mlx5_fw_reset_complete_reload(dev); |
| 617 | } | 682 | } |
| 618 | 683 | ||
| 619 | static void mlx5_sync_reset_unload_event(struct work_struct *work) | 684 | static void mlx5_sync_reset_unload_event(struct work_struct *work) |
| 620 | { | 685 | { |
| 621 | struct mlx5_fw_reset *fw_reset; | 686 | struct mlx5_fw_reset *fw_reset; |
| 622 | struct mlx5_core_dev *dev; | 687 | struct mlx5_core_dev *dev; |
| 623 | unsigned long timeout; | ||
| 624 | int poll_freq = 20; | ||
| 625 | bool reset_action; | ||
| 626 | u8 rst_state; | ||
| 627 | int err; | 688 | int err; |
| 628 | 689 | ||
| 629 | fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work); | 690 | fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work); |
| @@ -632,6 +693,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work) · 2 unmodified lines | |||
| 632 | if (mlx5_sync_reset_clear_reset_requested(dev, false)) | 693 | if (mlx5_sync_reset_clear_reset_requested(dev, false)) |
| 633 | return; | 694 | return; |
| 634 | 695 | ||
| 696 | set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags); | ||
| 635 | mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n"); | 697 | mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n"); |
| 636 | 698 | ||
| 637 | err = mlx5_cmd_fast_teardown_hca(dev); | 699 | err = mlx5_cmd_fast_teardown_hca(dev); |
| @@ -640,49 +702,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work) · 2 unmodified lines | |||
| 640 | else | 702 | else |
| 641 | mlx5_enter_error_state(dev, true); | 703 | mlx5_enter_error_state(dev, true); |
| 642 | 704 | ||
| 643 | if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) | 705 | mlx5_fw_reset_complete_reload(dev); |
| 644 | mlx5_unload_one_devl_locked(dev, false); | ||
| 645 | else | ||
| 646 | mlx5_unload_one(dev, false); | ||
| 647 | |||
| 648 | mlx5_set_fw_rst_ack(dev); | ||
| 649 | mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n"); | ||
| 650 | |||
| 651 | reset_action = false; | ||
| 652 | timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD)); | ||
| 653 | do { | ||
| 654 | rst_state = mlx5_get_fw_rst_state(dev); | ||
| 655 | if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ || | ||
| 656 | rst_state == MLX5_FW_RST_STATE_IDLE) { | ||
| 657 | reset_action = true; | ||
| 658 | break; | ||
| 659 | } | ||
| 660 | if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) { | ||
| 661 | mlx5_core_info(dev, "Sync Reset Drop mode ack\n"); | ||
| 662 | mlx5_set_fw_rst_ack(dev); | ||
| 663 | poll_freq = 1000; | ||
| 664 | } | ||
| 665 | msleep(poll_freq); | ||
| 666 | } while (!time_after(jiffies, timeout)); | ||
| 667 | |||
| 668 | if (!reset_action) { | ||
| 669 | mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n", | ||
| 670 | rst_state); | ||
| 671 | fw_reset->ret = -ETIMEDOUT; | ||
| 672 | goto done; | ||
| 673 | } | ||
| 674 | |||
| 675 | mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state); | ||
| 676 | if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) { | ||
| 677 | err = mlx5_sync_pci_reset(dev, fw_reset->reset_method); | ||
| 678 | if (err) { | ||
| 679 | mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err); | ||
| 680 | fw_reset->ret = err; | ||
| 681 | } | ||
| 682 | } | ||
| 683 | |||
| 684 | done: | ||
| 685 | mlx5_fw_reset_complete_reload(dev, true); | ||
| 686 | } | 706 | } |
| 687 | 707 | ||
| 688 | static void mlx5_sync_reset_abort_event(struct work_struct *work) | 708 | static void mlx5_sync_reset_abort_event(struct work_struct *work) |
| @@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel, · 11 unmodified lines | |||
| 12 | int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev); | 12 | int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev); |
| 13 | 13 | ||
| 14 | int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev); | 14 | int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev); |
| 15 | void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked); | ||
| 15 | int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev, | 16 | int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev, |
| 16 | struct netlink_ext_ack *extack); | 17 | struct netlink_ext_ack *extack); |
| 17 | void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev); | 18 | void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev); |
| @@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) · 517 unmodified lines | |||
| 518 | WARN_ON(!xa_empty(&table->function_ids)); | 518 | WARN_ON(!xa_empty(&table->function_ids)); |
| 519 | kfree(table); | 519 | kfree(table); |
| 520 | } | 520 | } |
| 521 | |||
| 522 | bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev) | ||
| 523 | { | ||
| 524 | struct mlx5_sf_table *table = dev->priv.sf_table; | ||
| 525 | |||
| 526 | if (!table) | ||
| 527 | return true; | ||
| 528 | |||
| 529 | return xa_empty(&table->function_ids); | ||
| 530 | } | ||
| @@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev); · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | int mlx5_sf_table_init(struct mlx5_core_dev *dev); | 18 | int mlx5_sf_table_init(struct mlx5_core_dev *dev); |
| 19 | void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev); | 19 | void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev); |
| 20 | bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev); | ||
| 20 | 21 | ||
| 21 | int mlx5_devlink_sf_port_new(struct devlink *devlink, | 22 | int mlx5_devlink_sf_port_new(struct devlink *devlink, |
| 22 | const struct devlink_port_new_attrs *add_attr, | 23 | const struct devlink_port_new_attrs *add_attr, |
| @@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev) · 38 unmodified lines | |||
| 61 | { | 62 | { |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 65 | static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev) | ||
| 66 | { | ||
| 67 | return true; | ||
| 68 | } | ||
| 69 | |||
| 64 | #endif | 70 | #endif |
| 65 | 71 | ||
| 66 | #endif | 72 | #endif |
| @@ -117,7 +117,7 @@ static int hws_action_get_shared_stc_nic(struct mlx5hws_context *ctx, · 116 unmodified lines | |||
| 117 | mlx5hws_err(ctx, "No such stc_type: %d\n", stc_type); | 117 | mlx5hws_err(ctx, "No such stc_type: %d\n", stc_type); |
| 118 | pr_warn("HWS: Invalid stc_type: %d\n", stc_type); | 118 | pr_warn("HWS: Invalid stc_type: %d\n", stc_type); |
| 119 | ret = -EINVAL; | 119 | ret = -EINVAL; |
| 120 | goto unlock_and_out; | 120 | goto free_shared_stc; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | ret = mlx5hws_action_alloc_single_stc(ctx, &stc_attr, tbl_type, | 123 | ret = mlx5hws_action_alloc_single_stc(ctx, &stc_attr, tbl_type, |
| @@ -279,7 +279,7 @@ int mlx5hws_pat_get_pattern(struct mlx5hws_context *ctx, · 278 unmodified lines | |||
| 279 | return ret; | 279 | return ret; |
| 280 | 280 | ||
| 281 | clean_pattern: | 281 | clean_pattern: |
| 282 | mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, *pattern_id); | 282 | mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, ptrn_id); |
| 283 | out_unlock: | 283 | out_unlock: |
| 284 | mutex_unlock(&ctx->pattern_cache->lock); | 284 | mutex_unlock(&ctx->pattern_cache->lock); |
| 285 | return ret; | 285 | return ret; |
| @@ -527,7 +527,6 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions, · 241 unmodified lines | |||
| 527 | u32 *nop_locations, __be64 *new_pat) | 527 | u32 *nop_locations, __be64 *new_pat) |
| 528 | { | 528 | { |
| 529 | u16 prev_src_field = INVALID_FIELD, prev_dst_field = INVALID_FIELD; | 529 | u16 prev_src_field = INVALID_FIELD, prev_dst_field = INVALID_FIELD; |
| 530 | u16 src_field, dst_field; | ||
| 531 | u8 action_type; | 530 | u8 action_type; |
| 532 | bool dependent; | 531 | bool dependent; |
| 533 | size_t i, j; | 532 | size_t i, j; |
| @@ -539,6 +538,9 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions, · 5 unmodified lines | |||
| 539 | return 0; | 538 | return 0; |
| 540 | 539 | ||
| 541 | for (i = 0, j = 0; i < num_actions; i++, j++) { | 540 | for (i = 0, j = 0; i < num_actions; i++, j++) { |
| 541 | u16 src_field = INVALID_FIELD; | ||
| 542 | u16 dst_field = INVALID_FIELD; | ||
| 543 | |||
| 542 | if (j >= max_actions) | 544 | if (j >= max_actions) |
| 543 | return -EINVAL; | 545 | return -EINVAL; |
| 544 | 546 | ||
| @@ -124,6 +124,7 @@ static int hws_pool_buddy_init(struct mlx5hws_pool *pool) · 123 unmodified lines | |||
| 124 | mlx5hws_err(pool->ctx, "Failed to create resource type: %d size %zu\n", | 124 | mlx5hws_err(pool->ctx, "Failed to create resource type: %d size %zu\n", |
| 125 | pool->type, pool->alloc_log_sz); | 125 | pool->type, pool->alloc_log_sz); |
| 126 | mlx5hws_buddy_cleanup(buddy); | 126 | mlx5hws_buddy_cleanup(buddy); |
| 127 | kfree(buddy); | ||
| 127 | return -ENOMEM; | 128 | return -ENOMEM; |
| 128 | } | 129 | } |
| 129 | 130 | ||
| @@ -52,6 +52,8 @@ int __fbnic_open(struct fbnic_net *fbn) · 51 unmodified lines | |||
| 52 | fbnic_bmc_rpc_init(fbd); | 52 | fbnic_bmc_rpc_init(fbd); |
| 53 | fbnic_rss_reinit(fbd, fbn); | 53 | fbnic_rss_reinit(fbd, fbn); |
| 54 | 54 | ||
| 55 | phylink_resume(fbn->phylink); | ||
| 56 | |||
| 55 | return 0; | 57 | return 0; |
| 56 | time_stop: | 58 | time_stop: |
| 57 | fbnic_time_stop(fbn); | 59 | fbnic_time_stop(fbn); |
| @@ -84,6 +86,8 @@ static int fbnic_stop(struct net_device *netdev) · 26 unmodified lines | |||
| 84 | { | 86 | { |
| 85 | struct fbnic_net *fbn = netdev_priv(netdev); | 87 | struct fbnic_net *fbn = netdev_priv(netdev); |
| 86 | 88 | ||
| 89 | phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd)); | ||
| 90 | |||
| 87 | fbnic_down(fbn); | 91 | fbnic_down(fbn); |
| 88 | fbnic_pcs_free_irq(fbn->fbd); | 92 | fbnic_pcs_free_irq(fbn->fbd); |
| 89 | 93 | ||
| @@ -118,14 +118,12 @@ static void fbnic_service_task_start(struct fbnic_net *fbn) · 117 unmodified lines | |||
| 118 | struct fbnic_dev *fbd = fbn->fbd; | 118 | struct fbnic_dev *fbd = fbn->fbd; |
| 119 | 119 | ||
| 120 | schedule_delayed_work(&fbd->service_task, HZ); | 120 | schedule_delayed_work(&fbd->service_task, HZ); |
| 121 | phylink_resume(fbn->phylink); | ||
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | static void fbnic_service_task_stop(struct fbnic_net *fbn) | 123 | static void fbnic_service_task_stop(struct fbnic_net *fbn) |
| 125 | { | 124 | { |
| 126 | struct fbnic_dev *fbd = fbn->fbd; | 125 | struct fbnic_dev *fbd = fbn->fbd; |
| 127 | 126 | ||
| 128 | phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd)); | ||
| 129 | cancel_delayed_work(&fbd->service_task); | 127 | cancel_delayed_work(&fbd->service_task); |
| 130 | } | 128 | } |
| 131 | 129 | ||
| @@ -444,11 +442,10 @@ static int __fbnic_pm_resume(struct device *dev) · 312 unmodified lines | |||
| 444 | 442 | ||
| 445 | /* Re-enable mailbox */ | 443 | /* Re-enable mailbox */ |
| 446 | err = fbnic_fw_request_mbx(fbd); | 444 | err = fbnic_fw_request_mbx(fbd); |
| 445 | devl_unlock(priv_to_devlink(fbd)); | ||
| 447 | if (err) | 446 | if (err) |
| 448 | goto err_free_irqs; | 447 | goto err_free_irqs; |
| 449 | 448 | ||
| 450 | devl_unlock(priv_to_devlink(fbd)); | ||
| 451 | |||
| 452 | /* Only send log history if log buffer is empty to prevent duplicate | 449 | /* Only send log history if log buffer is empty to prevent duplicate |
| 453 | * log entries. | 450 | * log entries. |
| 454 | */ | 451 | */ |
| @@ -465,20 +462,20 @@ static int __fbnic_pm_resume(struct device *dev) · 10 unmodified lines | |||
| 465 | 462 | ||
| 466 | rtnl_lock(); | 463 | rtnl_lock(); |
| 467 | 464 | ||
| 468 | if (netif_running(netdev)) { | 465 | if (netif_running(netdev)) |
| 469 | err = __fbnic_open(fbn); | 466 | err = __fbnic_open(fbn); |
| 470 | if (err) | ||
| 471 | goto err_free_mbx; | ||
| 472 | } | ||
| 473 | 467 | ||
| 474 | rtnl_unlock(); | 468 | rtnl_unlock(); |
| 469 | if (err) | ||
| 470 | goto err_free_mbx; | ||
| 475 | 471 | ||
| 476 | return 0; | 472 | return 0; |
| 477 | err_free_mbx: | 473 | err_free_mbx: |
| 478 | fbnic_fw_log_disable(fbd); | 474 | fbnic_fw_log_disable(fbd); |
| 479 | 475 | ||
| 480 | rtnl_unlock(); | 476 | devl_lock(priv_to_devlink(fbd)); |
| 481 | fbnic_fw_free_mbx(fbd); | 477 | fbnic_fw_free_mbx(fbd); |
| 478 | devl_unlock(priv_to_devlink(fbd)); | ||
| 482 | err_free_irqs: | 479 | err_free_irqs: |
| 483 | fbnic_free_irqs(fbd); | 480 | fbnic_free_irqs(fbd); |
| 484 | err_invalidate_uc_addr: | 481 | err_invalidate_uc_addr: |
| @@ -49,6 +49,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw, · 48 unmodified lines | |||
| 49 | writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN); | 49 | writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static void dwxgmac2_update_caps(struct stmmac_priv *priv) | ||
| 53 | { | ||
| 54 | if (!priv->dma_cap.mbps_10_100) | ||
| 55 | priv->hw->link.caps &= ~(MAC_10 | MAC_100); | ||
| 56 | else if (!priv->dma_cap.half_duplex) | ||
| 57 | priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD); | ||
| 58 | } | ||
| 59 | |||
| 52 | static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable) | 60 | static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable) |
| 53 | { | 61 | { |
| 54 | u32 tx = readl(ioaddr + XGMAC_TX_CONFIG); | 62 | u32 tx = readl(ioaddr + XGMAC_TX_CONFIG); |
| @@ -1424,6 +1432,7 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en, · 1369 unmodified lines | |||
| 1424 | 1432 | ||
| 1425 | const struct stmmac_ops dwxgmac210_ops = { | 1433 | const struct stmmac_ops dwxgmac210_ops = { |
| 1426 | .core_init = dwxgmac2_core_init, | 1434 | .core_init = dwxgmac2_core_init, |
| 1435 | .update_caps = dwxgmac2_update_caps, | ||
| 1427 | .set_mac = dwxgmac2_set_mac, | 1436 | .set_mac = dwxgmac2_set_mac, |
| 1428 | .rx_ipc = dwxgmac2_rx_ipc, | 1437 | .rx_ipc = dwxgmac2_rx_ipc, |
| 1429 | .rx_queue_enable = dwxgmac2_rx_queue_enable, | 1438 | .rx_queue_enable = dwxgmac2_rx_queue_enable, |
| @@ -1532,8 +1541,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv) · 102 unmodified lines | |||
| 1532 | mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); | 1541 | mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); |
| 1533 | 1542 | ||
| 1534 | mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | | 1543 | mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | |
| 1535 | MAC_1000FD | MAC_2500FD | MAC_5000FD | | 1544 | MAC_10 | MAC_100 | MAC_1000FD | |
| 1536 | MAC_10000FD; | 1545 | MAC_2500FD | MAC_5000FD | MAC_10000FD; |
| 1537 | mac->link.duplex = 0; | 1546 | mac->link.duplex = 0; |
| 1538 | mac->link.speed10 = XGMAC_CONFIG_SS_10_MII; | 1547 | mac->link.speed10 = XGMAC_CONFIG_SS_10_MII; |
| 1539 | mac->link.speed100 = XGMAC_CONFIG_SS_100_MII; | 1548 | mac->link.speed100 = XGMAC_CONFIG_SS_100_MII; |
| @@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr, · 202 unmodified lines | |||
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel)); | 205 | writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel)); |
| 206 | |||
| 207 | /* Enable MTL RX overflow */ | ||
| 208 | value = readl(ioaddr + XGMAC_MTL_QINTEN(channel)); | ||
| 209 | writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel)); | ||
| 210 | } | 206 | } |
| 211 | 207 | ||
| 212 | static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr, | 208 | static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr, |
| @@ -386,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, · 173 unmodified lines | |||
| 386 | static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, | 382 | static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, |
| 387 | struct dma_features *dma_cap) | 383 | struct dma_features *dma_cap) |
| 388 | { | 384 | { |
| 385 | struct stmmac_priv *priv; | ||
| 389 | u32 hw_cap; | 386 | u32 hw_cap; |
| 390 | 387 | ||
| 388 | priv = container_of(dma_cap, struct stmmac_priv, dma_cap); | ||
| 389 | |||
| 391 | /* MAC HW feature 0 */ | 390 | /* MAC HW feature 0 */ |
| 392 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0); | 391 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0); |
| 393 | dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31; | 392 | dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31; |
| @@ -410,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, · 16 unmodified lines | |||
| 410 | dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4; | 409 | dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4; |
| 411 | dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3; | 410 | dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3; |
| 412 | dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1; | 411 | dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1; |
| 412 | if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20) | ||
| 413 | dma_cap->mbps_10_100 = 1; | ||
| 413 | 414 | ||
| 414 | /* MAC HW feature 1 */ | 415 | /* MAC HW feature 1 */ |
| 415 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1); | 416 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1); |
| @@ -2586,6 +2586,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 2585 unmodified lines | |||
| 2586 | struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); | 2586 | struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); |
| 2587 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 2587 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 2588 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; | 2588 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; |
| 2589 | bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported; | ||
| 2589 | struct xsk_buff_pool *pool = tx_q->xsk_pool; | 2590 | struct xsk_buff_pool *pool = tx_q->xsk_pool; |
| 2590 | unsigned int entry = tx_q->cur_tx; | 2591 | unsigned int entry = tx_q->cur_tx; |
| 2591 | struct dma_desc *tx_desc = NULL; | 2592 | struct dma_desc *tx_desc = NULL; |
| @@ -2673,7 +2674,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) · 81 unmodified lines | |||
| 2673 | } | 2674 | } |
| 2674 | 2675 | ||
| 2675 | stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len, | 2676 | stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len, |
| 2676 | true, priv->mode, true, true, | 2677 | csum, priv->mode, true, true, |
| 2677 | xdp_desc.len); | 2678 | xdp_desc.len); |
| 2678 | 2679 | ||
| 2679 | stmmac_enable_dma_transmission(priv, priv->ioaddr, queue); | 2680 | stmmac_enable_dma_transmission(priv, priv->ioaddr, queue); |
| @@ -4988,6 +4989,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, · 2308 unmodified lines | |||
| 4988 | { | 4989 | { |
| 4989 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; | 4990 | struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue]; |
| 4990 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; | 4991 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 4992 | bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported; | ||
| 4991 | unsigned int entry = tx_q->cur_tx; | 4993 | unsigned int entry = tx_q->cur_tx; |
| 4992 | struct dma_desc *tx_desc; | 4994 | struct dma_desc *tx_desc; |
| 4993 | dma_addr_t dma_addr; | 4995 | dma_addr_t dma_addr; |
| @@ -5039,7 +5041,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, · 45 unmodified lines | |||
| 5039 | stmmac_set_desc_addr(priv, tx_desc, dma_addr); | 5041 | stmmac_set_desc_addr(priv, tx_desc, dma_addr); |
| 5040 | 5042 | ||
| 5041 | stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len, | 5043 | stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len, |
| 5042 | true, priv->mode, true, true, | 5044 | csum, priv->mode, true, true, |
| 5043 | xdpf->len); | 5045 | xdpf->len); |
| 5044 | 5046 | ||
| 5045 | tx_q->tx_count_frames++; | 5047 | tx_q->tx_count_frames++; |
| @@ -1812,6 +1812,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device, · 1811 unmodified lines | |||
| 1812 | 1812 | ||
| 1813 | /* Enable NAPI handler before init callbacks */ | 1813 | /* Enable NAPI handler before init callbacks */ |
| 1814 | netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll); | 1814 | netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll); |
| 1815 | napi_enable(&net_device->chan_table[0].napi); | ||
| 1816 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, | ||
| 1817 | &net_device->chan_table[0].napi); | ||
| 1818 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, | ||
| 1819 | &net_device->chan_table[0].napi); | ||
| 1815 | 1820 | ||
| 1816 | /* Open the channel */ | 1821 | /* Open the channel */ |
| 1817 | device->channel->next_request_id_callback = vmbus_next_request_id; | 1822 | device->channel->next_request_id_callback = vmbus_next_request_id; |
| @@ -1831,12 +1836,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device, · 13 unmodified lines | |||
| 1831 | /* Channel is opened */ | 1836 | /* Channel is opened */ |
| 1832 | netdev_dbg(ndev, "hv_netvsc channel opened successfully\n"); | 1837 | netdev_dbg(ndev, "hv_netvsc channel opened successfully\n"); |
| 1833 | 1838 | ||
| 1834 | napi_enable(&net_device->chan_table[0].napi); | ||
| 1835 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, | ||
| 1836 | &net_device->chan_table[0].napi); | ||
| 1837 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, | ||
| 1838 | &net_device->chan_table[0].napi); | ||
| 1839 | |||
| 1840 | /* Connect with the NetVsp */ | 1839 | /* Connect with the NetVsp */ |
| 1841 | ret = netvsc_connect_vsp(device, net_device, device_info); | 1840 | ret = netvsc_connect_vsp(device, net_device, device_info); |
| 1842 | if (ret != 0) { | 1841 | if (ret != 0) { |
| @@ -1854,14 +1853,14 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device, · 11 unmodified lines | |||
| 1854 | 1853 | ||
| 1855 | close: | 1854 | close: |
| 1856 | RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); | 1855 | RCU_INIT_POINTER(net_device_ctx->nvdev, NULL); |
| 1857 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL); | ||
| 1858 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL); | ||
| 1859 | napi_disable(&net_device->chan_table[0].napi); | ||
| 1860 | 1856 | ||
| 1861 | /* Now, we can close the channel safely */ | 1857 | /* Now, we can close the channel safely */ |
| 1862 | vmbus_close(device->channel); | 1858 | vmbus_close(device->channel); |
| 1863 | 1859 | ||
| 1864 | cleanup: | 1860 | cleanup: |
| 1861 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL); | ||
| 1862 | netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL); | ||
| 1863 | napi_disable(&net_device->chan_table[0].napi); | ||
| 1865 | netif_napi_del(&net_device->chan_table[0].napi); | 1864 | netif_napi_del(&net_device->chan_table[0].napi); |
| 1866 | 1865 | ||
| 1867 | cleanup2: | 1866 | cleanup2: |
| @@ -1252,17 +1252,26 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc) · 1251 unmodified lines | |||
| 1252 | new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes); | 1252 | new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes); |
| 1253 | new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE; | 1253 | new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE; |
| 1254 | 1254 | ||
| 1255 | /* Enable napi before opening the vmbus channel to avoid races | ||
| 1256 | * as the host placing data on the host->guest ring may be left | ||
| 1257 | * out if napi was not enabled. | ||
| 1258 | */ | ||
| 1259 | napi_enable(&nvchan->napi); | ||
| 1260 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX, | ||
| 1261 | &nvchan->napi); | ||
| 1262 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX, | ||
| 1263 | &nvchan->napi); | ||
| 1264 | |||
| 1255 | ret = vmbus_open(new_sc, netvsc_ring_bytes, | 1265 | ret = vmbus_open(new_sc, netvsc_ring_bytes, |
| 1256 | netvsc_ring_bytes, NULL, 0, | 1266 | netvsc_ring_bytes, NULL, 0, |
| 1257 | netvsc_channel_cb, nvchan); | 1267 | netvsc_channel_cb, nvchan); |
| 1258 | if (ret == 0) { | 1268 | if (ret != 0) { |
| 1259 | napi_enable(&nvchan->napi); | ||
| 1260 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX, | ||
| 1261 | &nvchan->napi); | ||
| 1262 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX, | ||
| 1263 | &nvchan->napi); | ||
| 1264 | } else { | ||
| 1265 | netdev_notice(ndev, "sub channel open failed: %d\n", ret); | 1269 | netdev_notice(ndev, "sub channel open failed: %d\n", ret); |
| 1270 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX, | ||
| 1271 | NULL); | ||
| 1272 | netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX, | ||
| 1273 | NULL); | ||
| 1274 | napi_disable(&nvchan->napi); | ||
| 1266 | } | 1275 | } |
| 1267 | 1276 | ||
| 1268 | if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn) | 1277 | if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn) |
| @@ -484,6 +484,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev) · 483 unmodified lines | |||
| 484 | void vsc85xx_link_change_notify(struct phy_device *phydev); | 484 | void vsc85xx_link_change_notify(struct phy_device *phydev); |
| 485 | void vsc8584_config_ts_intr(struct phy_device *phydev); | 485 | void vsc8584_config_ts_intr(struct phy_device *phydev); |
| 486 | int vsc8584_ptp_init(struct phy_device *phydev); | 486 | int vsc8584_ptp_init(struct phy_device *phydev); |
| 487 | void vsc8584_ptp_deinit(struct phy_device *phydev); | ||
| 487 | int vsc8584_ptp_probe_once(struct phy_device *phydev); | 488 | int vsc8584_ptp_probe_once(struct phy_device *phydev); |
| 488 | int vsc8584_ptp_probe(struct phy_device *phydev); | 489 | int vsc8584_ptp_probe(struct phy_device *phydev); |
| 489 | irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev); | 490 | irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev); |
| @@ -498,6 +499,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev) · 8 unmodified lines | |||
| 498 | { | 499 | { |
| 499 | return 0; | 500 | return 0; |
| 500 | } | 501 | } |
| 502 | static inline void vsc8584_ptp_deinit(struct phy_device *phydev) | ||
| 503 | { | ||
| 504 | } | ||
| 501 | static inline int vsc8584_ptp_probe_once(struct phy_device *phydev) | 505 | static inline int vsc8584_ptp_probe_once(struct phy_device *phydev) |
| 502 | { | 506 | { |
| 503 | return 0; | 507 | return 0; |
| @@ -2359,9 +2359,7 @@ static int vsc85xx_probe(struct phy_device *phydev) · 2358 unmodified lines | |||
| 2359 | 2359 | ||
| 2360 | static void vsc85xx_remove(struct phy_device *phydev) | 2360 | static void vsc85xx_remove(struct phy_device *phydev) |
| 2361 | { | 2361 | { |
| 2362 | struct vsc8531_private *priv = phydev->priv; | 2362 | vsc8584_ptp_deinit(phydev); |
| 2363 | |||
| 2364 | skb_queue_purge(&priv->rx_skbs_list); | ||
| 2365 | } | 2363 | } |
| 2366 | 2364 | ||
| 2367 | /* Microsemi VSC85xx PHYs */ | 2365 | /* Microsemi VSC85xx PHYs */ |
| @@ -1298,7 +1298,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev) · 1297 unmodified lines | |||
| 1298 | 1298 | ||
| 1299 | static int __vsc8584_init_ptp(struct phy_device *phydev) | 1299 | static int __vsc8584_init_ptp(struct phy_device *phydev) |
| 1300 | { | 1300 | { |
| 1301 | struct vsc8531_private *vsc8531 = phydev->priv; | ||
| 1302 | static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 }; | 1301 | static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 }; |
| 1303 | static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 }; | 1302 | static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 }; |
| 1304 | u32 val; | 1303 | u32 val; |
| @@ -1515,17 +1514,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev) · 210 unmodified lines | |||
| 1515 | 1514 | ||
| 1516 | vsc85xx_ts_eth_cmp1_sig(phydev); | 1515 | vsc85xx_ts_eth_cmp1_sig(phydev); |
| 1517 | 1516 | ||
| 1518 | vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp; | 1517 | return 0; |
| 1519 | vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp; | ||
| 1520 | vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp; | ||
| 1521 | vsc8531->mii_ts.ts_info = vsc85xx_ts_info; | ||
| 1522 | phydev->mii_ts = &vsc8531->mii_ts; | ||
| 1523 | |||
| 1524 | memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps)); | ||
| 1525 | |||
| 1526 | vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps, | ||
| 1527 | &phydev->mdio.dev); | ||
| 1528 | return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock); | ||
| 1529 | } | 1518 | } |
| 1530 | 1519 | ||
| 1531 | void vsc8584_config_ts_intr(struct phy_device *phydev) | 1520 | void vsc8584_config_ts_intr(struct phy_device *phydev) |
| @@ -1552,6 +1541,16 @@ int vsc8584_ptp_init(struct phy_device *phydev) · 20 unmodified lines | |||
| 1552 | return 0; | 1541 | return 0; |
| 1553 | } | 1542 | } |
| 1554 | 1543 | ||
| 1544 | void vsc8584_ptp_deinit(struct phy_device *phydev) | ||
| 1545 | { | ||
| 1546 | struct vsc8531_private *vsc8531 = phydev->priv; | ||
| 1547 | |||
| 1548 | if (vsc8531->ptp->ptp_clock) { | ||
| 1549 | ptp_clock_unregister(vsc8531->ptp->ptp_clock); | ||
| 1550 | skb_queue_purge(&vsc8531->rx_skbs_list); | ||
| 1551 | } | ||
| 1552 | } | ||
| 1553 | |||
| 1555 | irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev) | 1554 | irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev) |
| 1556 | { | 1555 | { |
| 1557 | struct vsc8531_private *priv = phydev->priv; | 1556 | struct vsc8531_private *priv = phydev->priv; |
| @@ -1612,7 +1611,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev) · 54 unmodified lines | |||
| 1612 | 1611 | ||
| 1613 | vsc8531->ptp->phydev = phydev; | 1612 | vsc8531->ptp->phydev = phydev; |
| 1614 | 1613 | ||
| 1615 | return 0; | 1614 | vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp; |
| 1615 | vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp; | ||
| 1616 | vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp; | ||
| 1617 | vsc8531->mii_ts.ts_info = vsc85xx_ts_info; | ||
| 1618 | phydev->mii_ts = &vsc8531->mii_ts; | ||
| 1619 | |||
| 1620 | memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps)); | ||
| 1621 | vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps, | ||
| 1622 | &phydev->mdio.dev); | ||
| 1623 | return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock); | ||
| 1616 | } | 1624 | } |
| 1617 | 1625 | ||
| 1618 | int vsc8584_ptp_probe_once(struct phy_device *phydev) | 1626 | int vsc8584_ptp_probe_once(struct phy_device *phydev) |
| @@ -1355,6 +1355,9 @@ static const struct usb_device_id products[] = { · 1354 unmodified lines | |||
| 1355 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 1355 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 1356 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 1356 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| 1357 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ | 1357 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ |
| 1358 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1034, 2)}, /* Telit LE910C4-WWX */ | ||
| 1359 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1037, 4)}, /* Telit LE910C4-WWX */ | ||
| 1360 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1038, 3)}, /* Telit LE910C4-WWX */ | ||
| 1358 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */ | 1361 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */ |
| 1359 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ | 1362 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ |
| 1360 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ | 1363 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ |
| @@ -5758,14 +5758,15 @@ static void virtnet_freeze_down(struct virtio_device *vdev) · 5757 unmodified lines | |||
| 5758 | disable_rx_mode_work(vi); | 5758 | disable_rx_mode_work(vi); |
| 5759 | flush_work(&vi->rx_mode_work); | 5759 | flush_work(&vi->rx_mode_work); |
| 5760 | 5760 | ||
| 5761 | netif_tx_lock_bh(vi->dev); | ||
| 5762 | netif_device_detach(vi->dev); | ||
| 5763 | netif_tx_unlock_bh(vi->dev); | ||
| 5764 | if (netif_running(vi->dev)) { | 5761 | if (netif_running(vi->dev)) { |
| 5765 | rtnl_lock(); | 5762 | rtnl_lock(); |
| 5766 | virtnet_close(vi->dev); | 5763 | virtnet_close(vi->dev); |
| 5767 | rtnl_unlock(); | 5764 | rtnl_unlock(); |
| 5768 | } | 5765 | } |
| 5766 | |||
| 5767 | netif_tx_lock_bh(vi->dev); | ||
| 5768 | netif_device_detach(vi->dev); | ||
| 5769 | netif_tx_unlock_bh(vi->dev); | ||
| 5769 | } | 5770 | } |
| 5770 | 5771 | ||
| 5771 | static int init_vqs(struct virtnet_info *vi); | 5772 | static int init_vqs(struct virtnet_info *vi); |
| @@ -17,8 +17,8 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | * of_match_device - Tell if a struct device matches an of_device_id list | 19 | * of_match_device - Tell if a struct device matches an of_device_id list |
| 20 | * @matches: array of of device match structures to search in | 20 | * @matches: array of of_device_id match structures to search in |
| 21 | * @dev: the of device structure to match against | 21 | * @dev: the OF device structure to match against |
| 22 | * | 22 | * |
| 23 | * Used by a driver to check whether an platform_device present in the | 23 | * Used by a driver to check whether an platform_device present in the |
| 24 | * system is in its list of supported devices. | 24 | * system is in its list of supported devices. |
| @@ -935,10 +935,15 @@ static int of_changeset_add_prop_helper(struct of_changeset *ocs, · 934 unmodified lines | |||
| 935 | return -ENOMEM; | 935 | return -ENOMEM; |
| 936 | 936 | ||
| 937 | ret = of_changeset_add_property(ocs, np, new_pp); | 937 | ret = of_changeset_add_property(ocs, np, new_pp); |
| 938 | if (ret) | 938 | if (ret) { |
| 939 | __of_prop_free(new_pp); | 939 | __of_prop_free(new_pp); |
| 940 | return ret; | ||
| 941 | } | ||
| 940 | 942 | ||
| 941 | return ret; | 943 | new_pp->next = np->deadprops; |
| 944 | np->deadprops = new_pp; | ||
| 945 | |||
| 946 | return 0; | ||
| 942 | } | 947 | } |
| 943 | 948 | ||
| 944 | /** | 949 | /** |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | #include <linux/memblock.h> | 25 | #include <linux/memblock.h> |
| 26 | #include <linux/kmemleak.h> | 26 | #include <linux/kmemleak.h> |
| 27 | #include <linux/cma.h> | 27 | #include <linux/cma.h> |
| 28 | #include <linux/dma-map-ops.h> | ||
| 28 | 29 | ||
| 29 | #include "of_private.h" | 30 | #include "of_private.h" |
| 30 | 31 | ||
| @@ -175,13 +176,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, · 144 unmodified lines | |||
| 175 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); | 176 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); |
| 176 | size = dt_mem_next_cell(dt_root_size_cells, &prop); | 177 | size = dt_mem_next_cell(dt_root_size_cells, &prop); |
| 177 | 178 | ||
| 178 | if (size && | 179 | if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) { |
| 179 | early_init_dt_reserve_memory(base, size, nomap) == 0) | 180 | /* Architecture specific contiguous memory fixup. */ |
| 181 | if (of_flat_dt_is_compatible(node, "shared-dma-pool") && | ||
| 182 | of_get_flat_dt_prop(node, "reusable", NULL)) | ||
| 183 | dma_contiguous_early_fixup(base, size); | ||
| 180 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", | 184 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", |
| 181 | uname, &base, (unsigned long)(size / SZ_1M)); | 185 | uname, &base, (unsigned long)(size / SZ_1M)); |
| 182 | else | 186 | } else { |
| 183 | pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", | 187 | pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", |
| 184 | uname, &base, (unsigned long)(size / SZ_1M)); | 188 | uname, &base, (unsigned long)(size / SZ_1M)); |
| 189 | } | ||
| 185 | 190 | ||
| 186 | len -= t_len; | 191 | len -= t_len; |
| 187 | } | 192 | } |
| @@ -472,7 +477,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam · 284 unmodified lines | |||
| 472 | uname, (unsigned long)(size / SZ_1M)); | 477 | uname, (unsigned long)(size / SZ_1M)); |
| 473 | return -ENOMEM; | 478 | return -ENOMEM; |
| 474 | } | 479 | } |
| 475 | 480 | /* Architecture specific contiguous memory fixup. */ | |
| 481 | if (of_flat_dt_is_compatible(node, "shared-dma-pool") && | ||
| 482 | of_get_flat_dt_prop(node, "reusable", NULL)) | ||
| 483 | dma_contiguous_early_fixup(base, size); | ||
| 476 | /* Save region in the reserved_mem array */ | 484 | /* Save region in the reserved_mem array */ |
| 477 | fdt_reserved_mem_save_node(node, uname, base, size); | 485 | fdt_reserved_mem_save_node(node, uname, base, size); |
| 478 | return 0; | 486 | return 0; |
| @@ -771,6 +779,7 @@ int of_reserved_mem_region_to_resource(const struct device_node *np, · 292 unmodified lines | |||
| 771 | return -EINVAL; | 779 | return -EINVAL; |
| 772 | 780 | ||
| 773 | resource_set_range(res, rmem->base, rmem->size); | 781 | resource_set_range(res, rmem->base, rmem->size); |
| 782 | res->flags = IORESOURCE_MEM; | ||
| 774 | res->name = rmem->name; | 783 | res->name = rmem->name; |
| 775 | return 0; | 784 | return 0; |
| 776 | } | 785 | } |
| @@ -539,6 +539,7 @@ config PINCTRL_STMFX · 538 unmodified lines | |||
| 539 | tristate "STMicroelectronics STMFX GPIO expander pinctrl driver" | 539 | tristate "STMicroelectronics STMFX GPIO expander pinctrl driver" |
| 540 | depends on I2C | 540 | depends on I2C |
| 541 | depends on OF_GPIO | 541 | depends on OF_GPIO |
| 542 | depends on HAS_IOMEM | ||
| 542 | select GENERIC_PINCONF | 543 | select GENERIC_PINCONF |
| 543 | select GPIOLIB_IRQCHIP | 544 | select GPIOLIB_IRQCHIP |
| 544 | select MFD_STMFX | 545 | select MFD_STMFX |
| @@ -2696,7 +2696,7 @@ static int airoha_pinconf_get(struct pinctrl_dev *pctrl_dev, · 2695 unmodified lines | |||
| 2696 | arg = 1; | 2696 | arg = 1; |
| 2697 | break; | 2697 | break; |
| 2698 | default: | 2698 | default: |
| 2699 | return -EOPNOTSUPP; | 2699 | return -ENOTSUPP; |
| 2700 | } | 2700 | } |
| 2701 | 2701 | ||
| 2702 | *config = pinconf_to_config_packed(param, arg); | 2702 | *config = pinconf_to_config_packed(param, arg); |
| @@ -2788,7 +2788,7 @@ static int airoha_pinconf_set(struct pinctrl_dev *pctrl_dev, · 85 unmodified lines | |||
| 2788 | break; | 2788 | break; |
| 2789 | } | 2789 | } |
| 2790 | default: | 2790 | default: |
| 2791 | return -EOPNOTSUPP; | 2791 | return -ENOTSUPP; |
| 2792 | } | 2792 | } |
| 2793 | } | 2793 | } |
| 2794 | 2794 | ||
| @@ -2805,10 +2805,10 @@ static int airoha_pinconf_group_get(struct pinctrl_dev *pctrl_dev, · 10 unmodified lines | |||
| 2805 | if (airoha_pinconf_get(pctrl_dev, | 2805 | if (airoha_pinconf_get(pctrl_dev, |
| 2806 | airoha_pinctrl_groups[group].pins[i], | 2806 | airoha_pinctrl_groups[group].pins[i], |
| 2807 | config)) | 2807 | config)) |
| 2808 | return -EOPNOTSUPP; | 2808 | return -ENOTSUPP; |
| 2809 | 2809 | ||
| 2810 | if (i && cur_config != *config) | 2810 | if (i && cur_config != *config) |
| 2811 | return -EOPNOTSUPP; | 2811 | return -ENOTSUPP; |
| 2812 | 2812 | ||
| 2813 | cur_config = *config; | 2813 | cur_config = *config; |
| 2814 | } | 2814 | } |
| @@ -1093,7 +1093,7 @@ static const struct of_device_id aml_pctl_of_match[] = { · 1092 unmodified lines | |||
| 1093 | { .compatible = "amlogic,pinctrl-s6", .data = &s6_priv_data, }, | 1093 | { .compatible = "amlogic,pinctrl-s6", .data = &s6_priv_data, }, |
| 1094 | { /* sentinel */ } | 1094 | { /* sentinel */ } |
| 1095 | }; | 1095 | }; |
| 1096 | MODULE_DEVICE_TABLE(of, aml_pctl_dt_match); | 1096 | MODULE_DEVICE_TABLE(of, aml_pctl_of_match); |
| 1097 | 1097 | ||
| 1098 | static struct platform_driver aml_pctl_driver = { | 1098 | static struct platform_driver aml_pctl_driver = { |
| 1099 | .driver = { | 1099 | .driver = { |
| @@ -504,7 +504,7 @@ static int init_acpi(struct device *dev) · 503 unmodified lines | |||
| 504 | 504 | ||
| 505 | dev_set_drvdata(dev, &hsmp_pdev->sock[sock_ind]); | 505 | dev_set_drvdata(dev, &hsmp_pdev->sock[sock_ind]); |
| 506 | 506 | ||
| 507 | return ret; | 507 | return 0; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static const struct bin_attribute hsmp_metric_tbl_attr = { | 510 | static const struct bin_attribute hsmp_metric_tbl_attr = { |
| @@ -356,6 +356,11 @@ ssize_t hsmp_metric_tbl_read(struct hsmp_socket *sock, char *buf, size_t size) · 355 unmodified lines | |||
| 356 | if (!sock || !buf) | 356 | if (!sock || !buf) |
| 357 | return -EINVAL; | 357 | return -EINVAL; |
| 358 | 358 | ||
| 359 | if (!sock->metric_tbl_addr) { | ||
| 360 | dev_err(sock->dev, "Metrics table address not available\n"); | ||
| 361 | return -ENOMEM; | ||
| 362 | } | ||
| 363 | |||
| 359 | /* Do not support lseek(), also don't allow more than the size of metric table */ | 364 | /* Do not support lseek(), also don't allow more than the size of metric table */ |
| 360 | if (size != sizeof(struct hsmp_metric_table)) { | 365 | if (size != sizeof(struct hsmp_metric_table)) { |
| 361 | dev_err(sock->dev, "Wrong buffer size\n"); | 366 | dev_err(sock->dev, "Wrong buffer size\n"); |
| @@ -28,10 +28,15 @@ static struct quirk_entry quirk_spurious_8042 = { · 27 unmodified lines | |||
| 28 | .spurious_8042 = true, | 28 | .spurious_8042 = true, |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | static struct quirk_entry quirk_s2idle_spurious_8042 = { | ||
| 32 | .s2idle_bug_mmio = FCH_PM_BASE + FCH_PM_SCRATCH, | ||
| 33 | .spurious_8042 = true, | ||
| 34 | }; | ||
| 35 | |||
| 31 | static const struct dmi_system_id fwbug_list[] = { | 36 | static const struct dmi_system_id fwbug_list[] = { |
| 32 | { | 37 | { |
| 33 | .ident = "L14 Gen2 AMD", | 38 | .ident = "L14 Gen2 AMD", |
| 34 | .driver_data = &quirk_s2idle_bug, | 39 | .driver_data = &quirk_s2idle_spurious_8042, |
| 35 | .matches = { | 40 | .matches = { |
| 36 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 41 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 37 | DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), | 42 | DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), |
| @@ -39,7 +44,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 39 | }, | 44 | }, |
| 40 | { | 45 | { |
| 41 | .ident = "T14s Gen2 AMD", | 46 | .ident = "T14s Gen2 AMD", |
| 42 | .driver_data = &quirk_s2idle_bug, | 47 | .driver_data = &quirk_s2idle_spurious_8042, |
| 43 | .matches = { | 48 | .matches = { |
| 44 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 49 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 45 | DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), | 50 | DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), |
| @@ -47,7 +52,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 47 | }, | 52 | }, |
| 48 | { | 53 | { |
| 49 | .ident = "X13 Gen2 AMD", | 54 | .ident = "X13 Gen2 AMD", |
| 50 | .driver_data = &quirk_s2idle_bug, | 55 | .driver_data = &quirk_s2idle_spurious_8042, |
| 51 | .matches = { | 56 | .matches = { |
| 52 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 57 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 53 | DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), | 58 | DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), |
| @@ -55,7 +60,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 55 | }, | 60 | }, |
| 56 | { | 61 | { |
| 57 | .ident = "T14 Gen2 AMD", | 62 | .ident = "T14 Gen2 AMD", |
| 58 | .driver_data = &quirk_s2idle_bug, | 63 | .driver_data = &quirk_s2idle_spurious_8042, |
| 59 | .matches = { | 64 | .matches = { |
| 60 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 65 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 61 | DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), | 66 | DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), |
| @@ -63,7 +68,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 63 | }, | 68 | }, |
| 64 | { | 69 | { |
| 65 | .ident = "T14 Gen1 AMD", | 70 | .ident = "T14 Gen1 AMD", |
| 66 | .driver_data = &quirk_s2idle_bug, | 71 | .driver_data = &quirk_s2idle_spurious_8042, |
| 67 | .matches = { | 72 | .matches = { |
| 68 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 73 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 69 | DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), | 74 | DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), |
| @@ -71,7 +76,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 71 | }, | 76 | }, |
| 72 | { | 77 | { |
| 73 | .ident = "T14 Gen1 AMD", | 78 | .ident = "T14 Gen1 AMD", |
| 74 | .driver_data = &quirk_s2idle_bug, | 79 | .driver_data = &quirk_s2idle_spurious_8042, |
| 75 | .matches = { | 80 | .matches = { |
| 76 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 81 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 77 | DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), | 82 | DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), |
| @@ -79,7 +84,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 79 | }, | 84 | }, |
| 80 | { | 85 | { |
| 81 | .ident = "T14s Gen1 AMD", | 86 | .ident = "T14s Gen1 AMD", |
| 82 | .driver_data = &quirk_s2idle_bug, | 87 | .driver_data = &quirk_s2idle_spurious_8042, |
| 83 | .matches = { | 88 | .matches = { |
| 84 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 89 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 85 | DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), | 90 | DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), |
| @@ -87,7 +92,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 87 | }, | 92 | }, |
| 88 | { | 93 | { |
| 89 | .ident = "T14s Gen1 AMD", | 94 | .ident = "T14s Gen1 AMD", |
| 90 | .driver_data = &quirk_s2idle_bug, | 95 | .driver_data = &quirk_s2idle_spurious_8042, |
| 91 | .matches = { | 96 | .matches = { |
| 92 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 97 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 93 | DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"), | 98 | DMI_MATCH(DMI_PRODUCT_NAME, "20UJ"), |
| @@ -95,7 +100,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 95 | }, | 100 | }, |
| 96 | { | 101 | { |
| 97 | .ident = "P14s Gen1 AMD", | 102 | .ident = "P14s Gen1 AMD", |
| 98 | .driver_data = &quirk_s2idle_bug, | 103 | .driver_data = &quirk_s2idle_spurious_8042, |
| 99 | .matches = { | 104 | .matches = { |
| 100 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 105 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 101 | DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), | 106 | DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), |
| @@ -103,7 +108,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 103 | }, | 108 | }, |
| 104 | { | 109 | { |
| 105 | .ident = "P14s Gen2 AMD", | 110 | .ident = "P14s Gen2 AMD", |
| 106 | .driver_data = &quirk_s2idle_bug, | 111 | .driver_data = &quirk_s2idle_spurious_8042, |
| 107 | .matches = { | 112 | .matches = { |
| 108 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 113 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 109 | DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), | 114 | DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), |
| @@ -111,7 +116,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 111 | }, | 116 | }, |
| 112 | { | 117 | { |
| 113 | .ident = "P14s Gen2 AMD", | 118 | .ident = "P14s Gen2 AMD", |
| 114 | .driver_data = &quirk_s2idle_bug, | 119 | .driver_data = &quirk_s2idle_spurious_8042, |
| 115 | .matches = { | 120 | .matches = { |
| 116 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 121 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 117 | DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), | 122 | DMI_MATCH(DMI_PRODUCT_NAME, "21A1"), |
| @@ -152,7 +157,7 @@ static const struct dmi_system_id fwbug_list[] = { · 34 unmodified lines | |||
| 152 | }, | 157 | }, |
| 153 | { | 158 | { |
| 154 | .ident = "IdeaPad 1 14AMN7", | 159 | .ident = "IdeaPad 1 14AMN7", |
| 155 | .driver_data = &quirk_s2idle_bug, | 160 | .driver_data = &quirk_s2idle_spurious_8042, |
| 156 | .matches = { | 161 | .matches = { |
| 157 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 162 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 158 | DMI_MATCH(DMI_PRODUCT_NAME, "82VF"), | 163 | DMI_MATCH(DMI_PRODUCT_NAME, "82VF"), |
| @@ -160,7 +165,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 160 | }, | 165 | }, |
| 161 | { | 166 | { |
| 162 | .ident = "IdeaPad 1 15AMN7", | 167 | .ident = "IdeaPad 1 15AMN7", |
| 163 | .driver_data = &quirk_s2idle_bug, | 168 | .driver_data = &quirk_s2idle_spurious_8042, |
| 164 | .matches = { | 169 | .matches = { |
| 165 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 170 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 166 | DMI_MATCH(DMI_PRODUCT_NAME, "82VG"), | 171 | DMI_MATCH(DMI_PRODUCT_NAME, "82VG"), |
| @@ -168,7 +173,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 168 | }, | 173 | }, |
| 169 | { | 174 | { |
| 170 | .ident = "IdeaPad 1 15AMN7", | 175 | .ident = "IdeaPad 1 15AMN7", |
| 171 | .driver_data = &quirk_s2idle_bug, | 176 | .driver_data = &quirk_s2idle_spurious_8042, |
| 172 | .matches = { | 177 | .matches = { |
| 173 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 178 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 174 | DMI_MATCH(DMI_PRODUCT_NAME, "82X5"), | 179 | DMI_MATCH(DMI_PRODUCT_NAME, "82X5"), |
| @@ -176,7 +181,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 176 | }, | 181 | }, |
| 177 | { | 182 | { |
| 178 | .ident = "IdeaPad Slim 3 14AMN8", | 183 | .ident = "IdeaPad Slim 3 14AMN8", |
| 179 | .driver_data = &quirk_s2idle_bug, | 184 | .driver_data = &quirk_s2idle_spurious_8042, |
| 180 | .matches = { | 185 | .matches = { |
| 181 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 186 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 182 | DMI_MATCH(DMI_PRODUCT_NAME, "82XN"), | 187 | DMI_MATCH(DMI_PRODUCT_NAME, "82XN"), |
| @@ -184,7 +189,7 @@ static const struct dmi_system_id fwbug_list[] = { · 1 unmodified line | |||
| 184 | }, | 189 | }, |
| 185 | { | 190 | { |
| 186 | .ident = "IdeaPad Slim 3 15AMN8", | 191 | .ident = "IdeaPad Slim 3 15AMN8", |
| 187 | .driver_data = &quirk_s2idle_bug, | 192 | .driver_data = &quirk_s2idle_spurious_8042, |
| 188 | .matches = { | 193 | .matches = { |
| 189 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 194 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 190 | DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"), | 195 | DMI_MATCH(DMI_PRODUCT_NAME, "82XQ"), |
| @@ -193,7 +198,7 @@ static const struct dmi_system_id fwbug_list[] = { · 2 unmodified lines | |||
| 193 | /* https://gitlab.freedesktop.org/drm/amd/-/issues/4434 */ | 198 | /* https://gitlab.freedesktop.org/drm/amd/-/issues/4434 */ |
| 194 | { | 199 | { |
| 195 | .ident = "Lenovo Yoga 6 13ALC6", | 200 | .ident = "Lenovo Yoga 6 13ALC6", |
| 196 | .driver_data = &quirk_s2idle_bug, | 201 | .driver_data = &quirk_s2idle_spurious_8042, |
| 197 | .matches = { | 202 | .matches = { |
| 198 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | 203 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), |
| 199 | DMI_MATCH(DMI_PRODUCT_NAME, "82ND"), | 204 | DMI_MATCH(DMI_PRODUCT_NAME, "82ND"), |
| @@ -202,7 +207,7 @@ static const struct dmi_system_id fwbug_list[] = { · 2 unmodified lines | |||
| 202 | /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ | 207 | /* https://gitlab.freedesktop.org/drm/amd/-/issues/2684 */ |
| 203 | { | 208 | { |
| 204 | .ident = "HP Laptop 15s-eq2xxx", | 209 | .ident = "HP Laptop 15s-eq2xxx", |
| 205 | .driver_data = &quirk_s2idle_bug, | 210 | .driver_data = &quirk_s2idle_spurious_8042, |
| 206 | .matches = { | 211 | .matches = { |
| 207 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | 212 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
| 208 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"), | 213 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Laptop 15s-eq2xxx"), |
| @@ -285,6 +290,16 @@ void amd_pmc_quirks_init(struct amd_pmc_dev *dev) · 76 unmodified lines | |||
| 285 | { | 290 | { |
| 286 | const struct dmi_system_id *dmi_id; | 291 | const struct dmi_system_id *dmi_id; |
| 287 | 292 | ||
| 293 | /* | ||
| 294 | * IRQ1 may cause an interrupt during resume even without a keyboard | ||
| 295 | * press. | ||
| 296 | * | ||
| 297 | * Affects Renoir, Cezanne and Barcelo SoCs | ||
| 298 | * | ||
| 299 | * A solution is available in PMFW 64.66.0, but it must be activated by | ||
| 300 | * SBIOS. If SBIOS is known to have the fix a quirk can be added for | ||
| 301 | * a given system to avoid workaround. | ||
| 302 | */ | ||
| 288 | if (dev->cpu_id == AMD_CPU_ID_CZN) | 303 | if (dev->cpu_id == AMD_CPU_ID_CZN) |
| 289 | dev->disable_8042_wakeup = true; | 304 | dev->disable_8042_wakeup = true; |
| 290 | 305 | ||
| @@ -295,6 +310,5 @@ void amd_pmc_quirks_init(struct amd_pmc_dev *dev) · 4 unmodified lines | |||
| 295 | if (dev->quirks->s2idle_bug_mmio) | 310 | if (dev->quirks->s2idle_bug_mmio) |
| 296 | pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", | 311 | pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", |
| 297 | dmi_id->ident); | 312 | dmi_id->ident); |
| 298 | if (dev->quirks->spurious_8042) | 313 | dev->disable_8042_wakeup = dev->quirks->spurious_8042; |
| 299 | dev->disable_8042_wakeup = true; | ||
| 300 | } | 314 | } |
| @@ -530,19 +530,6 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev) · 529 unmodified lines | |||
| 530 | static int amd_pmc_wa_irq1(struct amd_pmc_dev *pdev) | 530 | static int amd_pmc_wa_irq1(struct amd_pmc_dev *pdev) |
| 531 | { | 531 | { |
| 532 | struct device *d; | 532 | struct device *d; |
| 533 | int rc; | ||
| 534 | |||
| 535 | /* cezanne platform firmware has a fix in 64.66.0 */ | ||
| 536 | if (pdev->cpu_id == AMD_CPU_ID_CZN) { | ||
| 537 | if (!pdev->major) { | ||
| 538 | rc = amd_pmc_get_smu_version(pdev); | ||
| 539 | if (rc) | ||
| 540 | return rc; | ||
| 541 | } | ||
| 542 | |||
| 543 | if (pdev->major > 64 || (pdev->major == 64 && pdev->minor > 65)) | ||
| 544 | return 0; | ||
| 545 | } | ||
| 546 | 533 | ||
| 547 | d = bus_find_device_by_name(&serio_bus, NULL, "serio0"); | 534 | d = bus_find_device_by_name(&serio_bus, NULL, "serio0"); |
| 548 | if (!d) | 535 | if (!d) |
| @@ -39,6 +39,7 @@ struct token_sysfs_data { · 38 unmodified lines | |||
| 39 | struct smbios_device { | 39 | struct smbios_device { |
| 40 | struct list_head list; | 40 | struct list_head list; |
| 41 | struct device *device; | 41 | struct device *device; |
| 42 | int priority; | ||
| 42 | int (*call_fn)(struct calling_interface_buffer *arg); | 43 | int (*call_fn)(struct calling_interface_buffer *arg); |
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| @@ -145,7 +146,7 @@ int dell_smbios_error(int value) · 100 unmodified lines | |||
| 145 | } | 146 | } |
| 146 | EXPORT_SYMBOL_GPL(dell_smbios_error); | 147 | EXPORT_SYMBOL_GPL(dell_smbios_error); |
| 147 | 148 | ||
| 148 | int dell_smbios_register_device(struct device *d, void *call_fn) | 149 | int dell_smbios_register_device(struct device *d, int priority, void *call_fn) |
| 149 | { | 150 | { |
| 150 | struct smbios_device *priv; | 151 | struct smbios_device *priv; |
| 151 | 152 | ||
| @@ -154,6 +155,7 @@ int dell_smbios_register_device(struct device *d, void *call_fn) · 2 unmodified lines | |||
| 154 | return -ENOMEM; | 155 | return -ENOMEM; |
| 155 | get_device(d); | 156 | get_device(d); |
| 156 | priv->device = d; | 157 | priv->device = d; |
| 158 | priv->priority = priority; | ||
| 157 | priv->call_fn = call_fn; | 159 | priv->call_fn = call_fn; |
| 158 | mutex_lock(&smbios_mutex); | 160 | mutex_lock(&smbios_mutex); |
| 159 | list_add_tail(&priv->list, &smbios_device_list); | 161 | list_add_tail(&priv->list, &smbios_device_list); |
| @@ -292,28 +294,25 @@ EXPORT_SYMBOL_GPL(dell_smbios_call_filter); · 132 unmodified lines | |||
| 292 | 294 | ||
| 293 | int dell_smbios_call(struct calling_interface_buffer *buffer) | 295 | int dell_smbios_call(struct calling_interface_buffer *buffer) |
| 294 | { | 296 | { |
| 295 | int (*call_fn)(struct calling_interface_buffer *) = NULL; | 297 | struct smbios_device *selected = NULL; |
| 296 | struct device *selected_dev = NULL; | ||
| 297 | struct smbios_device *priv; | 298 | struct smbios_device *priv; |
| 298 | int ret; | 299 | int ret; |
| 299 | 300 | ||
| 300 | mutex_lock(&smbios_mutex); | 301 | mutex_lock(&smbios_mutex); |
| 301 | list_for_each_entry(priv, &smbios_device_list, list) { | 302 | list_for_each_entry(priv, &smbios_device_list, list) { |
| 302 | if (!selected_dev || priv->device->id >= selected_dev->id) { | 303 | if (!selected || priv->priority >= selected->priority) { |
| 303 | dev_dbg(priv->device, "Trying device ID: %d\n", | 304 | dev_dbg(priv->device, "Trying device ID: %d\n", priv->priority); |
| 304 | priv->device->id); | 305 | selected = priv; |
| 305 | call_fn = priv->call_fn; | ||
| 306 | selected_dev = priv->device; | ||
| 307 | } | 306 | } |
| 308 | } | 307 | } |
| 309 | 308 | ||
| 310 | if (!selected_dev) { | 309 | if (!selected) { |
| 311 | ret = -ENODEV; | 310 | ret = -ENODEV; |
| 312 | pr_err("No dell-smbios drivers are loaded\n"); | 311 | pr_err("No dell-smbios drivers are loaded\n"); |
| 313 | goto out_smbios_call; | 312 | goto out_smbios_call; |
| 314 | } | 313 | } |
| 315 | 314 | ||
| 316 | ret = call_fn(buffer); | 315 | ret = selected->call_fn(buffer); |
| 317 | 316 | ||
| 318 | out_smbios_call: | 317 | out_smbios_call: |
| 319 | mutex_unlock(&smbios_mutex); | 318 | mutex_unlock(&smbios_mutex); |
| @@ -125,8 +125,7 @@ int init_dell_smbios_smm(void) · 124 unmodified lines | |||
| 125 | if (ret) | 125 | if (ret) |
| 126 | goto fail_platform_device_add; | 126 | goto fail_platform_device_add; |
| 127 | 127 | ||
| 128 | ret = dell_smbios_register_device(&platform_device->dev, | 128 | ret = dell_smbios_register_device(&platform_device->dev, 0, &dell_smbios_smm_call); |
| 129 | &dell_smbios_smm_call); | ||
| 130 | if (ret) | 129 | if (ret) |
| 131 | goto fail_register; | 130 | goto fail_register; |
| 132 | 131 | ||
| @@ -264,9 +264,7 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context) · 263 unmodified lines | |||
| 264 | if (ret) | 264 | if (ret) |
| 265 | return ret; | 265 | return ret; |
| 266 | 266 | ||
| 267 | /* ID is used by dell-smbios to set priority of drivers */ | 267 | ret = dell_smbios_register_device(&wdev->dev, 1, &dell_smbios_wmi_call); |
| 268 | wdev->dev.id = 1; | ||
| 269 | ret = dell_smbios_register_device(&wdev->dev, &dell_smbios_wmi_call); | ||
| 270 | if (ret) | 268 | if (ret) |
| 271 | return ret; | 269 | return ret; |
| 272 | 270 | ||
| @@ -64,7 +64,7 @@ struct calling_interface_structure { · 63 unmodified lines | |||
| 64 | struct calling_interface_token tokens[]; | 64 | struct calling_interface_token tokens[]; |
| 65 | } __packed; | 65 | } __packed; |
| 66 | 66 | ||
| 67 | int dell_smbios_register_device(struct device *d, void *call_fn); | 67 | int dell_smbios_register_device(struct device *d, int priority, void *call_fn); |
| 68 | void dell_smbios_unregister_device(struct device *d); | 68 | void dell_smbios_unregister_device(struct device *d); |
| 69 | 69 | ||
| 70 | int dell_smbios_error(int value); | 70 | int dell_smbios_error(int value); |
| @@ -92,9 +92,9 @@ static const char * const victus_thermal_profile_boards[] = { · 91 unmodified lines | |||
| 92 | "8A25" | 92 | "8A25" |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | /* DMI Board names of Victus 16-s1000 laptops */ | 95 | /* DMI Board names of Victus 16-r1000 and Victus 16-s1000 laptops */ |
| 96 | static const char * const victus_s_thermal_profile_boards[] = { | 96 | static const char * const victus_s_thermal_profile_boards[] = { |
| 97 | "8C9C" | 97 | "8C99", "8C9C" |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | enum hp_wmi_radio { | 100 | enum hp_wmi_radio { |
| @@ -193,6 +193,10 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3 · 192 unmodified lines | |||
| 193 | *con_id = "privacy-led"; | 193 | *con_id = "privacy-led"; |
| 194 | *gpio_flags = GPIO_ACTIVE_HIGH; | 194 | *gpio_flags = GPIO_ACTIVE_HIGH; |
| 195 | break; | 195 | break; |
| 196 | case INT3472_GPIO_TYPE_HOTPLUG_DETECT: | ||
| 197 | *con_id = "hpd"; | ||
| 198 | *gpio_flags = GPIO_ACTIVE_HIGH; | ||
| 199 | break; | ||
| 196 | case INT3472_GPIO_TYPE_POWER_ENABLE: | 200 | case INT3472_GPIO_TYPE_POWER_ENABLE: |
| 197 | *con_id = "avdd"; | 201 | *con_id = "avdd"; |
| 198 | *gpio_flags = GPIO_ACTIVE_HIGH; | 202 | *gpio_flags = GPIO_ACTIVE_HIGH; |
| @@ -223,6 +227,7 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3 · 24 unmodified lines | |||
| 223 | * 0x0b Power enable | 227 | * 0x0b Power enable |
| 224 | * 0x0c Clock enable | 228 | * 0x0c Clock enable |
| 225 | * 0x0d Privacy LED | 229 | * 0x0d Privacy LED |
| 230 | * 0x13 Hotplug detect | ||
| 226 | * | 231 | * |
| 227 | * There are some known platform specific quirks where that does not quite | 232 | * There are some known platform specific quirks where that does not quite |
| 228 | * hold up; for example where a pin with type 0x01 (Power down) is mapped to | 233 | * hold up; for example where a pin with type 0x01 (Power down) is mapped to |
| @@ -292,6 +297,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, · 63 unmodified lines | |||
| 292 | switch (type) { | 297 | switch (type) { |
| 293 | case INT3472_GPIO_TYPE_RESET: | 298 | case INT3472_GPIO_TYPE_RESET: |
| 294 | case INT3472_GPIO_TYPE_POWERDOWN: | 299 | case INT3472_GPIO_TYPE_POWERDOWN: |
| 300 | case INT3472_GPIO_TYPE_HOTPLUG_DETECT: | ||
| 295 | ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, con_id, gpio_flags); | 301 | ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, con_id, gpio_flags); |
| 296 | if (ret) | 302 | if (ret) |
| 297 | err_msg = "Failed to map GPIO pin to sensor\n"; | 303 | err_msg = "Failed to map GPIO pin to sensor\n"; |
| @@ -192,9 +192,14 @@ static int uncore_read_control_freq(struct uncore_data *data, unsigned int *valu · 191 unmodified lines | |||
| 192 | static int write_eff_lat_ctrl(struct uncore_data *data, unsigned int val, enum uncore_index index) | 192 | static int write_eff_lat_ctrl(struct uncore_data *data, unsigned int val, enum uncore_index index) |
| 193 | { | 193 | { |
| 194 | struct tpmi_uncore_cluster_info *cluster_info; | 194 | struct tpmi_uncore_cluster_info *cluster_info; |
| 195 | struct tpmi_uncore_struct *uncore_root; | ||
| 195 | u64 control; | 196 | u64 control; |
| 196 | 197 | ||
| 197 | cluster_info = container_of(data, struct tpmi_uncore_cluster_info, uncore_data); | 198 | cluster_info = container_of(data, struct tpmi_uncore_cluster_info, uncore_data); |
| 199 | uncore_root = cluster_info->uncore_root; | ||
| 200 | |||
| 201 | if (uncore_root->write_blocked) | ||
| 202 | return -EPERM; | ||
| 198 | 203 | ||
| 199 | if (cluster_info->root_domain) | 204 | if (cluster_info->root_domain) |
| 200 | return -ENODATA; | 205 | return -ENODATA; |
| @@ -40,7 +40,6 @@ struct pca9450 { · 39 unmodified lines | |||
| 40 | struct device *dev; | 40 | struct device *dev; |
| 41 | struct regmap *regmap; | 41 | struct regmap *regmap; |
| 42 | struct gpio_desc *sd_vsel_gpio; | 42 | struct gpio_desc *sd_vsel_gpio; |
| 43 | struct notifier_block restart_nb; | ||
| 44 | enum pca9450_chip_type type; | 43 | enum pca9450_chip_type type; |
| 45 | unsigned int rcnt; | 44 | unsigned int rcnt; |
| 46 | int irq; | 45 | int irq; |
| @@ -1100,10 +1099,9 @@ static irqreturn_t pca9450_irq_handler(int irq, void *data) · 1053 unmodified lines | |||
| 1100 | return IRQ_HANDLED; | 1099 | return IRQ_HANDLED; |
| 1101 | } | 1100 | } |
| 1102 | 1101 | ||
| 1103 | static int pca9450_i2c_restart_handler(struct notifier_block *nb, | 1102 | static int pca9450_i2c_restart_handler(struct sys_off_data *data) |
| 1104 | unsigned long action, void *data) | ||
| 1105 | { | 1103 | { |
| 1106 | struct pca9450 *pca9450 = container_of(nb, struct pca9450, restart_nb); | 1104 | struct pca9450 *pca9450 = data->cb_data; |
| 1107 | struct i2c_client *i2c = container_of(pca9450->dev, struct i2c_client, dev); | 1105 | struct i2c_client *i2c = container_of(pca9450->dev, struct i2c_client, dev); |
| 1108 | 1106 | ||
| 1109 | dev_dbg(&i2c->dev, "Restarting device..\n"); | 1107 | dev_dbg(&i2c->dev, "Restarting device..\n"); |
| @@ -1261,10 +1259,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) · 151 unmodified lines | |||
| 1261 | pca9450->sd_vsel_fixed_low = | 1259 | pca9450->sd_vsel_fixed_low = |
| 1262 | of_property_read_bool(ldo5->dev.of_node, "nxp,sd-vsel-fixed-low"); | 1260 | of_property_read_bool(ldo5->dev.of_node, "nxp,sd-vsel-fixed-low"); |
| 1263 | 1261 | ||
| 1264 | pca9450->restart_nb.notifier_call = pca9450_i2c_restart_handler; | 1262 | if (devm_register_sys_off_handler(&i2c->dev, SYS_OFF_MODE_RESTART, |
| 1265 | pca9450->restart_nb.priority = PCA9450_RESTART_HANDLER_PRIORITY; | 1263 | PCA9450_RESTART_HANDLER_PRIORITY, |
| 1266 | 1264 | pca9450_i2c_restart_handler, pca9450)) | |
| 1267 | if (register_restart_handler(&pca9450->restart_nb)) | ||
| 1268 | dev_warn(&i2c->dev, "Failed to register restart handler\n"); | 1265 | dev_warn(&i2c->dev, "Failed to register restart handler\n"); |
| 1269 | 1266 | ||
| 1270 | dev_info(&i2c->dev, "%s probed.\n", | 1267 | dev_info(&i2c->dev, "%s probed.\n", |
| @@ -454,9 +454,9 @@ static int tps65219_regulator_probe(struct platform_device *pdev) · 453 unmodified lines | |||
| 454 | irq_type->irq_name, | 454 | irq_type->irq_name, |
| 455 | irq_data); | 455 | irq_data); |
| 456 | if (error) | 456 | if (error) |
| 457 | return dev_err_probe(tps->dev, PTR_ERR(rdev), | 457 | return dev_err_probe(tps->dev, error, |
| 458 | "Failed to request %s IRQ %d: %d\n", | 458 | "Failed to request %s IRQ %d\n", |
| 459 | irq_type->irq_name, irq, error); | 459 | irq_type->irq_name, irq); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | for (i = 0; i < pmic->dev_irq_size; ++i) { | 462 | for (i = 0; i < pmic->dev_irq_size; ++i) { |
| @@ -477,9 +477,9 @@ static int tps65219_regulator_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 477 | irq_type->irq_name, | 477 | irq_type->irq_name, |
| 478 | irq_data); | 478 | irq_data); |
| 479 | if (error) | 479 | if (error) |
| 480 | return dev_err_probe(tps->dev, PTR_ERR(rdev), | 480 | return dev_err_probe(tps->dev, error, |
| 481 | "Failed to request %s IRQ %d: %d\n", | 481 | "Failed to request %s IRQ %d\n", |
| 482 | irq_type->irq_name, irq, error); | 482 | irq_type->irq_name, irq); |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | return 0; | 485 | return 0; |
| @@ -77,6 +77,13 @@ unsigned long sclp_console_full; · 76 unmodified lines | |||
| 77 | /* The currently active SCLP command word. */ | 77 | /* The currently active SCLP command word. */ |
| 78 | static sclp_cmdw_t active_cmd; | 78 | static sclp_cmdw_t active_cmd; |
| 79 | 79 | ||
| 80 | static inline struct sccb_header *sclpint_to_sccb(u32 sccb_int) | ||
| 81 | { | ||
| 82 | if (sccb_int) | ||
| 83 | return __va(sccb_int); | ||
| 84 | return NULL; | ||
| 85 | } | ||
| 86 | |||
| 80 | static inline void sclp_trace(int prio, char *id, u32 a, u64 b, bool err) | 87 | static inline void sclp_trace(int prio, char *id, u32 a, u64 b, bool err) |
| 81 | { | 88 | { |
| 82 | struct sclp_trace_entry e; | 89 | struct sclp_trace_entry e; |
| @@ -620,7 +627,7 @@ __sclp_find_req(u32 sccb) · 537 unmodified lines | |||
| 620 | 627 | ||
| 621 | static bool ok_response(u32 sccb_int, sclp_cmdw_t cmd) | 628 | static bool ok_response(u32 sccb_int, sclp_cmdw_t cmd) |
| 622 | { | 629 | { |
| 623 | struct sccb_header *sccb = (struct sccb_header *)__va(sccb_int); | 630 | struct sccb_header *sccb = sclpint_to_sccb(sccb_int); |
| 624 | struct evbuf_header *evbuf; | 631 | struct evbuf_header *evbuf; |
| 625 | u16 response; | 632 | u16 response; |
| 626 | 633 | ||
| @@ -659,7 +666,7 @@ static void sclp_interrupt_handler(struct ext_code ext_code, · 32 unmodified lines | |||
| 659 | 666 | ||
| 660 | /* INT: Interrupt received (a=intparm, b=cmd) */ | 667 | /* INT: Interrupt received (a=intparm, b=cmd) */ |
| 661 | sclp_trace_sccb(0, "INT", param32, active_cmd, active_cmd, | 668 | sclp_trace_sccb(0, "INT", param32, active_cmd, active_cmd, |
| 662 | (struct sccb_header *)__va(finished_sccb), | 669 | sclpint_to_sccb(finished_sccb), |
| 663 | !ok_response(finished_sccb, active_cmd)); | 670 | !ok_response(finished_sccb, active_cmd)); |
| 664 | 671 | ||
| 665 | if (finished_sccb) { | 672 | if (finished_sccb) { |
| @@ -323,8 +323,6 @@ enum fnic_state { · 322 unmodified lines | |||
| 323 | FNIC_IN_ETH_TRANS_FC_MODE, | 323 | FNIC_IN_ETH_TRANS_FC_MODE, |
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | struct mempool; | ||
| 327 | |||
| 328 | enum fnic_role_e { | 326 | enum fnic_role_e { |
| 329 | FNIC_ROLE_FCP_INITIATOR = 0, | 327 | FNIC_ROLE_FCP_INITIATOR = 0, |
| 330 | }; | 328 | }; |
| @@ -6606,6 +6606,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, · 6605 unmodified lines | |||
| 6606 | 6606 | ||
| 6607 | ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0); | 6607 | ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0); |
| 6608 | vfree(dst_addr); | 6608 | vfree(dst_addr); |
| 6609 | if (IS_ERR(ep)) | ||
| 6610 | return NULL; | ||
| 6609 | return ep; | 6611 | return ep; |
| 6610 | } | 6612 | } |
| 6611 | 6613 | ||
| @@ -330,13 +330,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) · 329 unmodified lines | |||
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | if (config.speed_hz > perclk_rate / 2) { | 332 | if (config.speed_hz > perclk_rate / 2) { |
| 333 | dev_err(fsl_lpspi->dev, | 333 | div = 2; |
| 334 | "per-clk should be at least two times of transfer speed"); | 334 | } else { |
| 335 | return -EINVAL; | 335 | div = DIV_ROUND_UP(perclk_rate, config.speed_hz); |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | div = DIV_ROUND_UP(perclk_rate, config.speed_hz); | ||
| 339 | |||
| 340 | for (prescale = 0; prescale <= prescale_max; prescale++) { | 338 | for (prescale = 0; prescale <= prescale_max; prescale++) { |
| 341 | scldiv = div / (1 << prescale) - 2; | 339 | scldiv = div / (1 << prescale) - 2; |
| 342 | if (scldiv >= 0 && scldiv < 256) { | 340 | if (scldiv >= 0 && scldiv < 256) { |
| @@ -265,6 +265,9 @@ static bool spi_mem_internal_supports_op(struct spi_mem *mem, · 264 unmodified lines | |||
| 265 | */ | 265 | */ |
| 266 | bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) | 266 | bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) |
| 267 | { | 267 | { |
| 268 | /* Make sure the operation frequency is correct before going futher */ | ||
| 269 | spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op); | ||
| 270 | |||
| 268 | if (spi_mem_check_op(op)) | 271 | if (spi_mem_check_op(op)) |
| 269 | return false; | 272 | return false; |
| 270 | 273 | ||
| @@ -577,6 +580,7 @@ EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq); · 306 unmodified lines | |||
| 577 | * spi_mem_calc_op_duration() - Derives the theoretical length (in ns) of an | 580 | * spi_mem_calc_op_duration() - Derives the theoretical length (in ns) of an |
| 578 | * operation. This helps finding the best variant | 581 | * operation. This helps finding the best variant |
| 579 | * among a list of possible choices. | 582 | * among a list of possible choices. |
| 583 | * @mem: the SPI memory | ||
| 580 | * @op: the operation to benchmark | 584 | * @op: the operation to benchmark |
| 581 | * | 585 | * |
| 582 | * Some chips have per-op frequency limitations, PCBs usually have their own | 586 | * Some chips have per-op frequency limitations, PCBs usually have their own |
| @@ -210,13 +210,21 @@ static int qcom_spi_ooblayout_ecc(struct mtd_info *mtd, int section, · 209 unmodified lines | |||
| 210 | struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); | 210 | struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); |
| 211 | struct qpic_ecc *qecc = snandc->qspi->ecc; | 211 | struct qpic_ecc *qecc = snandc->qspi->ecc; |
| 212 | 212 | ||
| 213 | if (section > 1) | 213 | switch (section) { |
| 214 | return -ERANGE; | 214 | case 0: |
| 215 | 215 | oobregion->offset = 0; | |
| 216 | oobregion->length = qecc->ecc_bytes_hw + qecc->spare_bytes; | 216 | oobregion->length = qecc->bytes * (qecc->steps - 1) + |
| 217 | oobregion->offset = mtd->oobsize - oobregion->length; | 217 | qecc->bbm_size; |
| 218 | return 0; | ||
| 219 | case 1: | ||
| 220 | oobregion->offset = qecc->bytes * (qecc->steps - 1) + | ||
| 221 | qecc->bbm_size + | ||
| 222 | qecc->steps * 4; | ||
| 223 | oobregion->length = mtd->oobsize - oobregion->offset; | ||
| 224 | return 0; | ||
| 225 | } | ||
| 218 | 226 | ||
| 219 | return 0; | 227 | return -ERANGE; |
| 220 | } | 228 | } |
| 221 | 229 | ||
| 222 | static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section, | 230 | static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section, |
| @@ -1196,7 +1204,7 @@ static int qcom_spi_program_oob(struct qcom_nand_controller *snandc, · 973 unmodified lines | |||
| 1196 | u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; | 1204 | u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; |
| 1197 | 1205 | ||
| 1198 | cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) | | 1206 | cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) | |
| 1199 | FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1); | 1207 | FIELD_PREP(CW_PER_PAGE_MASK, 0); |
| 1200 | cfg1 = ecc_cfg->cfg1; | 1208 | cfg1 = ecc_cfg->cfg1; |
| 1201 | ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; | 1209 | ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; |
| 1202 | ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; | 1210 | ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; |
| @@ -378,7 +378,7 @@ static void spi_st_remove(struct platform_device *pdev) · 377 unmodified lines | |||
| 378 | pinctrl_pm_select_sleep_state(&pdev->dev); | 378 | pinctrl_pm_select_sleep_state(&pdev->dev); |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static int __maybe_unused spi_st_runtime_suspend(struct device *dev) | 381 | static int spi_st_runtime_suspend(struct device *dev) |
| 382 | { | 382 | { |
| 383 | struct spi_controller *host = dev_get_drvdata(dev); | 383 | struct spi_controller *host = dev_get_drvdata(dev); |
| 384 | struct spi_st *spi_st = spi_controller_get_devdata(host); | 384 | struct spi_st *spi_st = spi_controller_get_devdata(host); |
| @@ -391,7 +391,7 @@ static int __maybe_unused spi_st_runtime_suspend(struct device *dev) · 6 unmodified lines | |||
| 391 | return 0; | 391 | return 0; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | static int __maybe_unused spi_st_runtime_resume(struct device *dev) | 394 | static int spi_st_runtime_resume(struct device *dev) |
| 395 | { | 395 | { |
| 396 | struct spi_controller *host = dev_get_drvdata(dev); | 396 | struct spi_controller *host = dev_get_drvdata(dev); |
| 397 | struct spi_st *spi_st = spi_controller_get_devdata(host); | 397 | struct spi_st *spi_st = spi_controller_get_devdata(host); |
| @@ -428,8 +428,8 @@ static int __maybe_unused spi_st_resume(struct device *dev) · 30 unmodified lines | |||
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | static const struct dev_pm_ops spi_st_pm = { | 430 | static const struct dev_pm_ops spi_st_pm = { |
| 431 | SET_SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume) | 431 | SYSTEM_SLEEP_PM_OPS(spi_st_suspend, spi_st_resume) |
| 432 | SET_RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL) | 432 | RUNTIME_PM_OPS(spi_st_runtime_suspend, spi_st_runtime_resume, NULL) |
| 433 | }; | 433 | }; |
| 434 | 434 | ||
| 435 | static const struct of_device_id stm_spi_match[] = { | 435 | static const struct of_device_id stm_spi_match[] = { |
| @@ -441,7 +441,7 @@ MODULE_DEVICE_TABLE(of, stm_spi_match); · 5 unmodified lines | |||
| 441 | static struct platform_driver spi_st_driver = { | 441 | static struct platform_driver spi_st_driver = { |
| 442 | .driver = { | 442 | .driver = { |
| 443 | .name = "spi-st", | 443 | .name = "spi-st", |
| 444 | .pm = pm_sleep_ptr(&spi_st_pm), | 444 | .pm = pm_ptr(&spi_st_pm), |
| 445 | .of_match_table = of_match_ptr(stm_spi_match), | 445 | .of_match_table = of_match_ptr(stm_spi_match), |
| 446 | }, | 446 | }, |
| 447 | .probe = spi_st_probe, | 447 | .probe = spi_st_probe, |
| @@ -1303,7 +1303,7 @@ static u32 ufshcd_pending_cmds(struct ufs_hba *hba) · 1302 unmodified lines | |||
| 1303 | * | 1303 | * |
| 1304 | * Return: 0 upon success; -EBUSY upon timeout. | 1304 | * Return: 0 upon success; -EBUSY upon timeout. |
| 1305 | */ | 1305 | */ |
| 1306 | static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba, | 1306 | static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba, |
| 1307 | u64 wait_timeout_us) | 1307 | u64 wait_timeout_us) |
| 1308 | { | 1308 | { |
| 1309 | int ret = 0; | 1309 | int ret = 0; |
| @@ -1431,7 +1431,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) · 121 unmodified lines | |||
| 1431 | down_write(&hba->clk_scaling_lock); | 1431 | down_write(&hba->clk_scaling_lock); |
| 1432 | 1432 | ||
| 1433 | if (!hba->clk_scaling.is_allowed || | 1433 | if (!hba->clk_scaling.is_allowed || |
| 1434 | ufshcd_wait_for_doorbell_clr(hba, timeout_us)) { | 1434 | ufshcd_wait_for_pending_cmds(hba, timeout_us)) { |
| 1435 | ret = -EBUSY; | 1435 | ret = -EBUSY; |
| 1436 | up_write(&hba->clk_scaling_lock); | 1436 | up_write(&hba->clk_scaling_lock); |
| 1437 | mutex_unlock(&hba->wb_mutex); | 1437 | mutex_unlock(&hba->wb_mutex); |
| @@ -3199,7 +3199,8 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) · 1761 unmodified lines | |||
| 3199 | } | 3199 | } |
| 3200 | 3200 | ||
| 3201 | /* | 3201 | /* |
| 3202 | * Return: 0 upon success; < 0 upon failure. | 3202 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3203 | * < 0 if another error occurred. | ||
| 3203 | */ | 3204 | */ |
| 3204 | static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, | 3205 | static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, |
| 3205 | struct ufshcd_lrb *lrbp, int max_timeout) | 3206 | struct ufshcd_lrb *lrbp, int max_timeout) |
| @@ -3275,7 +3276,6 @@ retry: · 69 unmodified lines | |||
| 3275 | } | 3276 | } |
| 3276 | } | 3277 | } |
| 3277 | 3278 | ||
| 3278 | WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err); | ||
| 3279 | return err; | 3279 | return err; |
| 3280 | } | 3280 | } |
| 3281 | 3281 | ||
| @@ -3294,7 +3294,8 @@ static void ufshcd_dev_man_unlock(struct ufs_hba *hba) · 12 unmodified lines | |||
| 3294 | } | 3294 | } |
| 3295 | 3295 | ||
| 3296 | /* | 3296 | /* |
| 3297 | * Return: 0 upon success; < 0 upon failure. | 3297 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3298 | * < 0 if another error occurred. | ||
| 3298 | */ | 3299 | */ |
| 3299 | static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, | 3300 | static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, |
| 3300 | const u32 tag, int timeout) | 3301 | const u32 tag, int timeout) |
| @@ -3317,7 +3318,8 @@ static int ufshcd_issue_dev_cmd(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 16 unmodified lines | |||
| 3317 | * @cmd_type: specifies the type (NOP, Query...) | 3318 | * @cmd_type: specifies the type (NOP, Query...) |
| 3318 | * @timeout: timeout in milliseconds | 3319 | * @timeout: timeout in milliseconds |
| 3319 | * | 3320 | * |
| 3320 | * Return: 0 upon success; < 0 upon failure. | 3321 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3322 | * < 0 if another error occurred. | ||
| 3321 | * | 3323 | * |
| 3322 | * NOTE: Since there is only one available tag for device management commands, | 3324 | * NOTE: Since there is only one available tag for device management commands, |
| 3323 | * it is expected you hold the hba->dev_cmd.lock mutex. | 3325 | * it is expected you hold the hba->dev_cmd.lock mutex. |
| @@ -3363,6 +3365,10 @@ static inline void ufshcd_init_query(struct ufs_hba *hba, · 39 unmodified lines | |||
| 3363 | (*request)->upiu_req.selector = selector; | 3365 | (*request)->upiu_req.selector = selector; |
| 3364 | } | 3366 | } |
| 3365 | 3367 | ||
| 3368 | /* | ||
| 3369 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; | ||
| 3370 | * < 0 if another error occurred. | ||
| 3371 | */ | ||
| 3366 | static int ufshcd_query_flag_retry(struct ufs_hba *hba, | 3372 | static int ufshcd_query_flag_retry(struct ufs_hba *hba, |
| 3367 | enum query_opcode opcode, enum flag_idn idn, u8 index, bool *flag_res) | 3373 | enum query_opcode opcode, enum flag_idn idn, u8 index, bool *flag_res) |
| 3368 | { | 3374 | { |
| @@ -3383,7 +3389,6 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba, · 14 unmodified lines | |||
| 3383 | dev_err(hba->dev, | 3389 | dev_err(hba->dev, |
| 3384 | "%s: query flag, opcode %d, idn %d, failed with error %d after %d retries\n", | 3390 | "%s: query flag, opcode %d, idn %d, failed with error %d after %d retries\n", |
| 3385 | __func__, opcode, idn, ret, retries); | 3391 | __func__, opcode, idn, ret, retries); |
| 3386 | WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret); | ||
| 3387 | return ret; | 3392 | return ret; |
| 3388 | } | 3393 | } |
| 3389 | 3394 | ||
| @@ -3395,7 +3400,8 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba, · 5 unmodified lines | |||
| 3395 | * @index: flag index to access | 3400 | * @index: flag index to access |
| 3396 | * @flag_res: the flag value after the query request completes | 3401 | * @flag_res: the flag value after the query request completes |
| 3397 | * | 3402 | * |
| 3398 | * Return: 0 for success; < 0 upon failure. | 3403 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3404 | * < 0 if another error occurred. | ||
| 3399 | */ | 3405 | */ |
| 3400 | int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, | 3406 | int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, |
| 3401 | enum flag_idn idn, u8 index, bool *flag_res) | 3407 | enum flag_idn idn, u8 index, bool *flag_res) |
| @@ -3451,7 +3457,6 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, · 49 unmodified lines | |||
| 3451 | 3457 | ||
| 3452 | out_unlock: | 3458 | out_unlock: |
| 3453 | ufshcd_dev_man_unlock(hba); | 3459 | ufshcd_dev_man_unlock(hba); |
| 3454 | WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err); | ||
| 3455 | return err; | 3460 | return err; |
| 3456 | } | 3461 | } |
| 3457 | 3462 | ||
| @@ -3464,8 +3469,9 @@ out_unlock: · 6 unmodified lines | |||
| 3464 | * @selector: selector field | 3469 | * @selector: selector field |
| 3465 | * @attr_val: the attribute value after the query request completes | 3470 | * @attr_val: the attribute value after the query request completes |
| 3466 | * | 3471 | * |
| 3467 | * Return: 0 upon success; < 0 upon failure. | 3472 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3468 | */ | 3473 | * < 0 if another error occurred. |
| 3474 | */ | ||
| 3469 | int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, | 3475 | int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, |
| 3470 | enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) | 3476 | enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) |
| 3471 | { | 3477 | { |
| @@ -3513,7 +3519,6 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, · 41 unmodified lines | |||
| 3513 | 3519 | ||
| 3514 | out_unlock: | 3520 | out_unlock: |
| 3515 | ufshcd_dev_man_unlock(hba); | 3521 | ufshcd_dev_man_unlock(hba); |
| 3516 | WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err); | ||
| 3517 | return err; | 3522 | return err; |
| 3518 | } | 3523 | } |
| 3519 | 3524 | ||
| @@ -3528,8 +3533,9 @@ out_unlock: · 8 unmodified lines | |||
| 3528 | * @attr_val: the attribute value after the query request | 3533 | * @attr_val: the attribute value after the query request |
| 3529 | * completes | 3534 | * completes |
| 3530 | * | 3535 | * |
| 3531 | * Return: 0 for success; < 0 upon failure. | 3536 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3532 | */ | 3537 | * < 0 if another error occurred. |
| 3538 | */ | ||
| 3533 | int ufshcd_query_attr_retry(struct ufs_hba *hba, | 3539 | int ufshcd_query_attr_retry(struct ufs_hba *hba, |
| 3534 | enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector, | 3540 | enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector, |
| 3535 | u32 *attr_val) | 3541 | u32 *attr_val) |
| @@ -3551,12 +3557,12 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba, · 15 unmodified lines | |||
| 3551 | dev_err(hba->dev, | 3557 | dev_err(hba->dev, |
| 3552 | "%s: query attribute, idn %d, failed with error %d after %d retries\n", | 3558 | "%s: query attribute, idn %d, failed with error %d after %d retries\n", |
| 3553 | __func__, idn, ret, QUERY_REQ_RETRIES); | 3559 | __func__, idn, ret, QUERY_REQ_RETRIES); |
| 3554 | WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret); | ||
| 3555 | return ret; | 3560 | return ret; |
| 3556 | } | 3561 | } |
| 3557 | 3562 | ||
| 3558 | /* | 3563 | /* |
| 3559 | * Return: 0 if successful; < 0 upon failure. | 3564 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3565 | * < 0 if another error occurred. | ||
| 3560 | */ | 3566 | */ |
| 3561 | static int __ufshcd_query_descriptor(struct ufs_hba *hba, | 3567 | static int __ufshcd_query_descriptor(struct ufs_hba *hba, |
| 3562 | enum query_opcode opcode, enum desc_idn idn, u8 index, | 3568 | enum query_opcode opcode, enum desc_idn idn, u8 index, |
| @@ -3615,7 +3621,6 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba, · 52 unmodified lines | |||
| 3615 | out_unlock: | 3621 | out_unlock: |
| 3616 | hba->dev_cmd.query.descriptor = NULL; | 3622 | hba->dev_cmd.query.descriptor = NULL; |
| 3617 | ufshcd_dev_man_unlock(hba); | 3623 | ufshcd_dev_man_unlock(hba); |
| 3618 | WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err); | ||
| 3619 | return err; | 3624 | return err; |
| 3620 | } | 3625 | } |
| 3621 | 3626 | ||
| @@ -3632,7 +3637,8 @@ out_unlock: · 10 unmodified lines | |||
| 3632 | * The buf_len parameter will contain, on return, the length parameter | 3637 | * The buf_len parameter will contain, on return, the length parameter |
| 3633 | * received on the response. | 3638 | * received on the response. |
| 3634 | * | 3639 | * |
| 3635 | * Return: 0 for success; < 0 upon failure. | 3640 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3641 | * < 0 if another error occurred. | ||
| 3636 | */ | 3642 | */ |
| 3637 | int ufshcd_query_descriptor_retry(struct ufs_hba *hba, | 3643 | int ufshcd_query_descriptor_retry(struct ufs_hba *hba, |
| 3638 | enum query_opcode opcode, | 3644 | enum query_opcode opcode, |
| @@ -3650,7 +3656,6 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, · 11 unmodified lines | |||
| 3650 | break; | 3656 | break; |
| 3651 | } | 3657 | } |
| 3652 | 3658 | ||
| 3653 | WARN_ONCE(err > 0, "Incorrect return value %d > 0\n", err); | ||
| 3654 | return err; | 3659 | return err; |
| 3655 | } | 3660 | } |
| 3656 | 3661 | ||
| @@ -3663,7 +3668,8 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, · 6 unmodified lines | |||
| 3663 | * @param_read_buf: pointer to buffer where parameter would be read | 3668 | * @param_read_buf: pointer to buffer where parameter would be read |
| 3664 | * @param_size: sizeof(param_read_buf) | 3669 | * @param_size: sizeof(param_read_buf) |
| 3665 | * | 3670 | * |
| 3666 | * Return: 0 in case of success; < 0 upon failure. | 3671 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 3672 | * < 0 if another error occurred. | ||
| 3667 | */ | 3673 | */ |
| 3668 | int ufshcd_read_desc_param(struct ufs_hba *hba, | 3674 | int ufshcd_read_desc_param(struct ufs_hba *hba, |
| 3669 | enum desc_idn desc_id, | 3675 | enum desc_idn desc_id, |
| @@ -3730,7 +3736,6 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, · 60 unmodified lines | |||
| 3730 | out: | 3736 | out: |
| 3731 | if (is_kmalloc) | 3737 | if (is_kmalloc) |
| 3732 | kfree(desc_buf); | 3738 | kfree(desc_buf); |
| 3733 | WARN_ONCE(ret > 0, "Incorrect return value %d > 0\n", ret); | ||
| 3734 | return ret; | 3739 | return ret; |
| 3735 | } | 3740 | } |
| 3736 | 3741 | ||
| @@ -4781,7 +4786,8 @@ EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode); · 1044 unmodified lines | |||
| 4781 | * | 4786 | * |
| 4782 | * Set fDeviceInit flag and poll until device toggles it. | 4787 | * Set fDeviceInit flag and poll until device toggles it. |
| 4783 | * | 4788 | * |
| 4784 | * Return: 0 upon success; < 0 upon failure. | 4789 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 4790 | * < 0 if another error occurred. | ||
| 4785 | */ | 4791 | */ |
| 4786 | static int ufshcd_complete_dev_init(struct ufs_hba *hba) | 4792 | static int ufshcd_complete_dev_init(struct ufs_hba *hba) |
| 4787 | { | 4793 | { |
| @@ -5135,7 +5141,8 @@ out: · 347 unmodified lines | |||
| 5135 | * not respond with NOP IN UPIU within timeout of %NOP_OUT_TIMEOUT | 5141 | * not respond with NOP IN UPIU within timeout of %NOP_OUT_TIMEOUT |
| 5136 | * and we retry sending NOP OUT for %NOP_OUT_RETRIES iterations. | 5142 | * and we retry sending NOP OUT for %NOP_OUT_RETRIES iterations. |
| 5137 | * | 5143 | * |
| 5138 | * Return: 0 upon success; < 0 upon failure. | 5144 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 5145 | * < 0 if another error occurred. | ||
| 5139 | */ | 5146 | */ |
| 5140 | static int ufshcd_verify_dev_init(struct ufs_hba *hba) | 5147 | static int ufshcd_verify_dev_init(struct ufs_hba *hba) |
| 5141 | { | 5148 | { |
| @@ -5559,9 +5566,9 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) · 417 unmodified lines | |||
| 5559 | irqreturn_t retval = IRQ_NONE; | 5566 | irqreturn_t retval = IRQ_NONE; |
| 5560 | struct uic_command *cmd; | 5567 | struct uic_command *cmd; |
| 5561 | 5568 | ||
| 5562 | spin_lock(hba->host->host_lock); | 5569 | guard(spinlock_irqsave)(hba->host->host_lock); |
| 5563 | cmd = hba->active_uic_cmd; | 5570 | cmd = hba->active_uic_cmd; |
| 5564 | if (WARN_ON_ONCE(!cmd)) | 5571 | if (!cmd) |
| 5565 | goto unlock; | 5572 | goto unlock; |
| 5566 | 5573 | ||
| 5567 | if (ufshcd_is_auto_hibern8_error(hba, intr_status)) | 5574 | if (ufshcd_is_auto_hibern8_error(hba, intr_status)) |
| @@ -5586,8 +5593,6 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) · 18 unmodified lines | |||
| 5586 | ufshcd_add_uic_command_trace(hba, cmd, UFS_CMD_COMP); | 5593 | ufshcd_add_uic_command_trace(hba, cmd, UFS_CMD_COMP); |
| 5587 | 5594 | ||
| 5588 | unlock: | 5595 | unlock: |
| 5589 | spin_unlock(hba->host->host_lock); | ||
| 5590 | |||
| 5591 | return retval; | 5596 | return retval; |
| 5592 | } | 5597 | } |
| 5593 | 5598 | ||
| @@ -5869,7 +5874,8 @@ static inline int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask) · 275 unmodified lines | |||
| 5869 | * as the device is allowed to manage its own way of handling background | 5874 | * as the device is allowed to manage its own way of handling background |
| 5870 | * operations. | 5875 | * operations. |
| 5871 | * | 5876 | * |
| 5872 | * Return: zero on success, non-zero on failure. | 5877 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 5878 | * < 0 if another error occurred. | ||
| 5873 | */ | 5879 | */ |
| 5874 | static int ufshcd_enable_auto_bkops(struct ufs_hba *hba) | 5880 | static int ufshcd_enable_auto_bkops(struct ufs_hba *hba) |
| 5875 | { | 5881 | { |
| @@ -5908,7 +5914,8 @@ out: · 32 unmodified lines | |||
| 5908 | * host is idle so that BKOPS are managed effectively without any negative | 5914 | * host is idle so that BKOPS are managed effectively without any negative |
| 5909 | * impacts. | 5915 | * impacts. |
| 5910 | * | 5916 | * |
| 5911 | * Return: zero on success, non-zero on failure. | 5917 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 5918 | * < 0 if another error occurred. | ||
| 5912 | */ | 5919 | */ |
| 5913 | static int ufshcd_disable_auto_bkops(struct ufs_hba *hba) | 5920 | static int ufshcd_disable_auto_bkops(struct ufs_hba *hba) |
| 5914 | { | 5921 | { |
| @@ -6058,6 +6065,10 @@ out: · 143 unmodified lines | |||
| 6058 | __func__, err); | 6065 | __func__, err); |
| 6059 | } | 6066 | } |
| 6060 | 6067 | ||
| 6068 | /* | ||
| 6069 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; | ||
| 6070 | * < 0 if another error occurred. | ||
| 6071 | */ | ||
| 6061 | int ufshcd_read_device_lvl_exception_id(struct ufs_hba *hba, u64 *exception_id) | 6072 | int ufshcd_read_device_lvl_exception_id(struct ufs_hba *hba, u64 *exception_id) |
| 6062 | { | 6073 | { |
| 6063 | struct utp_upiu_query_v4_0 *upiu_resp; | 6074 | struct utp_upiu_query_v4_0 *upiu_resp; |
| @@ -6920,7 +6931,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) · 856 unmodified lines | |||
| 6920 | bool queue_eh_work = false; | 6931 | bool queue_eh_work = false; |
| 6921 | irqreturn_t retval = IRQ_NONE; | 6932 | irqreturn_t retval = IRQ_NONE; |
| 6922 | 6933 | ||
| 6923 | spin_lock(hba->host->host_lock); | 6934 | guard(spinlock_irqsave)(hba->host->host_lock); |
| 6924 | hba->errors |= UFSHCD_ERROR_MASK & intr_status; | 6935 | hba->errors |= UFSHCD_ERROR_MASK & intr_status; |
| 6925 | 6936 | ||
| 6926 | if (hba->errors & INT_FATAL_ERRORS) { | 6937 | if (hba->errors & INT_FATAL_ERRORS) { |
| @@ -6979,7 +6990,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) · 52 unmodified lines | |||
| 6979 | */ | 6990 | */ |
| 6980 | hba->errors = 0; | 6991 | hba->errors = 0; |
| 6981 | hba->uic_error = 0; | 6992 | hba->uic_error = 0; |
| 6982 | spin_unlock(hba->host->host_lock); | 6993 | |
| 6983 | return retval; | 6994 | return retval; |
| 6984 | } | 6995 | } |
| 6985 | 6996 | ||
| @@ -7454,7 +7465,8 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, · 468 unmodified lines | |||
| 7454 | * @sg_list: Pointer to SG list when DATA IN/OUT UPIU is required in ARPMB operation | 7465 | * @sg_list: Pointer to SG list when DATA IN/OUT UPIU is required in ARPMB operation |
| 7455 | * @dir: DMA direction | 7466 | * @dir: DMA direction |
| 7456 | * | 7467 | * |
| 7457 | * Return: zero on success, non-zero on failure. | 7468 | * Return: 0 upon success; > 0 in case the UFS device reported an OCS error; |
| 7469 | * < 0 if another error occurred. | ||
| 7458 | */ | 7470 | */ |
| 7459 | int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *req_upiu, | 7471 | int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *req_upiu, |
| 7460 | struct utp_upiu_req *rsp_upiu, struct ufs_ehs *req_ehs, | 7472 | struct utp_upiu_req *rsp_upiu, struct ufs_ehs *req_ehs, |
| @@ -2070,17 +2070,6 @@ static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data) · 2069 unmodified lines | |||
| 2070 | return IRQ_HANDLED; | 2070 | return IRQ_HANDLED; |
| 2071 | } | 2071 | } |
| 2072 | 2072 | ||
| 2073 | static void ufs_qcom_irq_free(struct ufs_qcom_irq *uqi) | ||
| 2074 | { | ||
| 2075 | for (struct ufs_qcom_irq *q = uqi; q->irq; q++) | ||
| 2076 | devm_free_irq(q->hba->dev, q->irq, q->hba); | ||
| 2077 | |||
| 2078 | platform_device_msi_free_irqs_all(uqi->hba->dev); | ||
| 2079 | devm_kfree(uqi->hba->dev, uqi); | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | DEFINE_FREE(ufs_qcom_irq, struct ufs_qcom_irq *, if (_T) ufs_qcom_irq_free(_T)) | ||
| 2083 | |||
| 2084 | static int ufs_qcom_config_esi(struct ufs_hba *hba) | 2073 | static int ufs_qcom_config_esi(struct ufs_hba *hba) |
| 2085 | { | 2074 | { |
| 2086 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); | 2075 | struct ufs_qcom_host *host = ufshcd_get_variant(hba); |
| @@ -2095,18 +2084,18 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) · 8 unmodified lines | |||
| 2095 | */ | 2084 | */ |
| 2096 | nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; | 2085 | nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; |
| 2097 | 2086 | ||
| 2098 | struct ufs_qcom_irq *qi __free(ufs_qcom_irq) = | ||
| 2099 | devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL); | ||
| 2100 | if (!qi) | ||
| 2101 | return -ENOMEM; | ||
| 2102 | /* Preset so __free() has a pointer to hba in all error paths */ | ||
| 2103 | qi[0].hba = hba; | ||
| 2104 | |||
| 2105 | ret = platform_device_msi_init_and_alloc_irqs(hba->dev, nr_irqs, | 2087 | ret = platform_device_msi_init_and_alloc_irqs(hba->dev, nr_irqs, |
| 2106 | ufs_qcom_write_msi_msg); | 2088 | ufs_qcom_write_msi_msg); |
| 2107 | if (ret) { | 2089 | if (ret) { |
| 2108 | dev_err(hba->dev, "Failed to request Platform MSI %d\n", ret); | 2090 | dev_warn(hba->dev, "Platform MSI not supported or failed, continuing without ESI\n"); |
| 2109 | return ret; | 2091 | return ret; /* Continue without ESI */ |
| 2092 | } | ||
| 2093 | |||
| 2094 | struct ufs_qcom_irq *qi = devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL); | ||
| 2095 | |||
| 2096 | if (!qi) { | ||
| 2097 | platform_device_msi_free_irqs_all(hba->dev); | ||
| 2098 | return -ENOMEM; | ||
| 2110 | } | 2099 | } |
| 2111 | 2100 | ||
| 2112 | for (int idx = 0; idx < nr_irqs; idx++) { | 2101 | for (int idx = 0; idx < nr_irqs; idx++) { |
| @@ -2117,15 +2106,17 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) · 4 unmodified lines | |||
| 2117 | ret = devm_request_irq(hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler, | 2106 | ret = devm_request_irq(hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler, |
| 2118 | IRQF_SHARED, "qcom-mcq-esi", qi + idx); | 2107 | IRQF_SHARED, "qcom-mcq-esi", qi + idx); |
| 2119 | if (ret) { | 2108 | if (ret) { |
| 2120 | dev_err(hba->dev, "%s: Fail to request IRQ for %d, err = %d\n", | 2109 | dev_err(hba->dev, "%s: Failed to request IRQ for %d, err = %d\n", |
| 2121 | __func__, qi[idx].irq, ret); | 2110 | __func__, qi[idx].irq, ret); |
| 2122 | qi[idx].irq = 0; | 2111 | /* Free previously allocated IRQs */ |
| 2112 | for (int j = 0; j < idx; j++) | ||
| 2113 | devm_free_irq(hba->dev, qi[j].irq, qi + j); | ||
| 2114 | platform_device_msi_free_irqs_all(hba->dev); | ||
| 2115 | devm_kfree(hba->dev, qi); | ||
| 2123 | return ret; | 2116 | return ret; |
| 2124 | } | 2117 | } |
| 2125 | } | 2118 | } |
| 2126 | 2119 | ||
| 2127 | retain_and_null_ptr(qi); | ||
| 2128 | |||
| 2129 | if (host->hw_ver.major >= 6) { | 2120 | if (host->hw_ver.major >= 6) { |
| 2130 | ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1), | 2121 | ufshcd_rmwl(hba, ESI_VEC_MASK, FIELD_PREP(ESI_VEC_MASK, MAX_ESI_VEC - 1), |
| 2131 | REG_UFS_CFG3); | 2122 | REG_UFS_CFG3); |
| @@ -630,6 +630,7 @@ static const struct pci_device_id ufshcd_pci_tbl[] = { · 629 unmodified lines | |||
| 630 | { PCI_VDEVICE(INTEL, 0xA847), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, | 630 | { PCI_VDEVICE(INTEL, 0xA847), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, |
| 631 | { PCI_VDEVICE(INTEL, 0x7747), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, | 631 | { PCI_VDEVICE(INTEL, 0x7747), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, |
| 632 | { PCI_VDEVICE(INTEL, 0xE447), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, | 632 | { PCI_VDEVICE(INTEL, 0xE447), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, |
| 633 | { PCI_VDEVICE(INTEL, 0x4D47), (kernel_ulong_t)&ufs_intel_mtl_hba_vops }, | ||
| 633 | { } /* terminate list */ | 634 | { } /* terminate list */ |
| 634 | }; | 635 | }; |
| 635 | 636 | ||
| @@ -338,7 +338,8 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event) · 337 unmodified lines | |||
| 338 | schedule_work(&ci->usb_phy->chg_work); | 338 | schedule_work(&ci->usb_phy->chg_work); |
| 339 | break; | 339 | break; |
| 340 | case CI_HDRC_CONTROLLER_PULLUP_EVENT: | 340 | case CI_HDRC_CONTROLLER_PULLUP_EVENT: |
| 341 | if (ci->role == CI_ROLE_GADGET) | 341 | if (ci->role == CI_ROLE_GADGET && |
| 342 | ci->gadget.speed == USB_SPEED_HIGH) | ||
| 342 | imx_usbmisc_pullup(data->usbmisc_data, | 343 | imx_usbmisc_pullup(data->usbmisc_data, |
| 343 | ci->gadget.connected); | 344 | ci->gadget.connected); |
| 344 | break; | 345 | break; |
| @@ -1068,15 +1068,24 @@ static void usbmisc_imx7d_pullup(struct imx_usbmisc_data *data, bool on) · 1067 unmodified lines | |||
| 1068 | unsigned long flags; | 1068 | unsigned long flags; |
| 1069 | u32 val; | 1069 | u32 val; |
| 1070 | 1070 | ||
| 1071 | if (on) | ||
| 1072 | return; | ||
| 1073 | |||
| 1071 | spin_lock_irqsave(&usbmisc->lock, flags); | 1074 | spin_lock_irqsave(&usbmisc->lock, flags); |
| 1072 | val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); | 1075 | val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); |
| 1073 | if (!on) { | 1076 | val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; |
| 1074 | val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; | 1077 | val |= MX7D_USBNC_USB_CTRL2_OPMODE(1); |
| 1075 | val |= MX7D_USBNC_USB_CTRL2_OPMODE(1); | 1078 | val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; |
| 1076 | val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; | 1079 | writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); |
| 1077 | } else { | 1080 | spin_unlock_irqrestore(&usbmisc->lock, flags); |
| 1078 | val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; | 1081 | |
| 1079 | } | 1082 | /* Last for at least 1 micro-frame to let host see disconnect signal */ |
| 1083 | usleep_range(125, 150); | ||
| 1084 | |||
| 1085 | spin_lock_irqsave(&usbmisc->lock, flags); | ||
| 1086 | val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; | ||
| 1087 | val |= MX7D_USBNC_USB_CTRL2_OPMODE(0); | ||
| 1088 | val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; | ||
| 1080 | writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); | 1089 | writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); |
| 1081 | spin_unlock_irqrestore(&usbmisc->lock, flags); | 1090 | spin_unlock_irqrestore(&usbmisc->lock, flags); |
| 1082 | } | 1091 | } |
| @@ -1636,7 +1636,6 @@ static void __usb_hcd_giveback_urb(struct urb *urb) · 1635 unmodified lines | |||
| 1636 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | 1636 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); |
| 1637 | struct usb_anchor *anchor = urb->anchor; | 1637 | struct usb_anchor *anchor = urb->anchor; |
| 1638 | int status = urb->unlinked; | 1638 | int status = urb->unlinked; |
| 1639 | unsigned long flags; | ||
| 1640 | 1639 | ||
| 1641 | urb->hcpriv = NULL; | 1640 | urb->hcpriv = NULL; |
| 1642 | if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | 1641 | if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && |
| @@ -1654,14 +1653,13 @@ static void __usb_hcd_giveback_urb(struct urb *urb) · 11 unmodified lines | |||
| 1654 | /* pass ownership to the completion handler */ | 1653 | /* pass ownership to the completion handler */ |
| 1655 | urb->status = status; | 1654 | urb->status = status; |
| 1656 | /* | 1655 | /* |
| 1657 | * Only collect coverage in the softirq context and disable interrupts | 1656 | * This function can be called in task context inside another remote |
| 1658 | * to avoid scenarios with nested remote coverage collection sections | 1657 | * coverage collection section, but kcov doesn't support that kind of |
| 1659 | * that KCOV does not support. | 1658 | * recursion yet. Only collect coverage in softirq context for now. |
| 1660 | * See the comment next to kcov_remote_start_usb_softirq() for details. | ||
| 1661 | */ | 1659 | */ |
| 1662 | flags = kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); | 1660 | kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); |
| 1663 | urb->complete(urb); | 1661 | urb->complete(urb); |
| 1664 | kcov_remote_stop_softirq(flags); | 1662 | kcov_remote_stop_softirq(); |
| 1665 | 1663 | ||
| 1666 | usb_anchor_resume_wakeups(anchor); | 1664 | usb_anchor_resume_wakeups(anchor); |
| 1667 | atomic_dec(&urb->use_count); | 1665 | atomic_dec(&urb->use_count); |
| @@ -1719,10 +1717,10 @@ static void usb_giveback_urb_bh(struct work_struct *work) · 51 unmodified lines | |||
| 1719 | * @urb: urb being returned to the USB device driver. | 1717 | * @urb: urb being returned to the USB device driver. |
| 1720 | * @status: completion status code for the URB. | 1718 | * @status: completion status code for the URB. |
| 1721 | * | 1719 | * |
| 1722 | * Context: atomic. The completion callback is invoked in caller's context. | 1720 | * Context: atomic. The completion callback is invoked either in a work queue |
| 1723 | * For HCDs with HCD_BH flag set, the completion callback is invoked in BH | 1721 | * (BH) context or in the caller's context, depending on whether the HCD_BH |
| 1724 | * context (except for URBs submitted to the root hub which always complete in | 1722 | * flag is set in the @hcd structure, except that URBs submitted to the |
| 1725 | * caller's context). | 1723 | * root hub always complete in BH context. |
| 1726 | * | 1724 | * |
| 1727 | * This hands the URB from HCD to its USB device driver, using its | 1725 | * This hands the URB from HCD to its USB device driver, using its |
| 1728 | * completion function. The HCD has freed all per-urb resources | 1726 | * completion function. The HCD has freed all per-urb resources |
| @@ -2166,7 +2164,7 @@ static struct urb *request_single_step_set_feature_urb( · 437 unmodified lines | |||
| 2166 | urb->complete = usb_ehset_completion; | 2164 | urb->complete = usb_ehset_completion; |
| 2167 | urb->status = -EINPROGRESS; | 2165 | urb->status = -EINPROGRESS; |
| 2168 | urb->actual_length = 0; | 2166 | urb->actual_length = 0; |
| 2169 | urb->transfer_flags = URB_DIR_IN; | 2167 | urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP; |
| 2170 | usb_get_urb(urb); | 2168 | usb_get_urb(urb); |
| 2171 | atomic_inc(&urb->use_count); | 2169 | atomic_inc(&urb->use_count); |
| 2172 | atomic_inc(&urb->dev->urbnum); | 2170 | atomic_inc(&urb->dev->urbnum); |
| @@ -2230,9 +2228,15 @@ int ehset_single_step_set_feature(struct usb_hcd *hcd, int port) · 57 unmodified lines | |||
| 2230 | 2228 | ||
| 2231 | /* Complete remaining DATA and STATUS stages using the same URB */ | 2229 | /* Complete remaining DATA and STATUS stages using the same URB */ |
| 2232 | urb->status = -EINPROGRESS; | 2230 | urb->status = -EINPROGRESS; |
| 2231 | urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP; | ||
| 2233 | usb_get_urb(urb); | 2232 | usb_get_urb(urb); |
| 2234 | atomic_inc(&urb->use_count); | 2233 | atomic_inc(&urb->use_count); |
| 2235 | atomic_inc(&urb->dev->urbnum); | 2234 | atomic_inc(&urb->dev->urbnum); |
| 2235 | if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) { | ||
| 2236 | usb_put_urb(urb); | ||
| 2237 | goto out1; | ||
| 2238 | } | ||
| 2239 | |||
| 2236 | retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0); | 2240 | retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0); |
| 2237 | if (!retval && !wait_for_completion_timeout(&done, | 2241 | if (!retval && !wait_for_completion_timeout(&done, |
| 2238 | msecs_to_jiffies(2000))) { | 2242 | msecs_to_jiffies(2000))) { |
| @@ -371,6 +371,7 @@ static const struct usb_device_id usb_quirk_list[] = { · 370 unmodified lines | |||
| 371 | { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, | 371 | { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, |
| 372 | 372 | ||
| 373 | /* SanDisk Corp. SanDisk 3.2Gen1 */ | 373 | /* SanDisk Corp. SanDisk 3.2Gen1 */ |
| 374 | { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
| 374 | { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT }, | 375 | { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT }, |
| 375 | 376 | ||
| 376 | /* SanDisk Extreme 55AE */ | 377 | /* SanDisk Extreme 55AE */ |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | |||
| 41 | #define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee | 41 | #define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee |
| 42 | #define PCI_DEVICE_ID_INTEL_TGPH 0x43ee | 42 | #define PCI_DEVICE_ID_INTEL_TGPH 0x43ee |
| 43 | #define PCI_DEVICE_ID_INTEL_JSP 0x4dee | 43 | #define PCI_DEVICE_ID_INTEL_JSP 0x4dee |
| 44 | #define PCI_DEVICE_ID_INTEL_WCL 0x4d7e | ||
| 44 | #define PCI_DEVICE_ID_INTEL_ADL 0x460e | 45 | #define PCI_DEVICE_ID_INTEL_ADL 0x460e |
| 45 | #define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee | 46 | #define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee |
| 46 | #define PCI_DEVICE_ID_INTEL_ADLN 0x465e | 47 | #define PCI_DEVICE_ID_INTEL_ADLN 0x465e |
| @@ -431,6 +432,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { · 384 unmodified lines | |||
| 431 | { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, | 432 | { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, |
| 432 | { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) }, | 433 | { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) }, |
| 433 | { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, | 434 | { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, |
| 435 | { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) }, | ||
| 434 | { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) }, | 436 | { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) }, |
| 435 | { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, | 437 | { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, |
| 436 | { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) }, | 438 | { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) }, |
| @@ -288,7 +288,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) · 287 unmodified lines | |||
| 288 | dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8, | 288 | dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 8, |
| 289 | DWC3_TRBCTL_CONTROL_SETUP, false); | 289 | DWC3_TRBCTL_CONTROL_SETUP, false); |
| 290 | ret = dwc3_ep0_start_trans(dep); | 290 | ret = dwc3_ep0_start_trans(dep); |
| 291 | WARN_ON(ret < 0); | 291 | if (ret < 0) |
| 292 | dev_err(dwc->dev, "ep0 out start transfer failed: %d\n", ret); | ||
| 293 | |||
| 292 | for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) { | 294 | for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) { |
| 293 | struct dwc3_ep *dwc3_ep; | 295 | struct dwc3_ep *dwc3_ep; |
| 294 | 296 | ||
| @@ -1061,7 +1063,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, · 766 unmodified lines | |||
| 1061 | ret = dwc3_ep0_start_trans(dep); | 1063 | ret = dwc3_ep0_start_trans(dep); |
| 1062 | } | 1064 | } |
| 1063 | 1065 | ||
| 1064 | WARN_ON(ret < 0); | 1066 | if (ret < 0) |
| 1067 | dev_err(dwc->dev, | ||
| 1068 | "ep0 data phase start transfer failed: %d\n", ret); | ||
| 1065 | } | 1069 | } |
| 1066 | 1070 | ||
| 1067 | static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) | 1071 | static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) |
| @@ -1078,7 +1082,12 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) · 10 unmodified lines | |||
| 1078 | 1082 | ||
| 1079 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) | 1083 | static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) |
| 1080 | { | 1084 | { |
| 1081 | WARN_ON(dwc3_ep0_start_control_status(dep)); | 1085 | int ret; |
| 1086 | |||
| 1087 | ret = dwc3_ep0_start_control_status(dep); | ||
| 1088 | if (ret) | ||
| 1089 | dev_err(dwc->dev, | ||
| 1090 | "ep0 status phase start transfer failed: %d\n", ret); | ||
| 1082 | } | 1091 | } |
| 1083 | 1092 | ||
| 1084 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, | 1093 | static void dwc3_ep0_do_control_status(struct dwc3 *dwc, |
| @@ -1121,7 +1130,10 @@ void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) · 36 unmodified lines | |||
| 1121 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); | 1130 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); |
| 1122 | memset(¶ms, 0, sizeof(params)); | 1131 | memset(¶ms, 0, sizeof(params)); |
| 1123 | ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); | 1132 | ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); |
| 1124 | WARN_ON_ONCE(ret); | 1133 | if (ret) |
| 1134 | dev_err_ratelimited(dwc->dev, | ||
| 1135 | "ep0 data phase end transfer failed: %d\n", ret); | ||
| 1136 | |||
| 1125 | dep->resource_index = 0; | 1137 | dep->resource_index = 0; |
| 1126 | } | 1138 | } |
| 1127 | 1139 | ||
| @@ -1772,7 +1772,11 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int · 1771 unmodified lines | |||
| 1772 | dep->flags |= DWC3_EP_DELAY_STOP; | 1772 | dep->flags |= DWC3_EP_DELAY_STOP; |
| 1773 | return 0; | 1773 | return 0; |
| 1774 | } | 1774 | } |
| 1775 | WARN_ON_ONCE(ret); | 1775 | |
| 1776 | if (ret) | ||
| 1777 | dev_err_ratelimited(dep->dwc->dev, | ||
| 1778 | "end transfer failed: %d\n", ret); | ||
| 1779 | |||
| 1776 | dep->resource_index = 0; | 1780 | dep->resource_index = 0; |
| 1777 | 1781 | ||
| 1778 | if (!interrupt) | 1782 | if (!interrupt) |
| @@ -3777,6 +3781,15 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep, · 1998 unmodified lines | |||
| 3777 | static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, | 3781 | static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, |
| 3778 | const struct dwc3_event_depevt *event) | 3782 | const struct dwc3_event_depevt *event) |
| 3779 | { | 3783 | { |
| 3784 | /* | ||
| 3785 | * During a device-initiated disconnect, a late xferNotReady event can | ||
| 3786 | * be generated after the End Transfer command resets the event filter, | ||
| 3787 | * but before the controller is halted. Ignore it to prevent a new | ||
| 3788 | * transfer from starting. | ||
| 3789 | */ | ||
| 3790 | if (!dep->dwc->connected) | ||
| 3791 | return; | ||
| 3792 | |||
| 3780 | dwc3_gadget_endpoint_frame_from_event(dep, event); | 3793 | dwc3_gadget_endpoint_frame_from_event(dep, event); |
| 3781 | 3794 | ||
| 3782 | /* | 3795 | /* |
| @@ -4039,7 +4052,9 @@ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) · 256 unmodified lines | |||
| 4039 | dep->flags &= ~DWC3_EP_STALL; | 4052 | dep->flags &= ~DWC3_EP_STALL; |
| 4040 | 4053 | ||
| 4041 | ret = dwc3_send_clear_stall_ep_cmd(dep); | 4054 | ret = dwc3_send_clear_stall_ep_cmd(dep); |
| 4042 | WARN_ON_ONCE(ret); | 4055 | if (ret) |
| 4056 | dev_err_ratelimited(dwc->dev, | ||
| 4057 | "failed to clear STALL on %s\n", dep->name); | ||
| 4043 | } | 4058 | } |
| 4044 | } | 4059 | } |
| 4045 | 4060 | ||
| @@ -502,6 +502,7 @@ struct tegra_xudc { · 501 unmodified lines | |||
| 502 | struct clk_bulk_data *clks; | 502 | struct clk_bulk_data *clks; |
| 503 | 503 | ||
| 504 | bool device_mode; | 504 | bool device_mode; |
| 505 | bool current_device_mode; | ||
| 505 | struct work_struct usb_role_sw_work; | 506 | struct work_struct usb_role_sw_work; |
| 506 | 507 | ||
| 507 | struct phy **usb3_phy; | 508 | struct phy **usb3_phy; |
| @@ -715,6 +716,8 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc) · 207 unmodified lines | |||
| 715 | 716 | ||
| 716 | phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG, | 717 | phy_set_mode_ext(xudc->curr_utmi_phy, PHY_MODE_USB_OTG, |
| 717 | USB_ROLE_DEVICE); | 718 | USB_ROLE_DEVICE); |
| 719 | |||
| 720 | xudc->current_device_mode = true; | ||
| 718 | } | 721 | } |
| 719 | 722 | ||
| 720 | static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc) | 723 | static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc) |
| @@ -725,6 +728,8 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc) · 4 unmodified lines | |||
| 725 | 728 | ||
| 726 | dev_dbg(xudc->dev, "device mode off\n"); | 729 | dev_dbg(xudc->dev, "device mode off\n"); |
| 727 | 730 | ||
| 731 | xudc->current_device_mode = false; | ||
| 732 | |||
| 728 | connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS); | 733 | connected = !!(xudc_readl(xudc, PORTSC) & PORTSC_CCS); |
| 729 | 734 | ||
| 730 | reinit_completion(&xudc->disconnect_complete); | 735 | reinit_completion(&xudc->disconnect_complete); |
| @@ -4044,10 +4049,10 @@ static int __maybe_unused tegra_xudc_resume(struct device *dev) · 3313 unmodified lines | |||
| 4044 | 4049 | ||
| 4045 | spin_lock_irqsave(&xudc->lock, flags); | 4050 | spin_lock_irqsave(&xudc->lock, flags); |
| 4046 | xudc->suspended = false; | 4051 | xudc->suspended = false; |
| 4052 | if (xudc->device_mode != xudc->current_device_mode) | ||
| 4053 | schedule_work(&xudc->usb_role_sw_work); | ||
| 4047 | spin_unlock_irqrestore(&xudc->lock, flags); | 4054 | spin_unlock_irqrestore(&xudc->lock, flags); |
| 4048 | 4055 | ||
| 4049 | schedule_work(&xudc->usb_role_sw_work); | ||
| 4050 | |||
| 4051 | pm_runtime_enable(dev); | 4056 | pm_runtime_enable(dev); |
| 4052 | 4057 | ||
| 4053 | return 0; | 4058 | return 0; |
| @@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, · 703 unmodified lines | |||
| 704 | if (!xhci->devs[i]) | 704 | if (!xhci->devs[i]) |
| 705 | continue; | 705 | continue; |
| 706 | 706 | ||
| 707 | retval = xhci_disable_slot(xhci, i); | 707 | retval = xhci_disable_and_free_slot(xhci, i); |
| 708 | xhci_free_virt_device(xhci, i); | ||
| 709 | if (retval) | 708 | if (retval) |
| 710 | xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", | 709 | xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", |
| 711 | i, retval); | 710 | i, retval); |
| @@ -865,21 +865,20 @@ free_tts: · 864 unmodified lines | |||
| 865 | * will be manipulated by the configure endpoint, allocate device, or update | 865 | * will be manipulated by the configure endpoint, allocate device, or update |
| 866 | * hub functions while this function is removing the TT entries from the list. | 866 | * hub functions while this function is removing the TT entries from the list. |
| 867 | */ | 867 | */ |
| 868 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | 868 | void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, |
| 869 | int slot_id) | ||
| 869 | { | 870 | { |
| 870 | struct xhci_virt_device *dev; | ||
| 871 | int i; | 871 | int i; |
| 872 | int old_active_eps = 0; | 872 | int old_active_eps = 0; |
| 873 | 873 | ||
| 874 | /* Slot ID 0 is reserved */ | 874 | /* Slot ID 0 is reserved */ |
| 875 | if (slot_id == 0 || !xhci->devs[slot_id]) | 875 | if (slot_id == 0 || !dev) |
| 876 | return; | 876 | return; |
| 877 | 877 | ||
| 878 | dev = xhci->devs[slot_id]; | 878 | /* If device ctx array still points to _this_ device, clear it */ |
| 879 | 879 | if (dev->out_ctx && | |
| 880 | xhci->dcbaa->dev_context_ptrs[slot_id] = 0; | 880 | xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma)) |
| 881 | if (!dev) | 881 | xhci->dcbaa->dev_context_ptrs[slot_id] = 0; |
| 882 | return; | ||
| 883 | 882 | ||
| 884 | trace_xhci_free_virt_device(dev); | 883 | trace_xhci_free_virt_device(dev); |
| 885 | 884 | ||
| @@ -920,8 +919,9 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) · 34 unmodified lines | |||
| 920 | dev->udev->slot_id = 0; | 919 | dev->udev->slot_id = 0; |
| 921 | if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) | 920 | if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) |
| 922 | dev->rhub_port->slot_id = 0; | 921 | dev->rhub_port->slot_id = 0; |
| 923 | kfree(xhci->devs[slot_id]); | 922 | if (xhci->devs[slot_id] == dev) |
| 924 | xhci->devs[slot_id] = NULL; | 923 | xhci->devs[slot_id] = NULL; |
| 924 | kfree(dev); | ||
| 925 | } | 925 | } |
| 926 | 926 | ||
| 927 | /* | 927 | /* |
| @@ -962,7 +962,7 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i · 34 unmodified lines | |||
| 962 | out: | 962 | out: |
| 963 | /* we are now at a leaf device */ | 963 | /* we are now at a leaf device */ |
| 964 | xhci_debugfs_remove_slot(xhci, slot_id); | 964 | xhci_debugfs_remove_slot(xhci, slot_id); |
| 965 | xhci_free_virt_device(xhci, slot_id); | 965 | xhci_free_virt_device(xhci, vdev, slot_id); |
| 966 | } | 966 | } |
| 967 | 967 | ||
| 968 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | 968 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, |
| @@ -47,8 +47,9 @@ · 46 unmodified lines | |||
| 47 | #define RENESAS_ROM_ERASE_MAGIC 0x5A65726F | 47 | #define RENESAS_ROM_ERASE_MAGIC 0x5A65726F |
| 48 | #define RENESAS_ROM_WRITE_MAGIC 0x53524F4D | 48 | #define RENESAS_ROM_WRITE_MAGIC 0x53524F4D |
| 49 | 49 | ||
| 50 | #define RENESAS_RETRY 10000 | 50 | #define RENESAS_RETRY 50000 /* 50000 * RENESAS_DELAY ~= 500ms */ |
| 51 | #define RENESAS_DELAY 10 | 51 | #define RENESAS_CHIP_ERASE_RETRY 500000 /* 500000 * RENESAS_DELAY ~= 5s */ |
| 52 | #define RENESAS_DELAY 10 | ||
| 52 | 53 | ||
| 53 | #define RENESAS_FW_NAME "renesas_usb_fw.mem" | 54 | #define RENESAS_FW_NAME "renesas_usb_fw.mem" |
| 54 | 55 | ||
| @@ -407,7 +408,7 @@ static void renesas_rom_erase(struct pci_dev *pdev) · 352 unmodified lines | |||
| 407 | /* sleep a bit while ROM is erased */ | 408 | /* sleep a bit while ROM is erased */ |
| 408 | msleep(20); | 409 | msleep(20); |
| 409 | 410 | ||
| 410 | for (i = 0; i < RENESAS_RETRY; i++) { | 411 | for (i = 0; i < RENESAS_CHIP_ERASE_RETRY; i++) { |
| 411 | retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, | 412 | retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, |
| 412 | &status); | 413 | &status); |
| 413 | status &= RENESAS_ROM_STATUS_ERASE; | 414 | status &= RENESAS_ROM_STATUS_ERASE; |
| @@ -1592,7 +1592,8 @@ static void xhci_handle_cmd_enable_slot(int slot_id, struct xhci_command *comman · 1591 unmodified lines | |||
| 1592 | command->slot_id = 0; | 1592 | command->slot_id = 0; |
| 1593 | } | 1593 | } |
| 1594 | 1594 | ||
| 1595 | static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) | 1595 | static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id, |
| 1596 | u32 cmd_comp_code) | ||
| 1596 | { | 1597 | { |
| 1597 | struct xhci_virt_device *virt_dev; | 1598 | struct xhci_virt_device *virt_dev; |
| 1598 | struct xhci_slot_ctx *slot_ctx; | 1599 | struct xhci_slot_ctx *slot_ctx; |
| @@ -1607,6 +1608,10 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) · 8 unmodified lines | |||
| 1607 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) | 1608 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) |
| 1608 | /* Delete default control endpoint resources */ | 1609 | /* Delete default control endpoint resources */ |
| 1609 | xhci_free_device_endpoint_resources(xhci, virt_dev, true); | 1610 | xhci_free_device_endpoint_resources(xhci, virt_dev, true); |
| 1611 | if (cmd_comp_code == COMP_SUCCESS) { | ||
| 1612 | xhci->dcbaa->dev_context_ptrs[slot_id] = 0; | ||
| 1613 | xhci->devs[slot_id] = NULL; | ||
| 1614 | } | ||
| 1610 | } | 1615 | } |
| 1611 | 1616 | ||
| 1612 | static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id) | 1617 | static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id) |
| @@ -1856,7 +1861,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, · 243 unmodified lines | |||
| 1856 | xhci_handle_cmd_enable_slot(slot_id, cmd, cmd_comp_code); | 1861 | xhci_handle_cmd_enable_slot(slot_id, cmd, cmd_comp_code); |
| 1857 | break; | 1862 | break; |
| 1858 | case TRB_DISABLE_SLOT: | 1863 | case TRB_DISABLE_SLOT: |
| 1859 | xhci_handle_cmd_disable_slot(xhci, slot_id); | 1864 | xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code); |
| 1860 | break; | 1865 | break; |
| 1861 | case TRB_CONFIG_EP: | 1866 | case TRB_CONFIG_EP: |
| 1862 | if (!cmd->completion) | 1867 | if (!cmd->completion) |
| @@ -309,6 +309,7 @@ int xhci_enable_interrupter(struct xhci_interrupter *ir) · 308 unmodified lines | |||
| 309 | return -EINVAL; | 309 | return -EINVAL; |
| 310 | 310 | ||
| 311 | iman = readl(&ir->ir_set->iman); | 311 | iman = readl(&ir->ir_set->iman); |
| 312 | iman &= ~IMAN_IP; | ||
| 312 | iman |= IMAN_IE; | 313 | iman |= IMAN_IE; |
| 313 | writel(iman, &ir->ir_set->iman); | 314 | writel(iman, &ir->ir_set->iman); |
| 314 | 315 | ||
| @@ -325,6 +326,7 @@ int xhci_disable_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir) · 10 unmodified lines | |||
| 325 | return -EINVAL; | 326 | return -EINVAL; |
| 326 | 327 | ||
| 327 | iman = readl(&ir->ir_set->iman); | 328 | iman = readl(&ir->ir_set->iman); |
| 329 | iman &= ~IMAN_IP; | ||
| 328 | iman &= ~IMAN_IE; | 330 | iman &= ~IMAN_IE; |
| 329 | writel(iman, &ir->ir_set->iman); | 331 | writel(iman, &ir->ir_set->iman); |
| 330 | 332 | ||
| @@ -3932,8 +3934,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, · 3601 unmodified lines | |||
| 3932 | * Obtaining a new device slot to inform the xHCI host that | 3934 | * Obtaining a new device slot to inform the xHCI host that |
| 3933 | * the USB device has been reset. | 3935 | * the USB device has been reset. |
| 3934 | */ | 3936 | */ |
| 3935 | ret = xhci_disable_slot(xhci, udev->slot_id); | 3937 | ret = xhci_disable_and_free_slot(xhci, udev->slot_id); |
| 3936 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 3937 | if (!ret) { | 3938 | if (!ret) { |
| 3938 | ret = xhci_alloc_dev(hcd, udev); | 3939 | ret = xhci_alloc_dev(hcd, udev); |
| 3939 | if (ret == 1) | 3940 | if (ret == 1) |
| @@ -4090,7 +4091,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) · 150 unmodified lines | |||
| 4090 | xhci_disable_slot(xhci, udev->slot_id); | 4091 | xhci_disable_slot(xhci, udev->slot_id); |
| 4091 | 4092 | ||
| 4092 | spin_lock_irqsave(&xhci->lock, flags); | 4093 | spin_lock_irqsave(&xhci->lock, flags); |
| 4093 | xhci_free_virt_device(xhci, udev->slot_id); | 4094 | xhci_free_virt_device(xhci, virt_dev, udev->slot_id); |
| 4094 | spin_unlock_irqrestore(&xhci->lock, flags); | 4095 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 4095 | 4096 | ||
| 4096 | } | 4097 | } |
| @@ -4139,6 +4140,16 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) · 42 unmodified lines | |||
| 4139 | return 0; | 4140 | return 0; |
| 4140 | } | 4141 | } |
| 4141 | 4142 | ||
| 4143 | int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id) | ||
| 4144 | { | ||
| 4145 | struct xhci_virt_device *vdev = xhci->devs[slot_id]; | ||
| 4146 | int ret; | ||
| 4147 | |||
| 4148 | ret = xhci_disable_slot(xhci, slot_id); | ||
| 4149 | xhci_free_virt_device(xhci, vdev, slot_id); | ||
| 4150 | return ret; | ||
| 4151 | } | ||
| 4152 | |||
| 4142 | /* | 4153 | /* |
| 4143 | * Checks if we have enough host controller resources for the default control | 4154 | * Checks if we have enough host controller resources for the default control |
| 4144 | * endpoint. | 4155 | * endpoint. |
| @@ -4245,8 +4256,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) · 100 unmodified lines | |||
| 4245 | return 1; | 4256 | return 1; |
| 4246 | 4257 | ||
| 4247 | disable_slot: | 4258 | disable_slot: |
| 4248 | xhci_disable_slot(xhci, udev->slot_id); | 4259 | xhci_disable_and_free_slot(xhci, udev->slot_id); |
| 4249 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 4250 | 4260 | ||
| 4251 | return 0; | 4261 | return 0; |
| 4252 | } | 4262 | } |
| @@ -4382,8 +4392,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, · 129 unmodified lines | |||
| 4382 | dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); | 4392 | dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); |
| 4383 | 4393 | ||
| 4384 | mutex_unlock(&xhci->mutex); | 4394 | mutex_unlock(&xhci->mutex); |
| 4385 | ret = xhci_disable_slot(xhci, udev->slot_id); | 4395 | ret = xhci_disable_and_free_slot(xhci, udev->slot_id); |
| 4386 | xhci_free_virt_device(xhci, udev->slot_id); | ||
| 4387 | if (!ret) { | 4396 | if (!ret) { |
| 4388 | if (xhci_alloc_dev(hcd, udev) == 1) | 4397 | if (xhci_alloc_dev(hcd, udev) == 1) |
| 4389 | xhci_setup_addressable_virt_dev(xhci, udev); | 4398 | xhci_setup_addressable_virt_dev(xhci, udev); |
| @@ -1791,7 +1791,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *), · 1790 unmodified lines | |||
| 1791 | /* xHCI memory management */ | 1791 | /* xHCI memory management */ |
| 1792 | void xhci_mem_cleanup(struct xhci_hcd *xhci); | 1792 | void xhci_mem_cleanup(struct xhci_hcd *xhci); |
| 1793 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); | 1793 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); |
| 1794 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id); | 1794 | void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id); |
| 1795 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); | 1795 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); |
| 1796 | int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); | 1796 | int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); |
| 1797 | void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, | 1797 | void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, |
| @@ -1888,6 +1888,7 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); · 90 unmodified lines | |||
| 1888 | int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, | 1888 | int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, |
| 1889 | struct usb_tt *tt, gfp_t mem_flags); | 1889 | struct usb_tt *tt, gfp_t mem_flags); |
| 1890 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); | 1890 | int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); |
| 1891 | int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id); | ||
| 1891 | int xhci_ext_cap_init(struct xhci_hcd *xhci); | 1892 | int xhci_ext_cap_init(struct xhci_hcd *xhci); |
| 1892 | 1893 | ||
| 1893 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); | 1894 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); |
| @@ -252,7 +252,7 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun, · 251 unmodified lines | |||
| 252 | return USB_STOR_TRANSPORT_ERROR; | 252 | return USB_STOR_TRANSPORT_ERROR; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | residue = bcs->Residue; | 255 | residue = le32_to_cpu(bcs->Residue); |
| 256 | if (bcs->Tag != us->tag) | 256 | if (bcs->Tag != us->tag) |
| 257 | return USB_STOR_TRANSPORT_ERROR; | 257 | return USB_STOR_TRANSPORT_ERROR; |
| 258 | 258 | ||
| @@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, · 933 unmodified lines | |||
| 934 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 934 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 935 | US_FL_SANE_SENSE ), | 935 | US_FL_SANE_SENSE ), |
| 936 | 936 | ||
| 937 | /* Added by Maël GUERIN <mael.guerin@murena.io> */ | ||
| 938 | UNUSUAL_DEV( 0x0603, 0x8611, 0x0000, 0xffff, | ||
| 939 | "Novatek", | ||
| 940 | "NTK96550-based camera", | ||
| 941 | USB_SC_SCSI, USB_PR_BULK, NULL, | ||
| 942 | US_FL_BULK_IGNORE_TAG ), | ||
| 943 | |||
| 937 | /* | 944 | /* |
| 938 | * Reported by Hanno Boeck <hanno@gmx.de> | 945 | * Reported by Hanno Boeck <hanno@gmx.de> |
| 939 | * Taken from the Lycoris Kernel | 946 | * Taken from the Lycoris Kernel |
| @@ -1494,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, · 554 unmodified lines | |||
| 1494 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1501 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 1495 | US_FL_NO_WP_DETECT ), | 1502 | US_FL_NO_WP_DETECT ), |
| 1496 | 1503 | ||
| 1504 | /* | ||
| 1505 | * Reported by Zenm Chen <zenmchen@gmail.com> | ||
| 1506 | * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch | ||
| 1507 | * the device into Wi-Fi mode. | ||
| 1508 | */ | ||
| 1509 | UNUSUAL_DEV( 0x0bda, 0x1a2b, 0x0000, 0xffff, | ||
| 1510 | "Realtek", | ||
| 1511 | "DISK", | ||
| 1512 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 1513 | US_FL_IGNORE_DEVICE ), | ||
| 1514 | |||
| 1515 | /* | ||
| 1516 | * Reported by Zenm Chen <zenmchen@gmail.com> | ||
| 1517 | * Ignore driver CD mode, otherwise usb_modeswitch may fail to switch | ||
| 1518 | * the device into Wi-Fi mode. | ||
| 1519 | */ | ||
| 1520 | UNUSUAL_DEV( 0x0bda, 0xa192, 0x0000, 0xffff, | ||
| 1521 | "Realtek", | ||
| 1522 | "DISK", | ||
| 1523 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 1524 | US_FL_IGNORE_DEVICE ), | ||
| 1525 | |||
| 1497 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, | 1526 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, |
| 1498 | "Maxtor", | 1527 | "Maxtor", |
| 1499 | "USB to SATA", | 1528 | "USB to SATA", |
| @@ -1485,6 +1485,9 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) · 1484 unmodified lines | |||
| 1485 | struct fusb302_chip *chip = dev_id; | 1485 | struct fusb302_chip *chip = dev_id; |
| 1486 | unsigned long flags; | 1486 | unsigned long flags; |
| 1487 | 1487 | ||
| 1488 | /* Disable our level triggered IRQ until our irq_work has cleared it */ | ||
| 1489 | disable_irq_nosync(chip->gpio_int_n_irq); | ||
| 1490 | |||
| 1488 | spin_lock_irqsave(&chip->irq_lock, flags); | 1491 | spin_lock_irqsave(&chip->irq_lock, flags); |
| 1489 | if (chip->irq_suspended) | 1492 | if (chip->irq_suspended) |
| 1490 | chip->irq_while_suspended = true; | 1493 | chip->irq_while_suspended = true; |
| @@ -1627,6 +1630,7 @@ static void fusb302_irq_work(struct work_struct *work) · 136 unmodified lines | |||
| 1627 | } | 1630 | } |
| 1628 | done: | 1631 | done: |
| 1629 | mutex_unlock(&chip->lock); | 1632 | mutex_unlock(&chip->lock); |
| 1633 | enable_irq(chip->gpio_int_n_irq); | ||
| 1630 | } | 1634 | } |
| 1631 | 1635 | ||
| 1632 | static int init_gpio(struct fusb302_chip *chip) | 1636 | static int init_gpio(struct fusb302_chip *chip) |
| @@ -1751,10 +1755,9 @@ static int fusb302_probe(struct i2c_client *client) · 118 unmodified lines | |||
| 1751 | goto destroy_workqueue; | 1755 | goto destroy_workqueue; |
| 1752 | } | 1756 | } |
| 1753 | 1757 | ||
| 1754 | ret = devm_request_threaded_irq(dev, chip->gpio_int_n_irq, | 1758 | ret = request_irq(chip->gpio_int_n_irq, fusb302_irq_intn, |
| 1755 | NULL, fusb302_irq_intn, | 1759 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, |
| 1756 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, | 1760 | "fsc_interrupt_int_n", chip); |
| 1757 | "fsc_interrupt_int_n", chip); | ||
| 1758 | if (ret < 0) { | 1761 | if (ret < 0) { |
| 1759 | dev_err(dev, "cannot request IRQ for GPIO Int_N, ret=%d", ret); | 1762 | dev_err(dev, "cannot request IRQ for GPIO Int_N, ret=%d", ret); |
| 1760 | goto tcpm_unregister_port; | 1763 | goto tcpm_unregister_port; |
| @@ -1779,6 +1782,7 @@ static void fusb302_remove(struct i2c_client *client) · 18 unmodified lines | |||
| 1779 | struct fusb302_chip *chip = i2c_get_clientdata(client); | 1782 | struct fusb302_chip *chip = i2c_get_clientdata(client); |
| 1780 | 1783 | ||
| 1781 | disable_irq_wake(chip->gpio_int_n_irq); | 1784 | disable_irq_wake(chip->gpio_int_n_irq); |
| 1785 | free_irq(chip->gpio_int_n_irq, chip); | ||
| 1782 | cancel_work_sync(&chip->irq_work); | 1786 | cancel_work_sync(&chip->irq_work); |
| 1783 | cancel_delayed_work_sync(&chip->bc_lvl_handler); | 1787 | cancel_delayed_work_sync(&chip->bc_lvl_handler); |
| 1784 | tcpm_unregister_port(chip->tcpm_port); | 1788 | tcpm_unregister_port(chip->tcpm_port); |
| @@ -188,6 +188,11 @@ static int max_contaminant_read_comparators(struct max_tcpci_chip *chip, u8 *ven · 187 unmodified lines | |||
| 188 | if (ret < 0) | 188 | if (ret < 0) |
| 189 | return ret; | 189 | return ret; |
| 190 | 190 | ||
| 191 | /* Disable low power mode */ | ||
| 192 | ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL, | ||
| 193 | FIELD_PREP(CCLPMODESEL, | ||
| 194 | LOW_POWER_MODE_DISABLE)); | ||
| 195 | |||
| 191 | /* Sleep to allow comparators settle */ | 196 | /* Sleep to allow comparators settle */ |
| 192 | usleep_range(5000, 6000); | 197 | usleep_range(5000, 6000); |
| 193 | ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1); | 198 | ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1); |
| @@ -324,6 +329,39 @@ static int max_contaminant_enable_dry_detection(struct max_tcpci_chip *chip) · 130 unmodified lines | |||
| 324 | return 0; | 329 | return 0; |
| 325 | } | 330 | } |
| 326 | 331 | ||
| 332 | static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip) | ||
| 333 | { | ||
| 334 | struct regmap *regmap = chip->data.regmap; | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | /* Disable dry detection if enabled. */ | ||
| 338 | ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL, | ||
| 339 | FIELD_PREP(CCLPMODESEL, | ||
| 340 | LOW_POWER_MODE_DISABLE)); | ||
| 341 | if (ret) | ||
| 342 | return ret; | ||
| 343 | |||
| 344 | ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0); | ||
| 345 | if (ret) | ||
| 346 | return ret; | ||
| 347 | |||
| 348 | ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP | | ||
| 349 | FIELD_PREP(TCPC_ROLE_CTRL_CC1, | ||
| 350 | TCPC_ROLE_CTRL_CC_RD) | | ||
| 351 | FIELD_PREP(TCPC_ROLE_CTRL_CC2, | ||
| 352 | TCPC_ROLE_CTRL_CC_RD)); | ||
| 353 | if (ret) | ||
| 354 | return ret; | ||
| 355 | |||
| 356 | ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, | ||
| 357 | TCPC_TCPC_CTRL_EN_LK4CONN_ALRT, | ||
| 358 | TCPC_TCPC_CTRL_EN_LK4CONN_ALRT); | ||
| 359 | if (ret) | ||
| 360 | return ret; | ||
| 361 | |||
| 362 | return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION); | ||
| 363 | } | ||
| 364 | |||
| 327 | bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce, | 365 | bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce, |
| 328 | bool *cc_handled) | 366 | bool *cc_handled) |
| 329 | { | 367 | { |
| @@ -340,6 +378,12 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect · 10 unmodified lines | |||
| 340 | if (ret < 0) | 378 | if (ret < 0) |
| 341 | return false; | 379 | return false; |
| 342 | 380 | ||
| 381 | if (cc_status & TCPC_CC_STATUS_TOGGLING) { | ||
| 382 | if (chip->contaminant_state == DETECTED) | ||
| 383 | return true; | ||
| 384 | return false; | ||
| 385 | } | ||
| 386 | |||
| 343 | if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) { | 387 | if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) { |
| 344 | if (!disconnect_while_debounce) | 388 | if (!disconnect_while_debounce) |
| 345 | msleep(100); | 389 | msleep(100); |
| @@ -372,6 +416,12 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect · 26 unmodified lines | |||
| 372 | max_contaminant_enable_dry_detection(chip); | 416 | max_contaminant_enable_dry_detection(chip); |
| 373 | return true; | 417 | return true; |
| 374 | } | 418 | } |
| 419 | |||
| 420 | ret = max_contaminant_enable_toggling(chip); | ||
| 421 | if (ret) | ||
| 422 | dev_err(chip->dev, | ||
| 423 | "Failed to enable toggling, ret=%d", | ||
| 424 | ret); | ||
| 375 | } | 425 | } |
| 376 | } else if (chip->contaminant_state == DETECTED) { | 426 | } else if (chip->contaminant_state == DETECTED) { |
| 377 | if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) { | 427 | if (!(cc_status & TCPC_CC_STATUS_TOGGLING)) { |
| @@ -379,6 +429,14 @@ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect · 1 unmodified line | |||
| 379 | if (chip->contaminant_state == DETECTED) { | 429 | if (chip->contaminant_state == DETECTED) { |
| 380 | max_contaminant_enable_dry_detection(chip); | 430 | max_contaminant_enable_dry_detection(chip); |
| 381 | return true; | 431 | return true; |
| 432 | } else { | ||
| 433 | ret = max_contaminant_enable_toggling(chip); | ||
| 434 | if (ret) { | ||
| 435 | dev_err(chip->dev, | ||
| 436 | "Failed to enable toggling, ret=%d", | ||
| 437 | ret); | ||
| 438 | return true; | ||
| 439 | } | ||
| 382 | } | 440 | } |
| 383 | } | 441 | } |
| 384 | } | 442 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #define CCOVPDIS BIT(6) | 21 | #define CCOVPDIS BIT(6) |
| 22 | #define SBURPCTRL BIT(5) | 22 | #define SBURPCTRL BIT(5) |
| 23 | #define CCLPMODESEL GENMASK(4, 3) | 23 | #define CCLPMODESEL GENMASK(4, 3) |
| 24 | #define LOW_POWER_MODE_DISABLE 0 | ||
| 24 | #define ULTRA_LOW_POWER_MODE 1 | 25 | #define ULTRA_LOW_POWER_MODE 1 |
| 25 | #define CCRPCTRL GENMASK(2, 0) | 26 | #define CCRPCTRL GENMASK(2, 0) |
| 26 | #define UA_1_SRC 1 | 27 | #define UA_1_SRC 1 |
| @@ -99,6 +99,7 @@ struct vhost_net_ubuf_ref { · 98 unmodified lines | |||
| 99 | atomic_t refcount; | 99 | atomic_t refcount; |
| 100 | wait_queue_head_t wait; | 100 | wait_queue_head_t wait; |
| 101 | struct vhost_virtqueue *vq; | 101 | struct vhost_virtqueue *vq; |
| 102 | struct rcu_head rcu; | ||
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | #define VHOST_NET_BATCH 64 | 105 | #define VHOST_NET_BATCH 64 |
| @@ -250,9 +251,13 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) · 145 unmodified lines | |||
| 250 | 251 | ||
| 251 | static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) | 252 | static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) |
| 252 | { | 253 | { |
| 253 | int r = atomic_sub_return(1, &ubufs->refcount); | 254 | int r; |
| 255 | |||
| 256 | rcu_read_lock(); | ||
| 257 | r = atomic_sub_return(1, &ubufs->refcount); | ||
| 254 | if (unlikely(!r)) | 258 | if (unlikely(!r)) |
| 255 | wake_up(&ubufs->wait); | 259 | wake_up(&ubufs->wait); |
| 260 | rcu_read_unlock(); | ||
| 256 | return r; | 261 | return r; |
| 257 | } | 262 | } |
| 258 | 263 | ||
| @@ -265,7 +270,7 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) · 6 unmodified lines | |||
| 265 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) | 270 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) |
| 266 | { | 271 | { |
| 267 | vhost_net_ubuf_put_and_wait(ubufs); | 272 | vhost_net_ubuf_put_and_wait(ubufs); |
| 268 | kfree(ubufs); | 273 | kfree_rcu(ubufs, rcu); |
| 269 | } | 274 | } |
| 270 | 275 | ||
| 271 | static void vhost_net_clear_ubuf_info(struct vhost_net *n) | 276 | static void vhost_net_clear_ubuf_info(struct vhost_net *n) |
| @@ -360,11 +360,15 @@ static int virtinput_freeze(struct virtio_device *vdev) · 359 unmodified lines | |||
| 360 | { | 360 | { |
| 361 | struct virtio_input *vi = vdev->priv; | 361 | struct virtio_input *vi = vdev->priv; |
| 362 | unsigned long flags; | 362 | unsigned long flags; |
| 363 | void *buf; | ||
| 363 | 364 | ||
| 364 | spin_lock_irqsave(&vi->lock, flags); | 365 | spin_lock_irqsave(&vi->lock, flags); |
| 365 | vi->ready = false; | 366 | vi->ready = false; |
| 366 | spin_unlock_irqrestore(&vi->lock, flags); | 367 | spin_unlock_irqrestore(&vi->lock, flags); |
| 367 | 368 | ||
| 369 | virtio_reset_device(vdev); | ||
| 370 | while ((buf = virtqueue_detach_unused_buf(vi->sts)) != NULL) | ||
| 371 | kfree(buf); | ||
| 368 | vdev->config->del_vqs(vdev); | 372 | vdev->config->del_vqs(vdev); |
| 369 | return 0; | 373 | return 0; |
| 370 | } | 374 | } |
| @@ -140,9 +140,9 @@ EXPORT_SYMBOL_GPL(vp_legacy_set_status); · 139 unmodified lines | |||
| 140 | * vp_legacy_queue_vector - set the MSIX vector for a specific virtqueue | 140 | * vp_legacy_queue_vector - set the MSIX vector for a specific virtqueue |
| 141 | * @ldev: the legacy virtio-pci device | 141 | * @ldev: the legacy virtio-pci device |
| 142 | * @index: queue index | 142 | * @index: queue index |
| 143 | * @vector: the config vector | 143 | * @vector: the queue vector |
| 144 | * | 144 | * |
| 145 | * Returns the config vector read from the device | 145 | * Returns the queue vector read from the device |
| 146 | */ | 146 | */ |
| 147 | u16 vp_legacy_queue_vector(struct virtio_pci_legacy_device *ldev, | 147 | u16 vp_legacy_queue_vector(struct virtio_pci_legacy_device *ldev, |
| 148 | u16 index, u16 vector) | 148 | u16 index, u16 vector) |
| @@ -546,9 +546,9 @@ EXPORT_SYMBOL_GPL(vp_modern_set_queue_reset); · 545 unmodified lines | |||
| 546 | * vp_modern_queue_vector - set the MSIX vector for a specific virtqueue | 546 | * vp_modern_queue_vector - set the MSIX vector for a specific virtqueue |
| 547 | * @mdev: the modern virtio-pci device | 547 | * @mdev: the modern virtio-pci device |
| 548 | * @index: queue index | 548 | * @index: queue index |
| 549 | * @vector: the config vector | 549 | * @vector: the queue vector |
| 550 | * | 550 | * |
| 551 | * Returns the config vector read from the device | 551 | * Returns the queue vector read from the device |
| 552 | */ | 552 | */ |
| 553 | u16 vp_modern_queue_vector(struct virtio_pci_modern_device *mdev, | 553 | u16 vp_modern_queue_vector(struct virtio_pci_modern_device *mdev, |
| 554 | u16 index, u16 vector) | 554 | u16 index, u16 vector) |
| @@ -718,26 +718,6 @@ int xs_watch_msg(struct xs_watch_event *event) · 717 unmodified lines | |||
| 718 | return 0; | 718 | return 0; |
| 719 | } | 719 | } |
| 720 | 720 | ||
| 721 | /* | ||
| 722 | * Certain older XenBus toolstack cannot handle reading values that are | ||
| 723 | * not populated. Some Xen 3.4 installation are incapable of doing this | ||
| 724 | * so if we are running on anything older than 4 do not attempt to read | ||
| 725 | * control/platform-feature-xs_reset_watches. | ||
| 726 | */ | ||
| 727 | static bool xen_strict_xenbus_quirk(void) | ||
| 728 | { | ||
| 729 | #ifdef CONFIG_X86 | ||
| 730 | uint32_t eax, ebx, ecx, edx, base; | ||
| 731 | |||
| 732 | base = xen_cpuid_base(); | ||
| 733 | cpuid(base + 1, &eax, &ebx, &ecx, &edx); | ||
| 734 | |||
| 735 | if ((eax >> 16) < 4) | ||
| 736 | return true; | ||
| 737 | #endif | ||
| 738 | return false; | ||
| 739 | |||
| 740 | } | ||
| 741 | static void xs_reset_watches(void) | 721 | static void xs_reset_watches(void) |
| 742 | { | 722 | { |
| 743 | int err; | 723 | int err; |
| @@ -745,9 +725,6 @@ static void xs_reset_watches(void) · 1 unmodified line | |||
| 745 | if (!xen_hvm_domain() || xen_initial_domain()) | 725 | if (!xen_hvm_domain() || xen_initial_domain()) |
| 746 | return; | 726 | return; |
| 747 | 727 | ||
| 748 | if (xen_strict_xenbus_quirk()) | ||
| 749 | return; | ||
| 750 | |||
| 751 | if (!xenbus_read_unsigned("control", | 728 | if (!xenbus_read_unsigned("control", |
| 752 | "platform-feature-xs_reset_watches", 0)) | 729 | "platform-feature-xs_reset_watches", 0)) |
| 753 | return; | 730 | return; |
| @@ -183,6 +183,9 @@ static int debugfs_reconfigure(struct fs_context *fc) · 182 unmodified lines | |||
| 183 | struct debugfs_fs_info *sb_opts = sb->s_fs_info; | 183 | struct debugfs_fs_info *sb_opts = sb->s_fs_info; |
| 184 | struct debugfs_fs_info *new_opts = fc->s_fs_info; | 184 | struct debugfs_fs_info *new_opts = fc->s_fs_info; |
| 185 | 185 | ||
| 186 | if (!new_opts) | ||
| 187 | return 0; | ||
| 188 | |||
| 186 | sync_filesystem(sb); | 189 | sync_filesystem(sb); |
| 187 | 190 | ||
| 188 | /* structure copy of new mount options to sb */ | 191 | /* structure copy of new mount options to sb */ |
| @@ -282,10 +285,16 @@ static int debugfs_fill_super(struct super_block *sb, struct fs_context *fc) · 93 unmodified lines | |||
| 282 | 285 | ||
| 283 | static int debugfs_get_tree(struct fs_context *fc) | 286 | static int debugfs_get_tree(struct fs_context *fc) |
| 284 | { | 287 | { |
| 288 | int err; | ||
| 289 | |||
| 285 | if (!(debugfs_allow & DEBUGFS_ALLOW_API)) | 290 | if (!(debugfs_allow & DEBUGFS_ALLOW_API)) |
| 286 | return -EPERM; | 291 | return -EPERM; |
| 287 | 292 | ||
| 288 | return get_tree_single(fc, debugfs_fill_super); | 293 | err = get_tree_single(fc, debugfs_fill_super); |
| 294 | if (err) | ||
| 295 | return err; | ||
| 296 | |||
| 297 | return debugfs_reconfigure(fc); | ||
| 289 | } | 298 | } |
| 290 | 299 | ||
| 291 | static void debugfs_free_fc(struct fs_context *fc) | 300 | static void debugfs_free_fc(struct fs_context *fc) |
| @@ -253,13 +253,14 @@ nfs_page_group_unlock(struct nfs_page *req) · 252 unmodified lines | |||
| 253 | nfs_page_clear_headlock(req); | 253 | nfs_page_clear_headlock(req); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | /* | 256 | /** |
| 257 | * nfs_page_group_sync_on_bit_locked | 257 | * nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set |
| 258 | * @req: request in page group | ||
| 259 | * @bit: PG_* bit that is used to sync page group | ||
| 258 | * | 260 | * |
| 259 | * must be called with page group lock held | 261 | * must be called with page group lock held |
| 260 | */ | 262 | */ |
| 261 | static bool | 263 | bool nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit) |
| 262 | nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit) | ||
| 263 | { | 264 | { |
| 264 | struct nfs_page *head = req->wb_head; | 265 | struct nfs_page *head = req->wb_head; |
| 265 | struct nfs_page *tmp; | 266 | struct nfs_page *tmp; |
| @@ -153,20 +153,10 @@ nfs_page_set_inode_ref(struct nfs_page *req, struct inode *inode) · 152 unmodified lines | |||
| 153 | } | 153 | } |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static int | 156 | static void nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode) |
| 157 | nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode) | ||
| 158 | { | 157 | { |
| 159 | int ret; | ||
| 160 | |||
| 161 | if (!test_bit(PG_REMOVE, &req->wb_flags)) | ||
| 162 | return 0; | ||
| 163 | ret = nfs_page_group_lock(req); | ||
| 164 | if (ret) | ||
| 165 | return ret; | ||
| 166 | if (test_and_clear_bit(PG_REMOVE, &req->wb_flags)) | 158 | if (test_and_clear_bit(PG_REMOVE, &req->wb_flags)) |
| 167 | nfs_page_set_inode_ref(req, inode); | 159 | nfs_page_set_inode_ref(req, inode); |
| 168 | nfs_page_group_unlock(req); | ||
| 169 | return 0; | ||
| 170 | } | 160 | } |
| 171 | 161 | ||
| 172 | /** | 162 | /** |
| @@ -585,19 +575,18 @@ retry: · 412 unmodified lines | |||
| 585 | } | 575 | } |
| 586 | } | 576 | } |
| 587 | 577 | ||
| 578 | ret = nfs_page_group_lock(head); | ||
| 579 | if (ret < 0) | ||
| 580 | goto out_unlock; | ||
| 581 | |||
| 588 | /* Ensure that nobody removed the request before we locked it */ | 582 | /* Ensure that nobody removed the request before we locked it */ |
| 589 | if (head != folio->private) { | 583 | if (head != folio->private) { |
| 584 | nfs_page_group_unlock(head); | ||
| 590 | nfs_unlock_and_release_request(head); | 585 | nfs_unlock_and_release_request(head); |
| 591 | goto retry; | 586 | goto retry; |
| 592 | } | 587 | } |
| 593 | 588 | ||
| 594 | ret = nfs_cancel_remove_inode(head, inode); | 589 | nfs_cancel_remove_inode(head, inode); |
| 595 | if (ret < 0) | ||
| 596 | goto out_unlock; | ||
| 597 | |||
| 598 | ret = nfs_page_group_lock(head); | ||
| 599 | if (ret < 0) | ||
| 600 | goto out_unlock; | ||
| 601 | 590 | ||
| 602 | /* lock each request in the page group */ | 591 | /* lock each request in the page group */ |
| 603 | for (subreq = head->wb_this_page; | 592 | for (subreq = head->wb_this_page; |
| @@ -786,7 +775,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) · 182 unmodified lines | |||
| 786 | { | 775 | { |
| 787 | struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req)); | 776 | struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req)); |
| 788 | 777 | ||
| 789 | if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { | 778 | nfs_page_group_lock(req); |
| 779 | if (nfs_page_group_sync_on_bit_locked(req, PG_REMOVE)) { | ||
| 790 | struct folio *folio = nfs_page_to_folio(req->wb_head); | 780 | struct folio *folio = nfs_page_to_folio(req->wb_head); |
| 791 | struct address_space *mapping = folio->mapping; | 781 | struct address_space *mapping = folio->mapping; |
| 792 | 782 | ||
| @@ -798,6 +788,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) · 5 unmodified lines | |||
| 798 | } | 788 | } |
| 799 | spin_unlock(&mapping->i_private_lock); | 789 | spin_unlock(&mapping->i_private_lock); |
| 800 | } | 790 | } |
| 791 | nfs_page_group_unlock(req); | ||
| 801 | 792 | ||
| 802 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { | 793 | if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { |
| 803 | atomic_long_dec(&nfsi->nrequests); | 794 | atomic_long_dec(&nfsi->nrequests); |
| @@ -4496,7 +4496,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, · 4495 unmodified lines | |||
| 4496 | for (int i = 1; i < num_rqst; i++) { | 4496 | for (int i = 1; i < num_rqst; i++) { |
| 4497 | struct smb_rqst *old = &old_rq[i - 1]; | 4497 | struct smb_rqst *old = &old_rq[i - 1]; |
| 4498 | struct smb_rqst *new = &new_rq[i]; | 4498 | struct smb_rqst *new = &new_rq[i]; |
| 4499 | struct folio_queue *buffer; | 4499 | struct folio_queue *buffer = NULL; |
| 4500 | size_t size = iov_iter_count(&old->rq_iter); | 4500 | size_t size = iov_iter_count(&old->rq_iter); |
| 4501 | 4501 | ||
| 4502 | orig_len += smb_rqst_len(server, old); | 4502 | orig_len += smb_rqst_len(server, old); |
| @@ -187,10 +187,15 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) · 186 unmodified lines | |||
| 187 | unsigned short flags; | 187 | unsigned short flags; |
| 188 | unsigned int fragments; | 188 | unsigned int fragments; |
| 189 | u64 lookup_table_start, xattr_id_table_start, next_table; | 189 | u64 lookup_table_start, xattr_id_table_start, next_table; |
| 190 | int err; | 190 | int err, devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); |
| 191 | 191 | ||
| 192 | TRACE("Entered squashfs_fill_superblock\n"); | 192 | TRACE("Entered squashfs_fill_superblock\n"); |
| 193 | 193 | ||
| 194 | if (!devblksize) { | ||
| 195 | errorf(fc, "squashfs: unable to set blocksize\n"); | ||
| 196 | return -EINVAL; | ||
| 197 | } | ||
| 198 | |||
| 194 | sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); | 199 | sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); |
| 195 | if (sb->s_fs_info == NULL) { | 200 | if (sb->s_fs_info == NULL) { |
| 196 | ERROR("Failed to allocate squashfs_sb_info\n"); | 201 | ERROR("Failed to allocate squashfs_sb_info\n"); |
| @@ -201,12 +206,7 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) · 4 unmodified lines | |||
| 201 | 206 | ||
| 202 | msblk->panic_on_errors = (opts->errors == Opt_errors_panic); | 207 | msblk->panic_on_errors = (opts->errors == Opt_errors_panic); |
| 203 | 208 | ||
| 204 | msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE); | 209 | msblk->devblksize = devblksize; |
| 205 | if (!msblk->devblksize) { | ||
| 206 | errorf(fc, "squashfs: unable to set blocksize\n"); | ||
| 207 | return -EINVAL; | ||
| 208 | } | ||
| 209 | |||
| 210 | msblk->devblksize_log2 = ffz(~msblk->devblksize); | 210 | msblk->devblksize_log2 = ffz(~msblk->devblksize); |
| 211 | 211 | ||
| 212 | mutex_init(&msblk->meta_index_mutex); | 212 | mutex_init(&msblk->meta_index_mutex); |
| @@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */ · 184 unmodified lines | |||
| 185 | int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd, | 185 | int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd, |
| 186 | void __user *arg); | 186 | void __user *arg); |
| 187 | #endif | 187 | #endif |
| 188 | int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb); | ||
| 188 | int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); | 189 | int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); |
| 189 | int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb); | 190 | int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb); |
| 190 | int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags); | 191 | int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags); |
| @@ -656,6 +656,7 @@ enum { · 655 unmodified lines | |||
| 656 | QUEUE_FLAG_SQ_SCHED, /* single queue style io dispatch */ | 656 | QUEUE_FLAG_SQ_SCHED, /* single queue style io dispatch */ |
| 657 | QUEUE_FLAG_DISABLE_WBT_DEF, /* for sched to disable/enable wbt */ | 657 | QUEUE_FLAG_DISABLE_WBT_DEF, /* for sched to disable/enable wbt */ |
| 658 | QUEUE_FLAG_NO_ELV_SWITCH, /* can't switch elevator any more */ | 658 | QUEUE_FLAG_NO_ELV_SWITCH, /* can't switch elevator any more */ |
| 659 | QUEUE_FLAG_QOS_ENABLED, /* qos is enabled */ | ||
| 659 | QUEUE_FLAG_MAX | 660 | QUEUE_FLAG_MAX |
| 660 | }; | 661 | }; |
| 661 | 662 | ||
| @@ -288,14 +288,6 @@ static inline void *offset_to_ptr(const int *off) · 287 unmodified lines | |||
| 288 | #define __ADDRESSABLE(sym) \ | 288 | #define __ADDRESSABLE(sym) \ |
| 289 | ___ADDRESSABLE(sym, __section(".discard.addressable")) | 289 | ___ADDRESSABLE(sym, __section(".discard.addressable")) |
| 290 | 290 | ||
| 291 | #define __ADDRESSABLE_ASM(sym) \ | ||
| 292 | .pushsection .discard.addressable,"aw"; \ | ||
| 293 | .align ARCH_SEL(8,4); \ | ||
| 294 | ARCH_SEL(.quad, .long) __stringify(sym); \ | ||
| 295 | .popsection; | ||
| 296 | |||
| 297 | #define __ADDRESSABLE_ASM_STR(sym) __stringify(__ADDRESSABLE_ASM(sym)) | ||
| 298 | |||
| 299 | /* | 291 | /* |
| 300 | * This returns a constant expression while determining if an argument is | 292 | * This returns a constant expression while determining if an argument is |
| 301 | * a constant expression, most importantly without evaluating the argument. | 293 | * a constant expression, most importantly without evaluating the argument. |
| @@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page, · 152 unmodified lines | |||
| 153 | { | 153 | { |
| 154 | __free_pages(page, get_order(size)); | 154 | __free_pages(page, get_order(size)); |
| 155 | } | 155 | } |
| 156 | static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) | ||
| 157 | { | ||
| 158 | } | ||
| 156 | #endif /* CONFIG_DMA_CMA*/ | 159 | #endif /* CONFIG_DMA_CMA*/ |
| 157 | 160 | ||
| 158 | #ifdef CONFIG_DMA_DECLARE_COHERENT | 161 | #ifdef CONFIG_DMA_DECLARE_COHERENT |
| @@ -264,12 +264,7 @@ static inline bool iosys_map_is_set(const struct iosys_map *map) · 263 unmodified lines | |||
| 264 | */ | 264 | */ |
| 265 | static inline void iosys_map_clear(struct iosys_map *map) | 265 | static inline void iosys_map_clear(struct iosys_map *map) |
| 266 | { | 266 | { |
| 267 | if (map->is_iomem) { | 267 | memset(map, 0, sizeof(*map)); |
| 268 | map->vaddr_iomem = NULL; | ||
| 269 | map->is_iomem = false; | ||
| 270 | } else { | ||
| 271 | map->vaddr = NULL; | ||
| 272 | } | ||
| 273 | } | 268 | } |
| 274 | 269 | ||
| 275 | /** | 270 | /** |
| @@ -160,7 +160,7 @@ size_t iterate_folioq(struct iov_iter *iter, size_t len, void *priv, void *priv2 · 159 unmodified lines | |||
| 160 | 160 | ||
| 161 | do { | 161 | do { |
| 162 | struct folio *folio = folioq_folio(folioq, slot); | 162 | struct folio *folio = folioq_folio(folioq, slot); |
| 163 | size_t part, remain, consumed; | 163 | size_t part, remain = 0, consumed; |
| 164 | size_t fsize; | 164 | size_t fsize; |
| 165 | void *base; | 165 | void *base; |
| 166 | 166 | ||
| @@ -168,14 +168,16 @@ size_t iterate_folioq(struct iov_iter *iter, size_t len, void *priv, void *priv2 · 1 unmodified line | |||
| 168 | break; | 168 | break; |
| 169 | 169 | ||
| 170 | fsize = folioq_folio_size(folioq, slot); | 170 | fsize = folioq_folio_size(folioq, slot); |
| 171 | base = kmap_local_folio(folio, skip); | 171 | if (skip < fsize) { |
| 172 | part = umin(len, PAGE_SIZE - skip % PAGE_SIZE); | 172 | base = kmap_local_folio(folio, skip); |
| 173 | remain = step(base, progress, part, priv, priv2); | 173 | part = umin(len, PAGE_SIZE - skip % PAGE_SIZE); |
| 174 | kunmap_local(base); | 174 | remain = step(base, progress, part, priv, priv2); |
| 175 | consumed = part - remain; | 175 | kunmap_local(base); |
| 176 | len -= consumed; | 176 | consumed = part - remain; |
| 177 | progress += consumed; | 177 | len -= consumed; |
| 178 | skip += consumed; | 178 | progress += consumed; |
| 179 | skip += consumed; | ||
| 180 | } | ||
| 179 | if (skip >= fsize) { | 181 | if (skip >= fsize) { |
| 180 | skip = 0; | 182 | skip = 0; |
| 181 | slot++; | 183 | slot++; |
| @@ -57,47 +57,21 @@ static inline void kcov_remote_start_usb(u64 id) · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | /* | 58 | /* |
| 59 | * The softirq flavor of kcov_remote_*() functions is introduced as a temporary | 59 | * The softirq flavor of kcov_remote_*() functions is introduced as a temporary |
| 60 | * workaround for KCOV's lack of nested remote coverage sections support. | 60 | * work around for kcov's lack of nested remote coverage sections support in |
| 61 | * | 61 | * task context. Adding support for nested sections is tracked in: |
| 62 | * Adding support is tracked in https://bugzilla.kernel.org/show_bug.cgi?id=210337. | 62 | * https://bugzilla.kernel.org/show_bug.cgi?id=210337 |
| 63 | * | ||
| 64 | * kcov_remote_start_usb_softirq(): | ||
| 65 | * | ||
| 66 | * 1. Only collects coverage when called in the softirq context. This allows | ||
| 67 | * avoiding nested remote coverage collection sections in the task context. | ||
| 68 | * For example, USB/IP calls usb_hcd_giveback_urb() in the task context | ||
| 69 | * within an existing remote coverage collection section. Thus, KCOV should | ||
| 70 | * not attempt to start collecting coverage within the coverage collection | ||
| 71 | * section in __usb_hcd_giveback_urb() in this case. | ||
| 72 | * | ||
| 73 | * 2. Disables interrupts for the duration of the coverage collection section. | ||
| 74 | * This allows avoiding nested remote coverage collection sections in the | ||
| 75 | * softirq context (a softirq might occur during the execution of a work in | ||
| 76 | * the BH workqueue, which runs with in_serving_softirq() > 0). | ||
| 77 | * For example, usb_giveback_urb_bh() runs in the BH workqueue with | ||
| 78 | * interrupts enabled, so __usb_hcd_giveback_urb() might be interrupted in | ||
| 79 | * the middle of its remote coverage collection section, and the interrupt | ||
| 80 | * handler might invoke __usb_hcd_giveback_urb() again. | ||
| 81 | */ | 63 | */ |
| 82 | 64 | ||
| 83 | static inline unsigned long kcov_remote_start_usb_softirq(u64 id) | 65 | static inline void kcov_remote_start_usb_softirq(u64 id) |
| 84 | { | 66 | { |
| 85 | unsigned long flags = 0; | 67 | if (in_serving_softirq() && !in_hardirq()) |
| 86 | |||
| 87 | if (in_serving_softirq()) { | ||
| 88 | local_irq_save(flags); | ||
| 89 | kcov_remote_start_usb(id); | 68 | kcov_remote_start_usb(id); |
| 90 | } | ||
| 91 | |||
| 92 | return flags; | ||
| 93 | } | 69 | } |
| 94 | 70 | ||
| 95 | static inline void kcov_remote_stop_softirq(unsigned long flags) | 71 | static inline void kcov_remote_stop_softirq(void) |
| 96 | { | 72 | { |
| 97 | if (in_serving_softirq()) { | 73 | if (in_serving_softirq() && !in_hardirq()) |
| 98 | kcov_remote_stop(); | 74 | kcov_remote_stop(); |
| 99 | local_irq_restore(flags); | ||
| 100 | } | ||
| 101 | } | 75 | } |
| 102 | 76 | ||
| 103 | #ifdef CONFIG_64BIT | 77 | #ifdef CONFIG_64BIT |
| @@ -131,11 +105,8 @@ static inline u64 kcov_common_handle(void) · 27 unmodified lines | |||
| 131 | } | 105 | } |
| 132 | static inline void kcov_remote_start_common(u64 id) {} | 106 | static inline void kcov_remote_start_common(u64 id) {} |
| 133 | static inline void kcov_remote_start_usb(u64 id) {} | 107 | static inline void kcov_remote_start_usb(u64 id) {} |
| 134 | static inline unsigned long kcov_remote_start_usb_softirq(u64 id) | 108 | static inline void kcov_remote_start_usb_softirq(u64 id) {} |
| 135 | { | 109 | static inline void kcov_remote_stop_softirq(void) {} |
| 136 | return 0; | ||
| 137 | } | ||
| 138 | static inline void kcov_remote_stop_softirq(unsigned long flags) {} | ||
| 139 | 110 | ||
| 140 | #endif /* CONFIG_KCOV */ | 111 | #endif /* CONFIG_KCOV */ |
| 141 | #endif /* _LINUX_KCOV_H */ | 112 | #endif /* _LINUX_KCOV_H */ |
| @@ -40,8 +40,9 @@ extern unsigned long long max_possible_pfn; · 39 unmodified lines | |||
| 40 | * via a driver, and never indicated in the firmware-provided memory map as | 40 | * via a driver, and never indicated in the firmware-provided memory map as |
| 41 | * system RAM. This corresponds to IORESOURCE_SYSRAM_DRIVER_MANAGED in the | 41 | * system RAM. This corresponds to IORESOURCE_SYSRAM_DRIVER_MANAGED in the |
| 42 | * kernel resource tree. | 42 | * kernel resource tree. |
| 43 | * @MEMBLOCK_RSRV_NOINIT: memory region for which struct pages are | 43 | * @MEMBLOCK_RSRV_NOINIT: reserved memory region for which struct pages are not |
| 44 | * not initialized (only for reserved regions). | 44 | * fully initialized. Users of this flag are responsible to properly initialize |
| 45 | * struct pages of this region | ||
| 45 | * @MEMBLOCK_RSRV_KERN: memory region that is reserved for kernel use, | 46 | * @MEMBLOCK_RSRV_KERN: memory region that is reserved for kernel use, |
| 46 | * either explictitly with memblock_reserve_kern() or via memblock | 47 | * either explictitly with memblock_reserve_kern() or via memblock |
| 47 | * allocation APIs. All memblock allocations set this flag. | 48 | * allocation APIs. All memblock allocations set this flag. |
| @@ -79,6 +79,7 @@ void migration_entry_wait_on_locked(swp_entry_t entry, spinlock_t *ptl) · 78 unmodified lines | |||
| 79 | void folio_migrate_flags(struct folio *newfolio, struct folio *folio); | 79 | void folio_migrate_flags(struct folio *newfolio, struct folio *folio); |
| 80 | int folio_migrate_mapping(struct address_space *mapping, | 80 | int folio_migrate_mapping(struct address_space *mapping, |
| 81 | struct folio *newfolio, struct folio *folio, int extra_count); | 81 | struct folio *newfolio, struct folio *folio, int extra_count); |
| 82 | int set_movable_ops(const struct movable_operations *ops, enum pagetype type); | ||
| 82 | 83 | ||
| 83 | #else | 84 | #else |
| 84 | 85 | ||
| @@ -100,6 +101,10 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, · 15 unmodified lines | |||
| 100 | { | 101 | { |
| 101 | return -ENOSYS; | 102 | return -ENOSYS; |
| 102 | } | 103 | } |
| 104 | static inline int set_movable_ops(const struct movable_operations *ops, enum pagetype type) | ||
| 105 | { | ||
| 106 | return -ENOSYS; | ||
| 107 | } | ||
| 103 | 108 | ||
| 104 | #endif /* CONFIG_MIGRATION */ | 109 | #endif /* CONFIG_MIGRATION */ |
| 105 | 110 | ||
| @@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct nfs_page *head, · 159 unmodified lines | |||
| 160 | extern int nfs_page_group_lock(struct nfs_page *); | 160 | extern int nfs_page_group_lock(struct nfs_page *); |
| 161 | extern void nfs_page_group_unlock(struct nfs_page *); | 161 | extern void nfs_page_group_unlock(struct nfs_page *); |
| 162 | extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); | 162 | extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); |
| 163 | extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int); | ||
| 163 | extern int nfs_page_set_headlock(struct nfs_page *req); | 164 | extern int nfs_page_set_headlock(struct nfs_page *req); |
| 164 | extern void nfs_page_clear_headlock(struct nfs_page *req); | 165 | extern void nfs_page_clear_headlock(struct nfs_page *req); |
| 165 | extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *); | 166 | extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *); |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c | 27 | #define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c |
| 28 | #define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d | 28 | #define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d |
| 29 | #define INT3472_GPIO_TYPE_HANDSHAKE 0x12 | 29 | #define INT3472_GPIO_TYPE_HANDSHAKE 0x12 |
| 30 | #define INT3472_GPIO_TYPE_HOTPLUG_DETECT 0x13 | ||
| 30 | 31 | ||
| 31 | #define INT3472_PDEV_MAX_NAME_LEN 23 | 32 | #define INT3472_PDEV_MAX_NAME_LEN 23 |
| 32 | #define INT3472_MAX_SENSOR_GPIOS 3 | 33 | #define INT3472_MAX_SENSOR_GPIOS 3 |
| @@ -4213,6 +4213,8 @@ int skb_copy_and_crc32c_datagram_iter(const struct sk_buff *skb, int offset, · 4212 unmodified lines | |||
| 4213 | struct iov_iter *to, int len, u32 *crcp); | 4213 | struct iov_iter *to, int len, u32 *crcp); |
| 4214 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, | 4214 | int skb_copy_datagram_from_iter(struct sk_buff *skb, int offset, |
| 4215 | struct iov_iter *from, int len); | 4215 | struct iov_iter *from, int len); |
| 4216 | int skb_copy_datagram_from_iter_full(struct sk_buff *skb, int offset, | ||
| 4217 | struct iov_iter *from, int len); | ||
| 4216 | int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm); | 4218 | int zerocopy_sg_from_iter(struct sk_buff *skb, struct iov_iter *frm); |
| 4217 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); | 4219 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); |
| 4218 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); | 4220 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); |
| @@ -328,8 +328,6 @@ static inline · 327 unmodified lines | |||
| 328 | bool virtio_get_shm_region(struct virtio_device *vdev, | 328 | bool virtio_get_shm_region(struct virtio_device *vdev, |
| 329 | struct virtio_shm_region *region, u8 id) | 329 | struct virtio_shm_region *region, u8 id) |
| 330 | { | 330 | { |
| 331 | if (!region->len) | ||
| 332 | return false; | ||
| 333 | if (!vdev->config->get_shm_region) | 331 | if (!vdev->config->get_shm_region) |
| 334 | return false; | 332 | return false; |
| 335 | return vdev->config->get_shm_region(vdev, region, id); | 333 | return vdev->config->get_shm_region(vdev, region, id); |
| @@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev); · 92 unmodified lines | |||
| 93 | 93 | ||
| 94 | int hci_update_eir_sync(struct hci_dev *hdev); | 94 | int hci_update_eir_sync(struct hci_dev *hdev); |
| 95 | int hci_update_class_sync(struct hci_dev *hdev); | 95 | int hci_update_class_sync(struct hci_dev *hdev); |
| 96 | int hci_update_name_sync(struct hci_dev *hdev); | 96 | int hci_update_name_sync(struct hci_dev *hdev, const u8 *name); |
| 97 | int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode); | 97 | int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode); |
| 98 | 98 | ||
| 99 | int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, | 99 | int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #ifndef _ROSE_H | 8 | #ifndef _ROSE_H |
| 9 | #define _ROSE_H | 9 | #define _ROSE_H |
| 10 | 10 | ||
| 11 | #include <linux/refcount.h> | ||
| 11 | #include <linux/rose.h> | 12 | #include <linux/rose.h> |
| 12 | #include <net/ax25.h> | 13 | #include <net/ax25.h> |
| 13 | #include <net/sock.h> | 14 | #include <net/sock.h> |
| @@ -96,7 +97,7 @@ struct rose_neigh { · 82 unmodified lines | |||
| 96 | ax25_cb *ax25; | 97 | ax25_cb *ax25; |
| 97 | struct net_device *dev; | 98 | struct net_device *dev; |
| 98 | unsigned short count; | 99 | unsigned short count; |
| 99 | unsigned short use; | 100 | refcount_t use; |
| 100 | unsigned int number; | 101 | unsigned int number; |
| 101 | char restarted; | 102 | char restarted; |
| 102 | char dce_mode; | 103 | char dce_mode; |
| @@ -151,6 +152,21 @@ struct rose_sock { · 48 unmodified lines | |||
| 151 | 152 | ||
| 152 | #define rose_sk(sk) ((struct rose_sock *)(sk)) | 153 | #define rose_sk(sk) ((struct rose_sock *)(sk)) |
| 153 | 154 | ||
| 155 | static inline void rose_neigh_hold(struct rose_neigh *rose_neigh) | ||
| 156 | { | ||
| 157 | refcount_inc(&rose_neigh->use); | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline void rose_neigh_put(struct rose_neigh *rose_neigh) | ||
| 161 | { | ||
| 162 | if (refcount_dec_and_test(&rose_neigh->use)) { | ||
| 163 | if (rose_neigh->ax25) | ||
| 164 | ax25_cb_put(rose_neigh->ax25); | ||
| 165 | kfree(rose_neigh->digipeat); | ||
| 166 | kfree(rose_neigh); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 154 | /* af_rose.c */ | 170 | /* af_rose.c */ |
| 155 | extern ax25_address rose_callsign; | 171 | extern ax25_address rose_callsign; |
| 156 | extern int sysctl_rose_restart_request_timeout; | 172 | extern int sysctl_rose_restart_request_timeout; |
| @@ -107,8 +107,8 @@ · 106 unmodified lines | |||
| 107 | #define CS35L56_DSP1_PMEM_5114 0x3804FE8 | 107 | #define CS35L56_DSP1_PMEM_5114 0x3804FE8 |
| 108 | 108 | ||
| 109 | #define CS35L63_DSP1_FW_VER CS35L56_DSP1_FW_VER | 109 | #define CS35L63_DSP1_FW_VER CS35L56_DSP1_FW_VER |
| 110 | #define CS35L63_DSP1_HALO_STATE 0x280396C | 110 | #define CS35L63_DSP1_HALO_STATE 0x2803C04 |
| 111 | #define CS35L63_DSP1_PM_CUR_STATE 0x28042C8 | 111 | #define CS35L63_DSP1_PM_CUR_STATE 0x2804518 |
| 112 | #define CS35L63_PROTECTION_STATUS 0x340009C | 112 | #define CS35L63_PROTECTION_STATUS 0x340009C |
| 113 | #define CS35L63_TRANSDUCER_ACTUAL_PS 0x34000F4 | 113 | #define CS35L63_TRANSDUCER_ACTUAL_PS 0x34000F4 |
| 114 | #define CS35L63_MAIN_RENDER_USER_MUTE 0x3400020 | 114 | #define CS35L63_MAIN_RENDER_USER_MUTE 0x3400020 |
| @@ -306,6 +306,7 @@ struct cs35l56_base { · 191 unmodified lines | |||
| 306 | struct gpio_desc *reset_gpio; | 306 | struct gpio_desc *reset_gpio; |
| 307 | struct cs35l56_spi_payload *spi_payload_buf; | 307 | struct cs35l56_spi_payload *spi_payload_buf; |
| 308 | const struct cs35l56_fw_reg *fw_reg; | 308 | const struct cs35l56_fw_reg *fw_reg; |
| 309 | const struct cirrus_amp_cal_controls *calibration_controls; | ||
| 309 | }; | 310 | }; |
| 310 | 311 | ||
| 311 | static inline bool cs35l56_is_otp_register(unsigned int reg) | 312 | static inline bool cs35l56_is_otp_register(unsigned int reg) |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | // | 2 | // |
| 3 | // ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier | 3 | // ALSA SoC Texas Instruments TAS2781 Audio Smart Amplifier |
| 4 | // | 4 | // |
| 5 | // Copyright (C) 2022 - 2024 Texas Instruments Incorporated | 5 | // Copyright (C) 2022 - 2025 Texas Instruments Incorporated |
| 6 | // https://www.ti.com | 6 | // https://www.ti.com |
| 7 | // | 7 | // |
| 8 | // The TAS2781 driver implements a flexible and configurable | 8 | // The TAS2781 driver implements a flexible and configurable |
| @@ -15,7 +15,7 @@ · 6 unmodified lines | |||
| 15 | #ifndef __TAS2781_TLV_H__ | 15 | #ifndef __TAS2781_TLV_H__ |
| 16 | #define __TAS2781_TLV_H__ | 16 | #define __TAS2781_TLV_H__ |
| 17 | 17 | ||
| 18 | static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 50, 0); | 18 | static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2781_dvc_tlv, -10000, 50, 0); |
| 19 | static const __maybe_unused DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0); | 19 | static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2781_amp_tlv, 1100, 50, 0); |
| 20 | 20 | ||
| 21 | #endif | 21 | #endif |
| @@ -89,6 +89,7 @@ struct pfru_payload_hdr { · 88 unmodified lines | |||
| 89 | __u32 hw_ver; | 89 | __u32 hw_ver; |
| 90 | __u32 rt_ver; | 90 | __u32 rt_ver; |
| 91 | __u8 platform_id[16]; | 91 | __u8 platform_id[16]; |
| 92 | __u32 svn_ver; | ||
| 92 | }; | 93 | }; |
| 93 | 94 | ||
| 94 | enum pfru_dsm_status { | 95 | enum pfru_dsm_status { |
| @@ -173,7 +173,7 @@ typedef struct mdp_superblock_s { · 172 unmodified lines | |||
| 173 | #else | 173 | #else |
| 174 | #error unspecified endianness | 174 | #error unspecified endianness |
| 175 | #endif | 175 | #endif |
| 176 | __u32 resync_offset; /* 11 resync checkpoint sector count */ | 176 | __u32 recovery_cp; /* 11 resync checkpoint sector count */ |
| 177 | /* There are only valid for minor_version > 90 */ | 177 | /* There are only valid for minor_version > 90 */ |
| 178 | __u64 reshape_position; /* 12,13 next address in array-space for reshape */ | 178 | __u64 reshape_position; /* 12,13 next address in array-space for reshape */ |
| 179 | __u32 new_level; /* 14 new level we are reshaping to */ | 179 | __u32 new_level; /* 14 new level we are reshaping to */ |
| @@ -260,7 +260,7 @@ · 259 unmodified lines | |||
| 260 | * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: | 260 | * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: |
| 261 | * - Vhost will create vhost workers as kernel threads. | 261 | * - Vhost will create vhost workers as kernel threads. |
| 262 | */ | 262 | */ |
| 263 | #define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x83, __u8) | 263 | #define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8) |
| 264 | 264 | ||
| 265 | /** | 265 | /** |
| 266 | * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. | 266 | * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. |
| @@ -268,6 +268,6 @@ · 1 unmodified line | |||
| 268 | * | 268 | * |
| 269 | * @return: An 8-bit value indicating the current thread mode. | 269 | * @return: An 8-bit value indicating the current thread mode. |
| 270 | */ | 270 | */ |
| 271 | #define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x84, __u8) | 271 | #define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8) |
| 272 | 272 | ||
| 273 | #endif | 273 | #endif |
| @@ -288,6 +288,7 @@ int io_futex_wait(struct io_kiocb *req, unsigned int issue_flags) · 287 unmodified lines | |||
| 288 | goto done_unlock; | 288 | goto done_unlock; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | req->flags |= REQ_F_ASYNC_DATA; | ||
| 291 | req->async_data = ifd; | 292 | req->async_data = ifd; |
| 292 | ifd->q = futex_q_init; | 293 | ifd->q = futex_q_init; |
| 293 | ifd->q.bitset = iof->futex_mask; | 294 | ifd->q.bitset = iof->futex_mask; |
| @@ -309,6 +310,8 @@ done: · 15 unmodified lines | |||
| 309 | if (ret < 0) | 310 | if (ret < 0) |
| 310 | req_set_fail(req); | 311 | req_set_fail(req); |
| 311 | io_req_set_res(req, ret, 0); | 312 | io_req_set_res(req, ret, 0); |
| 313 | req->async_data = NULL; | ||
| 314 | req->flags &= ~REQ_F_ASYNC_DATA; | ||
| 312 | kfree(ifd); | 315 | kfree(ifd); |
| 313 | return IOU_COMPLETE; | 316 | return IOU_COMPLETE; |
| 314 | } | 317 | } |
| @@ -2119,6 +2119,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, · 2118 unmodified lines | |||
| 2119 | req->file = NULL; | 2119 | req->file = NULL; |
| 2120 | req->tctx = current->io_uring; | 2120 | req->tctx = current->io_uring; |
| 2121 | req->cancel_seq_set = false; | 2121 | req->cancel_seq_set = false; |
| 2122 | req->async_data = NULL; | ||
| 2122 | 2123 | ||
| 2123 | if (unlikely(opcode >= IORING_OP_LAST)) { | 2124 | if (unlikely(opcode >= IORING_OP_LAST)) { |
| 2124 | req->opcode = 0; | 2125 | req->opcode = 0; |
| @@ -97,6 +97,7 @@ config KEXEC_JUMP · 96 unmodified lines | |||
| 97 | config KEXEC_HANDOVER | 97 | config KEXEC_HANDOVER |
| 98 | bool "kexec handover" | 98 | bool "kexec handover" |
| 99 | depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE | 99 | depends on ARCH_SUPPORTS_KEXEC_HANDOVER && ARCH_SUPPORTS_KEXEC_FILE |
| 100 | depends on !DEFERRED_STRUCT_PAGE_INIT | ||
| 100 | select MEMBLOCK_KHO_SCRATCH | 101 | select MEMBLOCK_KHO_SCRATCH |
| 101 | select KEXEC_FILE | 102 | select KEXEC_FILE |
| 102 | select DEBUG_FS | 103 | select DEBUG_FS |
| @@ -280,7 +280,7 @@ static inline void check_insane_mems_config(nodemask_t *nodes) · 279 unmodified lines | |||
| 280 | { | 280 | { |
| 281 | if (!cpusets_insane_config() && | 281 | if (!cpusets_insane_config() && |
| 282 | movable_only_nodes(nodes)) { | 282 | movable_only_nodes(nodes)) { |
| 283 | static_branch_enable(&cpusets_insane_config_key); | 283 | static_branch_enable_cpuslocked(&cpusets_insane_config_key); |
| 284 | pr_info("Unsupported (movable nodes only) cpuset configuration detected (nmask=%*pbl)!\n" | 284 | pr_info("Unsupported (movable nodes only) cpuset configuration detected (nmask=%*pbl)!\n" |
| 285 | "Cpuset allocations might fail even with a lot of memory available.\n", | 285 | "Cpuset allocations might fail even with a lot of memory available.\n", |
| 286 | nodemask_pr_args(nodes)); | 286 | nodemask_pr_args(nodes)); |
| @@ -1843,7 +1843,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, · 1556 unmodified lines | |||
| 1843 | if (is_partition_valid(cs)) | 1843 | if (is_partition_valid(cs)) |
| 1844 | adding = cpumask_and(tmp->addmask, | 1844 | adding = cpumask_and(tmp->addmask, |
| 1845 | xcpus, parent->effective_xcpus); | 1845 | xcpus, parent->effective_xcpus); |
| 1846 | } else if (is_partition_invalid(cs) && | 1846 | } else if (is_partition_invalid(cs) && !cpumask_empty(xcpus) && |
| 1847 | cpumask_subset(xcpus, parent->effective_xcpus)) { | 1847 | cpumask_subset(xcpus, parent->effective_xcpus)) { |
| 1848 | struct cgroup_subsys_state *css; | 1848 | struct cgroup_subsys_state *css; |
| 1849 | struct cpuset *child; | 1849 | struct cpuset *child; |
| @@ -3358,14 +3358,12 @@ static ssize_t cpuset_partition_write(struct kernfs_open_file *of, char *buf, · 1508 unmodified lines | |||
| 3358 | else | 3358 | else |
| 3359 | return -EINVAL; | 3359 | return -EINVAL; |
| 3360 | 3360 | ||
| 3361 | css_get(&cs->css); | ||
| 3362 | cpus_read_lock(); | 3361 | cpus_read_lock(); |
| 3363 | mutex_lock(&cpuset_mutex); | 3362 | mutex_lock(&cpuset_mutex); |
| 3364 | if (is_cpuset_online(cs)) | 3363 | if (is_cpuset_online(cs)) |
| 3365 | retval = update_prstate(cs, val); | 3364 | retval = update_prstate(cs, val); |
| 3366 | mutex_unlock(&cpuset_mutex); | 3365 | mutex_unlock(&cpuset_mutex); |
| 3367 | cpus_read_unlock(); | 3366 | cpus_read_unlock(); |
| 3368 | css_put(&cs->css); | ||
| 3369 | return retval ?: nbytes; | 3367 | return retval ?: nbytes; |
| 3370 | } | 3368 | } |
| 3371 | 3369 | ||
| @@ -3870,9 +3868,10 @@ retry: · 498 unmodified lines | |||
| 3870 | partcmd = partcmd_invalidate; | 3868 | partcmd = partcmd_invalidate; |
| 3871 | /* | 3869 | /* |
| 3872 | * On the other hand, an invalid partition root may be transitioned | 3870 | * On the other hand, an invalid partition root may be transitioned |
| 3873 | * back to a regular one. | 3871 | * back to a regular one with a non-empty effective xcpus. |
| 3874 | */ | 3872 | */ |
| 3875 | else if (is_partition_valid(parent) && is_partition_invalid(cs)) | 3873 | else if (is_partition_valid(parent) && is_partition_invalid(cs) && |
| 3874 | !cpumask_empty(cs->effective_xcpus)) | ||
| 3876 | partcmd = partcmd_update; | 3875 | partcmd = partcmd_update; |
| 3877 | 3876 | ||
| 3878 | if (partcmd >= 0) { | 3877 | if (partcmd >= 0) { |
| @@ -479,6 +479,9 @@ void css_rstat_exit(struct cgroup_subsys_state *css) · 478 unmodified lines | |||
| 479 | if (!css_uses_rstat(css)) | 479 | if (!css_uses_rstat(css)) |
| 480 | return; | 480 | return; |
| 481 | 481 | ||
| 482 | if (!css->rstat_cpu) | ||
| 483 | return; | ||
| 484 | |||
| 482 | css_rstat_flush(css); | 485 | css_rstat_flush(css); |
| 483 | 486 | ||
| 484 | /* sanity check */ | 487 | /* sanity check */ |
| @@ -483,8 +483,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem) · 482 unmodified lines | |||
| 483 | pr_err("Reserved memory: unable to setup CMA region\n"); | 483 | pr_err("Reserved memory: unable to setup CMA region\n"); |
| 484 | return err; | 484 | return err; |
| 485 | } | 485 | } |
| 486 | /* Architecture specific contiguous memory fixup. */ | ||
| 487 | dma_contiguous_early_fixup(rmem->base, rmem->size); | ||
| 488 | 486 | ||
| 489 | if (default_cma) | 487 | if (default_cma) |
| 490 | dma_contiguous_default_area = cma; | 488 | dma_contiguous_default_area = cma; |
| @@ -102,8 +102,8 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, · 101 unmodified lines | |||
| 102 | 102 | ||
| 103 | #ifdef CONFIG_DMA_DIRECT_REMAP | 103 | #ifdef CONFIG_DMA_DIRECT_REMAP |
| 104 | addr = dma_common_contiguous_remap(page, pool_size, | 104 | addr = dma_common_contiguous_remap(page, pool_size, |
| 105 | pgprot_dmacoherent(PAGE_KERNEL), | 105 | pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)), |
| 106 | __builtin_return_address(0)); | 106 | __builtin_return_address(0)); |
| 107 | if (!addr) | 107 | if (!addr) |
| 108 | goto free_page; | 108 | goto free_page; |
| 109 | #else | 109 | #else |
| @@ -2665,6 +2665,9 @@ static void perf_log_itrace_start(struct perf_event *event); · 2664 unmodified lines | |||
| 2665 | 2665 | ||
| 2666 | static void perf_event_unthrottle(struct perf_event *event, bool start) | 2666 | static void perf_event_unthrottle(struct perf_event *event, bool start) |
| 2667 | { | 2667 | { |
| 2668 | if (event->state != PERF_EVENT_STATE_ACTIVE) | ||
| 2669 | return; | ||
| 2670 | |||
| 2668 | event->hw.interrupts = 0; | 2671 | event->hw.interrupts = 0; |
| 2669 | if (start) | 2672 | if (start) |
| 2670 | event->pmu->start(event, 0); | 2673 | event->pmu->start(event, 0); |
| @@ -2674,6 +2677,9 @@ static void perf_event_unthrottle(struct perf_event *event, bool start) · 3 unmodified lines | |||
| 2674 | 2677 | ||
| 2675 | static void perf_event_throttle(struct perf_event *event) | 2678 | static void perf_event_throttle(struct perf_event *event) |
| 2676 | { | 2679 | { |
| 2680 | if (event->state != PERF_EVENT_STATE_ACTIVE) | ||
| 2681 | return; | ||
| 2682 | |||
| 2677 | event->hw.interrupts = MAX_INTERRUPTS; | 2683 | event->hw.interrupts = MAX_INTERRUPTS; |
| 2678 | event->pmu->stop(event, 0); | 2684 | event->pmu->stop(event, 0); |
| 2679 | if (event == event->group_leader) | 2685 | if (event == event->group_leader) |
| @@ -144,14 +144,34 @@ static int __kho_preserve_order(struct kho_mem_track *track, unsigned long pfn, · 143 unmodified lines | |||
| 144 | unsigned int order) | 144 | unsigned int order) |
| 145 | { | 145 | { |
| 146 | struct kho_mem_phys_bits *bits; | 146 | struct kho_mem_phys_bits *bits; |
| 147 | struct kho_mem_phys *physxa; | 147 | struct kho_mem_phys *physxa, *new_physxa; |
| 148 | const unsigned long pfn_high = pfn >> order; | 148 | const unsigned long pfn_high = pfn >> order; |
| 149 | 149 | ||
| 150 | might_sleep(); | 150 | might_sleep(); |
| 151 | 151 | ||
| 152 | physxa = xa_load_or_alloc(&track->orders, order, sizeof(*physxa)); | 152 | physxa = xa_load(&track->orders, order); |
| 153 | if (IS_ERR(physxa)) | 153 | if (!physxa) { |
| 154 | return PTR_ERR(physxa); | 154 | int err; |
| 155 | |||
| 156 | new_physxa = kzalloc(sizeof(*physxa), GFP_KERNEL); | ||
| 157 | if (!new_physxa) | ||
| 158 | return -ENOMEM; | ||
| 159 | |||
| 160 | xa_init(&new_physxa->phys_bits); | ||
| 161 | physxa = xa_cmpxchg(&track->orders, order, NULL, new_physxa, | ||
| 162 | GFP_KERNEL); | ||
| 163 | |||
| 164 | err = xa_err(physxa); | ||
| 165 | if (err || physxa) { | ||
| 166 | xa_destroy(&new_physxa->phys_bits); | ||
| 167 | kfree(new_physxa); | ||
| 168 | |||
| 169 | if (err) | ||
| 170 | return err; | ||
| 171 | } else { | ||
| 172 | physxa = new_physxa; | ||
| 173 | } | ||
| 174 | } | ||
| 155 | 175 | ||
| 156 | bits = xa_load_or_alloc(&physxa->phys_bits, pfn_high / PRESERVE_BITS, | 176 | bits = xa_load_or_alloc(&physxa->phys_bits, pfn_high / PRESERVE_BITS, |
| 157 | sizeof(*bits)); | 177 | sizeof(*bits)); |
| @@ -544,6 +564,7 @@ err_free_scratch_areas: · 386 unmodified lines | |||
| 544 | err_free_scratch_desc: | 564 | err_free_scratch_desc: |
| 545 | memblock_free(kho_scratch, kho_scratch_cnt * sizeof(*kho_scratch)); | 565 | memblock_free(kho_scratch, kho_scratch_cnt * sizeof(*kho_scratch)); |
| 546 | err_disable_kho: | 566 | err_disable_kho: |
| 567 | pr_warn("Failed to reserve scratch area, disabling kexec handover\n"); | ||
| 547 | kho_enable = false; | 568 | kho_enable = false; |
| 548 | } | 569 | } |
| 549 | 570 | ||
| @@ -513,13 +513,14 @@ EXPORT_SYMBOL(param_array_ops); · 512 unmodified lines | |||
| 513 | int param_set_copystring(const char *val, const struct kernel_param *kp) | 513 | int param_set_copystring(const char *val, const struct kernel_param *kp) |
| 514 | { | 514 | { |
| 515 | const struct kparam_string *kps = kp->str; | 515 | const struct kparam_string *kps = kp->str; |
| 516 | const size_t len = strnlen(val, kps->maxlen); | ||
| 516 | 517 | ||
| 517 | if (strnlen(val, kps->maxlen) == kps->maxlen) { | 518 | if (len == kps->maxlen) { |
| 518 | pr_err("%s: string doesn't fit in %u chars.\n", | 519 | pr_err("%s: string doesn't fit in %u chars.\n", |
| 519 | kp->name, kps->maxlen-1); | 520 | kp->name, kps->maxlen-1); |
| 520 | return -ENOSPC; | 521 | return -ENOSPC; |
| 521 | } | 522 | } |
| 522 | strcpy(kps->string, val); | 523 | memcpy(kps->string, val, len + 1); |
| 523 | return 0; | 524 | return 0; |
| 524 | } | 525 | } |
| 525 | EXPORT_SYMBOL(param_set_copystring); | 526 | EXPORT_SYMBOL(param_set_copystring); |
| @@ -841,7 +842,7 @@ static void __init param_sysfs_builtin(void) · 315 unmodified lines | |||
| 841 | dot = strchr(kp->name, '.'); | 842 | dot = strchr(kp->name, '.'); |
| 842 | if (!dot) { | 843 | if (!dot) { |
| 843 | /* This happens for core_param() */ | 844 | /* This happens for core_param() */ |
| 844 | strcpy(modname, "kernel"); | 845 | strscpy(modname, "kernel"); |
| 845 | name_len = 0; | 846 | name_len = 0; |
| 846 | } else { | 847 | } else { |
| 847 | name_len = dot - kp->name + 1; | 848 | name_len = dot - kp->name + 1; |
| @@ -5749,6 +5749,9 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) · 5748 unmodified lines | |||
| 5749 | __setscheduler_class(p->policy, p->prio); | 5749 | __setscheduler_class(p->policy, p->prio); |
| 5750 | struct sched_enq_and_set_ctx ctx; | 5750 | struct sched_enq_and_set_ctx ctx; |
| 5751 | 5751 | ||
| 5752 | if (!tryget_task_struct(p)) | ||
| 5753 | continue; | ||
| 5754 | |||
| 5752 | if (old_class != new_class && p->se.sched_delayed) | 5755 | if (old_class != new_class && p->se.sched_delayed) |
| 5753 | dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED); | 5756 | dequeue_task(task_rq(p), p, DEQUEUE_SLEEP | DEQUEUE_DELAYED); |
| 5754 | 5757 | ||
| @@ -5761,6 +5764,7 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) · 6 unmodified lines | |||
| 5761 | sched_enq_and_set_task(&ctx); | 5764 | sched_enq_and_set_task(&ctx); |
| 5762 | 5765 | ||
| 5763 | check_class_changed(task_rq(p), p, old_class, p->prio); | 5766 | check_class_changed(task_rq(p), p, old_class, p->prio); |
| 5767 | put_task_struct(p); | ||
| 5764 | } | 5768 | } |
| 5765 | scx_task_iter_stop(&sti); | 5769 | scx_task_iter_stop(&sti); |
| 5766 | percpu_up_write(&scx_fork_rwsem); | 5770 | percpu_up_write(&scx_fork_rwsem); |
| @@ -1397,6 +1397,7 @@ error: · 1396 unmodified lines | |||
| 1397 | ftrace_graph_active--; | 1397 | ftrace_graph_active--; |
| 1398 | gops->saved_func = NULL; | 1398 | gops->saved_func = NULL; |
| 1399 | fgraph_lru_release_index(i); | 1399 | fgraph_lru_release_index(i); |
| 1400 | unregister_pm_notifier(&ftrace_suspend_notifier); | ||
| 1400 | } | 1401 | } |
| 1401 | return ret; | 1402 | return ret; |
| 1402 | } | 1403 | } |
| @@ -4661,13 +4661,17 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, · 4660 unmodified lines | |||
| 4661 | } else { | 4661 | } else { |
| 4662 | iter->hash = alloc_and_copy_ftrace_hash(size_bits, hash); | 4662 | iter->hash = alloc_and_copy_ftrace_hash(size_bits, hash); |
| 4663 | } | 4663 | } |
| 4664 | } else { | ||
| 4665 | if (hash) | ||
| 4666 | iter->hash = alloc_and_copy_ftrace_hash(hash->size_bits, hash); | ||
| 4667 | else | ||
| 4668 | iter->hash = EMPTY_HASH; | ||
| 4669 | } | ||
| 4664 | 4670 | ||
| 4665 | if (!iter->hash) { | 4671 | if (!iter->hash) { |
| 4666 | trace_parser_put(&iter->parser); | 4672 | trace_parser_put(&iter->parser); |
| 4667 | goto out_unlock; | 4673 | goto out_unlock; |
| 4668 | } | 4674 | } |
| 4669 | } else | ||
| 4670 | iter->hash = hash; | ||
| 4671 | 4675 | ||
| 4672 | ret = 0; | 4676 | ret = 0; |
| 4673 | 4677 | ||
| @@ -6543,9 +6547,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file) · 1869 unmodified lines | |||
| 6543 | ftrace_hash_move_and_update_ops(iter->ops, orig_hash, | 6547 | ftrace_hash_move_and_update_ops(iter->ops, orig_hash, |
| 6544 | iter->hash, filter_hash); | 6548 | iter->hash, filter_hash); |
| 6545 | mutex_unlock(&ftrace_lock); | 6549 | mutex_unlock(&ftrace_lock); |
| 6546 | } else { | ||
| 6547 | /* For read only, the hash is the ops hash */ | ||
| 6548 | iter->hash = NULL; | ||
| 6549 | } | 6550 | } |
| 6550 | 6551 | ||
| 6551 | mutex_unlock(&iter->ops->func_hash->regex_lock); | 6552 | mutex_unlock(&iter->ops->func_hash->regex_lock); |
| @@ -7666,7 +7666,7 @@ static __init int test_ringbuffer(void) · 7665 unmodified lines | |||
| 7666 | rb_test_started = true; | 7666 | rb_test_started = true; |
| 7667 | 7667 | ||
| 7668 | set_current_state(TASK_INTERRUPTIBLE); | 7668 | set_current_state(TASK_INTERRUPTIBLE); |
| 7669 | /* Just run for 10 seconds */; | 7669 | /* Just run for 10 seconds */ |
| 7670 | schedule_timeout(10 * HZ); | 7670 | schedule_timeout(10 * HZ); |
| 7671 | 7671 | ||
| 7672 | kthread_stop(rb_hammer); | 7672 | kthread_stop(rb_hammer); |
| @@ -1816,7 +1816,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, · 1815 unmodified lines | |||
| 1816 | 1816 | ||
| 1817 | ret = get_user(ch, ubuf++); | 1817 | ret = get_user(ch, ubuf++); |
| 1818 | if (ret) | 1818 | if (ret) |
| 1819 | return ret; | 1819 | goto fail; |
| 1820 | 1820 | ||
| 1821 | read++; | 1821 | read++; |
| 1822 | cnt--; | 1822 | cnt--; |
| @@ -1830,7 +1830,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, · 7 unmodified lines | |||
| 1830 | while (cnt && isspace(ch)) { | 1830 | while (cnt && isspace(ch)) { |
| 1831 | ret = get_user(ch, ubuf++); | 1831 | ret = get_user(ch, ubuf++); |
| 1832 | if (ret) | 1832 | if (ret) |
| 1833 | return ret; | 1833 | goto fail; |
| 1834 | read++; | 1834 | read++; |
| 1835 | cnt--; | 1835 | cnt--; |
| 1836 | } | 1836 | } |
| @@ -1848,12 +1848,14 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, · 11 unmodified lines | |||
| 1848 | while (cnt && !isspace(ch) && ch) { | 1848 | while (cnt && !isspace(ch) && ch) { |
| 1849 | if (parser->idx < parser->size - 1) | 1849 | if (parser->idx < parser->size - 1) |
| 1850 | parser->buffer[parser->idx++] = ch; | 1850 | parser->buffer[parser->idx++] = ch; |
| 1851 | else | 1851 | else { |
| 1852 | return -EINVAL; | 1852 | ret = -EINVAL; |
| 1853 | goto fail; | ||
| 1854 | } | ||
| 1853 | 1855 | ||
| 1854 | ret = get_user(ch, ubuf++); | 1856 | ret = get_user(ch, ubuf++); |
| 1855 | if (ret) | 1857 | if (ret) |
| 1856 | return ret; | 1858 | goto fail; |
| 1857 | read++; | 1859 | read++; |
| 1858 | cnt--; | 1860 | cnt--; |
| 1859 | } | 1861 | } |
| @@ -1868,11 +1870,15 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, · 8 unmodified lines | |||
| 1868 | /* Make sure the parsed string always terminates with '\0'. */ | 1870 | /* Make sure the parsed string always terminates with '\0'. */ |
| 1869 | parser->buffer[parser->idx] = 0; | 1871 | parser->buffer[parser->idx] = 0; |
| 1870 | } else { | 1872 | } else { |
| 1871 | return -EINVAL; | 1873 | ret = -EINVAL; |
| 1874 | goto fail; | ||
| 1872 | } | 1875 | } |
| 1873 | 1876 | ||
| 1874 | *ppos += read; | 1877 | *ppos += read; |
| 1875 | return read; | 1878 | return read; |
| 1879 | fail: | ||
| 1880 | trace_parser_fail(parser); | ||
| 1881 | return ret; | ||
| 1876 | } | 1882 | } |
| 1877 | 1883 | ||
| 1878 | /* TODO add a seq_buf_to_buffer() */ | 1884 | /* TODO add a seq_buf_to_buffer() */ |
| @@ -10632,10 +10638,10 @@ static void ftrace_dump_one(struct trace_array *tr, enum ftrace_dump_mode dump_m · 8753 unmodified lines | |||
| 10632 | ret = print_trace_line(&iter); | 10638 | ret = print_trace_line(&iter); |
| 10633 | if (ret != TRACE_TYPE_NO_CONSUME) | 10639 | if (ret != TRACE_TYPE_NO_CONSUME) |
| 10634 | trace_consume(&iter); | 10640 | trace_consume(&iter); |
| 10641 | |||
| 10642 | trace_printk_seq(&iter.seq); | ||
| 10635 | } | 10643 | } |
| 10636 | touch_nmi_watchdog(); | 10644 | touch_nmi_watchdog(); |
| 10637 | |||
| 10638 | trace_printk_seq(&iter.seq); | ||
| 10639 | } | 10645 | } |
| 10640 | 10646 | ||
| 10641 | if (!cnt) | 10647 | if (!cnt) |
| @@ -1292,6 +1292,7 @@ bool ftrace_event_is_function(struct trace_event_call *call); · 1291 unmodified lines | |||
| 1292 | */ | 1292 | */ |
| 1293 | struct trace_parser { | 1293 | struct trace_parser { |
| 1294 | bool cont; | 1294 | bool cont; |
| 1295 | bool fail; | ||
| 1295 | char *buffer; | 1296 | char *buffer; |
| 1296 | unsigned idx; | 1297 | unsigned idx; |
| 1297 | unsigned size; | 1298 | unsigned size; |
| @@ -1299,7 +1300,7 @@ struct trace_parser { · 1 unmodified line | |||
| 1299 | 1300 | ||
| 1300 | static inline bool trace_parser_loaded(struct trace_parser *parser) | 1301 | static inline bool trace_parser_loaded(struct trace_parser *parser) |
| 1301 | { | 1302 | { |
| 1302 | return (parser->idx != 0); | 1303 | return !parser->fail && parser->idx != 0; |
| 1303 | } | 1304 | } |
| 1304 | 1305 | ||
| 1305 | static inline bool trace_parser_cont(struct trace_parser *parser) | 1306 | static inline bool trace_parser_cont(struct trace_parser *parser) |
| @@ -1313,6 +1314,11 @@ static inline void trace_parser_clear(struct trace_parser *parser) · 7 unmodified lines | |||
| 1313 | parser->idx = 0; | 1314 | parser->idx = 0; |
| 1314 | } | 1315 | } |
| 1315 | 1316 | ||
| 1317 | static inline void trace_parser_fail(struct trace_parser *parser) | ||
| 1318 | { | ||
| 1319 | parser->fail = true; | ||
| 1320 | } | ||
| 1321 | |||
| 1316 | extern int trace_parser_get_init(struct trace_parser *parser, int size); | 1322 | extern int trace_parser_get_init(struct trace_parser *parser, int size); |
| 1317 | extern void trace_parser_put(struct trace_parser *parser); | 1323 | extern void trace_parser_put(struct trace_parser *parser); |
| 1318 | extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, | 1324 | extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, |
| @@ -27,14 +27,21 @@ struct fgraph_cpu_data { · 26 unmodified lines | |||
| 27 | unsigned long enter_funcs[FTRACE_RETFUNC_DEPTH]; | 27 | unsigned long enter_funcs[FTRACE_RETFUNC_DEPTH]; |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | struct fgraph_ent_args { | ||
| 31 | struct ftrace_graph_ent_entry ent; | ||
| 32 | /* Force the sizeof of args[] to have FTRACE_REGS_MAX_ARGS entries */ | ||
| 33 | unsigned long args[FTRACE_REGS_MAX_ARGS]; | ||
| 34 | }; | ||
| 35 | |||
| 30 | struct fgraph_data { | 36 | struct fgraph_data { |
| 31 | struct fgraph_cpu_data __percpu *cpu_data; | 37 | struct fgraph_cpu_data __percpu *cpu_data; |
| 32 | 38 | ||
| 33 | /* Place to preserve last processed entry. */ | 39 | /* Place to preserve last processed entry. */ |
| 34 | union { | 40 | union { |
| 35 | struct ftrace_graph_ent_entry ent; | 41 | struct fgraph_ent_args ent; |
| 42 | /* TODO allow retaddr to have args */ | ||
| 36 | struct fgraph_retaddr_ent_entry rent; | 43 | struct fgraph_retaddr_ent_entry rent; |
| 37 | } ent; | 44 | }; |
| 38 | struct ftrace_graph_ret_entry ret; | 45 | struct ftrace_graph_ret_entry ret; |
| 39 | int failed; | 46 | int failed; |
| 40 | int cpu; | 47 | int cpu; |
| @@ -627,10 +634,13 @@ get_return_for_leaf(struct trace_iterator *iter, · 586 unmodified lines | |||
| 627 | * Save current and next entries for later reference | 634 | * Save current and next entries for later reference |
| 628 | * if the output fails. | 635 | * if the output fails. |
| 629 | */ | 636 | */ |
| 630 | if (unlikely(curr->ent.type == TRACE_GRAPH_RETADDR_ENT)) | 637 | if (unlikely(curr->ent.type == TRACE_GRAPH_RETADDR_ENT)) { |
| 631 | data->ent.rent = *(struct fgraph_retaddr_ent_entry *)curr; | 638 | data->rent = *(struct fgraph_retaddr_ent_entry *)curr; |
| 632 | else | 639 | } else { |
| 633 | data->ent.ent = *curr; | 640 | int size = min((int)sizeof(data->ent), (int)iter->ent_size); |
| 641 | |||
| 642 | memcpy(&data->ent, curr, size); | ||
| 643 | } | ||
| 634 | /* | 644 | /* |
| 635 | * If the next event is not a return type, then | 645 | * If the next event is not a return type, then |
| 636 | * we only care about what type it is. Otherwise we can | 646 | * we only care about what type it is. Otherwise we can |
| @@ -254,4 +254,10 @@ const struct movable_operations balloon_mops = { · 253 unmodified lines | |||
| 254 | .putback_page = balloon_page_putback, | 254 | .putback_page = balloon_page_putback, |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | static int __init balloon_init(void) | ||
| 258 | { | ||
| 259 | return set_movable_ops(&balloon_mops, PGTY_offline); | ||
| 260 | } | ||
| 261 | core_initcall(balloon_init); | ||
| 262 | |||
| 257 | #endif /* CONFIG_BALLOON_COMPACTION */ | 263 | #endif /* CONFIG_BALLOON_COMPACTION */ |
| @@ -845,6 +845,18 @@ static struct damos_filter *damos_nth_filter(int n, struct damos *s) · 844 unmodified lines | |||
| 845 | return NULL; | 845 | return NULL; |
| 846 | } | 846 | } |
| 847 | 847 | ||
| 848 | static struct damos_filter *damos_nth_ops_filter(int n, struct damos *s) | ||
| 849 | { | ||
| 850 | struct damos_filter *filter; | ||
| 851 | int i = 0; | ||
| 852 | |||
| 853 | damos_for_each_ops_filter(filter, s) { | ||
| 854 | if (i++ == n) | ||
| 855 | return filter; | ||
| 856 | } | ||
| 857 | return NULL; | ||
| 858 | } | ||
| 859 | |||
| 848 | static void damos_commit_filter_arg( | 860 | static void damos_commit_filter_arg( |
| 849 | struct damos_filter *dst, struct damos_filter *src) | 861 | struct damos_filter *dst, struct damos_filter *src) |
| 850 | { | 862 | { |
| @@ -871,6 +883,7 @@ static void damos_commit_filter( · 20 unmodified lines | |||
| 871 | { | 883 | { |
| 872 | dst->type = src->type; | 884 | dst->type = src->type; |
| 873 | dst->matching = src->matching; | 885 | dst->matching = src->matching; |
| 886 | dst->allow = src->allow; | ||
| 874 | damos_commit_filter_arg(dst, src); | 887 | damos_commit_filter_arg(dst, src); |
| 875 | } | 888 | } |
| 876 | 889 | ||
| @@ -908,7 +921,7 @@ static int damos_commit_ops_filters(struct damos *dst, struct damos *src) · 31 unmodified lines | |||
| 908 | int i = 0, j = 0; | 921 | int i = 0, j = 0; |
| 909 | 922 | ||
| 910 | damos_for_each_ops_filter_safe(dst_filter, next, dst) { | 923 | damos_for_each_ops_filter_safe(dst_filter, next, dst) { |
| 911 | src_filter = damos_nth_filter(i++, src); | 924 | src_filter = damos_nth_ops_filter(i++, src); |
| 912 | if (src_filter) | 925 | if (src_filter) |
| 913 | damos_commit_filter(dst_filter, src_filter); | 926 | damos_commit_filter(dst_filter, src_filter); |
| 914 | else | 927 | else |
| @@ -2158,8 +2158,8 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme) · 2157 unmodified lines | |||
| 2158 | { | 2158 | { |
| 2159 | damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern); | 2159 | damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern); |
| 2160 | kobject_put(&scheme->access_pattern->kobj); | 2160 | kobject_put(&scheme->access_pattern->kobj); |
| 2161 | kobject_put(&scheme->dests->kobj); | ||
| 2162 | damos_sysfs_dests_rm_dirs(scheme->dests); | 2161 | damos_sysfs_dests_rm_dirs(scheme->dests); |
| 2162 | kobject_put(&scheme->dests->kobj); | ||
| 2163 | damon_sysfs_quotas_rm_dirs(scheme->quotas); | 2163 | damon_sysfs_quotas_rm_dirs(scheme->quotas); |
| 2164 | kobject_put(&scheme->quotas->kobj); | 2164 | kobject_put(&scheme->quotas->kobj); |
| 2165 | kobject_put(&scheme->watermarks->kobj); | 2165 | kobject_put(&scheme->watermarks->kobj); |
| @@ -990,29 +990,34 @@ static void __init destroy_args(struct pgtable_debug_args *args) · 989 unmodified lines | |||
| 990 | 990 | ||
| 991 | /* Free page table entries */ | 991 | /* Free page table entries */ |
| 992 | if (args->start_ptep) { | 992 | if (args->start_ptep) { |
| 993 | pmd_clear(args->pmdp); | ||
| 993 | pte_free(args->mm, args->start_ptep); | 994 | pte_free(args->mm, args->start_ptep); |
| 994 | mm_dec_nr_ptes(args->mm); | 995 | mm_dec_nr_ptes(args->mm); |
| 995 | } | 996 | } |
| 996 | 997 | ||
| 997 | if (args->start_pmdp) { | 998 | if (args->start_pmdp) { |
| 999 | pud_clear(args->pudp); | ||
| 998 | pmd_free(args->mm, args->start_pmdp); | 1000 | pmd_free(args->mm, args->start_pmdp); |
| 999 | mm_dec_nr_pmds(args->mm); | 1001 | mm_dec_nr_pmds(args->mm); |
| 1000 | } | 1002 | } |
| 1001 | 1003 | ||
| 1002 | if (args->start_pudp) { | 1004 | if (args->start_pudp) { |
| 1005 | p4d_clear(args->p4dp); | ||
| 1003 | pud_free(args->mm, args->start_pudp); | 1006 | pud_free(args->mm, args->start_pudp); |
| 1004 | mm_dec_nr_puds(args->mm); | 1007 | mm_dec_nr_puds(args->mm); |
| 1005 | } | 1008 | } |
| 1006 | 1009 | ||
| 1007 | if (args->start_p4dp) | 1010 | if (args->start_p4dp) { |
| 1011 | pgd_clear(args->pgdp); | ||
| 1008 | p4d_free(args->mm, args->start_p4dp); | 1012 | p4d_free(args->mm, args->start_p4dp); |
| 1013 | } | ||
| 1009 | 1014 | ||
| 1010 | /* Free vma and mm struct */ | 1015 | /* Free vma and mm struct */ |
| 1011 | if (args->vma) | 1016 | if (args->vma) |
| 1012 | vm_area_free(args->vma); | 1017 | vm_area_free(args->vma); |
| 1013 | 1018 | ||
| 1014 | if (args->mm) | 1019 | if (args->mm) |
| 1015 | mmdrop(args->mm); | 1020 | mmput(args->mm); |
| 1016 | } | 1021 | } |
| 1017 | 1022 | ||
| 1018 | static struct page * __init | 1023 | static struct page * __init |
| @@ -780,9 +780,9 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt · 779 unmodified lines | |||
| 780 | } | 780 | } |
| 781 | 781 | ||
| 782 | if ((nr_pages << PAGE_SHIFT) > threshold_bytes) { | 782 | if ((nr_pages << PAGE_SHIFT) > threshold_bytes) { |
| 783 | mem_size_mb = memblock_phys_mem_size() >> 20; | 783 | mem_size_mb = memblock_phys_mem_size() / SZ_1M; |
| 784 | pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n", | 784 | pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n", |
| 785 | (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb); | 785 | (nr_pages << PAGE_SHIFT) / SZ_1M, mem_size_mb); |
| 786 | return false; | 786 | return false; |
| 787 | } | 787 | } |
| 788 | 788 | ||
| @@ -1091,13 +1091,20 @@ int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size) · 302 unmodified lines | |||
| 1091 | 1091 | ||
| 1092 | /** | 1092 | /** |
| 1093 | * memblock_reserved_mark_noinit - Mark a reserved memory region with flag | 1093 | * memblock_reserved_mark_noinit - Mark a reserved memory region with flag |
| 1094 | * MEMBLOCK_RSRV_NOINIT which results in the struct pages not being initialized | 1094 | * MEMBLOCK_RSRV_NOINIT |
| 1095 | * for this region. | 1095 | * |
| 1096 | * @base: the base phys addr of the region | 1096 | * @base: the base phys addr of the region |
| 1097 | * @size: the size of the region | 1097 | * @size: the size of the region |
| 1098 | * | 1098 | * |
| 1099 | * struct pages will not be initialized for reserved memory regions marked with | 1099 | * The struct pages for the reserved regions marked %MEMBLOCK_RSRV_NOINIT will |
| 1100 | * %MEMBLOCK_RSRV_NOINIT. | 1100 | * not be fully initialized to allow the caller optimize their initialization. |
| 1101 | * | ||
| 1102 | * When %CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, setting this flag | ||
| 1103 | * completely bypasses the initialization of struct pages for such region. | ||
| 1104 | * | ||
| 1105 | * When %CONFIG_DEFERRED_STRUCT_PAGE_INIT is disabled, struct pages in this | ||
| 1106 | * region will be initialized with default values but won't be marked as | ||
| 1107 | * reserved. | ||
| 1101 | * | 1108 | * |
| 1102 | * Return: 0 on success, -errno on failure. | 1109 | * Return: 0 on success, -errno on failure. |
| 1103 | */ | 1110 | */ |
| @@ -853,9 +853,17 @@ static int hwpoison_hugetlb_range(pte_t *ptep, unsigned long hmask, · 852 unmodified lines | |||
| 853 | #define hwpoison_hugetlb_range NULL | 853 | #define hwpoison_hugetlb_range NULL |
| 854 | #endif | 854 | #endif |
| 855 | 855 | ||
| 856 | static int hwpoison_test_walk(unsigned long start, unsigned long end, | ||
| 857 | struct mm_walk *walk) | ||
| 858 | { | ||
| 859 | /* We also want to consider pages mapped into VM_PFNMAP. */ | ||
| 860 | return 0; | ||
| 861 | } | ||
| 862 | |||
| 856 | static const struct mm_walk_ops hwpoison_walk_ops = { | 863 | static const struct mm_walk_ops hwpoison_walk_ops = { |
| 857 | .pmd_entry = hwpoison_pte_range, | 864 | .pmd_entry = hwpoison_pte_range, |
| 858 | .hugetlb_entry = hwpoison_hugetlb_range, | 865 | .hugetlb_entry = hwpoison_hugetlb_range, |
| 866 | .test_walk = hwpoison_test_walk, | ||
| 859 | .walk_lock = PGWALK_RDLOCK, | 867 | .walk_lock = PGWALK_RDLOCK, |
| 860 | }; | 868 | }; |
| 861 | 869 | ||
| @@ -43,8 +43,6 @@ · 42 unmodified lines | |||
| 43 | #include <linux/sched/sysctl.h> | 43 | #include <linux/sched/sysctl.h> |
| 44 | #include <linux/memory-tiers.h> | 44 | #include <linux/memory-tiers.h> |
| 45 | #include <linux/pagewalk.h> | 45 | #include <linux/pagewalk.h> |
| 46 | #include <linux/balloon_compaction.h> | ||
| 47 | #include <linux/zsmalloc.h> | ||
| 48 | 46 | ||
| 49 | #include <asm/tlbflush.h> | 47 | #include <asm/tlbflush.h> |
| 50 | 48 | ||
| @@ -53,6 +51,33 @@ · 2 unmodified lines | |||
| 53 | #include "internal.h" | 51 | #include "internal.h" |
| 54 | #include "swap.h" | 52 | #include "swap.h" |
| 55 | 53 | ||
| 54 | static const struct movable_operations *offline_movable_ops; | ||
| 55 | static const struct movable_operations *zsmalloc_movable_ops; | ||
| 56 | |||
| 57 | int set_movable_ops(const struct movable_operations *ops, enum pagetype type) | ||
| 58 | { | ||
| 59 | /* | ||
| 60 | * We only allow for selected types and don't handle concurrent | ||
| 61 | * registration attempts yet. | ||
| 62 | */ | ||
| 63 | switch (type) { | ||
| 64 | case PGTY_offline: | ||
| 65 | if (offline_movable_ops && ops) | ||
| 66 | return -EBUSY; | ||
| 67 | offline_movable_ops = ops; | ||
| 68 | break; | ||
| 69 | case PGTY_zsmalloc: | ||
| 70 | if (zsmalloc_movable_ops && ops) | ||
| 71 | return -EBUSY; | ||
| 72 | zsmalloc_movable_ops = ops; | ||
| 73 | break; | ||
| 74 | default: | ||
| 75 | return -EINVAL; | ||
| 76 | } | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL_GPL(set_movable_ops); | ||
| 80 | |||
| 56 | static const struct movable_operations *page_movable_ops(struct page *page) | 81 | static const struct movable_operations *page_movable_ops(struct page *page) |
| 57 | { | 82 | { |
| 58 | VM_WARN_ON_ONCE_PAGE(!page_has_movable_ops(page), page); | 83 | VM_WARN_ON_ONCE_PAGE(!page_has_movable_ops(page), page); |
| @@ -62,15 +87,12 @@ static const struct movable_operations *page_movable_ops(struct page *page) · 3 unmodified lines | |||
| 62 | * it as movable, the page type must be sticky until the page gets freed | 87 | * it as movable, the page type must be sticky until the page gets freed |
| 63 | * back to the buddy. | 88 | * back to the buddy. |
| 64 | */ | 89 | */ |
| 65 | #ifdef CONFIG_BALLOON_COMPACTION | ||
| 66 | if (PageOffline(page)) | 90 | if (PageOffline(page)) |
| 67 | /* Only balloon compaction sets PageOffline pages movable. */ | 91 | /* Only balloon compaction sets PageOffline pages movable. */ |
| 68 | return &balloon_mops; | 92 | return offline_movable_ops; |
| 69 | #endif /* CONFIG_BALLOON_COMPACTION */ | ||
| 70 | #if defined(CONFIG_ZSMALLOC) && defined(CONFIG_COMPACTION) | ||
| 71 | if (PageZsmalloc(page)) | 93 | if (PageZsmalloc(page)) |
| 72 | return &zsmalloc_mops; | 94 | return zsmalloc_movable_ops; |
| 73 | #endif /* defined(CONFIG_ZSMALLOC) && defined(CONFIG_COMPACTION) */ | 95 | |
| 74 | return NULL; | 96 | return NULL; |
| 75 | } | 97 | } |
| 76 | 98 | ||
| @@ -323,6 +323,25 @@ static inline bool arch_supports_page_table_move(void) · 322 unmodified lines | |||
| 323 | } | 323 | } |
| 324 | #endif | 324 | #endif |
| 325 | 325 | ||
| 326 | static inline bool uffd_supports_page_table_move(struct pagetable_move_control *pmc) | ||
| 327 | { | ||
| 328 | /* | ||
| 329 | * If we are moving a VMA that has uffd-wp registered but with | ||
| 330 | * remap events disabled (new VMA will not be registered with uffd), we | ||
| 331 | * need to ensure that the uffd-wp state is cleared from all pgtables. | ||
| 332 | * This means recursing into lower page tables in move_page_tables(). | ||
| 333 | * | ||
| 334 | * We might get called with VMAs reversed when recovering from a | ||
| 335 | * failed page table move. In that case, the | ||
| 336 | * "old"-but-actually-"originally new" VMA during recovery will not have | ||
| 337 | * a uffd context. Recursing into lower page tables during the original | ||
| 338 | * move but not during the recovery move will cause trouble, because we | ||
| 339 | * run into already-existing page tables. So check both VMAs. | ||
| 340 | */ | ||
| 341 | return !vma_has_uffd_without_event_remap(pmc->old) && | ||
| 342 | !vma_has_uffd_without_event_remap(pmc->new); | ||
| 343 | } | ||
| 344 | |||
| 326 | #ifdef CONFIG_HAVE_MOVE_PMD | 345 | #ifdef CONFIG_HAVE_MOVE_PMD |
| 327 | static bool move_normal_pmd(struct pagetable_move_control *pmc, | 346 | static bool move_normal_pmd(struct pagetable_move_control *pmc, |
| 328 | pmd_t *old_pmd, pmd_t *new_pmd) | 347 | pmd_t *old_pmd, pmd_t *new_pmd) |
| @@ -335,6 +354,8 @@ static bool move_normal_pmd(struct pagetable_move_control *pmc, · 6 unmodified lines | |||
| 335 | 354 | ||
| 336 | if (!arch_supports_page_table_move()) | 355 | if (!arch_supports_page_table_move()) |
| 337 | return false; | 356 | return false; |
| 357 | if (!uffd_supports_page_table_move(pmc)) | ||
| 358 | return false; | ||
| 338 | /* | 359 | /* |
| 339 | * The destination pmd shouldn't be established, free_pgtables() | 360 | * The destination pmd shouldn't be established, free_pgtables() |
| 340 | * should have released it. | 361 | * should have released it. |
| @@ -361,15 +382,6 @@ static bool move_normal_pmd(struct pagetable_move_control *pmc, · 20 unmodified lines | |||
| 361 | if (WARN_ON_ONCE(!pmd_none(*new_pmd))) | 382 | if (WARN_ON_ONCE(!pmd_none(*new_pmd))) |
| 362 | return false; | 383 | return false; |
| 363 | 384 | ||
| 364 | /* If this pmd belongs to a uffd vma with remap events disabled, we need | ||
| 365 | * to ensure that the uffd-wp state is cleared from all pgtables. This | ||
| 366 | * means recursing into lower page tables in move_page_tables(), and we | ||
| 367 | * can reuse the existing code if we simply treat the entry as "not | ||
| 368 | * moved". | ||
| 369 | */ | ||
| 370 | if (vma_has_uffd_without_event_remap(vma)) | ||
| 371 | return false; | ||
| 372 | |||
| 373 | /* | 385 | /* |
| 374 | * We don't have to worry about the ordering of src and dst | 386 | * We don't have to worry about the ordering of src and dst |
| 375 | * ptlocks because exclusive mmap_lock prevents deadlock. | 387 | * ptlocks because exclusive mmap_lock prevents deadlock. |
| @@ -418,6 +430,8 @@ static bool move_normal_pud(struct pagetable_move_control *pmc, · 42 unmodified lines | |||
| 418 | 430 | ||
| 419 | if (!arch_supports_page_table_move()) | 431 | if (!arch_supports_page_table_move()) |
| 420 | return false; | 432 | return false; |
| 433 | if (!uffd_supports_page_table_move(pmc)) | ||
| 434 | return false; | ||
| 421 | /* | 435 | /* |
| 422 | * The destination pud shouldn't be established, free_pgtables() | 436 | * The destination pud shouldn't be established, free_pgtables() |
| 423 | * should have released it. | 437 | * should have released it. |
| @@ -425,15 +439,6 @@ static bool move_normal_pud(struct pagetable_move_control *pmc, · 1 unmodified line | |||
| 425 | if (WARN_ON_ONCE(!pud_none(*new_pud))) | 439 | if (WARN_ON_ONCE(!pud_none(*new_pud))) |
| 426 | return false; | 440 | return false; |
| 427 | 441 | ||
| 428 | /* If this pud belongs to a uffd vma with remap events disabled, we need | ||
| 429 | * to ensure that the uffd-wp state is cleared from all pgtables. This | ||
| 430 | * means recursing into lower page tables in move_page_tables(), and we | ||
| 431 | * can reuse the existing code if we simply treat the entry as "not | ||
| 432 | * moved". | ||
| 433 | */ | ||
| 434 | if (vma_has_uffd_without_event_remap(vma)) | ||
| 435 | return false; | ||
| 436 | |||
| 437 | /* | 442 | /* |
| 438 | * We don't have to worry about the ordering of src and dst | 443 | * We don't have to worry about the ordering of src and dst |
| 439 | * ptlocks because exclusive mmap_lock prevents deadlock. | 444 | * ptlocks because exclusive mmap_lock prevents deadlock. |
| @@ -1620,7 +1625,7 @@ static void notify_uffd(struct vma_remap_struct *vrm, bool failed) · 1180 unmodified lines | |||
| 1620 | 1625 | ||
| 1621 | static bool vma_multi_allowed(struct vm_area_struct *vma) | 1626 | static bool vma_multi_allowed(struct vm_area_struct *vma) |
| 1622 | { | 1627 | { |
| 1623 | struct file *file; | 1628 | struct file *file = vma->vm_file; |
| 1624 | 1629 | ||
| 1625 | /* | 1630 | /* |
| 1626 | * We can't support moving multiple uffd VMAs as notify requires | 1631 | * We can't support moving multiple uffd VMAs as notify requires |
| @@ -1633,15 +1638,17 @@ static bool vma_multi_allowed(struct vm_area_struct *vma) · 6 unmodified lines | |||
| 1633 | * Custom get unmapped area might result in MREMAP_FIXED not | 1638 | * Custom get unmapped area might result in MREMAP_FIXED not |
| 1634 | * being obeyed. | 1639 | * being obeyed. |
| 1635 | */ | 1640 | */ |
| 1636 | file = vma->vm_file; | 1641 | if (!file || !file->f_op->get_unmapped_area) |
| 1637 | if (file && !vma_is_shmem(vma) && !is_vm_hugetlb_page(vma)) { | 1642 | return true; |
| 1638 | const struct file_operations *fop = file->f_op; | 1643 | /* Known good. */ |
| 1639 | 1644 | if (vma_is_shmem(vma)) | |
| 1640 | if (fop->get_unmapped_area) | 1645 | return true; |
| 1641 | return false; | 1646 | if (is_vm_hugetlb_page(vma)) |
| 1642 | } | 1647 | return true; |
| 1648 | if (file->f_op->get_unmapped_area == thp_get_unmapped_area) | ||
| 1649 | return true; | ||
| 1643 | 1650 | ||
| 1644 | return true; | 1651 | return false; |
| 1645 | } | 1652 | } |
| 1646 | 1653 | ||
| 1647 | static int check_prep_vma(struct vma_remap_struct *vrm) | 1654 | static int check_prep_vma(struct vma_remap_struct *vrm) |
| @@ -1818,10 +1825,11 @@ static unsigned long remap_move(struct vma_remap_struct *vrm) · 170 unmodified lines | |||
| 1818 | unsigned long start = vrm->addr; | 1825 | unsigned long start = vrm->addr; |
| 1819 | unsigned long end = vrm->addr + vrm->old_len; | 1826 | unsigned long end = vrm->addr + vrm->old_len; |
| 1820 | unsigned long new_addr = vrm->new_addr; | 1827 | unsigned long new_addr = vrm->new_addr; |
| 1821 | bool allowed = true, seen_vma = false; | ||
| 1822 | unsigned long target_addr = new_addr; | 1828 | unsigned long target_addr = new_addr; |
| 1823 | unsigned long res = -EFAULT; | 1829 | unsigned long res = -EFAULT; |
| 1824 | unsigned long last_end; | 1830 | unsigned long last_end; |
| 1831 | bool seen_vma = false; | ||
| 1832 | |||
| 1825 | VMA_ITERATOR(vmi, current->mm, start); | 1833 | VMA_ITERATOR(vmi, current->mm, start); |
| 1826 | 1834 | ||
| 1827 | /* | 1835 | /* |
| @@ -1834,9 +1842,7 @@ static unsigned long remap_move(struct vma_remap_struct *vrm) · 6 unmodified lines | |||
| 1834 | unsigned long addr = max(vma->vm_start, start); | 1842 | unsigned long addr = max(vma->vm_start, start); |
| 1835 | unsigned long len = min(end, vma->vm_end) - addr; | 1843 | unsigned long len = min(end, vma->vm_end) - addr; |
| 1836 | unsigned long offset, res_vma; | 1844 | unsigned long offset, res_vma; |
| 1837 | 1845 | bool multi_allowed; | |
| 1838 | if (!allowed) | ||
| 1839 | return -EFAULT; | ||
| 1840 | 1846 | ||
| 1841 | /* No gap permitted at the start of the range. */ | 1847 | /* No gap permitted at the start of the range. */ |
| 1842 | if (!seen_vma && start < vma->vm_start) | 1848 | if (!seen_vma && start < vma->vm_start) |
| @@ -1865,9 +1871,15 @@ static unsigned long remap_move(struct vma_remap_struct *vrm) · 22 unmodified lines | |||
| 1865 | vrm->new_addr = target_addr + offset; | 1871 | vrm->new_addr = target_addr + offset; |
| 1866 | vrm->old_len = vrm->new_len = len; | 1872 | vrm->old_len = vrm->new_len = len; |
| 1867 | 1873 | ||
| 1868 | allowed = vma_multi_allowed(vma); | 1874 | multi_allowed = vma_multi_allowed(vma); |
| 1869 | if (seen_vma && !allowed) | 1875 | if (!multi_allowed) { |
| 1870 | return -EFAULT; | 1876 | /* This is not the first VMA, abort immediately. */ |
| 1877 | if (seen_vma) | ||
| 1878 | return -EFAULT; | ||
| 1879 | /* This is the first, but there are more, abort. */ | ||
| 1880 | if (vma->vm_end < end) | ||
| 1881 | return -EFAULT; | ||
| 1882 | } | ||
| 1871 | 1883 | ||
| 1872 | res_vma = check_prep_vma(vrm); | 1884 | res_vma = check_prep_vma(vrm); |
| 1873 | if (!res_vma) | 1885 | if (!res_vma) |
| @@ -1876,7 +1888,7 @@ static unsigned long remap_move(struct vma_remap_struct *vrm) · 2 unmodified lines | |||
| 1876 | return res_vma; | 1888 | return res_vma; |
| 1877 | 1889 | ||
| 1878 | if (!seen_vma) { | 1890 | if (!seen_vma) { |
| 1879 | VM_WARN_ON_ONCE(allowed && res_vma != new_addr); | 1891 | VM_WARN_ON_ONCE(multi_allowed && res_vma != new_addr); |
| 1880 | res = res_vma; | 1892 | res = res_vma; |
| 1881 | } | 1893 | } |
| 1882 | 1894 | ||
| @@ -73,7 +73,7 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei, · 72 unmodified lines | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | printk(KERN_INFO "Faking node %d at [mem %#018Lx-%#018Lx] (%LuMB)\n", | 75 | printk(KERN_INFO "Faking node %d at [mem %#018Lx-%#018Lx] (%LuMB)\n", |
| 76 | nid, eb->start, eb->end - 1, (eb->end - eb->start) >> 20); | 76 | nid, eb->start, eb->end - 1, (eb->end - eb->start) / SZ_1M); |
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| @@ -264,7 +264,7 @@ static int __init split_nodes_size_interleave_uniform(struct numa_meminfo *ei, · 184 unmodified lines | |||
| 264 | min_size = ALIGN(max(min_size, FAKE_NODE_MIN_SIZE), FAKE_NODE_MIN_SIZE); | 264 | min_size = ALIGN(max(min_size, FAKE_NODE_MIN_SIZE), FAKE_NODE_MIN_SIZE); |
| 265 | if (size < min_size) { | 265 | if (size < min_size) { |
| 266 | pr_err("Fake node size %LuMB too small, increasing to %LuMB\n", | 266 | pr_err("Fake node size %LuMB too small, increasing to %LuMB\n", |
| 267 | size >> 20, min_size >> 20); | 267 | size / SZ_1M, min_size / SZ_1M); |
| 268 | size = min_size; | 268 | size = min_size; |
| 269 | } | 269 | } |
| 270 | size = ALIGN_DOWN(size, FAKE_NODE_MIN_SIZE); | 270 | size = ALIGN_DOWN(size, FAKE_NODE_MIN_SIZE); |
| @@ -76,7 +76,7 @@ static int __init numa_alloc_distance(void) · 75 unmodified lines | |||
| 76 | for (j = 0; j < cnt; j++) | 76 | for (j = 0; j < cnt; j++) |
| 77 | numa_distance[i * cnt + j] = i == j ? | 77 | numa_distance[i * cnt + j] = i == j ? |
| 78 | LOCAL_DISTANCE : REMOTE_DISTANCE; | 78 | LOCAL_DISTANCE : REMOTE_DISTANCE; |
| 79 | printk(KERN_DEBUG "NUMA: Initialized distance table, cnt=%d\n", cnt); | 79 | pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt); |
| 80 | 80 | ||
| 81 | return 0; | 81 | return 0; |
| 82 | } | 82 | } |
| @@ -427,9 +427,9 @@ static int __init numa_register_meminfo(struct numa_meminfo *mi) · 344 unmodified lines | |||
| 427 | unsigned long pfn_align = node_map_pfn_alignment(); | 427 | unsigned long pfn_align = node_map_pfn_alignment(); |
| 428 | 428 | ||
| 429 | if (pfn_align && pfn_align < PAGES_PER_SECTION) { | 429 | if (pfn_align && pfn_align < PAGES_PER_SECTION) { |
| 430 | unsigned long node_align_mb = PFN_PHYS(pfn_align) >> 20; | 430 | unsigned long node_align_mb = PFN_PHYS(pfn_align) / SZ_1M; |
| 431 | 431 | ||
| 432 | unsigned long sect_align_mb = PFN_PHYS(PAGES_PER_SECTION) >> 20; | 432 | unsigned long sect_align_mb = PFN_PHYS(PAGES_PER_SECTION) / SZ_1M; |
| 433 | 433 | ||
| 434 | pr_warn("Node alignment %luMB < min %luMB, rejecting NUMA config\n", | 434 | pr_warn("Node alignment %luMB < min %luMB, rejecting NUMA config\n", |
| 435 | node_align_mb, sect_align_mb); | 435 | node_align_mb, sect_align_mb); |
| @@ -5772,9 +5772,9 @@ static int __init init_lru_gen(void) · 5771 unmodified lines | |||
| 5772 | if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) | 5772 | if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) |
| 5773 | pr_err("lru_gen: failed to create sysfs group\n"); | 5773 | pr_err("lru_gen: failed to create sysfs group\n"); |
| 5774 | 5774 | ||
| 5775 | debugfs_create_file_aux_num("lru_gen", 0644, NULL, NULL, 1, | 5775 | debugfs_create_file_aux_num("lru_gen", 0644, NULL, NULL, false, |
| 5776 | &lru_gen_rw_fops); | 5776 | &lru_gen_rw_fops); |
| 5777 | debugfs_create_file_aux_num("lru_gen_full", 0444, NULL, NULL, 0, | 5777 | debugfs_create_file_aux_num("lru_gen_full", 0444, NULL, NULL, true, |
| 5778 | &lru_gen_ro_fops); | 5778 | &lru_gen_ro_fops); |
| 5779 | 5779 | ||
| 5780 | return 0; | 5780 | return 0; |
| @@ -2246,8 +2246,15 @@ EXPORT_SYMBOL_GPL(zs_destroy_pool); · 2245 unmodified lines | |||
| 2246 | 2246 | ||
| 2247 | static int __init zs_init(void) | 2247 | static int __init zs_init(void) |
| 2248 | { | 2248 | { |
| 2249 | int rc __maybe_unused; | ||
| 2250 | |||
| 2249 | #ifdef CONFIG_ZPOOL | 2251 | #ifdef CONFIG_ZPOOL |
| 2250 | zpool_register_driver(&zs_zpool_driver); | 2252 | zpool_register_driver(&zs_zpool_driver); |
| 2253 | #endif | ||
| 2254 | #ifdef CONFIG_COMPACTION | ||
| 2255 | rc = set_movable_ops(&zsmalloc_mops, PGTY_zsmalloc); | ||
| 2256 | if (rc) | ||
| 2257 | return rc; | ||
| 2251 | #endif | 2258 | #endif |
| 2252 | zs_stat_init(); | 2259 | zs_stat_init(); |
| 2253 | return 0; | 2260 | return 0; |
| @@ -2257,6 +2264,9 @@ static void __exit zs_exit(void) · 3 unmodified lines | |||
| 2257 | { | 2264 | { |
| 2258 | #ifdef CONFIG_ZPOOL | 2265 | #ifdef CONFIG_ZPOOL |
| 2259 | zpool_unregister_driver(&zs_zpool_driver); | 2266 | zpool_unregister_driver(&zs_zpool_driver); |
| 2267 | #endif | ||
| 2268 | #ifdef CONFIG_COMPACTION | ||
| 2269 | set_movable_ops(NULL, PGTY_zsmalloc); | ||
| 2260 | #endif | 2270 | #endif |
| 2261 | zs_stat_exit(); | 2271 | zs_stat_exit(); |
| 2262 | } | 2272 | } |
| @@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size) · 634 unmodified lines | |||
| 635 | 635 | ||
| 636 | skb->dev = NULL; /* for paths shared with net_device interfaces */ | 636 | skb->dev = NULL; /* for paths shared with net_device interfaces */ |
| 637 | if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) { | 637 | if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) { |
| 638 | atm_return_tx(vcc, skb); | ||
| 639 | kfree_skb(skb); | ||
| 640 | error = -EFAULT; | 638 | error = -EFAULT; |
| 641 | goto out; | 639 | goto free_skb; |
| 642 | } | 640 | } |
| 643 | if (eff != size) | 641 | if (eff != size) |
| 644 | memset(skb->data + size, 0, eff-size); | 642 | memset(skb->data + size, 0, eff-size); |
| 643 | |||
| 644 | if (vcc->dev->ops->pre_send) { | ||
| 645 | error = vcc->dev->ops->pre_send(vcc, skb); | ||
| 646 | if (error) | ||
| 647 | goto free_skb; | ||
| 648 | } | ||
| 649 | |||
| 645 | error = vcc->dev->ops->send(vcc, skb); | 650 | error = vcc->dev->ops->send(vcc, skb); |
| 646 | error = error ? error : size; | 651 | error = error ? error : size; |
| 647 | out: | 652 | out: |
| 648 | release_sock(sk); | 653 | release_sock(sk); |
| 649 | return error; | 654 | return error; |
| 655 | free_skb: | ||
| 656 | atm_return_tx(vcc, skb); | ||
| 657 | kfree_skb(skb); | ||
| 658 | goto out; | ||
| 650 | } | 659 | } |
| 651 | 660 | ||
| 652 | __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait) | 661 | __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait) |
| @@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn) · 148 unmodified lines | |||
| 149 | 149 | ||
| 150 | hci_chan_list_flush(conn); | 150 | hci_chan_list_flush(conn); |
| 151 | 151 | ||
| 152 | hci_conn_hash_del(hdev, conn); | ||
| 153 | |||
| 154 | if (HCI_CONN_HANDLE_UNSET(conn->handle)) | 152 | if (HCI_CONN_HANDLE_UNSET(conn->handle)) |
| 155 | ida_free(&hdev->unset_handle_ida, conn->handle); | 153 | ida_free(&hdev->unset_handle_ida, conn->handle); |
| 156 | 154 | ||
| @@ -1152,28 +1150,54 @@ void hci_conn_del(struct hci_conn *conn) · 995 unmodified lines | |||
| 1152 | disable_delayed_work_sync(&conn->auto_accept_work); | 1150 | disable_delayed_work_sync(&conn->auto_accept_work); |
| 1153 | disable_delayed_work_sync(&conn->idle_work); | 1151 | disable_delayed_work_sync(&conn->idle_work); |
| 1154 | 1152 | ||
| 1155 | if (conn->type == ACL_LINK) { | 1153 | /* Remove the connection from the list so unacked logic can detect when |
| 1156 | /* Unacked frames */ | 1154 | * a certain pool is not being utilized. |
| 1157 | hdev->acl_cnt += conn->sent; | 1155 | */ |
| 1158 | } else if (conn->type == LE_LINK) { | 1156 | hci_conn_hash_del(hdev, conn); |
| 1159 | cancel_delayed_work(&conn->le_conn_timeout); | ||
| 1160 | 1157 | ||
| 1161 | if (hdev->le_pkts) | 1158 | /* Handle unacked frames: |
| 1162 | hdev->le_cnt += conn->sent; | 1159 | * |
| 1160 | * - In case there are no connection, or if restoring the buffers | ||
| 1161 | * considered in transist would overflow, restore all buffers to the | ||
| 1162 | * pool. | ||
| 1163 | * - Otherwise restore just the buffers considered in transit for the | ||
| 1164 | * hci_conn | ||
| 1165 | */ | ||
| 1166 | switch (conn->type) { | ||
| 1167 | case ACL_LINK: | ||
| 1168 | if (!hci_conn_num(hdev, ACL_LINK) || | ||
| 1169 | hdev->acl_cnt + conn->sent > hdev->acl_pkts) | ||
| 1170 | hdev->acl_cnt = hdev->acl_pkts; | ||
| 1163 | else | 1171 | else |
| 1164 | hdev->acl_cnt += conn->sent; | 1172 | hdev->acl_cnt += conn->sent; |
| 1165 | } else { | 1173 | break; |
| 1166 | /* Unacked ISO frames */ | 1174 | case LE_LINK: |
| 1167 | if (conn->type == CIS_LINK || | 1175 | cancel_delayed_work(&conn->le_conn_timeout); |
| 1168 | conn->type == BIS_LINK || | 1176 | |
| 1169 | conn->type == PA_LINK) { | 1177 | if (hdev->le_pkts) { |
| 1170 | if (hdev->iso_pkts) | 1178 | if (!hci_conn_num(hdev, LE_LINK) || |
| 1171 | hdev->iso_cnt += conn->sent; | 1179 | hdev->le_cnt + conn->sent > hdev->le_pkts) |
| 1172 | else if (hdev->le_pkts) | 1180 | hdev->le_cnt = hdev->le_pkts; |
| 1181 | else | ||
| 1173 | hdev->le_cnt += conn->sent; | 1182 | hdev->le_cnt += conn->sent; |
| 1183 | } else { | ||
| 1184 | if ((!hci_conn_num(hdev, LE_LINK) && | ||
| 1185 | !hci_conn_num(hdev, ACL_LINK)) || | ||
| 1186 | hdev->acl_cnt + conn->sent > hdev->acl_pkts) | ||
| 1187 | hdev->acl_cnt = hdev->acl_pkts; | ||
| 1174 | else | 1188 | else |
| 1175 | hdev->acl_cnt += conn->sent; | 1189 | hdev->acl_cnt += conn->sent; |
| 1176 | } | 1190 | } |
| 1191 | break; | ||
| 1192 | case CIS_LINK: | ||
| 1193 | case BIS_LINK: | ||
| 1194 | case PA_LINK: | ||
| 1195 | if (!hci_iso_count(hdev) || | ||
| 1196 | hdev->iso_cnt + conn->sent > hdev->iso_pkts) | ||
| 1197 | hdev->iso_cnt = hdev->iso_pkts; | ||
| 1198 | else | ||
| 1199 | hdev->iso_cnt += conn->sent; | ||
| 1200 | break; | ||
| 1177 | } | 1201 | } |
| 1178 | 1202 | ||
| 1179 | skb_queue_purge(&conn->data_q); | 1203 | skb_queue_purge(&conn->data_q); |
| @@ -2703,7 +2703,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 2702 unmodified lines | |||
| 2703 | if (!conn) | 2703 | if (!conn) |
| 2704 | goto unlock; | 2704 | goto unlock; |
| 2705 | 2705 | ||
| 2706 | if (status) { | 2706 | if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) { |
| 2707 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, | 2707 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, |
| 2708 | conn->dst_type, status); | 2708 | conn->dst_type, status); |
| 2709 | 2709 | ||
| @@ -2718,6 +2718,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 8 unmodified lines | |||
| 2718 | goto done; | 2718 | goto done; |
| 2719 | } | 2719 | } |
| 2720 | 2720 | ||
| 2721 | /* During suspend, mark connection as closed immediately | ||
| 2722 | * since we might not receive HCI_EV_DISCONN_COMPLETE | ||
| 2723 | */ | ||
| 2724 | if (hdev->suspended) | ||
| 2725 | conn->state = BT_CLOSED; | ||
| 2726 | |||
| 2721 | mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); | 2727 | mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags); |
| 2722 | 2728 | ||
| 2723 | if (conn->type == ACL_LINK) { | 2729 | if (conn->type == ACL_LINK) { |
| @@ -4398,7 +4404,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data, · 1674 unmodified lines | |||
| 4398 | if (!conn) | 4404 | if (!conn) |
| 4399 | continue; | 4405 | continue; |
| 4400 | 4406 | ||
| 4401 | conn->sent -= count; | 4407 | /* Check if there is really enough packets outstanding before |
| 4408 | * attempting to decrease the sent counter otherwise it could | ||
| 4409 | * underflow.. | ||
| 4410 | */ | ||
| 4411 | if (conn->sent >= count) { | ||
| 4412 | conn->sent -= count; | ||
| 4413 | } else { | ||
| 4414 | bt_dev_warn(hdev, "hcon %p sent %u < count %u", | ||
| 4415 | conn, conn->sent, count); | ||
| 4416 | conn->sent = 0; | ||
| 4417 | } | ||
| 4402 | 4418 | ||
| 4403 | for (i = 0; i < count; ++i) | 4419 | for (i = 0; i < count; ++i) |
| 4404 | hci_conn_tx_dequeue(conn); | 4420 | hci_conn_tx_dequeue(conn); |
| @@ -7008,6 +7024,7 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, · 2603 unmodified lines | |||
| 7008 | { | 7024 | { |
| 7009 | struct hci_evt_le_big_sync_lost *ev = data; | 7025 | struct hci_evt_le_big_sync_lost *ev = data; |
| 7010 | struct hci_conn *bis, *conn; | 7026 | struct hci_conn *bis, *conn; |
| 7027 | bool mgmt_conn; | ||
| 7011 | 7028 | ||
| 7012 | bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle); | 7029 | bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle); |
| 7013 | 7030 | ||
| @@ -7026,6 +7043,10 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data, · 12 unmodified lines | |||
| 7026 | while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle, | 7043 | while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle, |
| 7027 | BT_CONNECTED, | 7044 | BT_CONNECTED, |
| 7028 | HCI_ROLE_SLAVE))) { | 7045 | HCI_ROLE_SLAVE))) { |
| 7046 | mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags); | ||
| 7047 | mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type, | ||
| 7048 | ev->reason, mgmt_conn); | ||
| 7049 | |||
| 7029 | clear_bit(HCI_CONN_BIG_SYNC, &bis->flags); | 7050 | clear_bit(HCI_CONN_BIG_SYNC, &bis->flags); |
| 7030 | hci_disconn_cfm(bis, ev->reason); | 7051 | hci_disconn_cfm(bis, ev->reason); |
| 7031 | hci_conn_del(bis); | 7052 | hci_conn_del(bis); |
| @@ -3481,13 +3481,13 @@ int hci_update_scan_sync(struct hci_dev *hdev) · 3480 unmodified lines | |||
| 3481 | return hci_write_scan_enable_sync(hdev, scan); | 3481 | return hci_write_scan_enable_sync(hdev, scan); |
| 3482 | } | 3482 | } |
| 3483 | 3483 | ||
| 3484 | int hci_update_name_sync(struct hci_dev *hdev) | 3484 | int hci_update_name_sync(struct hci_dev *hdev, const u8 *name) |
| 3485 | { | 3485 | { |
| 3486 | struct hci_cp_write_local_name cp; | 3486 | struct hci_cp_write_local_name cp; |
| 3487 | 3487 | ||
| 3488 | memset(&cp, 0, sizeof(cp)); | 3488 | memset(&cp, 0, sizeof(cp)); |
| 3489 | 3489 | ||
| 3490 | memcpy(cp.name, hdev->dev_name, sizeof(cp.name)); | 3490 | memcpy(cp.name, name, sizeof(cp.name)); |
| 3491 | 3491 | ||
| 3492 | return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME, | 3492 | return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME, |
| 3493 | sizeof(cp), &cp, | 3493 | sizeof(cp), &cp, |
| @@ -3540,7 +3540,7 @@ int hci_powered_update_sync(struct hci_dev *hdev) · 46 unmodified lines | |||
| 3540 | hci_write_fast_connectable_sync(hdev, false); | 3540 | hci_write_fast_connectable_sync(hdev, false); |
| 3541 | hci_update_scan_sync(hdev); | 3541 | hci_update_scan_sync(hdev); |
| 3542 | hci_update_class_sync(hdev); | 3542 | hci_update_class_sync(hdev); |
| 3543 | hci_update_name_sync(hdev); | 3543 | hci_update_name_sync(hdev, hdev->dev_name); |
| 3544 | hci_update_eir_sync(hdev); | 3544 | hci_update_eir_sync(hdev); |
| 3545 | } | 3545 | } |
| 3546 | 3546 | ||
| @@ -3892,8 +3892,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err) · 3891 unmodified lines | |||
| 3892 | 3892 | ||
| 3893 | static int set_name_sync(struct hci_dev *hdev, void *data) | 3893 | static int set_name_sync(struct hci_dev *hdev, void *data) |
| 3894 | { | 3894 | { |
| 3895 | struct mgmt_pending_cmd *cmd = data; | ||
| 3896 | struct mgmt_cp_set_local_name *cp = cmd->param; | ||
| 3897 | |||
| 3895 | if (lmp_bredr_capable(hdev)) { | 3898 | if (lmp_bredr_capable(hdev)) { |
| 3896 | hci_update_name_sync(hdev); | 3899 | hci_update_name_sync(hdev, cp->name); |
| 3897 | hci_update_eir_sync(hdev); | 3900 | hci_update_eir_sync(hdev); |
| 3898 | } | 3901 | } |
| 3899 | 3902 | ||
| @@ -9705,7 +9708,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, · 5805 unmodified lines | |||
| 9705 | if (!mgmt_connected) | 9708 | if (!mgmt_connected) |
| 9706 | return; | 9709 | return; |
| 9707 | 9710 | ||
| 9708 | if (link_type != ACL_LINK && link_type != LE_LINK) | 9711 | if (link_type != ACL_LINK && |
| 9712 | link_type != LE_LINK && | ||
| 9713 | link_type != BIS_LINK) | ||
| 9709 | return; | 9714 | return; |
| 9710 | 9715 | ||
| 9711 | bacpy(&ev.addr.bdaddr, bdaddr); | 9716 | bacpy(&ev.addr.bdaddr, bdaddr); |
| @@ -618,6 +618,20 @@ fault: · 617 unmodified lines | |||
| 618 | } | 618 | } |
| 619 | EXPORT_SYMBOL(skb_copy_datagram_from_iter); | 619 | EXPORT_SYMBOL(skb_copy_datagram_from_iter); |
| 620 | 620 | ||
| 621 | int skb_copy_datagram_from_iter_full(struct sk_buff *skb, int offset, | ||
| 622 | struct iov_iter *from, int len) | ||
| 623 | { | ||
| 624 | struct iov_iter_state state; | ||
| 625 | int ret; | ||
| 626 | |||
| 627 | iov_iter_save_state(from, &state); | ||
| 628 | ret = skb_copy_datagram_from_iter(skb, offset, from, len); | ||
| 629 | if (ret) | ||
| 630 | iov_iter_restore(from, &state); | ||
| 631 | return ret; | ||
| 632 | } | ||
| 633 | EXPORT_SYMBOL(skb_copy_datagram_from_iter_full); | ||
| 634 | |||
| 621 | int zerocopy_fill_skb_from_iter(struct sk_buff *skb, | 635 | int zerocopy_fill_skb_from_iter(struct sk_buff *skb, |
| 622 | struct iov_iter *from, size_t length) | 636 | struct iov_iter *from, size_t length) |
| 623 | { | 637 | { |
| @@ -287,8 +287,10 @@ static int page_pool_init(struct page_pool *pool, · 286 unmodified lines | |||
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | if (pool->mp_ops) { | 289 | if (pool->mp_ops) { |
| 290 | if (!pool->dma_map || !pool->dma_sync) | 290 | if (!pool->dma_map || !pool->dma_sync) { |
| 291 | return -EOPNOTSUPP; | 291 | err = -EOPNOTSUPP; |
| 292 | goto free_ptr_ring; | ||
| 293 | } | ||
| 292 | 294 | ||
| 293 | if (WARN_ON(!is_kernel_rodata((unsigned long)pool->mp_ops))) { | 295 | if (WARN_ON(!is_kernel_rodata((unsigned long)pool->mp_ops))) { |
| 294 | err = -EFAULT; | 296 | err = -EFAULT; |
| @@ -2576,12 +2576,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res, · 2575 unmodified lines | |||
| 2576 | !netif_is_l3_master(dev_out)) | 2576 | !netif_is_l3_master(dev_out)) |
| 2577 | return ERR_PTR(-EINVAL); | 2577 | return ERR_PTR(-EINVAL); |
| 2578 | 2578 | ||
| 2579 | if (ipv4_is_lbcast(fl4->daddr)) | 2579 | if (ipv4_is_lbcast(fl4->daddr)) { |
| 2580 | type = RTN_BROADCAST; | 2580 | type = RTN_BROADCAST; |
| 2581 | else if (ipv4_is_multicast(fl4->daddr)) | 2581 | |
| 2582 | /* reset fi to prevent gateway resolution */ | ||
| 2583 | fi = NULL; | ||
| 2584 | } else if (ipv4_is_multicast(fl4->daddr)) { | ||
| 2582 | type = RTN_MULTICAST; | 2585 | type = RTN_MULTICAST; |
| 2583 | else if (ipv4_is_zeronet(fl4->daddr)) | 2586 | } else if (ipv4_is_zeronet(fl4->daddr)) { |
| 2584 | return ERR_PTR(-EINVAL); | 2587 | return ERR_PTR(-EINVAL); |
| 2588 | } | ||
| 2585 | 2589 | ||
| 2586 | if (dev_out->flags & IFF_LOOPBACK) | 2590 | if (dev_out->flags & IFF_LOOPBACK) |
| 2587 | flags |= RTCF_LOCAL; | 2591 | flags |= RTCF_LOCAL; |
| @@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = { · 128 unmodified lines | |||
| 129 | 129 | ||
| 130 | static const struct proto_ops pppol2tp_ops; | 130 | static const struct proto_ops pppol2tp_ops; |
| 131 | 131 | ||
| 132 | /* Retrieves the pppol2tp socket associated to a session. | 132 | /* Retrieves the pppol2tp socket associated to a session. */ |
| 133 | * A reference is held on the returned socket, so this function must be paired | ||
| 134 | * with sock_put(). | ||
| 135 | */ | ||
| 136 | static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session) | 133 | static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session) |
| 137 | { | 134 | { |
| 138 | struct pppol2tp_session *ps = l2tp_session_priv(session); | 135 | struct pppol2tp_session *ps = l2tp_session_priv(session); |
| 139 | struct sock *sk; | ||
| 140 | |||
| 141 | rcu_read_lock(); | ||
| 142 | sk = rcu_dereference(ps->sk); | ||
| 143 | if (sk) | ||
| 144 | sock_hold(sk); | ||
| 145 | rcu_read_unlock(); | ||
| 146 | 136 | ||
| 147 | return sk; | 137 | return rcu_dereference(ps->sk); |
| 148 | } | 138 | } |
| 149 | 139 | ||
| 150 | /* Helpers to obtain tunnel/session contexts from sockets. | 140 | /* Helpers to obtain tunnel/session contexts from sockets. |
| @@ -206,14 +196,13 @@ end: · 55 unmodified lines | |||
| 206 | 196 | ||
| 207 | static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) | 197 | static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) |
| 208 | { | 198 | { |
| 209 | struct pppol2tp_session *ps = l2tp_session_priv(session); | 199 | struct sock *sk; |
| 210 | struct sock *sk = NULL; | ||
| 211 | 200 | ||
| 212 | /* If the socket is bound, send it in to PPP's input queue. Otherwise | 201 | /* If the socket is bound, send it in to PPP's input queue. Otherwise |
| 213 | * queue it on the session socket. | 202 | * queue it on the session socket. |
| 214 | */ | 203 | */ |
| 215 | rcu_read_lock(); | 204 | rcu_read_lock(); |
| 216 | sk = rcu_dereference(ps->sk); | 205 | sk = pppol2tp_session_get_sock(session); |
| 217 | if (!sk) | 206 | if (!sk) |
| 218 | goto no_sock; | 207 | goto no_sock; |
| 219 | 208 | ||
| @@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg) · 290 unmodified lines | |||
| 510 | struct l2tp_session *session = arg; | 499 | struct l2tp_session *session = arg; |
| 511 | struct sock *sk; | 500 | struct sock *sk; |
| 512 | 501 | ||
| 502 | rcu_read_lock(); | ||
| 513 | sk = pppol2tp_session_get_sock(session); | 503 | sk = pppol2tp_session_get_sock(session); |
| 514 | if (sk) { | 504 | if (sk) { |
| 515 | struct pppox_sock *po = pppox_sk(sk); | 505 | struct pppox_sock *po = pppox_sk(sk); |
| 516 | 506 | ||
| 517 | seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); | 507 | seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); |
| 518 | sock_put(sk); | ||
| 519 | } | 508 | } |
| 509 | rcu_read_unlock(); | ||
| 520 | } | 510 | } |
| 521 | 511 | ||
| 522 | static void pppol2tp_session_init(struct l2tp_session *session) | 512 | static void pppol2tp_session_init(struct l2tp_session *session) |
| @@ -1530,6 +1520,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) · 1007 unmodified lines | |||
| 1530 | port = ntohs(inet->inet_sport); | 1520 | port = ntohs(inet->inet_sport); |
| 1531 | } | 1521 | } |
| 1532 | 1522 | ||
| 1523 | rcu_read_lock(); | ||
| 1533 | sk = pppol2tp_session_get_sock(session); | 1524 | sk = pppol2tp_session_get_sock(session); |
| 1534 | if (sk) { | 1525 | if (sk) { |
| 1535 | state = sk->sk_state; | 1526 | state = sk->sk_state; |
| @@ -1565,8 +1556,8 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v) · 29 unmodified lines | |||
| 1565 | struct pppox_sock *po = pppox_sk(sk); | 1556 | struct pppox_sock *po = pppox_sk(sk); |
| 1566 | 1557 | ||
| 1567 | seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); | 1558 | seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); |
| 1568 | sock_put(sk); | ||
| 1569 | } | 1559 | } |
| 1560 | rcu_read_unlock(); | ||
| 1570 | } | 1561 | } |
| 1571 | 1562 | ||
| 1572 | static int pppol2tp_seq_show(struct seq_file *m, void *v) | 1563 | static int pppol2tp_seq_show(struct seq_file *m, void *v) |
| @@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh) · 169 unmodified lines | |||
| 170 | 170 | ||
| 171 | if (rose->neighbour == neigh) { | 171 | if (rose->neighbour == neigh) { |
| 172 | rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); | 172 | rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); |
| 173 | rose->neighbour->use--; | 173 | rose_neigh_put(rose->neighbour); |
| 174 | rose->neighbour = NULL; | 174 | rose->neighbour = NULL; |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| @@ -212,7 +212,7 @@ start: · 35 unmodified lines | |||
| 212 | if (rose->device == dev) { | 212 | if (rose->device == dev) { |
| 213 | rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); | 213 | rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0); |
| 214 | if (rose->neighbour) | 214 | if (rose->neighbour) |
| 215 | rose->neighbour->use--; | 215 | rose_neigh_put(rose->neighbour); |
| 216 | netdev_put(rose->device, &rose->dev_tracker); | 216 | netdev_put(rose->device, &rose->dev_tracker); |
| 217 | rose->device = NULL; | 217 | rose->device = NULL; |
| 218 | } | 218 | } |
| @@ -655,7 +655,7 @@ static int rose_release(struct socket *sock) · 436 unmodified lines | |||
| 655 | break; | 655 | break; |
| 656 | 656 | ||
| 657 | case ROSE_STATE_2: | 657 | case ROSE_STATE_2: |
| 658 | rose->neighbour->use--; | 658 | rose_neigh_put(rose->neighbour); |
| 659 | release_sock(sk); | 659 | release_sock(sk); |
| 660 | rose_disconnect(sk, 0, -1, -1); | 660 | rose_disconnect(sk, 0, -1, -1); |
| 661 | lock_sock(sk); | 661 | lock_sock(sk); |
| @@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le · 161 unmodified lines | |||
| 823 | rose->lci = rose_new_lci(rose->neighbour); | 823 | rose->lci = rose_new_lci(rose->neighbour); |
| 824 | if (!rose->lci) { | 824 | if (!rose->lci) { |
| 825 | err = -ENETUNREACH; | 825 | err = -ENETUNREACH; |
| 826 | rose_neigh_put(rose->neighbour); | ||
| 826 | goto out_release; | 827 | goto out_release; |
| 827 | } | 828 | } |
| 828 | 829 | ||
| @@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le · 5 unmodified lines | |||
| 834 | dev = rose_dev_first(); | 835 | dev = rose_dev_first(); |
| 835 | if (!dev) { | 836 | if (!dev) { |
| 836 | err = -ENETUNREACH; | 837 | err = -ENETUNREACH; |
| 838 | rose_neigh_put(rose->neighbour); | ||
| 837 | goto out_release; | 839 | goto out_release; |
| 838 | } | 840 | } |
| 839 | 841 | ||
| 840 | user = ax25_findbyuid(current_euid()); | 842 | user = ax25_findbyuid(current_euid()); |
| 841 | if (!user) { | 843 | if (!user) { |
| 842 | err = -EINVAL; | 844 | err = -EINVAL; |
| 845 | rose_neigh_put(rose->neighbour); | ||
| 843 | dev_put(dev); | 846 | dev_put(dev); |
| 844 | goto out_release; | 847 | goto out_release; |
| 845 | } | 848 | } |
| @@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le · 28 unmodified lines | |||
| 874 | 877 | ||
| 875 | rose->state = ROSE_STATE_1; | 878 | rose->state = ROSE_STATE_1; |
| 876 | 879 | ||
| 877 | rose->neighbour->use++; | ||
| 878 | |||
| 879 | rose_write_internal(sk, ROSE_CALL_REQUEST); | 880 | rose_write_internal(sk, ROSE_CALL_REQUEST); |
| 880 | rose_start_heartbeat(sk); | 881 | rose_start_heartbeat(sk); |
| 881 | rose_start_t1timer(sk); | 882 | rose_start_t1timer(sk); |
| @@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros · 195 unmodified lines | |||
| 1077 | GFP_ATOMIC); | 1078 | GFP_ATOMIC); |
| 1078 | make_rose->facilities = facilities; | 1079 | make_rose->facilities = facilities; |
| 1079 | 1080 | ||
| 1080 | make_rose->neighbour->use++; | 1081 | rose_neigh_hold(make_rose->neighbour); |
| 1081 | 1082 | ||
| 1082 | if (rose_sk(sk)->defer) { | 1083 | if (rose_sk(sk)->defer) { |
| 1083 | make_rose->state = ROSE_STATE_5; | 1084 | make_rose->state = ROSE_STATE_5; |
| @@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety · 55 unmodified lines | |||
| 56 | case ROSE_CLEAR_REQUEST: | 56 | case ROSE_CLEAR_REQUEST: |
| 57 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); | 57 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); |
| 58 | rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); | 58 | rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); |
| 59 | rose->neighbour->use--; | 59 | rose_neigh_put(rose->neighbour); |
| 60 | break; | 60 | break; |
| 61 | 61 | ||
| 62 | default: | 62 | default: |
| @@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety · 16 unmodified lines | |||
| 79 | case ROSE_CLEAR_REQUEST: | 79 | case ROSE_CLEAR_REQUEST: |
| 80 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); | 80 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); |
| 81 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); | 81 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 82 | rose->neighbour->use--; | 82 | rose_neigh_put(rose->neighbour); |
| 83 | break; | 83 | break; |
| 84 | 84 | ||
| 85 | case ROSE_CLEAR_CONFIRMATION: | 85 | case ROSE_CLEAR_CONFIRMATION: |
| 86 | rose_disconnect(sk, 0, -1, -1); | 86 | rose_disconnect(sk, 0, -1, -1); |
| 87 | rose->neighbour->use--; | 87 | rose_neigh_put(rose->neighbour); |
| 88 | break; | 88 | break; |
| 89 | 89 | ||
| 90 | default: | 90 | default: |
| @@ -121,7 +121,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety · 30 unmodified lines | |||
| 121 | case ROSE_CLEAR_REQUEST: | 121 | case ROSE_CLEAR_REQUEST: |
| 122 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); | 122 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); |
| 123 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); | 123 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 124 | rose->neighbour->use--; | 124 | rose_neigh_put(rose->neighbour); |
| 125 | break; | 125 | break; |
| 126 | 126 | ||
| 127 | case ROSE_RR: | 127 | case ROSE_RR: |
| @@ -234,7 +234,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety · 106 unmodified lines | |||
| 234 | case ROSE_CLEAR_REQUEST: | 234 | case ROSE_CLEAR_REQUEST: |
| 235 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); | 235 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); |
| 236 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); | 236 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 237 | rose->neighbour->use--; | 237 | rose_neigh_put(rose->neighbour); |
| 238 | break; | 238 | break; |
| 239 | 239 | ||
| 240 | default: | 240 | default: |
| @@ -254,7 +254,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety · 13 unmodified lines | |||
| 254 | if (frametype == ROSE_CLEAR_REQUEST) { | 254 | if (frametype == ROSE_CLEAR_REQUEST) { |
| 255 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); | 255 | rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION); |
| 256 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); | 256 | rose_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 257 | rose_sk(sk)->neighbour->use--; | 257 | rose_neigh_put(rose_sk(sk)->neighbour); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | return 0; | 260 | return 0; |
| @@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, · 92 unmodified lines | |||
| 93 | rose_neigh->ax25 = NULL; | 93 | rose_neigh->ax25 = NULL; |
| 94 | rose_neigh->dev = dev; | 94 | rose_neigh->dev = dev; |
| 95 | rose_neigh->count = 0; | 95 | rose_neigh->count = 0; |
| 96 | rose_neigh->use = 0; | ||
| 97 | rose_neigh->dce_mode = 0; | 96 | rose_neigh->dce_mode = 0; |
| 98 | rose_neigh->loopback = 0; | 97 | rose_neigh->loopback = 0; |
| 99 | rose_neigh->number = rose_neigh_no++; | 98 | rose_neigh->number = rose_neigh_no++; |
| 100 | rose_neigh->restarted = 0; | 99 | rose_neigh->restarted = 0; |
| 100 | refcount_set(&rose_neigh->use, 1); | ||
| 101 | 101 | ||
| 102 | skb_queue_head_init(&rose_neigh->queue); | 102 | skb_queue_head_init(&rose_neigh->queue); |
| 103 | 103 | ||
| @@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, · 74 unmodified lines | |||
| 178 | } | 178 | } |
| 179 | } | 179 | } |
| 180 | rose_neigh->count++; | 180 | rose_neigh->count++; |
| 181 | rose_neigh_hold(rose_neigh); | ||
| 181 | 182 | ||
| 182 | goto out; | 183 | goto out; |
| 183 | } | 184 | } |
| @@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, · 3 unmodified lines | |||
| 187 | rose_node->neighbour[rose_node->count] = rose_neigh; | 188 | rose_node->neighbour[rose_node->count] = rose_neigh; |
| 188 | rose_node->count++; | 189 | rose_node->count++; |
| 189 | rose_neigh->count++; | 190 | rose_neigh->count++; |
| 191 | rose_neigh_hold(rose_neigh); | ||
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | out: | 194 | out: |
| @@ -234,20 +236,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) · 41 unmodified lines | |||
| 234 | 236 | ||
| 235 | if ((s = rose_neigh_list) == rose_neigh) { | 237 | if ((s = rose_neigh_list) == rose_neigh) { |
| 236 | rose_neigh_list = rose_neigh->next; | 238 | rose_neigh_list = rose_neigh->next; |
| 237 | if (rose_neigh->ax25) | ||
| 238 | ax25_cb_put(rose_neigh->ax25); | ||
| 239 | kfree(rose_neigh->digipeat); | ||
| 240 | kfree(rose_neigh); | ||
| 241 | return; | 239 | return; |
| 242 | } | 240 | } |
| 243 | 241 | ||
| 244 | while (s != NULL && s->next != NULL) { | 242 | while (s != NULL && s->next != NULL) { |
| 245 | if (s->next == rose_neigh) { | 243 | if (s->next == rose_neigh) { |
| 246 | s->next = rose_neigh->next; | 244 | s->next = rose_neigh->next; |
| 247 | if (rose_neigh->ax25) | ||
| 248 | ax25_cb_put(rose_neigh->ax25); | ||
| 249 | kfree(rose_neigh->digipeat); | ||
| 250 | kfree(rose_neigh); | ||
| 251 | return; | 245 | return; |
| 252 | } | 246 | } |
| 253 | 247 | ||
| @@ -263,10 +257,10 @@ static void rose_remove_route(struct rose_route *rose_route) · 9 unmodified lines | |||
| 263 | struct rose_route *s; | 257 | struct rose_route *s; |
| 264 | 258 | ||
| 265 | if (rose_route->neigh1 != NULL) | 259 | if (rose_route->neigh1 != NULL) |
| 266 | rose_route->neigh1->use--; | 260 | rose_neigh_put(rose_route->neigh1); |
| 267 | 261 | ||
| 268 | if (rose_route->neigh2 != NULL) | 262 | if (rose_route->neigh2 != NULL) |
| 269 | rose_route->neigh2->use--; | 263 | rose_neigh_put(rose_route->neigh2); |
| 270 | 264 | ||
| 271 | if ((s = rose_route_list) == rose_route) { | 265 | if ((s = rose_route_list) == rose_route) { |
| 272 | rose_route_list = rose_route->next; | 266 | rose_route_list = rose_route->next; |
| @@ -330,9 +324,12 @@ static int rose_del_node(struct rose_route_struct *rose_route, · 57 unmodified lines | |||
| 330 | for (i = 0; i < rose_node->count; i++) { | 324 | for (i = 0; i < rose_node->count; i++) { |
| 331 | if (rose_node->neighbour[i] == rose_neigh) { | 325 | if (rose_node->neighbour[i] == rose_neigh) { |
| 332 | rose_neigh->count--; | 326 | rose_neigh->count--; |
| 327 | rose_neigh_put(rose_neigh); | ||
| 333 | 328 | ||
| 334 | if (rose_neigh->count == 0 && rose_neigh->use == 0) | 329 | if (rose_neigh->count == 0) { |
| 335 | rose_remove_neigh(rose_neigh); | 330 | rose_remove_neigh(rose_neigh); |
| 331 | rose_neigh_put(rose_neigh); | ||
| 332 | } | ||
| 336 | 333 | ||
| 337 | rose_node->count--; | 334 | rose_node->count--; |
| 338 | 335 | ||
| @@ -381,11 +378,11 @@ void rose_add_loopback_neigh(void) · 42 unmodified lines | |||
| 381 | sn->ax25 = NULL; | 378 | sn->ax25 = NULL; |
| 382 | sn->dev = NULL; | 379 | sn->dev = NULL; |
| 383 | sn->count = 0; | 380 | sn->count = 0; |
| 384 | sn->use = 0; | ||
| 385 | sn->dce_mode = 1; | 381 | sn->dce_mode = 1; |
| 386 | sn->loopback = 1; | 382 | sn->loopback = 1; |
| 387 | sn->number = rose_neigh_no++; | 383 | sn->number = rose_neigh_no++; |
| 388 | sn->restarted = 1; | 384 | sn->restarted = 1; |
| 385 | refcount_set(&sn->use, 1); | ||
| 389 | 386 | ||
| 390 | skb_queue_head_init(&sn->queue); | 387 | skb_queue_head_init(&sn->queue); |
| 391 | 388 | ||
| @@ -436,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address) · 44 unmodified lines | |||
| 436 | rose_node_list = rose_node; | 433 | rose_node_list = rose_node; |
| 437 | 434 | ||
| 438 | rose_loopback_neigh->count++; | 435 | rose_loopback_neigh->count++; |
| 436 | rose_neigh_hold(rose_loopback_neigh); | ||
| 439 | 437 | ||
| 440 | out: | 438 | out: |
| 441 | spin_unlock_bh(&rose_node_list_lock); | 439 | spin_unlock_bh(&rose_node_list_lock); |
| @@ -467,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address) · 25 unmodified lines | |||
| 467 | rose_remove_node(rose_node); | 465 | rose_remove_node(rose_node); |
| 468 | 466 | ||
| 469 | rose_loopback_neigh->count--; | 467 | rose_loopback_neigh->count--; |
| 468 | rose_neigh_put(rose_loopback_neigh); | ||
| 470 | 469 | ||
| 471 | out: | 470 | out: |
| 472 | spin_unlock_bh(&rose_node_list_lock); | 471 | spin_unlock_bh(&rose_node_list_lock); |
| @@ -506,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev) · 33 unmodified lines | |||
| 506 | memmove(&t->neighbour[i], &t->neighbour[i + 1], | 505 | memmove(&t->neighbour[i], &t->neighbour[i + 1], |
| 507 | sizeof(t->neighbour[0]) * | 506 | sizeof(t->neighbour[0]) * |
| 508 | (t->count - i)); | 507 | (t->count - i)); |
| 508 | rose_neigh_put(s); | ||
| 509 | } | 509 | } |
| 510 | 510 | ||
| 511 | if (t->count <= 0) | 511 | if (t->count <= 0) |
| @@ -513,6 +513,7 @@ void rose_rt_device_down(struct net_device *dev) · 1 unmodified line | |||
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | rose_remove_neigh(s); | 515 | rose_remove_neigh(s); |
| 516 | rose_neigh_put(s); | ||
| 516 | } | 517 | } |
| 517 | spin_unlock_bh(&rose_neigh_list_lock); | 518 | spin_unlock_bh(&rose_neigh_list_lock); |
| 518 | spin_unlock_bh(&rose_node_list_lock); | 519 | spin_unlock_bh(&rose_node_list_lock); |
| @@ -548,6 +549,7 @@ static int rose_clear_routes(void) · 29 unmodified lines | |||
| 548 | { | 549 | { |
| 549 | struct rose_neigh *s, *rose_neigh; | 550 | struct rose_neigh *s, *rose_neigh; |
| 550 | struct rose_node *t, *rose_node; | 551 | struct rose_node *t, *rose_node; |
| 552 | int i; | ||
| 551 | 553 | ||
| 552 | spin_lock_bh(&rose_node_list_lock); | 554 | spin_lock_bh(&rose_node_list_lock); |
| 553 | spin_lock_bh(&rose_neigh_list_lock); | 555 | spin_lock_bh(&rose_neigh_list_lock); |
| @@ -558,17 +560,21 @@ static int rose_clear_routes(void) · 4 unmodified lines | |||
| 558 | while (rose_node != NULL) { | 560 | while (rose_node != NULL) { |
| 559 | t = rose_node; | 561 | t = rose_node; |
| 560 | rose_node = rose_node->next; | 562 | rose_node = rose_node->next; |
| 561 | if (!t->loopback) | 563 | |
| 564 | if (!t->loopback) { | ||
| 565 | for (i = 0; i < t->count; i++) | ||
| 566 | rose_neigh_put(t->neighbour[i]); | ||
| 562 | rose_remove_node(t); | 567 | rose_remove_node(t); |
| 568 | } | ||
| 563 | } | 569 | } |
| 564 | 570 | ||
| 565 | while (rose_neigh != NULL) { | 571 | while (rose_neigh != NULL) { |
| 566 | s = rose_neigh; | 572 | s = rose_neigh; |
| 567 | rose_neigh = rose_neigh->next; | 573 | rose_neigh = rose_neigh->next; |
| 568 | 574 | ||
| 569 | if (s->use == 0 && !s->loopback) { | 575 | if (!s->loopback) { |
| 570 | s->count = 0; | ||
| 571 | rose_remove_neigh(s); | 576 | rose_remove_neigh(s); |
| 577 | rose_neigh_put(s); | ||
| 572 | } | 578 | } |
| 573 | } | 579 | } |
| 574 | 580 | ||
| @@ -684,6 +690,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, · 109 unmodified lines | |||
| 684 | for (i = 0; i < node->count; i++) { | 690 | for (i = 0; i < node->count; i++) { |
| 685 | if (node->neighbour[i]->restarted) { | 691 | if (node->neighbour[i]->restarted) { |
| 686 | res = node->neighbour[i]; | 692 | res = node->neighbour[i]; |
| 693 | rose_neigh_hold(node->neighbour[i]); | ||
| 687 | goto out; | 694 | goto out; |
| 688 | } | 695 | } |
| 689 | } | 696 | } |
| @@ -695,6 +702,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, · 5 unmodified lines | |||
| 695 | for (i = 0; i < node->count; i++) { | 702 | for (i = 0; i < node->count; i++) { |
| 696 | if (!rose_ftimer_running(node->neighbour[i])) { | 703 | if (!rose_ftimer_running(node->neighbour[i])) { |
| 697 | res = node->neighbour[i]; | 704 | res = node->neighbour[i]; |
| 705 | rose_neigh_hold(node->neighbour[i]); | ||
| 698 | goto out; | 706 | goto out; |
| 699 | } | 707 | } |
| 700 | failed = 1; | 708 | failed = 1; |
| @@ -784,13 +792,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh) · 83 unmodified lines | |||
| 784 | } | 792 | } |
| 785 | 793 | ||
| 786 | if (rose_route->neigh1 == rose_neigh) { | 794 | if (rose_route->neigh1 == rose_neigh) { |
| 787 | rose_route->neigh1->use--; | 795 | rose_neigh_put(rose_route->neigh1); |
| 788 | rose_route->neigh1 = NULL; | 796 | rose_route->neigh1 = NULL; |
| 789 | rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0); | 797 | rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0); |
| 790 | } | 798 | } |
| 791 | 799 | ||
| 792 | if (rose_route->neigh2 == rose_neigh) { | 800 | if (rose_route->neigh2 == rose_neigh) { |
| 793 | rose_route->neigh2->use--; | 801 | rose_neigh_put(rose_route->neigh2); |
| 794 | rose_route->neigh2 = NULL; | 802 | rose_route->neigh2 = NULL; |
| 795 | rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0); | 803 | rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0); |
| 796 | } | 804 | } |
| @@ -919,7 +927,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) · 122 unmodified lines | |||
| 919 | rose_clear_queues(sk); | 927 | rose_clear_queues(sk); |
| 920 | rose->cause = ROSE_NETWORK_CONGESTION; | 928 | rose->cause = ROSE_NETWORK_CONGESTION; |
| 921 | rose->diagnostic = 0; | 929 | rose->diagnostic = 0; |
| 922 | rose->neighbour->use--; | 930 | rose_neigh_put(rose->neighbour); |
| 923 | rose->neighbour = NULL; | 931 | rose->neighbour = NULL; |
| 924 | rose->lci = 0; | 932 | rose->lci = 0; |
| 925 | rose->state = ROSE_STATE_0; | 933 | rose->state = ROSE_STATE_0; |
| @@ -1044,12 +1052,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) · 118 unmodified lines | |||
| 1044 | 1052 | ||
| 1045 | if ((new_lci = rose_new_lci(new_neigh)) == 0) { | 1053 | if ((new_lci = rose_new_lci(new_neigh)) == 0) { |
| 1046 | rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71); | 1054 | rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71); |
| 1047 | goto out; | 1055 | goto put_neigh; |
| 1048 | } | 1056 | } |
| 1049 | 1057 | ||
| 1050 | if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) { | 1058 | if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) { |
| 1051 | rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120); | 1059 | rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120); |
| 1052 | goto out; | 1060 | goto put_neigh; |
| 1053 | } | 1061 | } |
| 1054 | 1062 | ||
| 1055 | rose_route->lci1 = lci; | 1063 | rose_route->lci1 = lci; |
| @@ -1062,8 +1070,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) · 6 unmodified lines | |||
| 1062 | rose_route->lci2 = new_lci; | 1070 | rose_route->lci2 = new_lci; |
| 1063 | rose_route->neigh2 = new_neigh; | 1071 | rose_route->neigh2 = new_neigh; |
| 1064 | 1072 | ||
| 1065 | rose_route->neigh1->use++; | 1073 | rose_neigh_hold(rose_route->neigh1); |
| 1066 | rose_route->neigh2->use++; | 1074 | rose_neigh_hold(rose_route->neigh2); |
| 1067 | 1075 | ||
| 1068 | rose_route->next = rose_route_list; | 1076 | rose_route->next = rose_route_list; |
| 1069 | rose_route_list = rose_route; | 1077 | rose_route_list = rose_route; |
| @@ -1075,6 +1083,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) · 5 unmodified lines | |||
| 1075 | rose_transmit_link(skb, rose_route->neigh2); | 1083 | rose_transmit_link(skb, rose_route->neigh2); |
| 1076 | res = 1; | 1084 | res = 1; |
| 1077 | 1085 | ||
| 1086 | put_neigh: | ||
| 1087 | rose_neigh_put(new_neigh); | ||
| 1078 | out: | 1088 | out: |
| 1079 | spin_unlock_bh(&rose_route_list_lock); | 1089 | spin_unlock_bh(&rose_route_list_lock); |
| 1080 | spin_unlock_bh(&rose_neigh_list_lock); | 1090 | spin_unlock_bh(&rose_neigh_list_lock); |
| @@ -1190,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v) · 109 unmodified lines | |||
| 1190 | (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign), | 1200 | (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign), |
| 1191 | rose_neigh->dev ? rose_neigh->dev->name : "???", | 1201 | rose_neigh->dev ? rose_neigh->dev->name : "???", |
| 1192 | rose_neigh->count, | 1202 | rose_neigh->count, |
| 1193 | rose_neigh->use, | 1203 | refcount_read(&rose_neigh->use) - rose_neigh->count - 1, |
| 1194 | (rose_neigh->dce_mode) ? "DCE" : "DTE", | 1204 | (rose_neigh->dce_mode) ? "DCE" : "DTE", |
| 1195 | (rose_neigh->restarted) ? "yes" : "no", | 1205 | (rose_neigh->restarted) ? "yes" : "no", |
| 1196 | ax25_display_timer(&rose_neigh->t0timer) / HZ, | 1206 | ax25_display_timer(&rose_neigh->t0timer) / HZ, |
| @@ -1295,18 +1305,22 @@ void __exit rose_rt_free(void) · 98 unmodified lines | |||
| 1295 | struct rose_neigh *s, *rose_neigh = rose_neigh_list; | 1305 | struct rose_neigh *s, *rose_neigh = rose_neigh_list; |
| 1296 | struct rose_node *t, *rose_node = rose_node_list; | 1306 | struct rose_node *t, *rose_node = rose_node_list; |
| 1297 | struct rose_route *u, *rose_route = rose_route_list; | 1307 | struct rose_route *u, *rose_route = rose_route_list; |
| 1308 | int i; | ||
| 1298 | 1309 | ||
| 1299 | while (rose_neigh != NULL) { | 1310 | while (rose_neigh != NULL) { |
| 1300 | s = rose_neigh; | 1311 | s = rose_neigh; |
| 1301 | rose_neigh = rose_neigh->next; | 1312 | rose_neigh = rose_neigh->next; |
| 1302 | 1313 | ||
| 1303 | rose_remove_neigh(s); | 1314 | rose_remove_neigh(s); |
| 1315 | rose_neigh_put(s); | ||
| 1304 | } | 1316 | } |
| 1305 | 1317 | ||
| 1306 | while (rose_node != NULL) { | 1318 | while (rose_node != NULL) { |
| 1307 | t = rose_node; | 1319 | t = rose_node; |
| 1308 | rose_node = rose_node->next; | 1320 | rose_node = rose_node->next; |
| 1309 | 1321 | ||
| 1322 | for (i = 0; i < t->count; i++) | ||
| 1323 | rose_neigh_put(t->neighbour[i]); | ||
| 1310 | rose_remove_node(t); | 1324 | rose_remove_node(t); |
| 1311 | } | 1325 | } |
| 1312 | 1326 | ||
| @@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t) · 179 unmodified lines | |||
| 180 | break; | 180 | break; |
| 181 | 181 | ||
| 182 | case ROSE_STATE_2: /* T3 */ | 182 | case ROSE_STATE_2: /* T3 */ |
| 183 | rose->neighbour->use--; | 183 | rose_neigh_put(rose->neighbour); |
| 184 | rose_disconnect(sk, ETIMEDOUT, -1, -1); | 184 | rose_disconnect(sk, ETIMEDOUT, -1, -1); |
| 185 | break; | 185 | break; |
| 186 | 186 | ||
| @@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk) · 546 unmodified lines | |||
| 547 | { | 547 | { |
| 548 | addr->v6.sin6_family = AF_INET6; | 548 | addr->v6.sin6_family = AF_INET6; |
| 549 | addr->v6.sin6_port = 0; | 549 | addr->v6.sin6_port = 0; |
| 550 | addr->v6.sin6_flowinfo = 0; | ||
| 550 | addr->v6.sin6_addr = sk->sk_v6_rcv_saddr; | 551 | addr->v6.sin6_addr = sk->sk_v6_rcv_saddr; |
| 552 | addr->v6.sin6_scope_id = 0; | ||
| 551 | } | 553 | } |
| 552 | 554 | ||
| 553 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ | 555 | /* Initialize sk->sk_rcv_saddr from sctp_addr. */ |
| @@ -105,12 +105,14 @@ static int virtio_transport_fill_skb(struct sk_buff *skb, · 104 unmodified lines | |||
| 105 | size_t len, | 105 | size_t len, |
| 106 | bool zcopy) | 106 | bool zcopy) |
| 107 | { | 107 | { |
| 108 | struct msghdr *msg = info->msg; | ||
| 109 | |||
| 108 | if (zcopy) | 110 | if (zcopy) |
| 109 | return __zerocopy_sg_from_iter(info->msg, NULL, skb, | 111 | return __zerocopy_sg_from_iter(msg, NULL, skb, |
| 110 | &info->msg->msg_iter, len, NULL); | 112 | &msg->msg_iter, len, NULL); |
| 111 | 113 | ||
| 112 | virtio_vsock_skb_put(skb, len); | 114 | virtio_vsock_skb_put(skb, len); |
| 113 | return skb_copy_datagram_from_iter(skb, 0, &info->msg->msg_iter, len); | 115 | return skb_copy_datagram_from_iter_full(skb, 0, &msg->msg_iter, len); |
| 114 | } | 116 | } |
| 115 | 117 | ||
| 116 | static void virtio_transport_init_hdr(struct sk_buff *skb, | 118 | static void virtio_transport_init_hdr(struct sk_buff *skb, |
| @@ -43,17 +43,6 @@ pub struct Vmalloc; · 42 unmodified lines | |||
| 43 | /// For more details see [self]. | 43 | /// For more details see [self]. |
| 44 | pub struct KVmalloc; | 44 | pub struct KVmalloc; |
| 45 | 45 | ||
| 46 | /// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. | ||
| 47 | fn aligned_size(new_layout: Layout) -> usize { | ||
| 48 | // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. | ||
| 49 | let layout = new_layout.pad_to_align(); | ||
| 50 | |||
| 51 | // Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()` | ||
| 52 | // which together with the slab guarantees means the `krealloc` will return a properly aligned | ||
| 53 | // object (see comments in `kmalloc()` for more information). | ||
| 54 | layout.size() | ||
| 55 | } | ||
| 56 | |||
| 57 | /// # Invariants | 46 | /// # Invariants |
| 58 | /// | 47 | /// |
| 59 | /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`. | 48 | /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`. |
| @@ -88,7 +77,7 @@ impl ReallocFunc { · 28 unmodified lines | |||
| 88 | old_layout: Layout, | 77 | old_layout: Layout, |
| 89 | flags: Flags, | 78 | flags: Flags, |
| 90 | ) -> Result<NonNull<[u8]>, AllocError> { | 79 | ) -> Result<NonNull<[u8]>, AllocError> { |
| 91 | let size = aligned_size(layout); | 80 | let size = layout.size(); |
| 92 | let ptr = match ptr { | 81 | let ptr = match ptr { |
| 93 | Some(ptr) => { | 82 | Some(ptr) => { |
| 94 | if old_layout.size() == 0 { | 83 | if old_layout.size() == 0 { |
| @@ -123,6 +112,17 @@ impl ReallocFunc { · 28 unmodified lines | |||
| 123 | } | 112 | } |
| 124 | } | 113 | } |
| 125 | 114 | ||
| 115 | impl Kmalloc { | ||
| 116 | /// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of | ||
| 117 | /// `layout`. | ||
| 118 | pub fn aligned_layout(layout: Layout) -> Layout { | ||
| 119 | // Note that `layout.size()` (after padding) is guaranteed to be a multiple of | ||
| 120 | // `layout.align()` which together with the slab guarantees means that `Kmalloc` will return | ||
| 121 | // a properly aligned object (see comments in `kmalloc()` for more information). | ||
| 122 | layout.pad_to_align() | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | // SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that | 126 | // SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that |
| 127 | // - memory remains valid until it is explicitly freed, | 127 | // - memory remains valid until it is explicitly freed, |
| 128 | // - passing a pointer to a valid memory allocation is OK, | 128 | // - passing a pointer to a valid memory allocation is OK, |
| @@ -135,6 +135,8 @@ unsafe impl Allocator for Kmalloc { · 6 unmodified lines | |||
| 135 | old_layout: Layout, | 135 | old_layout: Layout, |
| 136 | flags: Flags, | 136 | flags: Flags, |
| 137 | ) -> Result<NonNull<[u8]>, AllocError> { | 137 | ) -> Result<NonNull<[u8]>, AllocError> { |
| 138 | let layout = Kmalloc::aligned_layout(layout); | ||
| 139 | |||
| 138 | // SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`. | 140 | // SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`. |
| 139 | unsafe { ReallocFunc::KREALLOC.call(ptr, layout, old_layout, flags) } | 141 | unsafe { ReallocFunc::KREALLOC.call(ptr, layout, old_layout, flags) } |
| 140 | } | 142 | } |
| @@ -176,6 +178,10 @@ unsafe impl Allocator for KVmalloc { · 35 unmodified lines | |||
| 176 | old_layout: Layout, | 178 | old_layout: Layout, |
| 177 | flags: Flags, | 179 | flags: Flags, |
| 178 | ) -> Result<NonNull<[u8]>, AllocError> { | 180 | ) -> Result<NonNull<[u8]>, AllocError> { |
| 181 | // `KVmalloc` may use the `Kmalloc` backend, hence we have to enforce a `Kmalloc` | ||
| 182 | // compatible layout. | ||
| 183 | let layout = Kmalloc::aligned_layout(layout); | ||
| 184 | |||
| 179 | // TODO: Support alignments larger than PAGE_SIZE. | 185 | // TODO: Support alignments larger than PAGE_SIZE. |
| 180 | if layout.align() > bindings::PAGE_SIZE { | 186 | if layout.align() > bindings::PAGE_SIZE { |
| 181 | pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n"); | 187 | pr_warn!("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n"); |
| @@ -22,6 +22,17 @@ pub type Kmalloc = Cmalloc; · 21 unmodified lines | |||
| 22 | pub type Vmalloc = Kmalloc; | 22 | pub type Vmalloc = Kmalloc; |
| 23 | pub type KVmalloc = Kmalloc; | 23 | pub type KVmalloc = Kmalloc; |
| 24 | 24 | ||
| 25 | impl Cmalloc { | ||
| 26 | /// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of | ||
| 27 | /// `layout`. | ||
| 28 | pub fn aligned_layout(layout: Layout) -> Layout { | ||
| 29 | // Note that `layout.size()` (after padding) is guaranteed to be a multiple of | ||
| 30 | // `layout.align()` which together with the slab guarantees means that `Kmalloc` will return | ||
| 31 | // a properly aligned object (see comments in `kmalloc()` for more information). | ||
| 32 | layout.pad_to_align() | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 25 | extern "C" { | 36 | extern "C" { |
| 26 | #[link_name = "aligned_alloc"] | 37 | #[link_name = "aligned_alloc"] |
| 27 | fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void; | 38 | fn libc_aligned_alloc(align: usize, size: usize) -> *mut crate::ffi::c_void; |
| @@ -15,23 +15,130 @@ use crate::c_str; · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | pub mod property; | 16 | pub mod property; |
| 17 | 17 | ||
| 18 | /// A reference-counted device. | 18 | /// The core representation of a device in the kernel's driver model. |
| 19 | /// | 19 | /// |
| 20 | /// This structure represents the Rust abstraction for a C `struct device`. This implementation | 20 | /// This structure represents the Rust abstraction for a C `struct device`. A [`Device`] can either |
| 21 | /// abstracts the usage of an already existing C `struct device` within Rust code that we get | 21 | /// exist as temporary reference (see also [`Device::from_raw`]), which is only valid within a |
| 22 | /// passed from the C side. | 22 | /// certain scope or as [`ARef<Device>`], owning a dedicated reference count. |
| 23 | /// | 23 | /// |
| 24 | /// An instance of this abstraction can be obtained temporarily or permanent. | 24 | /// # Device Types |
| 25 | /// | 25 | /// |
| 26 | /// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation. | 26 | /// A [`Device`] can represent either a bus device or a class device. |
| 27 | /// A permanent instance is always reference-counted and hence not restricted by any lifetime | ||
| 28 | /// boundaries. | ||
| 29 | /// | 27 | /// |
| 30 | /// For subsystems it is recommended to create a permanent instance to wrap into a subsystem | 28 | /// ## Bus Devices |
| 31 | /// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in | 29 | /// |
| 32 | /// `T::probe()`, such that a driver can store the `ARef<Device>` (equivalent to storing a | 30 | /// A bus device is a [`Device`] that is associated with a physical or virtual bus. Examples of |
| 33 | /// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent | 31 | /// buses include PCI, USB, I2C, and SPI. Devices attached to a bus are registered with a specific |
| 34 | /// memory. | 32 | /// bus type, which facilitates matching devices with appropriate drivers based on IDs or other |
| 33 | /// identifying information. Bus devices are visible in sysfs under `/sys/bus/<bus-name>/devices/`. | ||
| 34 | /// | ||
| 35 | /// ## Class Devices | ||
| 36 | /// | ||
| 37 | /// A class device is a [`Device`] that is associated with a logical category of functionality | ||
| 38 | /// rather than a physical bus. Examples of classes include block devices, network interfaces, sound | ||
| 39 | /// cards, and input devices. Class devices are grouped under a common class and exposed to | ||
| 40 | /// userspace via entries in `/sys/class/<class-name>/`. | ||
| 41 | /// | ||
| 42 | /// # Device Context | ||
| 43 | /// | ||
| 44 | /// [`Device`] references are generic over a [`DeviceContext`], which represents the type state of | ||
| 45 | /// a [`Device`]. | ||
| 46 | /// | ||
| 47 | /// As the name indicates, this type state represents the context of the scope the [`Device`] | ||
| 48 | /// reference is valid in. For instance, the [`Bound`] context guarantees that the [`Device`] is | ||
| 49 | /// bound to a driver for the entire duration of the existence of a [`Device<Bound>`] reference. | ||
| 50 | /// | ||
| 51 | /// Other [`DeviceContext`] types besides [`Bound`] are [`Normal`], [`Core`] and [`CoreInternal`]. | ||
| 52 | /// | ||
| 53 | /// Unless selected otherwise [`Device`] defaults to the [`Normal`] [`DeviceContext`], which by | ||
| 54 | /// itself has no additional requirements. | ||
| 55 | /// | ||
| 56 | /// It is always up to the caller of [`Device::from_raw`] to select the correct [`DeviceContext`] | ||
| 57 | /// type for the corresponding scope the [`Device`] reference is created in. | ||
| 58 | /// | ||
| 59 | /// All [`DeviceContext`] types other than [`Normal`] are intended to be used with | ||
| 60 | /// [bus devices](#bus-devices) only. | ||
| 61 | /// | ||
| 62 | /// # Implementing Bus Devices | ||
| 63 | /// | ||
| 64 | /// This section provides a guideline to implement bus specific devices, such as [`pci::Device`] or | ||
| 65 | /// [`platform::Device`]. | ||
| 66 | /// | ||
| 67 | /// A bus specific device should be defined as follows. | ||
| 68 | /// | ||
| 69 | /// ```ignore | ||
| 70 | /// #[repr(transparent)] | ||
| 71 | /// pub struct Device<Ctx: device::DeviceContext = device::Normal>( | ||
| 72 | /// Opaque<bindings::bus_device_type>, | ||
| 73 | /// PhantomData<Ctx>, | ||
| 74 | /// ); | ||
| 75 | /// ``` | ||
| 76 | /// | ||
| 77 | /// Since devices are reference counted, [`AlwaysRefCounted`] should be implemented for `Device` | ||
| 78 | /// (i.e. `Device<Normal>`). Note that [`AlwaysRefCounted`] must not be implemented for any other | ||
| 79 | /// [`DeviceContext`], since all other device context types are only valid within a certain scope. | ||
| 80 | /// | ||
| 81 | /// In order to be able to implement the [`DeviceContext`] dereference hierarchy, bus device | ||
| 82 | /// implementations should call the [`impl_device_context_deref`] macro as shown below. | ||
| 83 | /// | ||
| 84 | /// ```ignore | ||
| 85 | /// // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s | ||
| 86 | /// // generic argument. | ||
| 87 | /// kernel::impl_device_context_deref!(unsafe { Device }); | ||
| 88 | /// ``` | ||
| 89 | /// | ||
| 90 | /// In order to convert from a any [`Device<Ctx>`] to [`ARef<Device>`], bus devices can implement | ||
| 91 | /// the following macro call. | ||
| 92 | /// | ||
| 93 | /// ```ignore | ||
| 94 | /// kernel::impl_device_context_into_aref!(Device); | ||
| 95 | /// ``` | ||
| 96 | /// | ||
| 97 | /// Bus devices should also implement the following [`AsRef`] implementation, such that users can | ||
| 98 | /// easily derive a generic [`Device`] reference. | ||
| 99 | /// | ||
| 100 | /// ```ignore | ||
| 101 | /// impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> { | ||
| 102 | /// fn as_ref(&self) -> &device::Device<Ctx> { | ||
| 103 | /// ... | ||
| 104 | /// } | ||
| 105 | /// } | ||
| 106 | /// ``` | ||
| 107 | /// | ||
| 108 | /// # Implementing Class Devices | ||
| 109 | /// | ||
| 110 | /// Class device implementations require less infrastructure and depend slightly more on the | ||
| 111 | /// specific subsystem. | ||
| 112 | /// | ||
| 113 | /// An example implementation for a class device could look like this. | ||
| 114 | /// | ||
| 115 | /// ```ignore | ||
| 116 | /// #[repr(C)] | ||
| 117 | /// pub struct Device<T: class::Driver> { | ||
| 118 | /// dev: Opaque<bindings::class_device_type>, | ||
| 119 | /// data: T::Data, | ||
| 120 | /// } | ||
| 121 | /// ``` | ||
| 122 | /// | ||
| 123 | /// This class device uses the sub-classing pattern to embed the driver's private data within the | ||
| 124 | /// allocation of the class device. For this to be possible the class device is generic over the | ||
| 125 | /// class specific `Driver` trait implementation. | ||
| 126 | /// | ||
| 127 | /// Just like any device, class devices are reference counted and should hence implement | ||
| 128 | /// [`AlwaysRefCounted`] for `Device`. | ||
| 129 | /// | ||
| 130 | /// Class devices should also implement the following [`AsRef`] implementation, such that users can | ||
| 131 | /// easily derive a generic [`Device`] reference. | ||
| 132 | /// | ||
| 133 | /// ```ignore | ||
| 134 | /// impl<T: class::Driver> AsRef<device::Device> for Device<T> { | ||
| 135 | /// fn as_ref(&self) -> &device::Device { | ||
| 136 | /// ... | ||
| 137 | /// } | ||
| 138 | /// } | ||
| 139 | /// ``` | ||
| 140 | /// | ||
| 141 | /// An example for a class device implementation is [`drm::Device`]. | ||
| 35 | /// | 142 | /// |
| 36 | /// # Invariants | 143 | /// # Invariants |
| 37 | /// | 144 | /// |
| @@ -42,6 +149,12 @@ pub mod property; · 4 unmodified lines | |||
| 42 | /// | 149 | /// |
| 43 | /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be | 150 | /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be |
| 44 | /// dropped from any thread. | 151 | /// dropped from any thread. |
| 152 | /// | ||
| 153 | /// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted | ||
| 154 | /// [`drm::Device`]: kernel::drm::Device | ||
| 155 | /// [`impl_device_context_deref`]: kernel::impl_device_context_deref | ||
| 156 | /// [`pci::Device`]: kernel::pci::Device | ||
| 157 | /// [`platform::Device`]: kernel::platform::Device | ||
| 45 | #[repr(transparent)] | 158 | #[repr(transparent)] |
| 46 | pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>); | 159 | pub struct Device<Ctx: DeviceContext = Normal>(Opaque<bindings::device>, PhantomData<Ctx>); |
| 47 | 160 | ||
| @@ -311,28 +424,75 @@ unsafe impl Send for Device {} · 263 unmodified lines | |||
| 311 | // synchronization in `struct device`. | 424 | // synchronization in `struct device`. |
| 312 | unsafe impl Sync for Device {} | 425 | unsafe impl Sync for Device {} |
| 313 | 426 | ||
| 314 | /// Marker trait for the context of a bus specific device. | 427 | /// Marker trait for the context or scope of a bus specific device. |
| 428 | /// | ||
| 429 | /// [`DeviceContext`] is a marker trait for types representing the context of a bus specific | ||
| 430 | /// [`Device`]. | ||
| 431 | /// | ||
| 432 | /// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. | ||
| 315 | /// | 433 | /// |
| 316 | /// Some functions of a bus specific device should only be called from a certain context, i.e. bus | 434 | /// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that |
| 317 | /// callbacks, such as `probe()`. | 435 | /// defines which [`DeviceContext`] type can be derived from another. For instance, any |
| 436 | /// [`Device<Core>`] can dereference to a [`Device<Bound>`]. | ||
| 318 | /// | 437 | /// |
| 319 | /// This is the marker trait for structures representing the context of a bus specific device. | 438 | /// The following enumeration illustrates the dereference hierarchy of [`DeviceContext`] types. |
| 439 | /// | ||
| 440 | /// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] | ||
| 441 | /// | ||
| 442 | /// Bus devices can automatically implement the dereference hierarchy by using | ||
| 443 | /// [`impl_device_context_deref`]. | ||
| 444 | /// | ||
| 445 | /// Note that the guarantee for a [`Device`] reference to have a certain [`DeviceContext`] comes | ||
| 446 | /// from the specific scope the [`Device`] reference is valid in. | ||
| 447 | /// | ||
| 448 | /// [`impl_device_context_deref`]: kernel::impl_device_context_deref | ||
| 320 | pub trait DeviceContext: private::Sealed {} | 449 | pub trait DeviceContext: private::Sealed {} |
| 321 | 450 | ||
| 322 | /// The [`Normal`] context is the context of a bus specific device when it is not an argument of | 451 | /// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`]. |
| 323 | /// any bus callback. | 452 | /// |
| 453 | /// The normal context does not indicate any specific context. Any `Device<Ctx>` is also a valid | ||
| 454 | /// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement | ||
| 455 | /// [`AlwaysRefCounted`] for. | ||
| 456 | /// | ||
| 457 | /// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted | ||
| 324 | pub struct Normal; | 458 | pub struct Normal; |
| 325 | 459 | ||
| 326 | /// The [`Core`] context is the context of a bus specific device when it is supplied as argument of | 460 | /// The [`Core`] context is the context of a bus specific device when it appears as argument of |
| 327 | /// any of the bus callbacks, such as `probe()`. | 461 | /// any bus specific callback, such as `probe()`. |
| 462 | /// | ||
| 463 | /// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus | ||
| 464 | /// callback it appears in. It is intended to be used for synchronization purposes. Bus device | ||
| 465 | /// implementations can implement methods for [`Device<Core>`], such that they can only be called | ||
| 466 | /// from bus callbacks. | ||
| 328 | pub struct Core; | 467 | pub struct Core; |
| 329 | 468 | ||
| 330 | /// Semantically the same as [`Core`] but reserved for internal usage of the corresponding bus | 469 | /// Semantically the same as [`Core`], but reserved for internal usage of the corresponding bus |
| 331 | /// abstraction. | 470 | /// abstraction. |
| 471 | /// | ||
| 472 | /// The internal core context is intended to be used in exactly the same way as the [`Core`] | ||
| 473 | /// context, with the difference that this [`DeviceContext`] is internal to the corresponding bus | ||
| 474 | /// abstraction. | ||
| 475 | /// | ||
| 476 | /// This context mainly exists to share generic [`Device`] infrastructure that should only be called | ||
| 477 | /// from bus callbacks with bus abstractions, but without making them accessible for drivers. | ||
| 332 | pub struct CoreInternal; | 478 | pub struct CoreInternal; |
| 333 | 479 | ||
| 334 | /// The [`Bound`] context is the context of a bus specific device reference when it is guaranteed to | 480 | /// The [`Bound`] context is the [`DeviceContext`] of a bus specific device when it is guaranteed to |
| 335 | /// be bound for the duration of its lifetime. | 481 | /// be bound to a driver. |
| 482 | /// | ||
| 483 | /// The bound context indicates that for the entire duration of the lifetime of a [`Device<Bound>`] | ||
| 484 | /// reference, the [`Device`] is guaranteed to be bound to a driver. | ||
| 485 | /// | ||
| 486 | /// Some APIs, such as [`dma::CoherentAllocation`] or [`Devres`] rely on the [`Device`] to be bound, | ||
| 487 | /// which can be proven with the [`Bound`] device context. | ||
| 488 | /// | ||
| 489 | /// Any abstraction that can guarantee a scope where the corresponding bus device is bound, should | ||
| 490 | /// provide a [`Device<Bound>`] reference to its users for this scope. This allows users to benefit | ||
| 491 | /// from optimizations for accessing device resources, see also [`Devres::access`]. | ||
| 492 | /// | ||
| 493 | /// [`Devres`]: kernel::devres::Devres | ||
| 494 | /// [`Devres::access`]: kernel::devres::Devres::access | ||
| 495 | /// [`dma::CoherentAllocation`]: kernel::dma::CoherentAllocation | ||
| 336 | pub struct Bound; | 496 | pub struct Bound; |
| 337 | 497 | ||
| 338 | mod private { | 498 | mod private { |
| @@ -115,10 +115,11 @@ pub struct Devres<T: Send> { · 114 unmodified lines | |||
| 115 | /// Contains all the fields shared with [`Self::callback`]. | 115 | /// Contains all the fields shared with [`Self::callback`]. |
| 116 | // TODO: Replace with `UnsafePinned`, once available. | 116 | // TODO: Replace with `UnsafePinned`, once available. |
| 117 | // | 117 | // |
| 118 | // Subsequently, the `drop_in_place()` in `Devres::drop` and the explicit `Send` and `Sync' | 118 | // Subsequently, the `drop_in_place()` in `Devres::drop` and `Devres::new` as well as the |
| 119 | // impls can be removed. | 119 | // explicit `Send` and `Sync' impls can be removed. |
| 120 | #[pin] | 120 | #[pin] |
| 121 | inner: Opaque<Inner<T>>, | 121 | inner: Opaque<Inner<T>>, |
| 122 | _add_action: (), | ||
| 122 | } | 123 | } |
| 123 | 124 | ||
| 124 | impl<T: Send> Devres<T> { | 125 | impl<T: Send> Devres<T> { |
| @@ -140,7 +141,15 @@ impl<T: Send> Devres<T> { · 15 unmodified lines | |||
| 140 | dev: dev.into(), | 141 | dev: dev.into(), |
| 141 | callback, | 142 | callback, |
| 142 | // INVARIANT: `inner` is properly initialized. | 143 | // INVARIANT: `inner` is properly initialized. |
| 143 | inner <- { | 144 | inner <- Opaque::pin_init(try_pin_init!(Inner { |
| 145 | devm <- Completion::new(), | ||
| 146 | revoke <- Completion::new(), | ||
| 147 | data <- Revocable::new(data), | ||
| 148 | })), | ||
| 149 | // TODO: Replace with "initializer code blocks" [1] once available. | ||
| 150 | // | ||
| 151 | // [1] https://github.com/Rust-for-Linux/pin-init/pull/69 | ||
| 152 | _add_action: { | ||
| 144 | // SAFETY: `this` is a valid pointer to uninitialized memory. | 153 | // SAFETY: `this` is a valid pointer to uninitialized memory. |
| 145 | let inner = unsafe { &raw mut (*this.as_ptr()).inner }; | 154 | let inner = unsafe { &raw mut (*this.as_ptr()).inner }; |
| 146 | 155 | ||
| @@ -152,13 +161,13 @@ impl<T: Send> Devres<T> { · 5 unmodified lines | |||
| 152 | // live at least as long as the returned `impl PinInit<Self, Error>`. | 161 | // live at least as long as the returned `impl PinInit<Self, Error>`. |
| 153 | to_result(unsafe { | 162 | to_result(unsafe { |
| 154 | bindings::devm_add_action(dev.as_raw(), Some(callback), inner.cast()) | 163 | bindings::devm_add_action(dev.as_raw(), Some(callback), inner.cast()) |
| 155 | })?; | 164 | }).inspect_err(|_| { |
| 165 | let inner = Opaque::cast_into(inner); | ||
| 156 | 166 | ||
| 157 | Opaque::pin_init(try_pin_init!(Inner { | 167 | // SAFETY: `inner` is a valid pointer to an `Inner<T>` and valid for both reads |
| 158 | devm <- Completion::new(), | 168 | // and writes. |
| 159 | revoke <- Completion::new(), | 169 | unsafe { core::ptr::drop_in_place(inner) }; |
| 160 | data <- Revocable::new(data), | 170 | })?; |
| 161 | })) | ||
| 162 | }, | 171 | }, |
| 163 | }) | 172 | }) |
| 164 | } | 173 | } |
| @@ -2,8 +2,93 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | //! Generic support for drivers of different buses (e.g., PCI, Platform, Amba, etc.). | 3 | //! Generic support for drivers of different buses (e.g., PCI, Platform, Amba, etc.). |
| 4 | //! | 4 | //! |
| 5 | //! Each bus / subsystem is expected to implement [`RegistrationOps`], which allows drivers to | 5 | //! This documentation describes how to implement a bus specific driver API and how to align it with |
| 6 | //! register using the [`Registration`] class. | 6 | //! the design of (bus specific) devices. |
| 7 | //! | ||
| 8 | //! Note: Readers are expected to know the content of the documentation of [`Device`] and | ||
| 9 | //! [`DeviceContext`]. | ||
| 10 | //! | ||
| 11 | //! # Driver Trait | ||
| 12 | //! | ||
| 13 | //! The main driver interface is defined by a bus specific driver trait. For instance: | ||
| 14 | //! | ||
| 15 | //! ```ignore | ||
| 16 | //! pub trait Driver: Send { | ||
| 17 | //! /// The type holding information about each device ID supported by the driver. | ||
| 18 | //! type IdInfo: 'static; | ||
| 19 | //! | ||
| 20 | //! /// The table of OF device ids supported by the driver. | ||
| 21 | //! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; | ||
| 22 | //! | ||
| 23 | //! /// The table of ACPI device ids supported by the driver. | ||
| 24 | //! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; | ||
| 25 | //! | ||
| 26 | //! /// Driver probe. | ||
| 27 | //! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; | ||
| 28 | //! | ||
| 29 | //! /// Driver unbind (optional). | ||
| 30 | //! fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) { | ||
| 31 | //! let _ = (dev, this); | ||
| 32 | //! } | ||
| 33 | //! } | ||
| 34 | //! ``` | ||
| 35 | //! | ||
| 36 | //! For specific examples see [`auxiliary::Driver`], [`pci::Driver`] and [`platform::Driver`]. | ||
| 37 | //! | ||
| 38 | //! The `probe()` callback should return a `Result<Pin<KBox<Self>>>`, i.e. the driver's private | ||
| 39 | //! data. The bus abstraction should store the pointer in the corresponding bus device. The generic | ||
| 40 | //! [`Device`] infrastructure provides common helpers for this purpose on its | ||
| 41 | //! [`Device<CoreInternal>`] implementation. | ||
| 42 | //! | ||
| 43 | //! All driver callbacks should provide a reference to the driver's private data. Once the driver | ||
| 44 | //! is unbound from the device, the bus abstraction should take back the ownership of the driver's | ||
| 45 | //! private data from the corresponding [`Device`] and [`drop`] it. | ||
| 46 | //! | ||
| 47 | //! All driver callbacks should provide a [`Device<Core>`] reference (see also [`device::Core`]). | ||
| 48 | //! | ||
| 49 | //! # Adapter | ||
| 50 | //! | ||
| 51 | //! The adapter implementation of a bus represents the abstraction layer between the C bus | ||
| 52 | //! callbacks and the Rust bus callbacks. It therefore has to be generic over an implementation of | ||
| 53 | //! the [driver trait](#driver-trait). | ||
| 54 | //! | ||
| 55 | //! ```ignore | ||
| 56 | //! pub struct Adapter<T: Driver>; | ||
| 57 | //! ``` | ||
| 58 | //! | ||
| 59 | //! There's a common [`Adapter`] trait that can be implemented to inherit common driver | ||
| 60 | //! infrastructure, such as finding the ID info from an [`of::IdTable`] or [`acpi::IdTable`]. | ||
| 61 | //! | ||
| 62 | //! # Driver Registration | ||
| 63 | //! | ||
| 64 | //! In order to register C driver types (such as `struct platform_driver`) the [adapter](#adapter) | ||
| 65 | //! should implement the [`RegistrationOps`] trait. | ||
| 66 | //! | ||
| 67 | //! This trait implementation can be used to create the actual registration with the common | ||
| 68 | //! [`Registration`] type. | ||
| 69 | //! | ||
| 70 | //! Typically, bus abstractions want to provide a bus specific `module_bus_driver!` macro, which | ||
| 71 | //! creates a kernel module with exactly one [`Registration`] for the bus specific adapter. | ||
| 72 | //! | ||
| 73 | //! The generic driver infrastructure provides a helper for this with the [`module_driver`] macro. | ||
| 74 | //! | ||
| 75 | //! # Device IDs | ||
| 76 | //! | ||
| 77 | //! Besides the common device ID types, such as [`of::DeviceId`] and [`acpi::DeviceId`], most buses | ||
| 78 | //! may need to implement their own device ID types. | ||
| 79 | //! | ||
| 80 | //! For this purpose the generic infrastructure in [`device_id`] should be used. | ||
| 81 | //! | ||
| 82 | //! [`auxiliary::Driver`]: kernel::auxiliary::Driver | ||
| 83 | //! [`Core`]: device::Core | ||
| 84 | //! [`Device`]: device::Device | ||
| 85 | //! [`Device<Core>`]: device::Device<device::Core> | ||
| 86 | //! [`Device<CoreInternal>`]: device::Device<device::CoreInternal> | ||
| 87 | //! [`DeviceContext`]: device::DeviceContext | ||
| 88 | //! [`device_id`]: kernel::device_id | ||
| 89 | //! [`module_driver`]: kernel::module_driver | ||
| 90 | //! [`pci::Driver`]: kernel::pci::Driver | ||
| 91 | //! [`platform::Driver`]: kernel::platform::Driver | ||
| 7 | 92 | ||
| 8 | use crate::error::{Error, Result}; | 93 | use crate::error::{Error, Result}; |
| 9 | use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule}; | 94 | use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule}; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | //! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h) | 5 | //! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h) |
| 6 | 6 | ||
| 7 | use crate::{ | 7 | use crate::{ |
| 8 | alloc::allocator::Kmalloc, | ||
| 8 | bindings, device, drm, | 9 | bindings, device, drm, |
| 9 | drm::driver::AllocImpl, | 10 | drm::driver::AllocImpl, |
| 10 | error::from_err_ptr, | 11 | error::from_err_ptr, |
| @@ -12,7 +13,7 @@ use crate::{ · 1 unmodified line | |||
| 12 | prelude::*, | 13 | prelude::*, |
| 13 | types::{ARef, AlwaysRefCounted, Opaque}, | 14 | types::{ARef, AlwaysRefCounted, Opaque}, |
| 14 | }; | 15 | }; |
| 15 | use core::{mem, ops::Deref, ptr, ptr::NonNull}; | 16 | use core::{alloc::Layout, mem, ops::Deref, ptr, ptr::NonNull}; |
| 16 | 17 | ||
| 17 | #[cfg(CONFIG_DRM_LEGACY)] | 18 | #[cfg(CONFIG_DRM_LEGACY)] |
| 18 | macro_rules! drm_legacy_fields { | 19 | macro_rules! drm_legacy_fields { |
| @@ -53,10 +54,8 @@ macro_rules! drm_legacy_fields { · 34 unmodified lines | |||
| 53 | /// | 54 | /// |
| 54 | /// `self.dev` is a valid instance of a `struct device`. | 55 | /// `self.dev` is a valid instance of a `struct device`. |
| 55 | #[repr(C)] | 56 | #[repr(C)] |
| 56 | #[pin_data] | ||
| 57 | pub struct Device<T: drm::Driver> { | 57 | pub struct Device<T: drm::Driver> { |
| 58 | dev: Opaque<bindings::drm_device>, | 58 | dev: Opaque<bindings::drm_device>, |
| 59 | #[pin] | ||
| 60 | data: T::Data, | 59 | data: T::Data, |
| 61 | } | 60 | } |
| 62 | 61 | ||
| @@ -96,6 +95,10 @@ impl<T: drm::Driver> Device<T> { · 33 unmodified lines | |||
| 96 | 95 | ||
| 97 | /// Create a new `drm::Device` for a `drm::Driver`. | 96 | /// Create a new `drm::Device` for a `drm::Driver`. |
| 98 | pub fn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> { | 97 | pub fn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> { |
| 98 | // `__drm_dev_alloc` uses `kmalloc()` to allocate memory, hence ensure a `kmalloc()` | ||
| 99 | // compatible `Layout`. | ||
| 100 | let layout = Kmalloc::aligned_layout(Layout::new::<Self>()); | ||
| 101 | |||
| 99 | // SAFETY: | 102 | // SAFETY: |
| 100 | // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, | 103 | // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, |
| 101 | // - `dev` is valid by its type invarants, | 104 | // - `dev` is valid by its type invarants, |
| @@ -103,7 +106,7 @@ impl<T: drm::Driver> Device<T> { · 1 unmodified line | |||
| 103 | bindings::__drm_dev_alloc( | 106 | bindings::__drm_dev_alloc( |
| 104 | dev.as_raw(), | 107 | dev.as_raw(), |
| 105 | &Self::VTABLE, | 108 | &Self::VTABLE, |
| 106 | mem::size_of::<Self>(), | 109 | layout.size(), |
| 107 | mem::offset_of!(Self, dev), | 110 | mem::offset_of!(Self, dev), |
| 108 | ) | 111 | ) |
| 109 | } | 112 | } |
| @@ -117,9 +120,13 @@ impl<T: drm::Driver> Device<T> { · 7 unmodified lines | |||
| 117 | // - `raw_data` is a valid pointer to uninitialized memory. | 120 | // - `raw_data` is a valid pointer to uninitialized memory. |
| 118 | // - `raw_data` will not move until it is dropped. | 121 | // - `raw_data` will not move until it is dropped. |
| 119 | unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| { | 122 | unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| { |
| 120 | // SAFETY: `__drm_dev_alloc()` was successful, hence `raw_drm` must be valid and the | 123 | // SAFETY: `raw_drm` is a valid pointer to `Self`, given that `__drm_dev_alloc` was |
| 124 | // successful. | ||
| 125 | let drm_dev = unsafe { Self::into_drm_device(raw_drm) }; | ||
| 126 | |||
| 127 | // SAFETY: `__drm_dev_alloc()` was successful, hence `drm_dev` must be valid and the | ||
| 121 | // refcount must be non-zero. | 128 | // refcount must be non-zero. |
| 122 | unsafe { bindings::drm_dev_put(ptr::addr_of_mut!((*raw_drm.as_ptr()).dev).cast()) }; | 129 | unsafe { bindings::drm_dev_put(drm_dev) }; |
| 123 | })?; | 130 | })?; |
| 124 | 131 | ||
| 125 | // SAFETY: The reference count is one, and now we take ownership of that reference as a | 132 | // SAFETY: The reference count is one, and now we take ownership of that reference as a |
| @@ -140,6 +147,14 @@ impl<T: drm::Driver> Device<T> { · 14 unmodified lines | |||
| 140 | unsafe { crate::container_of!(Opaque::cast_from(ptr), Self, dev) }.cast_mut() | 147 | unsafe { crate::container_of!(Opaque::cast_from(ptr), Self, dev) }.cast_mut() |
| 141 | } | 148 | } |
| 142 | 149 | ||
| 150 | /// # Safety | ||
| 151 | /// | ||
| 152 | /// `ptr` must be a valid pointer to `Self`. | ||
| 153 | unsafe fn into_drm_device(ptr: NonNull<Self>) -> *mut bindings::drm_device { | ||
| 154 | // SAFETY: By the safety requirements of this function, `ptr` is a valid pointer to `Self`. | ||
| 155 | unsafe { &raw mut (*ptr.as_ptr()).dev }.cast() | ||
| 156 | } | ||
| 157 | |||
| 143 | /// Not intended to be called externally, except via declare_drm_ioctls!() | 158 | /// Not intended to be called externally, except via declare_drm_ioctls!() |
| 144 | /// | 159 | /// |
| 145 | /// # Safety | 160 | /// # Safety |
| @@ -189,8 +204,11 @@ unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> { · 43 unmodified lines | |||
| 189 | } | 204 | } |
| 190 | 205 | ||
| 191 | unsafe fn dec_ref(obj: NonNull<Self>) { | 206 | unsafe fn dec_ref(obj: NonNull<Self>) { |
| 207 | // SAFETY: `obj` is a valid pointer to `Self`. | ||
| 208 | let drm_dev = unsafe { Self::into_drm_device(obj) }; | ||
| 209 | |||
| 192 | // SAFETY: The safety requirements guarantee that the refcount is non-zero. | 210 | // SAFETY: The safety requirements guarantee that the refcount is non-zero. |
| 193 | unsafe { bindings::drm_dev_put(obj.cast().as_ptr()) }; | 211 | unsafe { bindings::drm_dev_put(drm_dev) }; |
| 194 | } | 212 | } |
| 195 | } | 213 | } |
| 196 | 214 | ||
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | //! | 4 | //! |
| 5 | //! This module provides bindings for working with faux devices in kernel modules. | 5 | //! This module provides bindings for working with faux devices in kernel modules. |
| 6 | //! | 6 | //! |
| 7 | //! C header: [`include/linux/device/faux.h`] | 7 | //! C header: [`include/linux/device/faux.h`](srctree/include/linux/device/faux.h) |
| 8 | 8 | ||
| 9 | use crate::{bindings, device, error::code::*, prelude::*}; | 9 | use crate::{bindings, device, error::code::*, prelude::*}; |
| 10 | use core::ptr::{addr_of_mut, null, null_mut, NonNull}; | 10 | use core::ptr::{addr_of_mut, null, null_mut, NonNull}; |
| @@ -2139,14 +2139,14 @@ static int snd_utimer_create(struct snd_timer_uinfo *utimer_info, · 2138 unmodified lines | |||
| 2139 | goto err_take_id; | 2139 | goto err_take_id; |
| 2140 | } | 2140 | } |
| 2141 | 2141 | ||
| 2142 | utimer->id = utimer_id; | ||
| 2143 | |||
| 2142 | utimer->name = kasprintf(GFP_KERNEL, "snd-utimer%d", utimer_id); | 2144 | utimer->name = kasprintf(GFP_KERNEL, "snd-utimer%d", utimer_id); |
| 2143 | if (!utimer->name) { | 2145 | if (!utimer->name) { |
| 2144 | err = -ENOMEM; | 2146 | err = -ENOMEM; |
| 2145 | goto err_get_name; | 2147 | goto err_get_name; |
| 2146 | } | 2148 | } |
| 2147 | 2149 | ||
| 2148 | utimer->id = utimer_id; | ||
| 2149 | |||
| 2150 | tid.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; | 2150 | tid.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; |
| 2151 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; | 2151 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; |
| 2152 | tid.card = -1; | 2152 | tid.card = -1; |
| @@ -510,6 +510,15 @@ static void alc256_shutup(struct hda_codec *codec) · 509 unmodified lines | |||
| 510 | hp_pin = 0x21; | 510 | hp_pin = 0x21; |
| 511 | 511 | ||
| 512 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ | 512 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ |
| 513 | |||
| 514 | /* 3k pull low control for Headset jack. */ | ||
| 515 | /* NOTE: call this before clearing the pin, otherwise codec stalls */ | ||
| 516 | /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly | ||
| 517 | * when booting with headset plugged. So skip setting it for the codec alc257 | ||
| 518 | */ | ||
| 519 | if (spec->en_3kpull_low) | ||
| 520 | alc_update_coef_idx(codec, 0x46, 0, 3 << 12); | ||
| 521 | |||
| 513 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 522 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
| 514 | 523 | ||
| 515 | if (hp_pin_sense) { | 524 | if (hp_pin_sense) { |
| @@ -520,14 +529,6 @@ static void alc256_shutup(struct hda_codec *codec) · 4 unmodified lines | |||
| 520 | 529 | ||
| 521 | msleep(75); | 530 | msleep(75); |
| 522 | 531 | ||
| 523 | /* 3k pull low control for Headset jack. */ | ||
| 524 | /* NOTE: call this before clearing the pin, otherwise codec stalls */ | ||
| 525 | /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly | ||
| 526 | * when booting with headset plugged. So skip setting it for the codec alc257 | ||
| 527 | */ | ||
| 528 | if (spec->en_3kpull_low) | ||
| 529 | alc_update_coef_idx(codec, 0x46, 0, 3 << 12); | ||
| 530 | |||
| 531 | if (!spec->no_shutup_pins) | 532 | if (!spec->no_shutup_pins) |
| 532 | snd_hda_codec_write(codec, hp_pin, 0, | 533 | snd_hda_codec_write(codec, hp_pin, 0, |
| 533 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 534 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
| @@ -3579,6 +3580,7 @@ enum { · 3045 unmodified lines | |||
| 3579 | ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE, | 3580 | ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE, |
| 3580 | ALC294_FIXUP_ASUS_MIC, | 3581 | ALC294_FIXUP_ASUS_MIC, |
| 3581 | ALC294_FIXUP_ASUS_HEADSET_MIC, | 3582 | ALC294_FIXUP_ASUS_HEADSET_MIC, |
| 3583 | ALC294_FIXUP_ASUS_I2C_HEADSET_MIC, | ||
| 3582 | ALC294_FIXUP_ASUS_SPK, | 3584 | ALC294_FIXUP_ASUS_SPK, |
| 3583 | ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE, | 3585 | ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE, |
| 3584 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, | 3586 | ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, |
| @@ -4889,6 +4891,15 @@ static const struct hda_fixup alc269_fixups[] = { · 1304 unmodified lines | |||
| 4889 | .chained = true, | 4891 | .chained = true, |
| 4890 | .chain_id = ALC269_FIXUP_HEADSET_MIC | 4892 | .chain_id = ALC269_FIXUP_HEADSET_MIC |
| 4891 | }, | 4893 | }, |
| 4894 | [ALC294_FIXUP_ASUS_I2C_HEADSET_MIC] = { | ||
| 4895 | .type = HDA_FIXUP_PINS, | ||
| 4896 | .v.pins = (const struct hda_pintbl[]) { | ||
| 4897 | { 0x19, 0x03a19020 }, /* use as headset mic */ | ||
| 4898 | { } | ||
| 4899 | }, | ||
| 4900 | .chained = true, | ||
| 4901 | .chain_id = ALC287_FIXUP_CS35L41_I2C_2 | ||
| 4902 | }, | ||
| 4892 | [ALC294_FIXUP_ASUS_SPK] = { | 4903 | [ALC294_FIXUP_ASUS_SPK] = { |
| 4893 | .type = HDA_FIXUP_VERBS, | 4904 | .type = HDA_FIXUP_VERBS, |
| 4894 | .v.verbs = (const struct hda_verb[]) { | 4905 | .v.verbs = (const struct hda_verb[]) { |
| @@ -6368,6 +6379,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = { · 1473 unmodified lines | |||
| 6368 | SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), | 6379 | SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), |
| 6369 | SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), | 6380 | SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), |
| 6370 | SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), | 6381 | SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), |
| 6382 | SND_PCI_QUIRK(0x103c, 0x8548, "HP EliteBook x360 830 G6", ALC285_FIXUP_HP_GPIO_LED), | ||
| 6383 | SND_PCI_QUIRK(0x103c, 0x854a, "HP EliteBook 830 G6", ALC285_FIXUP_HP_GPIO_LED), | ||
| 6371 | SND_PCI_QUIRK(0x103c, 0x85c6, "HP Pavilion x360 Convertible 14-dy1xxx", ALC295_FIXUP_HP_MUTE_LED_COEFBIT11), | 6384 | SND_PCI_QUIRK(0x103c, 0x85c6, "HP Pavilion x360 Convertible 14-dy1xxx", ALC295_FIXUP_HP_MUTE_LED_COEFBIT11), |
| 6372 | SND_PCI_QUIRK(0x103c, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360), | 6385 | SND_PCI_QUIRK(0x103c, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360), |
| 6373 | SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT), | 6386 | SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT), |
| @@ -6728,7 +6741,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { · 354 unmodified lines | |||
| 6728 | SND_PCI_QUIRK(0x1043, 0x1b13, "ASUS U41SV/GA403U", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC), | 6741 | SND_PCI_QUIRK(0x1043, 0x1b13, "ASUS U41SV/GA403U", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC), |
| 6729 | SND_PCI_QUIRK(0x1043, 0x1b93, "ASUS G614JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2), | 6742 | SND_PCI_QUIRK(0x1043, 0x1b93, "ASUS G614JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2), |
| 6730 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), | 6743 | SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), |
| 6731 | SND_PCI_QUIRK(0x1043, 0x1c03, "ASUS UM3406HA", ALC287_FIXUP_CS35L41_I2C_2), | 6744 | SND_PCI_QUIRK(0x1043, 0x1c03, "ASUS UM3406HA", ALC294_FIXUP_ASUS_I2C_HEADSET_MIC), |
| 6732 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 6745 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
| 6733 | SND_PCI_QUIRK(0x1043, 0x1c33, "ASUS UX5304MA", ALC245_FIXUP_CS35L41_SPI_2), | 6746 | SND_PCI_QUIRK(0x1043, 0x1c33, "ASUS UX5304MA", ALC245_FIXUP_CS35L41_SPI_2), |
| 6734 | SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2), | 6747 | SND_PCI_QUIRK(0x1043, 0x1c43, "ASUS UX8406MA", ALC245_FIXUP_CS35L41_SPI_2), |
| @@ -267,7 +267,7 @@ static const struct snd_kcontrol_new tas2770_snd_controls[] = { · 266 unmodified lines | |||
| 267 | static const struct snd_kcontrol_new tas2781_snd_controls[] = { | 267 | static const struct snd_kcontrol_new tas2781_snd_controls[] = { |
| 268 | ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL, | 268 | ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL, |
| 269 | 1, 0, 20, 0, tas2781_amp_getvol, | 269 | 1, 0, 20, 0, tas2781_amp_getvol, |
| 270 | tas2781_amp_putvol, amp_vol_tlv), | 270 | tas2781_amp_putvol, tas2781_amp_tlv), |
| 271 | ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, | 271 | ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0, |
| 272 | tas2781_force_fwload_get, tas2781_force_fwload_put), | 272 | tas2781_force_fwload_get, tas2781_force_fwload_put), |
| 273 | }; | 273 | }; |
| @@ -305,7 +305,7 @@ static int tas2563_save_calibration(struct tas2781_hda *h) · 31 unmodified lines | |||
| 305 | efi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX]; | 305 | efi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX]; |
| 306 | unsigned long max_size = TAS2563_CAL_DATA_SIZE; | 306 | unsigned long max_size = TAS2563_CAL_DATA_SIZE; |
| 307 | unsigned char var8[TAS2563_CAL_VAR_NAME_MAX]; | 307 | unsigned char var8[TAS2563_CAL_VAR_NAME_MAX]; |
| 308 | struct tasdevice_priv *p = h->hda_priv; | 308 | struct tasdevice_priv *p = h->priv; |
| 309 | struct calidata *cd = &p->cali_data; | 309 | struct calidata *cd = &p->cali_data; |
| 310 | struct cali_reg *r = &cd->cali_reg_array; | 310 | struct cali_reg *r = &cd->cali_reg_array; |
| 311 | unsigned int offset = 0; | 311 | unsigned int offset = 0; |
| @@ -494,9 +494,11 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol, · 493 unmodified lines | |||
| 494 | 494 | ||
| 495 | static struct snd_kcontrol_new tas2781_snd_ctls[] = { | 495 | static struct snd_kcontrol_new tas2781_snd_ctls[] = { |
| 496 | ACARD_SINGLE_RANGE_EXT_TLV(NULL, TAS2781_AMP_LEVEL, 1, 0, 20, 0, | 496 | ACARD_SINGLE_RANGE_EXT_TLV(NULL, TAS2781_AMP_LEVEL, 1, 0, 20, 0, |
| 497 | tas2781_amp_getvol, tas2781_amp_putvol, amp_vol_tlv), | 497 | tas2781_amp_getvol, tas2781_amp_putvol, |
| 498 | tas2781_amp_tlv), | ||
| 498 | ACARD_SINGLE_RANGE_EXT_TLV(NULL, TAS2781_DVC_LVL, 0, 0, 200, 1, | 499 | ACARD_SINGLE_RANGE_EXT_TLV(NULL, TAS2781_DVC_LVL, 0, 0, 200, 1, |
| 499 | tas2781_digital_getvol, tas2781_digital_putvol, dvc_tlv), | 500 | tas2781_digital_getvol, tas2781_digital_putvol, |
| 501 | tas2781_dvc_tlv), | ||
| 500 | ACARD_SINGLE_BOOL_EXT(NULL, 0, tas2781_force_fwload_get, | 502 | ACARD_SINGLE_BOOL_EXT(NULL, 0, tas2781_force_fwload_get, |
| 501 | tas2781_force_fwload_put), | 503 | tas2781_force_fwload_put), |
| 502 | }; | 504 | }; |
| @@ -393,74 +393,6 @@ static int cs35l56_sdw_update_status(struct sdw_slave *peripheral, · 392 unmodified lines | |||
| 393 | return 0; | 393 | return 0; |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | static int cs35l63_sdw_kick_divider(struct cs35l56_private *cs35l56, | ||
| 397 | struct sdw_slave *peripheral) | ||
| 398 | { | ||
| 399 | unsigned int curr_scale_reg, next_scale_reg; | ||
| 400 | int curr_scale, next_scale, ret; | ||
| 401 | |||
| 402 | if (!cs35l56->base.init_done) | ||
| 403 | return 0; | ||
| 404 | |||
| 405 | if (peripheral->bus->params.curr_bank) { | ||
| 406 | curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1; | ||
| 407 | next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0; | ||
| 408 | } else { | ||
| 409 | curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0; | ||
| 410 | next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* | ||
| 414 | * Current clock scale value must be different to new value. | ||
| 415 | * Modify current to guarantee this. If next still has the dummy | ||
| 416 | * value we wrote when it was current, the core code has not set | ||
| 417 | * a new scale so restore its original good value | ||
| 418 | */ | ||
| 419 | curr_scale = sdw_read_no_pm(peripheral, curr_scale_reg); | ||
| 420 | if (curr_scale < 0) { | ||
| 421 | dev_err(cs35l56->base.dev, "Failed to read current clock scale: %d\n", curr_scale); | ||
| 422 | return curr_scale; | ||
| 423 | } | ||
| 424 | |||
| 425 | next_scale = sdw_read_no_pm(peripheral, next_scale_reg); | ||
| 426 | if (next_scale < 0) { | ||
| 427 | dev_err(cs35l56->base.dev, "Failed to read next clock scale: %d\n", next_scale); | ||
| 428 | return next_scale; | ||
| 429 | } | ||
| 430 | |||
| 431 | if (next_scale == CS35L56_SDW_INVALID_BUS_SCALE) { | ||
| 432 | next_scale = cs35l56->old_sdw_clock_scale; | ||
| 433 | ret = sdw_write_no_pm(peripheral, next_scale_reg, next_scale); | ||
| 434 | if (ret < 0) { | ||
| 435 | dev_err(cs35l56->base.dev, "Failed to modify current clock scale: %d\n", | ||
| 436 | ret); | ||
| 437 | return ret; | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | cs35l56->old_sdw_clock_scale = curr_scale; | ||
| 442 | ret = sdw_write_no_pm(peripheral, curr_scale_reg, CS35L56_SDW_INVALID_BUS_SCALE); | ||
| 443 | if (ret < 0) { | ||
| 444 | dev_err(cs35l56->base.dev, "Failed to modify current clock scale: %d\n", ret); | ||
| 445 | return ret; | ||
| 446 | } | ||
| 447 | |||
| 448 | dev_dbg(cs35l56->base.dev, "Next bus scale: %#x\n", next_scale); | ||
| 449 | |||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
| 453 | static int cs35l56_sdw_bus_config(struct sdw_slave *peripheral, | ||
| 454 | struct sdw_bus_params *params) | ||
| 455 | { | ||
| 456 | struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev); | ||
| 457 | |||
| 458 | if ((cs35l56->base.type == 0x63) && (cs35l56->base.rev < 0xa1)) | ||
| 459 | return cs35l63_sdw_kick_divider(cs35l56, peripheral); | ||
| 460 | |||
| 461 | return 0; | ||
| 462 | } | ||
| 463 | |||
| 464 | static int __maybe_unused cs35l56_sdw_clk_stop(struct sdw_slave *peripheral, | 396 | static int __maybe_unused cs35l56_sdw_clk_stop(struct sdw_slave *peripheral, |
| 465 | enum sdw_clk_stop_mode mode, | 397 | enum sdw_clk_stop_mode mode, |
| 466 | enum sdw_clk_stop_type type) | 398 | enum sdw_clk_stop_type type) |
| @@ -476,7 +408,6 @@ static const struct sdw_slave_ops cs35l56_sdw_ops = { · 9 unmodified lines | |||
| 476 | .read_prop = cs35l56_sdw_read_prop, | 408 | .read_prop = cs35l56_sdw_read_prop, |
| 477 | .interrupt_callback = cs35l56_sdw_interrupt, | 409 | .interrupt_callback = cs35l56_sdw_interrupt, |
| 478 | .update_status = cs35l56_sdw_update_status, | 410 | .update_status = cs35l56_sdw_update_status, |
| 479 | .bus_config = cs35l56_sdw_bus_config, | ||
| 480 | #ifdef DEBUG | 411 | #ifdef DEBUG |
| 481 | .clk_stop = cs35l56_sdw_clk_stop, | 412 | .clk_stop = cs35l56_sdw_clk_stop, |
| 482 | #endif | 413 | #endif |
| @@ -838,6 +838,15 @@ const struct cirrus_amp_cal_controls cs35l56_calibration_controls = { · 837 unmodified lines | |||
| 838 | }; | 838 | }; |
| 839 | EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, "SND_SOC_CS35L56_SHARED"); | 839 | EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, "SND_SOC_CS35L56_SHARED"); |
| 840 | 840 | ||
| 841 | static const struct cirrus_amp_cal_controls cs35l63_calibration_controls = { | ||
| 842 | .alg_id = 0xbf210, | ||
| 843 | .mem_region = WMFW_ADSP2_YM, | ||
| 844 | .ambient = "CAL_AMBIENT", | ||
| 845 | .calr = "CAL_R", | ||
| 846 | .status = "CAL_STATUS", | ||
| 847 | .checksum = "CAL_CHECKSUM", | ||
| 848 | }; | ||
| 849 | |||
| 841 | int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) | 850 | int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base) |
| 842 | { | 851 | { |
| 843 | u64 silicon_uid = 0; | 852 | u64 silicon_uid = 0; |
| @@ -912,19 +921,31 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, "SND_SOC_CS35L56_SHARED"); · 68 unmodified lines | |||
| 912 | void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp) | 921 | void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp) |
| 913 | { | 922 | { |
| 914 | __be32 pid, sid, tid; | 923 | __be32 pid, sid, tid; |
| 924 | unsigned int alg_id; | ||
| 915 | int ret; | 925 | int ret; |
| 916 | 926 | ||
| 927 | switch (cs35l56_base->type) { | ||
| 928 | case 0x54: | ||
| 929 | case 0x56: | ||
| 930 | case 0x57: | ||
| 931 | alg_id = 0x9f212; | ||
| 932 | break; | ||
| 933 | default: | ||
| 934 | alg_id = 0xbf212; | ||
| 935 | break; | ||
| 936 | } | ||
| 937 | |||
| 917 | scoped_guard(mutex, &cs_dsp->pwr_lock) { | 938 | scoped_guard(mutex, &cs_dsp->pwr_lock) { |
| 918 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_PRJCT_ID", | 939 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_PRJCT_ID", |
| 919 | WMFW_ADSP2_XM, 0x9f212), | 940 | WMFW_ADSP2_XM, alg_id), |
| 920 | 0, &pid, sizeof(pid)); | 941 | 0, &pid, sizeof(pid)); |
| 921 | if (!ret) | 942 | if (!ret) |
| 922 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_CHNNL_ID", | 943 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_CHNNL_ID", |
| 923 | WMFW_ADSP2_XM, 0x9f212), | 944 | WMFW_ADSP2_XM, alg_id), |
| 924 | 0, &sid, sizeof(sid)); | 945 | 0, &sid, sizeof(sid)); |
| 925 | if (!ret) | 946 | if (!ret) |
| 926 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_SNPSHT_ID", | 947 | ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(cs_dsp, "AS_SNPSHT_ID", |
| 927 | WMFW_ADSP2_XM, 0x9f212), | 948 | WMFW_ADSP2_XM, alg_id), |
| 928 | 0, &tid, sizeof(tid)); | 949 | 0, &tid, sizeof(tid)); |
| 929 | } | 950 | } |
| 930 | 951 | ||
| @@ -974,8 +995,10 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base) · 43 unmodified lines | |||
| 974 | case 0x35A54: | 995 | case 0x35A54: |
| 975 | case 0x35A56: | 996 | case 0x35A56: |
| 976 | case 0x35A57: | 997 | case 0x35A57: |
| 998 | cs35l56_base->calibration_controls = &cs35l56_calibration_controls; | ||
| 977 | break; | 999 | break; |
| 978 | case 0x35A630: | 1000 | case 0x35A630: |
| 1001 | cs35l56_base->calibration_controls = &cs35l63_calibration_controls; | ||
| 979 | devid = devid >> 4; | 1002 | devid = devid >> 4; |
| 980 | break; | 1003 | break; |
| 981 | default: | 1004 | default: |
| @@ -695,7 +695,7 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56) · 694 unmodified lines | |||
| 695 | return ret; | 695 | return ret; |
| 696 | 696 | ||
| 697 | ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, | 697 | ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, |
| 698 | &cs35l56_calibration_controls, | 698 | cs35l56->base.calibration_controls, |
| 699 | &cs35l56->base.cal_data); | 699 | &cs35l56->base.cal_data); |
| 700 | 700 | ||
| 701 | wm_adsp_stop(&cs35l56->dsp); | 701 | wm_adsp_stop(&cs35l56->dsp); |
| @@ -20,8 +20,6 @@ · 19 unmodified lines | |||
| 20 | #define CS35L56_SDW_GEN_INT_MASK_1 0xc1 | 20 | #define CS35L56_SDW_GEN_INT_MASK_1 0xc1 |
| 21 | #define CS35L56_SDW_INT_MASK_CODEC_IRQ BIT(0) | 21 | #define CS35L56_SDW_INT_MASK_CODEC_IRQ BIT(0) |
| 22 | 22 | ||
| 23 | #define CS35L56_SDW_INVALID_BUS_SCALE 0xf | ||
| 24 | |||
| 25 | #define CS35L56_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | 23 | #define CS35L56_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) |
| 26 | #define CS35L56_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE \ | 24 | #define CS35L56_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE \ |
| 27 | | SNDRV_PCM_FMTBIT_S32_LE) | 25 | | SNDRV_PCM_FMTBIT_S32_LE) |
| @@ -52,7 +50,6 @@ struct cs35l56_private { · 24 unmodified lines | |||
| 52 | u8 asp_slot_count; | 50 | u8 asp_slot_count; |
| 53 | bool tdm_mode; | 51 | bool tdm_mode; |
| 54 | bool sysclk_set; | 52 | bool sysclk_set; |
| 55 | u8 old_sdw_clock_scale; | ||
| 56 | u8 sdw_link_num; | 53 | u8 sdw_link_num; |
| 57 | u8 sdw_unique_id; | 54 | u8 sdw_unique_id; |
| 58 | }; | 55 | }; |
| @@ -636,7 +636,7 @@ static int es8389_set_bias_level(struct snd_soc_component *component, · 635 unmodified lines | |||
| 636 | regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0x59); | 636 | regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0x59); |
| 637 | regmap_write(es8389->regmap, ES8389_ADC_EN, 0x00); | 637 | regmap_write(es8389->regmap, ES8389_ADC_EN, 0x00); |
| 638 | regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0x00); | 638 | regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0x00); |
| 639 | regmap_write(es8389->regmap, ES8389_RESET, 0x7E); | 639 | regmap_write(es8389->regmap, ES8389_RESET, 0x3E); |
| 640 | regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x80); | 640 | regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x80); |
| 641 | usleep_range(8000, 8500); | 641 | usleep_range(8000, 8500); |
| 642 | regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x00); | 642 | regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0x80, 0x00); |
| @@ -910,10 +910,10 @@ static const struct snd_kcontrol_new tasdevice_cali_controls[] = { · 909 unmodified lines | |||
| 910 | static const struct snd_kcontrol_new tas2781_snd_controls[] = { | 910 | static const struct snd_kcontrol_new tas2781_snd_controls[] = { |
| 911 | SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL, | 911 | SOC_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL, |
| 912 | 1, 0, 20, 0, tas2781_amp_getvol, | 912 | 1, 0, 20, 0, tas2781_amp_getvol, |
| 913 | tas2781_amp_putvol, amp_vol_tlv), | 913 | tas2781_amp_putvol, tas2781_amp_tlv), |
| 914 | SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2781_DVC_LVL, | 914 | SOC_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2781_DVC_LVL, |
| 915 | 0, 0, 200, 1, tas2781_digital_getvol, | 915 | 0, 0, 200, 1, tas2781_digital_getvol, |
| 916 | tas2781_digital_putvol, dvc_tlv), | 916 | tas2781_digital_putvol, tas2781_dvc_tlv), |
| 917 | }; | 917 | }; |
| 918 | 918 | ||
| 919 | static const struct snd_kcontrol_new tas2781_cali_controls[] = { | 919 | static const struct snd_kcontrol_new tas2781_cali_controls[] = { |
| @@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor · 348 unmodified lines | |||
| 349 | u16 cs_len; | 349 | u16 cs_len; |
| 350 | u8 cs_type; | 350 | u8 cs_type; |
| 351 | 351 | ||
| 352 | if (len < sizeof(*p)) | 352 | if (len < sizeof(*cs_desc)) |
| 353 | break; | 353 | break; |
| 354 | cs_len = le16_to_cpu(cs_desc->wLength); | 354 | cs_len = le16_to_cpu(cs_desc->wLength); |
| 355 | if (len < cs_len) | 355 | if (len < cs_len) |
| @@ -285,7 +285,7 @@ static const struct usb_desc_validator audio_validators[] = { · 284 unmodified lines | |||
| 285 | /* UAC_VERSION_3, UAC3_EXTENDED_TERMINAL: not implemented yet */ | 285 | /* UAC_VERSION_3, UAC3_EXTENDED_TERMINAL: not implemented yet */ |
| 286 | FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, validate_mixer_unit), | 286 | FUNC(UAC_VERSION_3, UAC3_MIXER_UNIT, validate_mixer_unit), |
| 287 | FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT, validate_selector_unit), | 287 | FUNC(UAC_VERSION_3, UAC3_SELECTOR_UNIT, validate_selector_unit), |
| 288 | FUNC(UAC_VERSION_3, UAC_FEATURE_UNIT, validate_uac3_feature_unit), | 288 | FUNC(UAC_VERSION_3, UAC3_FEATURE_UNIT, validate_uac3_feature_unit), |
| 289 | /* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */ | 289 | /* UAC_VERSION_3, UAC3_EFFECT_UNIT: not implemented yet */ |
| 290 | FUNC(UAC_VERSION_3, UAC3_PROCESSING_UNIT, validate_processing_unit), | 290 | FUNC(UAC_VERSION_3, UAC3_PROCESSING_UNIT, validate_processing_unit), |
| 291 | FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit), | 291 | FUNC(UAC_VERSION_3, UAC3_EXTENSION_UNIT, validate_processing_unit), |
| @@ -75,11 +75,13 @@ · 74 unmodified lines | |||
| 75 | #define ARM_CPU_PART_CORTEX_A76 0xD0B | 75 | #define ARM_CPU_PART_CORTEX_A76 0xD0B |
| 76 | #define ARM_CPU_PART_NEOVERSE_N1 0xD0C | 76 | #define ARM_CPU_PART_NEOVERSE_N1 0xD0C |
| 77 | #define ARM_CPU_PART_CORTEX_A77 0xD0D | 77 | #define ARM_CPU_PART_CORTEX_A77 0xD0D |
| 78 | #define ARM_CPU_PART_CORTEX_A76AE 0xD0E | ||
| 78 | #define ARM_CPU_PART_NEOVERSE_V1 0xD40 | 79 | #define ARM_CPU_PART_NEOVERSE_V1 0xD40 |
| 79 | #define ARM_CPU_PART_CORTEX_A78 0xD41 | 80 | #define ARM_CPU_PART_CORTEX_A78 0xD41 |
| 80 | #define ARM_CPU_PART_CORTEX_A78AE 0xD42 | 81 | #define ARM_CPU_PART_CORTEX_A78AE 0xD42 |
| 81 | #define ARM_CPU_PART_CORTEX_X1 0xD44 | 82 | #define ARM_CPU_PART_CORTEX_X1 0xD44 |
| 82 | #define ARM_CPU_PART_CORTEX_A510 0xD46 | 83 | #define ARM_CPU_PART_CORTEX_A510 0xD46 |
| 84 | #define ARM_CPU_PART_CORTEX_X1C 0xD4C | ||
| 83 | #define ARM_CPU_PART_CORTEX_A520 0xD80 | 85 | #define ARM_CPU_PART_CORTEX_A520 0xD80 |
| 84 | #define ARM_CPU_PART_CORTEX_A710 0xD47 | 86 | #define ARM_CPU_PART_CORTEX_A710 0xD47 |
| 85 | #define ARM_CPU_PART_CORTEX_A715 0xD4D | 87 | #define ARM_CPU_PART_CORTEX_A715 0xD4D |
| @@ -119,9 +121,11 @@ · 33 unmodified lines | |||
| 119 | #define QCOM_CPU_PART_KRYO 0x200 | 121 | #define QCOM_CPU_PART_KRYO 0x200 |
| 120 | #define QCOM_CPU_PART_KRYO_2XX_GOLD 0x800 | 122 | #define QCOM_CPU_PART_KRYO_2XX_GOLD 0x800 |
| 121 | #define QCOM_CPU_PART_KRYO_2XX_SILVER 0x801 | 123 | #define QCOM_CPU_PART_KRYO_2XX_SILVER 0x801 |
| 124 | #define QCOM_CPU_PART_KRYO_3XX_GOLD 0x802 | ||
| 122 | #define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 | 125 | #define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 |
| 123 | #define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 | 126 | #define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 |
| 124 | #define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 | 127 | #define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 |
| 128 | #define QCOM_CPU_PART_ORYON_X1 0x001 | ||
| 125 | 129 | ||
| 126 | #define NVIDIA_CPU_PART_DENVER 0x003 | 130 | #define NVIDIA_CPU_PART_DENVER 0x003 |
| 127 | #define NVIDIA_CPU_PART_CARMEL 0x004 | 131 | #define NVIDIA_CPU_PART_CARMEL 0x004 |
| @@ -129,6 +133,7 @@ · 1 unmodified line | |||
| 129 | #define FUJITSU_CPU_PART_A64FX 0x001 | 133 | #define FUJITSU_CPU_PART_A64FX 0x001 |
| 130 | 134 | ||
| 131 | #define HISI_CPU_PART_TSV110 0xD01 | 135 | #define HISI_CPU_PART_TSV110 0xD01 |
| 136 | #define HISI_CPU_PART_HIP09 0xD02 | ||
| 132 | #define HISI_CPU_PART_HIP12 0xD06 | 137 | #define HISI_CPU_PART_HIP12 0xD06 |
| 133 | 138 | ||
| 134 | #define APPLE_CPU_PART_M1_ICESTORM 0x022 | 139 | #define APPLE_CPU_PART_M1_ICESTORM 0x022 |
| @@ -159,11 +164,13 @@ · 24 unmodified lines | |||
| 159 | #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) | 164 | #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) |
| 160 | #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) | 165 | #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) |
| 161 | #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) | 166 | #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) |
| 167 | #define MIDR_CORTEX_A76AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76AE) | ||
| 162 | #define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1) | 168 | #define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1) |
| 163 | #define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) | 169 | #define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) |
| 164 | #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) | 170 | #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) |
| 165 | #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) | 171 | #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) |
| 166 | #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) | 172 | #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) |
| 173 | #define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C) | ||
| 167 | #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) | 174 | #define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) |
| 168 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) | 175 | #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) |
| 169 | #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) | 176 | #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) |
| @@ -196,13 +203,26 @@ · 26 unmodified lines | |||
| 196 | #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) | 203 | #define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) |
| 197 | #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD) | 204 | #define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_GOLD) |
| 198 | #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER) | 205 | #define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_2XX_SILVER) |
| 206 | #define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_GOLD) | ||
| 199 | #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER) | 207 | #define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_3XX_SILVER) |
| 200 | #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD) | 208 | #define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_GOLD) |
| 201 | #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER) | 209 | #define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO_4XX_SILVER) |
| 210 | #define MIDR_QCOM_ORYON_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_ORYON_X1) | ||
| 211 | |||
| 212 | /* | ||
| 213 | * NOTES: | ||
| 214 | * - Qualcomm Kryo 5XX Prime / Gold ID themselves as MIDR_CORTEX_A77 | ||
| 215 | * - Qualcomm Kryo 5XX Silver IDs itself as MIDR_QCOM_KRYO_4XX_SILVER | ||
| 216 | * - Qualcomm Kryo 6XX Prime IDs itself as MIDR_CORTEX_X1 | ||
| 217 | * - Qualcomm Kryo 6XX Gold IDs itself as ARM_CPU_PART_CORTEX_A78 | ||
| 218 | * - Qualcomm Kryo 6XX Silver IDs itself as MIDR_CORTEX_A55 | ||
| 219 | */ | ||
| 220 | |||
| 202 | #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) | 221 | #define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_DENVER) |
| 203 | #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) | 222 | #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) |
| 204 | #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) | 223 | #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) |
| 205 | #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) | 224 | #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) |
| 225 | #define MIDR_HISI_HIP09 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP09) | ||
| 206 | #define MIDR_HISI_HIP12 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP12) | 226 | #define MIDR_HISI_HIP12 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP12) |
| 207 | #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) | 227 | #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) |
| 208 | #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) | 228 | #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) |
| @@ -291,6 +311,14 @@ static inline u32 __attribute_const__ read_cpuid_id(void) · 82 unmodified lines | |||
| 291 | return read_cpuid(MIDR_EL1); | 311 | return read_cpuid(MIDR_EL1); |
| 292 | } | 312 | } |
| 293 | 313 | ||
| 314 | struct target_impl_cpu { | ||
| 315 | u64 midr; | ||
| 316 | u64 revidr; | ||
| 317 | u64 aidr; | ||
| 318 | }; | ||
| 319 | |||
| 320 | bool cpu_errata_set_target_impl(u64 num, void *impl_cpus); | ||
| 321 | |||
| 294 | static inline u64 __attribute_const__ read_cpuid_mpidr(void) | 322 | static inline u64 __attribute_const__ read_cpuid_mpidr(void) |
| 295 | { | 323 | { |
| 296 | return read_cpuid(MPIDR_EL1); | 324 | return read_cpuid(MPIDR_EL1); |
| @@ -1,18 +1,5 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
| 2 | /* | 2 | /* |
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License, version 2, as | ||
| 5 | * published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 15 | * | ||
| 16 | * Copyright IBM Corp. 2007 | 3 | * Copyright IBM Corp. 2007 |
| 17 | * | 4 | * |
| 18 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | 5 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> |
| @@ -218,6 +218,7 @@ · 217 unmodified lines | |||
| 218 | #define X86_FEATURE_FLEXPRIORITY ( 8*32+ 1) /* "flexpriority" Intel FlexPriority */ | 218 | #define X86_FEATURE_FLEXPRIORITY ( 8*32+ 1) /* "flexpriority" Intel FlexPriority */ |
| 219 | #define X86_FEATURE_EPT ( 8*32+ 2) /* "ept" Intel Extended Page Table */ | 219 | #define X86_FEATURE_EPT ( 8*32+ 2) /* "ept" Intel Extended Page Table */ |
| 220 | #define X86_FEATURE_VPID ( 8*32+ 3) /* "vpid" Intel Virtual Processor ID */ | 220 | #define X86_FEATURE_VPID ( 8*32+ 3) /* "vpid" Intel Virtual Processor ID */ |
| 221 | #define X86_FEATURE_COHERENCY_SFW_NO ( 8*32+ 4) /* SNP cache coherency software work around not needed */ | ||
| 221 | 222 | ||
| 222 | #define X86_FEATURE_VMMCALL ( 8*32+15) /* "vmmcall" Prefer VMMCALL to VMCALL */ | 223 | #define X86_FEATURE_VMMCALL ( 8*32+15) /* "vmmcall" Prefer VMMCALL to VMCALL */ |
| 223 | #define X86_FEATURE_XENPV ( 8*32+16) /* Xen paravirtual guest */ | 224 | #define X86_FEATURE_XENPV ( 8*32+16) /* Xen paravirtual guest */ |
| @@ -456,10 +457,14 @@ · 232 unmodified lines | |||
| 456 | #define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */ | 457 | #define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */ |
| 457 | #define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */ | 458 | #define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */ |
| 458 | #define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */ | 459 | #define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */ |
| 460 | #define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */ | ||
| 459 | #define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */ | 461 | #define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */ |
| 462 | |||
| 460 | #define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */ | 463 | #define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */ |
| 461 | #define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */ | 464 | #define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */ |
| 462 | 465 | ||
| 466 | #define X86_FEATURE_GP_ON_USER_CPUID (20*32+17) /* User CPUID faulting */ | ||
| 467 | |||
| 463 | #define X86_FEATURE_PREFETCHI (20*32+20) /* Prefetch Data/Instruction to Cache Level */ | 468 | #define X86_FEATURE_PREFETCHI (20*32+20) /* Prefetch Data/Instruction to Cache Level */ |
| 464 | #define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */ | 469 | #define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */ |
| 465 | #define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */ | 470 | #define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */ |
| @@ -487,6 +492,9 @@ · 21 unmodified lines | |||
| 487 | #define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */ | 492 | #define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */ |
| 488 | #define X86_FEATURE_APX (21*32+ 9) /* Advanced Performance Extensions */ | 493 | #define X86_FEATURE_APX (21*32+ 9) /* Advanced Performance Extensions */ |
| 489 | #define X86_FEATURE_INDIRECT_THUNK_ITS (21*32+10) /* Use thunk for indirect branches in lower half of cacheline */ | 494 | #define X86_FEATURE_INDIRECT_THUNK_ITS (21*32+10) /* Use thunk for indirect branches in lower half of cacheline */ |
| 495 | #define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */ | ||
| 496 | #define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */ | ||
| 497 | #define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */ | ||
| 490 | 498 | ||
| 491 | /* | 499 | /* |
| 492 | * BUG word(s) | 500 | * BUG word(s) |
| @@ -542,5 +550,5 @@ · 49 unmodified lines | |||
| 542 | #define X86_BUG_OLD_MICROCODE X86_BUG( 1*32+ 6) /* "old_microcode" CPU has old microcode, it is surely vulnerable to something */ | 550 | #define X86_BUG_OLD_MICROCODE X86_BUG( 1*32+ 6) /* "old_microcode" CPU has old microcode, it is surely vulnerable to something */ |
| 543 | #define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */ | 551 | #define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */ |
| 544 | #define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */ | 552 | #define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */ |
| 545 | 553 | #define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */ | |
| 546 | #endif /* _ASM_X86_CPUFEATURES_H */ | 554 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -419,6 +419,7 @@ · 418 unmodified lines | |||
| 419 | #define DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI (1UL << 12) | 419 | #define DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI (1UL << 12) |
| 420 | #define DEBUGCTLMSR_FREEZE_IN_SMM_BIT 14 | 420 | #define DEBUGCTLMSR_FREEZE_IN_SMM_BIT 14 |
| 421 | #define DEBUGCTLMSR_FREEZE_IN_SMM (1UL << DEBUGCTLMSR_FREEZE_IN_SMM_BIT) | 421 | #define DEBUGCTLMSR_FREEZE_IN_SMM (1UL << DEBUGCTLMSR_FREEZE_IN_SMM_BIT) |
| 422 | #define DEBUGCTLMSR_RTM_DEBUG BIT(15) | ||
| 422 | 423 | ||
| 423 | #define MSR_PEBS_FRONTEND 0x000003f7 | 424 | #define MSR_PEBS_FRONTEND 0x000003f7 |
| 424 | 425 | ||
| @@ -733,6 +734,11 @@ · 308 unmodified lines | |||
| 733 | #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301 | 734 | #define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301 |
| 734 | #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR 0xc0000302 | 735 | #define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR 0xc0000302 |
| 735 | 736 | ||
| 737 | /* AMD Hardware Feedback Support MSRs */ | ||
| 738 | #define MSR_AMD_WORKLOAD_CLASS_CONFIG 0xc0000500 | ||
| 739 | #define MSR_AMD_WORKLOAD_CLASS_ID 0xc0000501 | ||
| 740 | #define MSR_AMD_WORKLOAD_HRST 0xc0000502 | ||
| 741 | |||
| 736 | /* AMD Last Branch Record MSRs */ | 742 | /* AMD Last Branch Record MSRs */ |
| 737 | #define MSR_AMD64_LBR_SELECT 0xc000010e | 743 | #define MSR_AMD64_LBR_SELECT 0xc000010e |
| 738 | 744 | ||
| @@ -831,6 +837,7 @@ · 92 unmodified lines | |||
| 831 | #define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT) | 837 | #define MSR_K7_HWCR_SMMLOCK BIT_ULL(MSR_K7_HWCR_SMMLOCK_BIT) |
| 832 | #define MSR_K7_HWCR_IRPERF_EN_BIT 30 | 838 | #define MSR_K7_HWCR_IRPERF_EN_BIT 30 |
| 833 | #define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT) | 839 | #define MSR_K7_HWCR_IRPERF_EN BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT) |
| 840 | #define MSR_K7_HWCR_CPUID_USER_DIS_BIT 35 | ||
| 834 | #define MSR_K7_FID_VID_CTL 0xc0010041 | 841 | #define MSR_K7_FID_VID_CTL 0xc0010041 |
| 835 | #define MSR_K7_FID_VID_STATUS 0xc0010042 | 842 | #define MSR_K7_FID_VID_STATUS 0xc0010042 |
| 836 | #define MSR_K7_HWCR_CPB_DIS_BIT 25 | 843 | #define MSR_K7_HWCR_CPB_DIS_BIT 25 |
| @@ -965,7 +965,13 @@ struct kvm_tdx_cmd { · 964 unmodified lines | |||
| 965 | struct kvm_tdx_capabilities { | 965 | struct kvm_tdx_capabilities { |
| 966 | __u64 supported_attrs; | 966 | __u64 supported_attrs; |
| 967 | __u64 supported_xfam; | 967 | __u64 supported_xfam; |
| 968 | __u64 reserved[254]; | 968 | |
| 969 | __u64 kernel_tdvmcallinfo_1_r11; | ||
| 970 | __u64 user_tdvmcallinfo_1_r11; | ||
| 971 | __u64 kernel_tdvmcallinfo_1_r12; | ||
| 972 | __u64 user_tdvmcallinfo_1_r12; | ||
| 973 | |||
| 974 | __u64 reserved[250]; | ||
| 969 | 975 | ||
| 970 | /* Configurable CPUID bits for userspace */ | 976 | /* Configurable CPUID bits for userspace */ |
| 971 | struct kvm_cpuid2 cpuid; | 977 | struct kvm_cpuid2 cpuid; |
| @@ -0,0 +1,28 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | |||
| 3 | #ifndef _LINUX_ARGS_H | ||
| 4 | #define _LINUX_ARGS_H | ||
| 5 | |||
| 6 | /* | ||
| 7 | * How do these macros work? | ||
| 8 | * | ||
| 9 | * In __COUNT_ARGS() _0 to _12 are just placeholders from the start | ||
| 10 | * in order to make sure _n is positioned over the correct number | ||
| 11 | * from 12 to 0 (depending on X, which is a variadic argument list). | ||
| 12 | * They serve no purpose other than occupying a position. Since each | ||
| 13 | * macro parameter must have a distinct identifier, those identifiers | ||
| 14 | * are as good as any. | ||
| 15 | * | ||
| 16 | * In COUNT_ARGS() we use actual integers, so __COUNT_ARGS() returns | ||
| 17 | * that as _n. | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* This counts to 15. Any more, it will return 16th argument. */ | ||
| 21 | #define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _n, X...) _n | ||
| 22 | #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) | ||
| 23 | |||
| 24 | /* Concatenate two parameters, but allow them to be expanded beforehand. */ | ||
| 25 | #define __CONCAT(a, b) a ## b | ||
| 26 | #define CONCATENATE(a, b) __CONCAT(a, b) | ||
| 27 | |||
| 28 | #endif /* _LINUX_ARGS_H */ | ||
| @@ -2,10 +2,8 @@ · 1 unmodified line | |||
| 2 | #ifndef __LINUX_BITS_H | 2 | #ifndef __LINUX_BITS_H |
| 3 | #define __LINUX_BITS_H | 3 | #define __LINUX_BITS_H |
| 4 | 4 | ||
| 5 | #include <linux/const.h> | ||
| 6 | #include <vdso/bits.h> | 5 | #include <vdso/bits.h> |
| 7 | #include <uapi/linux/bits.h> | 6 | #include <uapi/linux/bits.h> |
| 8 | #include <asm/bitsperlong.h> | ||
| 9 | 7 | ||
| 10 | #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) | 8 | #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) |
| 11 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) | 9 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) |
| @@ -50,10 +48,14 @@ · 38 unmodified lines | |||
| 50 | (type_max(t) << (l) & \ | 48 | (type_max(t) << (l) & \ |
| 51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h))))) | 49 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h))))) |
| 52 | 50 | ||
| 51 | #define GENMASK(h, l) GENMASK_TYPE(unsigned long, h, l) | ||
| 52 | #define GENMASK_ULL(h, l) GENMASK_TYPE(unsigned long long, h, l) | ||
| 53 | |||
| 53 | #define GENMASK_U8(h, l) GENMASK_TYPE(u8, h, l) | 54 | #define GENMASK_U8(h, l) GENMASK_TYPE(u8, h, l) |
| 54 | #define GENMASK_U16(h, l) GENMASK_TYPE(u16, h, l) | 55 | #define GENMASK_U16(h, l) GENMASK_TYPE(u16, h, l) |
| 55 | #define GENMASK_U32(h, l) GENMASK_TYPE(u32, h, l) | 56 | #define GENMASK_U32(h, l) GENMASK_TYPE(u32, h, l) |
| 56 | #define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l) | 57 | #define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l) |
| 58 | #define GENMASK_U128(h, l) GENMASK_TYPE(u128, h, l) | ||
| 57 | 59 | ||
| 58 | /* | 60 | /* |
| 59 | * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The | 61 | * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The |
| @@ -79,28 +81,9 @@ · 19 unmodified lines | |||
| 79 | * BUILD_BUG_ON_ZERO is not available in h files included from asm files, | 81 | * BUILD_BUG_ON_ZERO is not available in h files included from asm files, |
| 80 | * disable the input check if that is the case. | 82 | * disable the input check if that is the case. |
| 81 | */ | 83 | */ |
| 82 | #define GENMASK_INPUT_CHECK(h, l) 0 | 84 | #define GENMASK(h, l) __GENMASK(h, l) |
| 85 | #define GENMASK_ULL(h, l) __GENMASK_ULL(h, l) | ||
| 83 | 86 | ||
| 84 | #endif /* !defined(__ASSEMBLY__) */ | 87 | #endif /* !defined(__ASSEMBLY__) */ |
| 85 | 88 | ||
| 86 | #define GENMASK(h, l) \ | ||
| 87 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l)) | ||
| 88 | #define GENMASK_ULL(h, l) \ | ||
| 89 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l)) | ||
| 90 | |||
| 91 | #if !defined(__ASSEMBLY__) | ||
| 92 | /* | ||
| 93 | * Missing asm support | ||
| 94 | * | ||
| 95 | * __GENMASK_U128() depends on _BIT128() which would not work | ||
| 96 | * in the asm code, as it shifts an 'unsigned __int128' data | ||
| 97 | * type instead of direct representation of 128 bit constants | ||
| 98 | * such as long and unsigned long. The fundamental problem is | ||
| 99 | * that a 128 bit constant will get silently truncated by the | ||
| 100 | * gcc compiler. | ||
| 101 | */ | ||
| 102 | #define GENMASK_U128(h, l) \ | ||
| 103 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U128(h, l)) | ||
| 104 | #endif | ||
| 105 | |||
| 106 | #endif /* __LINUX_BITS_H */ | 89 | #endif /* __LINUX_BITS_H */ |
| @@ -41,5 +41,28 @@ · 40 unmodified lines | |||
| 41 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) | 41 | SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #else /* __ASSEMBLY__ */ | ||
| 45 | |||
| 46 | #ifdef CONFIG_CFI_CLANG | ||
| 47 | #define DEFINE_CFI_TYPE(name, func) \ | ||
| 48 | /* \ | ||
| 49 | * Force a reference to the function so the compiler generates \ | ||
| 50 | * __kcfi_typeid_<func>. \ | ||
| 51 | */ \ | ||
| 52 | __ADDRESSABLE(func); \ | ||
| 53 | /* u32 name __ro_after_init = __kcfi_typeid_<func> */ \ | ||
| 54 | extern u32 name; \ | ||
| 55 | asm ( \ | ||
| 56 | " .pushsection .data..ro_after_init,\"aw\",\%progbits \n" \ | ||
| 57 | " .type " #name ",\%object \n" \ | ||
| 58 | " .globl " #name " \n" \ | ||
| 59 | " .p2align 2, 0x0 \n" \ | ||
| 60 | #name ": \n" \ | ||
| 61 | " .4byte __kcfi_typeid_" #func " \n" \ | ||
| 62 | " .size " #name ", 4 \n" \ | ||
| 63 | " .popsection \n" \ | ||
| 64 | ); | ||
| 65 | #endif | ||
| 66 | |||
| 44 | #endif /* __ASSEMBLY__ */ | 67 | #endif /* __ASSEMBLY__ */ |
| 45 | #endif /* _LINUX_CFI_TYPES_H */ | 68 | #endif /* _LINUX_CFI_TYPES_H */ |
| @@ -852,8 +852,14 @@ __SYSCALL(__NR_removexattrat, sys_removexattrat) · 851 unmodified lines | |||
| 852 | #define __NR_open_tree_attr 467 | 852 | #define __NR_open_tree_attr 467 |
| 853 | __SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) | 853 | __SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) |
| 854 | 854 | ||
| 855 | /* fs/inode.c */ | ||
| 856 | #define __NR_file_getattr 468 | ||
| 857 | __SYSCALL(__NR_file_getattr, sys_file_getattr) | ||
| 858 | #define __NR_file_setattr 469 | ||
| 859 | __SYSCALL(__NR_file_setattr, sys_file_setattr) | ||
| 860 | |||
| 855 | #undef __NR_syscalls | 861 | #undef __NR_syscalls |
| 856 | #define __NR_syscalls 468 | 862 | #define __NR_syscalls 470 |
| 857 | 863 | ||
| 858 | /* | 864 | /* |
| 859 | * 32 bit systems traditionally used different | 865 | * 32 bit systems traditionally used different |
| @@ -178,6 +178,7 @@ struct kvm_xen_exit { · 177 unmodified lines | |||
| 178 | #define KVM_EXIT_NOTIFY 37 | 178 | #define KVM_EXIT_NOTIFY 37 |
| 179 | #define KVM_EXIT_LOONGARCH_IOCSR 38 | 179 | #define KVM_EXIT_LOONGARCH_IOCSR 38 |
| 180 | #define KVM_EXIT_MEMORY_FAULT 39 | 180 | #define KVM_EXIT_MEMORY_FAULT 39 |
| 181 | #define KVM_EXIT_TDX 40 | ||
| 181 | 182 | ||
| 182 | /* For KVM_EXIT_INTERNAL_ERROR */ | 183 | /* For KVM_EXIT_INTERNAL_ERROR */ |
| 183 | /* Emulate instruction failed. */ | 184 | /* Emulate instruction failed. */ |
| @@ -447,6 +448,31 @@ struct kvm_run { · 263 unmodified lines | |||
| 447 | __u64 gpa; | 448 | __u64 gpa; |
| 448 | __u64 size; | 449 | __u64 size; |
| 449 | } memory_fault; | 450 | } memory_fault; |
| 451 | /* KVM_EXIT_TDX */ | ||
| 452 | struct { | ||
| 453 | __u64 flags; | ||
| 454 | __u64 nr; | ||
| 455 | union { | ||
| 456 | struct { | ||
| 457 | __u64 ret; | ||
| 458 | __u64 data[5]; | ||
| 459 | } unknown; | ||
| 460 | struct { | ||
| 461 | __u64 ret; | ||
| 462 | __u64 gpa; | ||
| 463 | __u64 size; | ||
| 464 | } get_quote; | ||
| 465 | struct { | ||
| 466 | __u64 ret; | ||
| 467 | __u64 leaf; | ||
| 468 | __u64 r11, r12, r13, r14; | ||
| 469 | } get_tdvmcall_info; | ||
| 470 | struct { | ||
| 471 | __u64 ret; | ||
| 472 | __u64 vector; | ||
| 473 | } setup_event_notify; | ||
| 474 | }; | ||
| 475 | } tdx; | ||
| 450 | /* Fix the size of the union. */ | 476 | /* Fix the size of the union. */ |
| 451 | char padding[256]; | 477 | char padding[256]; |
| 452 | }; | 478 | }; |
| @@ -935,6 +961,7 @@ struct kvm_enable_cap { · 482 unmodified lines | |||
| 935 | #define KVM_CAP_ARM_EL2 240 | 961 | #define KVM_CAP_ARM_EL2 240 |
| 936 | #define KVM_CAP_ARM_EL2_E2H0 241 | 962 | #define KVM_CAP_ARM_EL2_E2H0 241 |
| 937 | #define KVM_CAP_RISCV_MP_STATE_RESET 242 | 963 | #define KVM_CAP_RISCV_MP_STATE_RESET 242 |
| 964 | #define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243 | ||
| 938 | 965 | ||
| 939 | struct kvm_irq_routing_irqchip { | 966 | struct kvm_irq_routing_irqchip { |
| 940 | __u32 irqchip; | 967 | __u32 irqchip; |
| @@ -482,3 +482,5 @@ · 481 unmodified lines | |||
| 482 | 465 common listxattrat sys_listxattrat | 482 | 465 common listxattrat sys_listxattrat |
| 483 | 466 common removexattrat sys_removexattrat | 483 | 466 common removexattrat sys_removexattrat |
| 484 | 467 common open_tree_attr sys_open_tree_attr | 484 | 467 common open_tree_attr sys_open_tree_attr |
| 485 | 468 common file_getattr sys_file_getattr | ||
| 486 | 469 common file_setattr sys_file_setattr | ||
| @@ -382,3 +382,5 @@ · 381 unmodified lines | |||
| 382 | 465 n64 listxattrat sys_listxattrat | 382 | 465 n64 listxattrat sys_listxattrat |
| 383 | 466 n64 removexattrat sys_removexattrat | 383 | 466 n64 removexattrat sys_removexattrat |
| 384 | 467 n64 open_tree_attr sys_open_tree_attr | 384 | 467 n64 open_tree_attr sys_open_tree_attr |
| 385 | 468 n64 file_getattr sys_file_getattr | ||
| 386 | 469 n64 file_setattr sys_file_setattr | ||
| @@ -558,3 +558,5 @@ · 557 unmodified lines | |||
| 558 | 465 common listxattrat sys_listxattrat | 558 | 465 common listxattrat sys_listxattrat |
| 559 | 466 common removexattrat sys_removexattrat | 559 | 466 common removexattrat sys_removexattrat |
| 560 | 467 common open_tree_attr sys_open_tree_attr | 560 | 467 common open_tree_attr sys_open_tree_attr |
| 561 | 468 common file_getattr sys_file_getattr | ||
| 562 | 469 common file_setattr sys_file_setattr | ||
| @@ -470,3 +470,5 @@ · 469 unmodified lines | |||
| 470 | 465 common listxattrat sys_listxattrat sys_listxattrat | 470 | 465 common listxattrat sys_listxattrat sys_listxattrat |
| 471 | 466 common removexattrat sys_removexattrat sys_removexattrat | 471 | 466 common removexattrat sys_removexattrat sys_removexattrat |
| 472 | 467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr | 472 | 467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr |
| 473 | 468 common file_getattr sys_file_getattr sys_file_getattr | ||
| 474 | 469 common file_setattr sys_file_setattr sys_file_setattr | ||
| @@ -471,3 +471,5 @@ · 470 unmodified lines | |||
| 471 | 465 common listxattrat sys_listxattrat | 471 | 465 common listxattrat sys_listxattrat |
| 472 | 466 common removexattrat sys_removexattrat | 472 | 466 common removexattrat sys_removexattrat |
| 473 | 467 common open_tree_attr sys_open_tree_attr | 473 | 467 common open_tree_attr sys_open_tree_attr |
| 474 | 468 common file_getattr sys_file_getattr | ||
| 475 | 469 common file_setattr sys_file_setattr | ||
| @@ -513,3 +513,5 @@ · 512 unmodified lines | |||
| 513 | 465 common listxattrat sys_listxattrat | 513 | 465 common listxattrat sys_listxattrat |
| 514 | 466 common removexattrat sys_removexattrat | 514 | 466 common removexattrat sys_removexattrat |
| 515 | 467 common open_tree_attr sys_open_tree_attr | 515 | 467 common open_tree_attr sys_open_tree_attr |
| 516 | 468 common file_getattr sys_file_getattr | ||
| 517 | 469 common file_setattr sys_file_setattr | ||
| @@ -473,3 +473,5 @@ · 472 unmodified lines | |||
| 473 | 465 i386 listxattrat sys_listxattrat | 473 | 465 i386 listxattrat sys_listxattrat |
| 474 | 466 i386 removexattrat sys_removexattrat | 474 | 466 i386 removexattrat sys_removexattrat |
| 475 | 467 i386 open_tree_attr sys_open_tree_attr | 475 | 467 i386 open_tree_attr sys_open_tree_attr |
| 476 | 468 i386 file_getattr sys_file_getattr | ||
| 477 | 469 i386 file_setattr sys_file_setattr | ||
| @@ -391,6 +391,8 @@ · 390 unmodified lines | |||
| 391 | 465 common listxattrat sys_listxattrat | 391 | 465 common listxattrat sys_listxattrat |
| 392 | 466 common removexattrat sys_removexattrat | 392 | 466 common removexattrat sys_removexattrat |
| 393 | 467 common open_tree_attr sys_open_tree_attr | 393 | 467 common open_tree_attr sys_open_tree_attr |
| 394 | 468 common file_getattr sys_file_getattr | ||
| 395 | 469 common file_setattr sys_file_setattr | ||
| 394 | 396 | ||
| 395 | # | 397 | # |
| 396 | # Due to a historical design error, certain syscalls are numbered differently | 398 | # Due to a historical design error, certain syscalls are numbered differently |
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include "arch-tests.h" | 2 | #include "arch-tests.h" |
| 3 | #include "../util/topdown.h" | 3 | #include "../util/topdown.h" |
| 4 | #include "debug.h" | ||
| 4 | #include "evlist.h" | 5 | #include "evlist.h" |
| 5 | #include "parse-events.h" | 6 | #include "parse-events.h" |
| 6 | #include "pmu.h" | 7 | #include "pmu.h" |
| @@ -438,3 +438,5 @@ · 437 unmodified lines | |||
| 438 | 465 common listxattrat sys_listxattrat | 438 | 465 common listxattrat sys_listxattrat |
| 439 | 466 common removexattrat sys_removexattrat | 439 | 466 common removexattrat sys_removexattrat |
| 440 | 467 common open_tree_attr sys_open_tree_attr | 440 | 467 common open_tree_attr sys_open_tree_attr |
| 441 | 468 common file_getattr sys_file_getattr | ||
| 442 | 469 common file_setattr sys_file_setattr | ||
| @@ -85,7 +85,7 @@ static int add_dso(const char *fpath, const struct stat *sb __maybe_unused, · 84 unmodified lines | |||
| 85 | if (typeflag == FTW_D || typeflag == FTW_SL) | 85 | if (typeflag == FTW_D || typeflag == FTW_SL) |
| 86 | return 0; | 86 | return 0; |
| 87 | 87 | ||
| 88 | if (filename__read_build_id(fpath, &bid) < 0) | 88 | if (filename__read_build_id(fpath, &bid, /*block=*/true) < 0) |
| 89 | return 0; | 89 | return 0; |
| 90 | 90 | ||
| 91 | dso->name = realpath(fpath, NULL); | 91 | dso->name = realpath(fpath, NULL); |
| @@ -180,7 +180,7 @@ static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi) · 179 unmodified lines | |||
| 180 | struct nscookie nsc; | 180 | struct nscookie nsc; |
| 181 | 181 | ||
| 182 | nsinfo__mountns_enter(nsi, &nsc); | 182 | nsinfo__mountns_enter(nsi, &nsc); |
| 183 | err = filename__read_build_id(filename, &bid); | 183 | err = filename__read_build_id(filename, &bid, /*block=*/true); |
| 184 | nsinfo__mountns_exit(&nsc); | 184 | nsinfo__mountns_exit(&nsc); |
| 185 | if (err < 0) { | 185 | if (err < 0) { |
| 186 | pr_debug("Couldn't read a build-id in %s\n", filename); | 186 | pr_debug("Couldn't read a build-id in %s\n", filename); |
| @@ -204,7 +204,7 @@ static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi) · 17 unmodified lines | |||
| 204 | int err; | 204 | int err; |
| 205 | 205 | ||
| 206 | nsinfo__mountns_enter(nsi, &nsc); | 206 | nsinfo__mountns_enter(nsi, &nsc); |
| 207 | err = filename__read_build_id(filename, &bid); | 207 | err = filename__read_build_id(filename, &bid, /*block=*/true); |
| 208 | nsinfo__mountns_exit(&nsc); | 208 | nsinfo__mountns_exit(&nsc); |
| 209 | if (err < 0) { | 209 | if (err < 0) { |
| 210 | pr_debug("Couldn't read a build-id in %s\n", filename); | 210 | pr_debug("Couldn't read a build-id in %s\n", filename); |
| @@ -280,7 +280,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) · 69 unmodified lines | |||
| 280 | if (!dso__build_id_filename(dso, filename, sizeof(filename), false)) | 280 | if (!dso__build_id_filename(dso, filename, sizeof(filename), false)) |
| 281 | return true; | 281 | return true; |
| 282 | 282 | ||
| 283 | if (filename__read_build_id(filename, &bid) == -1) { | 283 | if (filename__read_build_id(filename, &bid, /*block=*/true) == -1) { |
| 284 | if (errno == ENOENT) | 284 | if (errno == ENOENT) |
| 285 | return false; | 285 | return false; |
| 286 | 286 | ||
| @@ -309,7 +309,7 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi) · 22 unmodified lines | |||
| 309 | int err; | 309 | int err; |
| 310 | 310 | ||
| 311 | nsinfo__mountns_enter(nsi, &nsc); | 311 | nsinfo__mountns_enter(nsi, &nsc); |
| 312 | err = filename__read_build_id(filename, &bid); | 312 | err = filename__read_build_id(filename, &bid, /*block=*/true); |
| 313 | nsinfo__mountns_exit(&nsc); | 313 | nsinfo__mountns_exit(&nsc); |
| 314 | if (err < 0) { | 314 | if (err < 0) { |
| 315 | pr_debug("Couldn't read a build-id in %s\n", filename); | 315 | pr_debug("Couldn't read a build-id in %s\n", filename); |
| @@ -680,12 +680,12 @@ static int dso__read_build_id(struct dso *dso) · 679 unmodified lines | |||
| 680 | 680 | ||
| 681 | mutex_lock(dso__lock(dso)); | 681 | mutex_lock(dso__lock(dso)); |
| 682 | nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); | 682 | nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); |
| 683 | if (filename__read_build_id(dso__long_name(dso), &bid) > 0) | 683 | if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0) |
| 684 | dso__set_build_id(dso, &bid); | 684 | dso__set_build_id(dso, &bid); |
| 685 | else if (dso__nsinfo(dso)) { | 685 | else if (dso__nsinfo(dso)) { |
| 686 | char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); | 686 | char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); |
| 687 | 687 | ||
| 688 | if (new_name && filename__read_build_id(new_name, &bid) > 0) | 688 | if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0) |
| 689 | dso__set_build_id(dso, &bid); | 689 | dso__set_build_id(dso, &bid); |
| 690 | free(new_name); | 690 | free(new_name); |
| 691 | } | 691 | } |
| @@ -31,7 +31,7 @@ static int build_id_cache__add_file(const char *filename) · 30 unmodified lines | |||
| 31 | struct build_id bid = { .size = 0, }; | 31 | struct build_id bid = { .size = 0, }; |
| 32 | int err; | 32 | int err; |
| 33 | 33 | ||
| 34 | err = filename__read_build_id(filename, &bid); | 34 | err = filename__read_build_id(filename, &bid, /*block=*/true); |
| 35 | if (err < 0) { | 35 | if (err < 0) { |
| 36 | pr_debug("Failed to read build id of %s\n", filename); | 36 | pr_debug("Failed to read build id of %s\n", filename); |
| 37 | return err; | 37 | return err; |
| @@ -90,10 +90,28 @@ · 89 unmodified lines | |||
| 90 | #define DN_ATTRIB 0x00000020 /* File changed attibutes */ | 90 | #define DN_ATTRIB 0x00000020 /* File changed attibutes */ |
| 91 | #define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ | 91 | #define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ |
| 92 | 92 | ||
| 93 | /* Reserved kernel ranges [-100], [-10000, -40000]. */ | ||
| 93 | #define AT_FDCWD -100 /* Special value for dirfd used to | 94 | #define AT_FDCWD -100 /* Special value for dirfd used to |
| 94 | indicate openat should use the | 95 | indicate openat should use the |
| 95 | current working directory. */ | 96 | current working directory. */ |
| 96 | 97 | ||
| 98 | /* | ||
| 99 | * The concept of process and threads in userland and the kernel is a confusing | ||
| 100 | * one - within the kernel every thread is a 'task' with its own individual PID, | ||
| 101 | * however from userland's point of view threads are grouped by a single PID, | ||
| 102 | * which is that of the 'thread group leader', typically the first thread | ||
| 103 | * spawned. | ||
| 104 | * | ||
| 105 | * To cut the Gideon knot, for internal kernel usage, we refer to | ||
| 106 | * PIDFD_SELF_THREAD to refer to the current thread (or task from a kernel | ||
| 107 | * perspective), and PIDFD_SELF_THREAD_GROUP to refer to the current thread | ||
| 108 | * group leader... | ||
| 109 | */ | ||
| 110 | #define PIDFD_SELF_THREAD -10000 /* Current thread. */ | ||
| 111 | #define PIDFD_SELF_THREAD_GROUP -10001 /* Current thread group leader. */ | ||
| 112 | |||
| 113 | #define FD_PIDFS_ROOT -10002 /* Root of the pidfs filesystem */ | ||
| 114 | #define FD_INVALID -10009 /* Invalid file descriptor: -10000 - EBADF = -10009 */ | ||
| 97 | 115 | ||
| 98 | /* Generic flags for the *at(2) family of syscalls. */ | 116 | /* Generic flags for the *at(2) family of syscalls. */ |
| 99 | 117 | ||
| @@ -60,6 +60,17 @@ · 59 unmodified lines | |||
| 60 | #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */ | 60 | #define RENAME_EXCHANGE (1 << 1) /* Exchange source and dest */ |
| 61 | #define RENAME_WHITEOUT (1 << 2) /* Whiteout source */ | 61 | #define RENAME_WHITEOUT (1 << 2) /* Whiteout source */ |
| 62 | 62 | ||
| 63 | /* | ||
| 64 | * The root inode of procfs is guaranteed to always have the same inode number. | ||
| 65 | * For programs that make heavy use of procfs, verifying that the root is a | ||
| 66 | * real procfs root and using openat2(RESOLVE_{NO_{XDEV,MAGICLINKS},BENEATH}) | ||
| 67 | * will allow you to make sure you are never tricked into operating on the | ||
| 68 | * wrong procfs file. | ||
| 69 | */ | ||
| 70 | enum procfs_ino { | ||
| 71 | PROCFS_ROOT_INO = 1, | ||
| 72 | }; | ||
| 73 | |||
| 63 | struct file_clone_range { | 74 | struct file_clone_range { |
| 64 | __s64 src_fd; | 75 | __s64 src_fd; |
| 65 | __u64 src_offset; | 76 | __u64 src_offset; |
| @@ -91,6 +102,63 @@ struct fs_sysfs_path { · 25 unmodified lines | |||
| 91 | __u8 name[128]; | 102 | __u8 name[128]; |
| 92 | }; | 103 | }; |
| 93 | 104 | ||
| 105 | /* Protection info capability flags */ | ||
| 106 | #define LBMD_PI_CAP_INTEGRITY (1 << 0) | ||
| 107 | #define LBMD_PI_CAP_REFTAG (1 << 1) | ||
| 108 | |||
| 109 | /* Checksum types for Protection Information */ | ||
| 110 | #define LBMD_PI_CSUM_NONE 0 | ||
| 111 | #define LBMD_PI_CSUM_IP 1 | ||
| 112 | #define LBMD_PI_CSUM_CRC16_T10DIF 2 | ||
| 113 | #define LBMD_PI_CSUM_CRC64_NVME 4 | ||
| 114 | |||
| 115 | /* sizeof first published struct */ | ||
| 116 | #define LBMD_SIZE_VER0 16 | ||
| 117 | |||
| 118 | /* | ||
| 119 | * Logical block metadata capability descriptor | ||
| 120 | * If the device does not support metadata, all the fields will be zero. | ||
| 121 | * Applications must check lbmd_flags to determine whether metadata is | ||
| 122 | * supported or not. | ||
| 123 | */ | ||
| 124 | struct logical_block_metadata_cap { | ||
| 125 | /* Bitmask of logical block metadata capability flags */ | ||
| 126 | __u32 lbmd_flags; | ||
| 127 | /* | ||
| 128 | * The amount of data described by each unit of logical block | ||
| 129 | * metadata | ||
| 130 | */ | ||
| 131 | __u16 lbmd_interval; | ||
| 132 | /* | ||
| 133 | * Size in bytes of the logical block metadata associated with each | ||
| 134 | * interval | ||
| 135 | */ | ||
| 136 | __u8 lbmd_size; | ||
| 137 | /* | ||
| 138 | * Size in bytes of the opaque block tag associated with each | ||
| 139 | * interval | ||
| 140 | */ | ||
| 141 | __u8 lbmd_opaque_size; | ||
| 142 | /* | ||
| 143 | * Offset in bytes of the opaque block tag within the logical block | ||
| 144 | * metadata | ||
| 145 | */ | ||
| 146 | __u8 lbmd_opaque_offset; | ||
| 147 | /* Size in bytes of the T10 PI tuple associated with each interval */ | ||
| 148 | __u8 lbmd_pi_size; | ||
| 149 | /* Offset in bytes of T10 PI tuple within the logical block metadata */ | ||
| 150 | __u8 lbmd_pi_offset; | ||
| 151 | /* T10 PI guard tag type */ | ||
| 152 | __u8 lbmd_guard_tag_type; | ||
| 153 | /* Size in bytes of the T10 PI application tag */ | ||
| 154 | __u8 lbmd_app_tag_size; | ||
| 155 | /* Size in bytes of the T10 PI reference tag */ | ||
| 156 | __u8 lbmd_ref_tag_size; | ||
| 157 | /* Size in bytes of the T10 PI storage tag */ | ||
| 158 | __u8 lbmd_storage_tag_size; | ||
| 159 | __u8 pad; | ||
| 160 | }; | ||
| 161 | |||
| 94 | /* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */ | 162 | /* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */ |
| 95 | #define FILE_DEDUPE_RANGE_SAME 0 | 163 | #define FILE_DEDUPE_RANGE_SAME 0 |
| 96 | #define FILE_DEDUPE_RANGE_DIFFERS 1 | 164 | #define FILE_DEDUPE_RANGE_DIFFERS 1 |
| @@ -148,6 +216,24 @@ struct fsxattr { · 51 unmodified lines | |||
| 148 | unsigned char fsx_pad[8]; | 216 | unsigned char fsx_pad[8]; |
| 149 | }; | 217 | }; |
| 150 | 218 | ||
| 219 | /* | ||
| 220 | * Variable size structure for file_[sg]et_attr(). | ||
| 221 | * | ||
| 222 | * Note. This is alternative to the structure 'struct file_kattr'/'struct fsxattr'. | ||
| 223 | * As this structure is passed to/from userspace with its size, this can | ||
| 224 | * be versioned based on the size. | ||
| 225 | */ | ||
| 226 | struct file_attr { | ||
| 227 | __u64 fa_xflags; /* xflags field value (get/set) */ | ||
| 228 | __u32 fa_extsize; /* extsize field value (get/set)*/ | ||
| 229 | __u32 fa_nextents; /* nextents field value (get) */ | ||
| 230 | __u32 fa_projid; /* project identifier (get/set) */ | ||
| 231 | __u32 fa_cowextsize; /* CoW extsize field value (get/set) */ | ||
| 232 | }; | ||
| 233 | |||
| 234 | #define FILE_ATTR_SIZE_VER0 24 | ||
| 235 | #define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0 | ||
| 236 | |||
| 151 | /* | 237 | /* |
| 152 | * Flags for the fsx_xflags field | 238 | * Flags for the fsx_xflags field |
| 153 | */ | 239 | */ |
| @@ -247,6 +333,8 @@ struct fsxattr { · 93 unmodified lines | |||
| 247 | * also /sys/kernel/debug/ for filesystems with debugfs exports | 333 | * also /sys/kernel/debug/ for filesystems with debugfs exports |
| 248 | */ | 334 | */ |
| 249 | #define FS_IOC_GETFSSYSFSPATH _IOR(0x15, 1, struct fs_sysfs_path) | 335 | #define FS_IOC_GETFSSYSFSPATH _IOR(0x15, 1, struct fs_sysfs_path) |
| 336 | /* Get logical block metadata capability details */ | ||
| 337 | #define FS_IOC_GETLBMD_CAP _IOWR(0x15, 2, struct logical_block_metadata_cap) | ||
| 250 | 338 | ||
| 251 | /* | 339 | /* |
| 252 | * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) | 340 | * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) |
| @@ -244,6 +244,8 @@ struct prctl_mm_map { · 243 unmodified lines | |||
| 244 | # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) | 244 | # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) |
| 245 | /* Unused; kept only for source compatibility */ | 245 | /* Unused; kept only for source compatibility */ |
| 246 | # define PR_MTE_TCF_SHIFT 1 | 246 | # define PR_MTE_TCF_SHIFT 1 |
| 247 | /* MTE tag check store only */ | ||
| 248 | # define PR_MTE_STORE_ONLY (1UL << 19) | ||
| 247 | /* RISC-V pointer masking tag length */ | 249 | /* RISC-V pointer masking tag length */ |
| 248 | # define PR_PMLEN_SHIFT 24 | 250 | # define PR_PMLEN_SHIFT 24 |
| 249 | # define PR_PMLEN_MASK (0x7fUL << PR_PMLEN_SHIFT) | 251 | # define PR_PMLEN_MASK (0x7fUL << PR_PMLEN_SHIFT) |
| @@ -255,7 +257,12 @@ struct prctl_mm_map { · 5 unmodified lines | |||
| 255 | /* Dispatch syscalls to a userspace handler */ | 257 | /* Dispatch syscalls to a userspace handler */ |
| 256 | #define PR_SET_SYSCALL_USER_DISPATCH 59 | 258 | #define PR_SET_SYSCALL_USER_DISPATCH 59 |
| 257 | # define PR_SYS_DISPATCH_OFF 0 | 259 | # define PR_SYS_DISPATCH_OFF 0 |
| 258 | # define PR_SYS_DISPATCH_ON 1 | 260 | /* Enable dispatch except for the specified range */ |
| 261 | # define PR_SYS_DISPATCH_EXCLUSIVE_ON 1 | ||
| 262 | /* Enable dispatch for the specified range */ | ||
| 263 | # define PR_SYS_DISPATCH_INCLUSIVE_ON 2 | ||
| 264 | /* Legacy name for backwards compatibility */ | ||
| 265 | # define PR_SYS_DISPATCH_ON PR_SYS_DISPATCH_EXCLUSIVE_ON | ||
| 259 | /* The control values for the user space selector when dispatch is enabled */ | 266 | /* The control values for the user space selector when dispatch is enabled */ |
| 260 | # define SYSCALL_DISPATCH_FILTER_ALLOW 0 | 267 | # define SYSCALL_DISPATCH_FILTER_ALLOW 0 |
| 261 | # define SYSCALL_DISPATCH_FILTER_BLOCK 1 | 268 | # define SYSCALL_DISPATCH_FILTER_BLOCK 1 |
| @@ -235,4 +235,39 @@ · 234 unmodified lines | |||
| 235 | */ | 235 | */ |
| 236 | #define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x82, \ | 236 | #define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x82, \ |
| 237 | struct vhost_vring_state) | 237 | struct vhost_vring_state) |
| 238 | |||
| 239 | /* Extended features manipulation */ | ||
| 240 | #define VHOST_GET_FEATURES_ARRAY _IOR(VHOST_VIRTIO, 0x83, \ | ||
| 241 | struct vhost_features_array) | ||
| 242 | #define VHOST_SET_FEATURES_ARRAY _IOW(VHOST_VIRTIO, 0x83, \ | ||
| 243 | struct vhost_features_array) | ||
| 244 | |||
| 245 | /* fork_owner values for vhost */ | ||
| 246 | #define VHOST_FORK_OWNER_KTHREAD 0 | ||
| 247 | #define VHOST_FORK_OWNER_TASK 1 | ||
| 248 | |||
| 249 | /** | ||
| 250 | * VHOST_SET_FORK_FROM_OWNER - Set the fork_owner flag for the vhost device, | ||
| 251 | * This ioctl must called before VHOST_SET_OWNER. | ||
| 252 | * Only available when CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y | ||
| 253 | * | ||
| 254 | * @param fork_owner: An 8-bit value that determines the vhost thread mode | ||
| 255 | * | ||
| 256 | * When fork_owner is set to VHOST_FORK_OWNER_TASK(default value): | ||
| 257 | * - Vhost will create vhost worker as tasks forked from the owner, | ||
| 258 | * inheriting all of the owner's attributes. | ||
| 259 | * | ||
| 260 | * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: | ||
| 261 | * - Vhost will create vhost workers as kernel threads. | ||
| 262 | */ | ||
| 263 | #define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8) | ||
| 264 | |||
| 265 | /** | ||
| 266 | * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. | ||
| 267 | * Only available when CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y | ||
| 268 | * | ||
| 269 | * @return: An 8-bit value indicating the current thread mode. | ||
| 270 | */ | ||
| 271 | #define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8) | ||
| 272 | |||
| 238 | #endif | 273 | #endif |
| @@ -115,7 +115,7 @@ int filename__snprintf_build_id(const char *pathname, char *sbuild_id, size_t sb · 114 unmodified lines | |||
| 115 | struct build_id bid = { .size = 0, }; | 115 | struct build_id bid = { .size = 0, }; |
| 116 | int ret; | 116 | int ret; |
| 117 | 117 | ||
| 118 | ret = filename__read_build_id(pathname, &bid); | 118 | ret = filename__read_build_id(pathname, &bid, /*block=*/true); |
| 119 | if (ret < 0) | 119 | if (ret < 0) |
| 120 | return ret; | 120 | return ret; |
| 121 | 121 | ||
| @@ -841,7 +841,7 @@ static int filename__read_build_id_ns(const char *filename, · 719 unmodified lines | |||
| 841 | int ret; | 841 | int ret; |
| 842 | 842 | ||
| 843 | nsinfo__mountns_enter(nsi, &nsc); | 843 | nsinfo__mountns_enter(nsi, &nsc); |
| 844 | ret = filename__read_build_id(filename, bid); | 844 | ret = filename__read_build_id(filename, bid, /*block=*/true); |
| 845 | nsinfo__mountns_exit(&nsc); | 845 | nsinfo__mountns_exit(&nsc); |
| 846 | 846 | ||
| 847 | return ret; | 847 | return ret; |
| @@ -110,8 +110,12 @@ struct debuginfo *debuginfo__new(const char *path) · 109 unmodified lines | |||
| 110 | if (!dso) | 110 | if (!dso) |
| 111 | goto out; | 111 | goto out; |
| 112 | 112 | ||
| 113 | /* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */ | 113 | /* |
| 114 | if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0) | 114 | * Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO. Don't block |
| 115 | * incase the path isn't for a regular file. | ||
| 116 | */ | ||
| 117 | assert(!dso__has_build_id(dso)); | ||
| 118 | if (filename__read_build_id(path, &bid, /*block=*/false) > 0) | ||
| 115 | dso__set_build_id(dso, &bid); | 119 | dso__set_build_id(dso, &bid); |
| 116 | 120 | ||
| 117 | for (type = distro_dwarf_types; | 121 | for (type = distro_dwarf_types; |
| @@ -81,13 +81,13 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data) · 80 unmodified lines | |||
| 81 | return 0; | 81 | return 0; |
| 82 | } | 82 | } |
| 83 | nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); | 83 | nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); |
| 84 | if (filename__read_build_id(dso__long_name(dso), &bid) > 0) { | 84 | if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0) { |
| 85 | dso__set_build_id(dso, &bid); | 85 | dso__set_build_id(dso, &bid); |
| 86 | args->have_build_id = true; | 86 | args->have_build_id = true; |
| 87 | } else if (errno == ENOENT && dso__nsinfo(dso)) { | 87 | } else if (errno == ENOENT && dso__nsinfo(dso)) { |
| 88 | char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); | 88 | char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); |
| 89 | 89 | ||
| 90 | if (new_name && filename__read_build_id(new_name, &bid) > 0) { | 90 | if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0) { |
| 91 | dso__set_build_id(dso, &bid); | 91 | dso__set_build_id(dso, &bid); |
| 92 | args->have_build_id = true; | 92 | args->have_build_id = true; |
| 93 | } | 93 | } |
| @@ -902,7 +902,7 @@ out_close: · 901 unmodified lines | |||
| 902 | 902 | ||
| 903 | #else // HAVE_LIBBFD_BUILDID_SUPPORT | 903 | #else // HAVE_LIBBFD_BUILDID_SUPPORT |
| 904 | 904 | ||
| 905 | static int read_build_id(const char *filename, struct build_id *bid) | 905 | static int read_build_id(const char *filename, struct build_id *bid, bool block) |
| 906 | { | 906 | { |
| 907 | size_t size = sizeof(bid->data); | 907 | size_t size = sizeof(bid->data); |
| 908 | int fd, err = -1; | 908 | int fd, err = -1; |
| @@ -911,7 +911,7 @@ static int read_build_id(const char *filename, struct build_id *bid) · 2 unmodified lines | |||
| 911 | if (size < BUILD_ID_SIZE) | 911 | if (size < BUILD_ID_SIZE) |
| 912 | goto out; | 912 | goto out; |
| 913 | 913 | ||
| 914 | fd = open(filename, O_RDONLY); | 914 | fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK)); |
| 915 | if (fd < 0) | 915 | if (fd < 0) |
| 916 | goto out; | 916 | goto out; |
| 917 | 917 | ||
| @@ -934,7 +934,7 @@ out: · 16 unmodified lines | |||
| 934 | 934 | ||
| 935 | #endif // HAVE_LIBBFD_BUILDID_SUPPORT | 935 | #endif // HAVE_LIBBFD_BUILDID_SUPPORT |
| 936 | 936 | ||
| 937 | int filename__read_build_id(const char *filename, struct build_id *bid) | 937 | int filename__read_build_id(const char *filename, struct build_id *bid, bool block) |
| 938 | { | 938 | { |
| 939 | struct kmod_path m = { .name = NULL, }; | 939 | struct kmod_path m = { .name = NULL, }; |
| 940 | char path[PATH_MAX]; | 940 | char path[PATH_MAX]; |
| @@ -958,9 +958,10 @@ int filename__read_build_id(const char *filename, struct build_id *bid) · 17 unmodified lines | |||
| 958 | } | 958 | } |
| 959 | close(fd); | 959 | close(fd); |
| 960 | filename = path; | 960 | filename = path; |
| 961 | block = true; | ||
| 961 | } | 962 | } |
| 962 | 963 | ||
| 963 | err = read_build_id(filename, bid); | 964 | err = read_build_id(filename, bid, block); |
| 964 | 965 | ||
| 965 | if (m.comp) | 966 | if (m.comp) |
| 966 | unlink(filename); | 967 | unlink(filename); |
| @@ -4,7 +4,6 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <errno.h> | 5 | #include <errno.h> |
| 6 | #include <unistd.h> | 6 | #include <unistd.h> |
| 7 | #include <stdio.h> | ||
| 8 | #include <fcntl.h> | 7 | #include <fcntl.h> |
| 9 | #include <string.h> | 8 | #include <string.h> |
| 10 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| @@ -86,13 +85,10 @@ int filename__read_debuglink(const char *filename __maybe_unused, · 75 unmodified lines | |||
| 86 | /* | 85 | /* |
| 87 | * Just try PT_NOTE header otherwise fails | 86 | * Just try PT_NOTE header otherwise fails |
| 88 | */ | 87 | */ |
| 89 | int filename__read_build_id(const char *filename, struct build_id *bid) | 88 | int filename__read_build_id(const char *filename, struct build_id *bid, bool block) |
| 90 | { | 89 | { |
| 91 | FILE *fp; | 90 | int fd, ret = -1; |
| 92 | int ret = -1; | ||
| 93 | bool need_swap = false, elf32; | 91 | bool need_swap = false, elf32; |
| 94 | u8 e_ident[EI_NIDENT]; | ||
| 95 | int i; | ||
| 96 | union { | 92 | union { |
| 97 | struct { | 93 | struct { |
| 98 | Elf32_Ehdr ehdr32; | 94 | Elf32_Ehdr ehdr32; |
| @@ -103,28 +99,27 @@ int filename__read_build_id(const char *filename, struct build_id *bid) · 4 unmodified lines | |||
| 103 | Elf64_Phdr *phdr64; | 99 | Elf64_Phdr *phdr64; |
| 104 | }; | 100 | }; |
| 105 | } hdrs; | 101 | } hdrs; |
| 106 | void *phdr; | 102 | void *phdr, *buf = NULL; |
| 107 | size_t phdr_size; | 103 | ssize_t phdr_size, ehdr_size, buf_size = 0; |
| 108 | void *buf = NULL; | ||
| 109 | size_t buf_size = 0; | ||
| 110 | 104 | ||
| 111 | fp = fopen(filename, "r"); | 105 | fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK)); |
| 112 | if (fp == NULL) | 106 | if (fd < 0) |
| 113 | return -1; | 107 | return -1; |
| 114 | 108 | ||
| 115 | if (fread(e_ident, sizeof(e_ident), 1, fp) != 1) | 109 | if (read(fd, hdrs.ehdr32.e_ident, EI_NIDENT) != EI_NIDENT) |
| 116 | goto out; | 110 | goto out; |
| 117 | 111 | ||
| 118 | if (memcmp(e_ident, ELFMAG, SELFMAG) || | 112 | if (memcmp(hdrs.ehdr32.e_ident, ELFMAG, SELFMAG) || |
| 119 | e_ident[EI_VERSION] != EV_CURRENT) | 113 | hdrs.ehdr32.e_ident[EI_VERSION] != EV_CURRENT) |
| 120 | goto out; | 114 | goto out; |
| 121 | 115 | ||
| 122 | need_swap = check_need_swap(e_ident[EI_DATA]); | 116 | need_swap = check_need_swap(hdrs.ehdr32.e_ident[EI_DATA]); |
| 123 | elf32 = e_ident[EI_CLASS] == ELFCLASS32; | 117 | elf32 = hdrs.ehdr32.e_ident[EI_CLASS] == ELFCLASS32; |
| 118 | ehdr_size = (elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64)) - EI_NIDENT; | ||
| 124 | 119 | ||
| 125 | if (fread(elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64, | 120 | if (read(fd, |
| 126 | elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64), | 121 | (elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64) + EI_NIDENT, |
| 127 | 1, fp) != 1) | 122 | ehdr_size) != ehdr_size) |
| 128 | goto out; | 123 | goto out; |
| 129 | 124 | ||
| 130 | if (need_swap) { | 125 | if (need_swap) { |
| @@ -138,14 +133,18 @@ int filename__read_build_id(const char *filename, struct build_id *bid) · 7 unmodified lines | |||
| 138 | hdrs.ehdr64.e_phnum = bswap_16(hdrs.ehdr64.e_phnum); | 133 | hdrs.ehdr64.e_phnum = bswap_16(hdrs.ehdr64.e_phnum); |
| 139 | } | 134 | } |
| 140 | } | 135 | } |
| 141 | phdr_size = elf32 ? hdrs.ehdr32.e_phentsize * hdrs.ehdr32.e_phnum | 136 | if ((elf32 && hdrs.ehdr32.e_phentsize != sizeof(Elf32_Phdr)) || |
| 142 | : hdrs.ehdr64.e_phentsize * hdrs.ehdr64.e_phnum; | 137 | (!elf32 && hdrs.ehdr64.e_phentsize != sizeof(Elf64_Phdr))) |
| 138 | goto out; | ||
| 139 | |||
| 140 | phdr_size = elf32 ? sizeof(Elf32_Phdr) * hdrs.ehdr32.e_phnum | ||
| 141 | : sizeof(Elf64_Phdr) * hdrs.ehdr64.e_phnum; | ||
| 143 | phdr = malloc(phdr_size); | 142 | phdr = malloc(phdr_size); |
| 144 | if (phdr == NULL) | 143 | if (phdr == NULL) |
| 145 | goto out; | 144 | goto out; |
| 146 | 145 | ||
| 147 | fseek(fp, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET); | 146 | lseek(fd, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET); |
| 148 | if (fread(phdr, phdr_size, 1, fp) != 1) | 147 | if (read(fd, phdr, phdr_size) != phdr_size) |
| 149 | goto out_free; | 148 | goto out_free; |
| 150 | 149 | ||
| 151 | if (elf32) | 150 | if (elf32) |
| @@ -153,8 +152,8 @@ int filename__read_build_id(const char *filename, struct build_id *bid) · 1 unmodified line | |||
| 153 | else | 152 | else |
| 154 | hdrs.phdr64 = phdr; | 153 | hdrs.phdr64 = phdr; |
| 155 | 154 | ||
| 156 | for (i = 0; i < elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum; i++) { | 155 | for (int i = 0; i < (elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum); i++) { |
| 157 | size_t p_filesz; | 156 | ssize_t p_filesz; |
| 158 | 157 | ||
| 159 | if (need_swap) { | 158 | if (need_swap) { |
| 160 | if (elf32) { | 159 | if (elf32) { |
| @@ -180,8 +179,8 @@ int filename__read_build_id(const char *filename, struct build_id *bid) · 19 unmodified lines | |||
| 180 | goto out_free; | 179 | goto out_free; |
| 181 | buf = tmp; | 180 | buf = tmp; |
| 182 | } | 181 | } |
| 183 | fseek(fp, elf32 ? hdrs.phdr32[i].p_offset : hdrs.phdr64[i].p_offset, SEEK_SET); | 182 | lseek(fd, elf32 ? hdrs.phdr32[i].p_offset : hdrs.phdr64[i].p_offset, SEEK_SET); |
| 184 | if (fread(buf, p_filesz, 1, fp) != 1) | 183 | if (read(fd, buf, p_filesz) != p_filesz) |
| 185 | goto out_free; | 184 | goto out_free; |
| 186 | 185 | ||
| 187 | ret = read_build_id(buf, p_filesz, bid, need_swap); | 186 | ret = read_build_id(buf, p_filesz, bid, need_swap); |
| @@ -194,7 +193,7 @@ out_free: · 6 unmodified lines | |||
| 194 | free(buf); | 193 | free(buf); |
| 195 | free(phdr); | 194 | free(phdr); |
| 196 | out: | 195 | out: |
| 197 | fclose(fp); | 196 | close(fd); |
| 198 | return ret; | 197 | return ret; |
| 199 | } | 198 | } |
| 200 | 199 | ||
| @@ -324,7 +323,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, · 123 unmodified lines | |||
| 324 | if (ret >= 0) | 323 | if (ret >= 0) |
| 325 | RC_CHK_ACCESS(dso)->is_64_bit = ret; | 324 | RC_CHK_ACCESS(dso)->is_64_bit = ret; |
| 326 | 325 | ||
| 327 | if (filename__read_build_id(ss->name, &bid) > 0) | 326 | if (filename__read_build_id(ss->name, &bid, /*block=*/true) > 0) |
| 328 | dso__set_build_id(dso, &bid); | 327 | dso__set_build_id(dso, &bid); |
| 329 | return 0; | 328 | return 0; |
| 330 | } | 329 | } |
| @@ -1869,14 +1869,14 @@ int dso__load(struct dso *dso, struct map *map) · 1868 unmodified lines | |||
| 1869 | 1869 | ||
| 1870 | /* | 1870 | /* |
| 1871 | * Read the build id if possible. This is required for | 1871 | * Read the build id if possible. This is required for |
| 1872 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work | 1872 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work. Don't block in case path |
| 1873 | * isn't for a regular file. | ||
| 1873 | */ | 1874 | */ |
| 1874 | if (!dso__has_build_id(dso) && | 1875 | if (!dso__has_build_id(dso)) { |
| 1875 | is_regular_file(dso__long_name(dso))) { | ||
| 1876 | struct build_id bid = { .size = 0, }; | 1876 | struct build_id bid = { .size = 0, }; |
| 1877 | 1877 | ||
| 1878 | __symbol__join_symfs(name, PATH_MAX, dso__long_name(dso)); | 1878 | __symbol__join_symfs(name, PATH_MAX, dso__long_name(dso)); |
| 1879 | if (filename__read_build_id(name, &bid) > 0) | 1879 | if (filename__read_build_id(name, &bid, /*block=*/false) > 0) |
| 1880 | dso__set_build_id(dso, &bid); | 1880 | dso__set_build_id(dso, &bid); |
| 1881 | } | 1881 | } |
| 1882 | 1882 | ||
| @@ -140,7 +140,7 @@ struct symbol *dso__next_symbol(struct symbol *sym); · 139 unmodified lines | |||
| 140 | 140 | ||
| 141 | enum dso_type dso__type_fd(int fd); | 141 | enum dso_type dso__type_fd(int fd); |
| 142 | 142 | ||
| 143 | int filename__read_build_id(const char *filename, struct build_id *id); | 143 | int filename__read_build_id(const char *filename, struct build_id *id, bool block); |
| 144 | int sysfs__read_build_id(const char *filename, struct build_id *bid); | 144 | int sysfs__read_build_id(const char *filename, struct build_id *bid); |
| 145 | int modules__parse(const char *filename, void *arg, | 145 | int modules__parse(const char *filename, void *arg, |
| 146 | int (*process_module)(void *arg, const char *name, | 146 | int (*process_module)(void *arg, const char *name, |
| @@ -401,7 +401,7 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event, · 400 unmodified lines | |||
| 401 | nsi = nsinfo__new(event->pid); | 401 | nsi = nsinfo__new(event->pid); |
| 402 | nsinfo__mountns_enter(nsi, &nc); | 402 | nsinfo__mountns_enter(nsi, &nc); |
| 403 | 403 | ||
| 404 | rc = filename__read_build_id(event->filename, &bid) > 0 ? 0 : -1; | 404 | rc = filename__read_build_id(event->filename, &bid, /*block=*/false) > 0 ? 0 : -1; |
| 405 | 405 | ||
| 406 | nsinfo__mountns_exit(&nc); | 406 | nsinfo__mountns_exit(&nc); |
| 407 | nsinfo__put(nsi); | 407 | nsinfo__put(nsi); |
| @@ -81,10 +81,11 @@ Refer to the AMD P-State kernel documentation for further information. · 80 unmodified lines | |||
| 81 | .RE | 81 | .RE |
| 82 | 82 | ||
| 83 | .PP | 83 | .PP |
| 84 | \-\-turbo\-boost, \-t | 84 | \-\-turbo\-boost, \-\-boost, \-t |
| 85 | .RS 4 | 85 | .RS 4 |
| 86 | This option is used to enable or disable the turbo boost feature on | 86 | This option is used to enable or disable the boost feature on |
| 87 | supported Intel and AMD processors. | 87 | supported Intel and AMD processors, and other boost supported systems. |
| 88 | (The --boost option is an alias for the --turbo-boost option) | ||
| 88 | 89 | ||
| 89 | This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature. | 90 | This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature. |
| 90 | 91 | ||
| @@ -128,7 +128,7 @@ static int get_boost_mode_x86(unsigned int cpu) · 127 unmodified lines | |||
| 128 | /* ToDo: Make this more global */ | 128 | /* ToDo: Make this more global */ |
| 129 | unsigned long pstates[MAX_HW_PSTATES] = {0,}; | 129 | unsigned long pstates[MAX_HW_PSTATES] = {0,}; |
| 130 | 130 | ||
| 131 | ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states); | 131 | ret = cpufreq_has_x86_boost_support(cpu, &support, &active, &b_states); |
| 132 | if (ret) { | 132 | if (ret) { |
| 133 | printf(_("Error while evaluating Boost Capabilities" | 133 | printf(_("Error while evaluating Boost Capabilities" |
| 134 | " on CPU %d -- are you root?\n"), cpu); | 134 | " on CPU %d -- are you root?\n"), cpu); |
| @@ -204,6 +204,18 @@ static int get_boost_mode_x86(unsigned int cpu) · 69 unmodified lines | |||
| 204 | return 0; | 204 | return 0; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | static int get_boost_mode_generic(unsigned int cpu) | ||
| 208 | { | ||
| 209 | bool active; | ||
| 210 | |||
| 211 | if (!cpufreq_has_generic_boost_support(&active)) { | ||
| 212 | printf(_(" boost state support:\n")); | ||
| 213 | printf(_(" Active: %s\n"), active ? _("yes") : _("no")); | ||
| 214 | } | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 207 | /* --boost / -b */ | 219 | /* --boost / -b */ |
| 208 | 220 | ||
| 209 | static int get_boost_mode(unsigned int cpu) | 221 | static int get_boost_mode(unsigned int cpu) |
| @@ -214,6 +226,8 @@ static int get_boost_mode(unsigned int cpu) · 4 unmodified lines | |||
| 214 | cpupower_cpu_info.vendor == X86_VENDOR_HYGON || | 226 | cpupower_cpu_info.vendor == X86_VENDOR_HYGON || |
| 215 | cpupower_cpu_info.vendor == X86_VENDOR_INTEL) | 227 | cpupower_cpu_info.vendor == X86_VENDOR_INTEL) |
| 216 | return get_boost_mode_x86(cpu); | 228 | return get_boost_mode_x86(cpu); |
| 229 | else | ||
| 230 | get_boost_mode_generic(cpu); | ||
| 217 | 231 | ||
| 218 | freqs = cpufreq_get_boost_frequencies(cpu); | 232 | freqs = cpufreq_get_boost_frequencies(cpu); |
| 219 | if (freqs) { | 233 | if (freqs) { |
| @@ -21,6 +21,7 @@ static struct option set_opts[] = { · 20 unmodified lines | |||
| 21 | {"epp", required_argument, NULL, 'e'}, | 21 | {"epp", required_argument, NULL, 'e'}, |
| 22 | {"amd-pstate-mode", required_argument, NULL, 'm'}, | 22 | {"amd-pstate-mode", required_argument, NULL, 'm'}, |
| 23 | {"turbo-boost", required_argument, NULL, 't'}, | 23 | {"turbo-boost", required_argument, NULL, 't'}, |
| 24 | {"boost", required_argument, NULL, 't'}, | ||
| 24 | { }, | 25 | { }, |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| @@ -62,8 +63,8 @@ int cmd_set(int argc, char **argv) · 35 unmodified lines | |||
| 62 | 63 | ||
| 63 | params.params = 0; | 64 | params.params = 0; |
| 64 | /* parameter parsing */ | 65 | /* parameter parsing */ |
| 65 | while ((ret = getopt_long(argc, argv, "b:e:m:", | 66 | while ((ret = getopt_long(argc, argv, "b:e:m:t:", |
| 66 | set_opts, NULL)) != -1) { | 67 | set_opts, NULL)) != -1) { |
| 67 | switch (ret) { | 68 | switch (ret) { |
| 68 | case 'b': | 69 | case 'b': |
| 69 | if (params.perf_bias) | 70 | if (params.perf_bias) |
| @@ -103,6 +103,9 @@ extern struct cpupower_cpu_info cpupower_cpu_info; · 102 unmodified lines | |||
| 103 | 103 | ||
| 104 | /* cpuid and cpuinfo helpers **************************/ | 104 | /* cpuid and cpuinfo helpers **************************/ |
| 105 | 105 | ||
| 106 | int cpufreq_has_generic_boost_support(bool *active); | ||
| 107 | int cpupower_set_turbo_boost(int turbo_boost); | ||
| 108 | |||
| 106 | /* X86 ONLY ****************************************/ | 109 | /* X86 ONLY ****************************************/ |
| 107 | #if defined(__i386__) || defined(__x86_64__) | 110 | #if defined(__i386__) || defined(__x86_64__) |
| 108 | 111 | ||
| @@ -118,7 +121,6 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu); · 9 unmodified lines | |||
| 118 | 121 | ||
| 119 | extern int cpupower_set_epp(unsigned int cpu, char *epp); | 122 | extern int cpupower_set_epp(unsigned int cpu, char *epp); |
| 120 | extern int cpupower_set_amd_pstate_mode(char *mode); | 123 | extern int cpupower_set_amd_pstate_mode(char *mode); |
| 121 | extern int cpupower_set_turbo_boost(int turbo_boost); | ||
| 122 | 124 | ||
| 123 | /* Read/Write msr ****************************/ | 125 | /* Read/Write msr ****************************/ |
| 124 | 126 | ||
| @@ -139,8 +141,8 @@ extern int decode_pstates(unsigned int cpu, int boost_states, · 14 unmodified lines | |||
| 139 | 141 | ||
| 140 | /* AMD HW pstate decoding **************************/ | 142 | /* AMD HW pstate decoding **************************/ |
| 141 | 143 | ||
| 142 | extern int cpufreq_has_boost_support(unsigned int cpu, int *support, | 144 | int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, |
| 143 | int *active, int * states); | 145 | int *active, int *states); |
| 144 | 146 | ||
| 145 | /* AMD P-State stuff **************************/ | 147 | /* AMD P-State stuff **************************/ |
| 146 | bool cpupower_amd_pstate_enabled(void); | 148 | bool cpupower_amd_pstate_enabled(void); |
| @@ -181,13 +183,11 @@ static inline int cpupower_set_epp(unsigned int cpu, char *epp) · 34 unmodified lines | |||
| 181 | { return -1; }; | 183 | { return -1; }; |
| 182 | static inline int cpupower_set_amd_pstate_mode(char *mode) | 184 | static inline int cpupower_set_amd_pstate_mode(char *mode) |
| 183 | { return -1; }; | 185 | { return -1; }; |
| 184 | static inline int cpupower_set_turbo_boost(int turbo_boost) | ||
| 185 | { return -1; }; | ||
| 186 | 186 | ||
| 187 | /* Read/Write msr ****************************/ | 187 | /* Read/Write msr ****************************/ |
| 188 | 188 | ||
| 189 | static inline int cpufreq_has_boost_support(unsigned int cpu, int *support, | 189 | static inline int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, |
| 190 | int *active, int * states) | 190 | int *active, int *states) |
| 191 | { return -1; } | 191 | { return -1; } |
| 192 | 192 | ||
| 193 | static inline bool cpupower_amd_pstate_enabled(void) | 193 | static inline bool cpupower_amd_pstate_enabled(void) |
| @@ -8,15 +8,14 @@ · 7 unmodified lines | |||
| 8 | #include "helpers/helpers.h" | 8 | #include "helpers/helpers.h" |
| 9 | #include "helpers/sysfs.h" | 9 | #include "helpers/sysfs.h" |
| 10 | #include "cpufreq.h" | 10 | #include "cpufreq.h" |
| 11 | #include "cpupower_intern.h" | ||
| 11 | 12 | ||
| 12 | #if defined(__i386__) || defined(__x86_64__) | 13 | #if defined(__i386__) || defined(__x86_64__) |
| 13 | 14 | ||
| 14 | #include "cpupower_intern.h" | ||
| 15 | |||
| 16 | #define MSR_AMD_HWCR 0xc0010015 | 15 | #define MSR_AMD_HWCR 0xc0010015 |
| 17 | 16 | ||
| 18 | int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, | 17 | int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, |
| 19 | int *states) | 18 | int *states) |
| 20 | { | 19 | { |
| 21 | int ret; | 20 | int ret; |
| 22 | unsigned long long val; | 21 | unsigned long long val; |
| @@ -124,24 +123,6 @@ int cpupower_set_amd_pstate_mode(char *mode) · 101 unmodified lines | |||
| 124 | return 0; | 123 | return 0; |
| 125 | } | 124 | } |
| 126 | 125 | ||
| 127 | int cpupower_set_turbo_boost(int turbo_boost) | ||
| 128 | { | ||
| 129 | char path[SYSFS_PATH_MAX]; | ||
| 130 | char linebuf[2] = {}; | ||
| 131 | |||
| 132 | snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); | ||
| 133 | |||
| 134 | if (!is_valid_path(path)) | ||
| 135 | return -1; | ||
| 136 | |||
| 137 | snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost); | ||
| 138 | |||
| 139 | if (cpupower_write_sysfs(path, linebuf, 2) <= 0) | ||
| 140 | return -1; | ||
| 141 | |||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | |||
| 145 | bool cpupower_amd_pstate_enabled(void) | 126 | bool cpupower_amd_pstate_enabled(void) |
| 146 | { | 127 | { |
| 147 | char *driver = cpufreq_get_driver(0); | 128 | char *driver = cpufreq_get_driver(0); |
| @@ -160,6 +141,39 @@ bool cpupower_amd_pstate_enabled(void) · 12 unmodified lines | |||
| 160 | 141 | ||
| 161 | #endif /* #if defined(__i386__) || defined(__x86_64__) */ | 142 | #endif /* #if defined(__i386__) || defined(__x86_64__) */ |
| 162 | 143 | ||
| 144 | int cpufreq_has_generic_boost_support(bool *active) | ||
| 145 | { | ||
| 146 | char path[SYSFS_PATH_MAX]; | ||
| 147 | char linebuf[2] = {}; | ||
| 148 | unsigned long val; | ||
| 149 | char *endp; | ||
| 150 | |||
| 151 | snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); | ||
| 152 | |||
| 153 | if (!is_valid_path(path)) | ||
| 154 | return -EACCES; | ||
| 155 | |||
| 156 | if (cpupower_read_sysfs(path, linebuf, 2) <= 0) | ||
| 157 | return -EINVAL; | ||
| 158 | |||
| 159 | val = strtoul(linebuf, &endp, 0); | ||
| 160 | if (endp == linebuf || errno == ERANGE) | ||
| 161 | return -EINVAL; | ||
| 162 | |||
| 163 | switch (val) { | ||
| 164 | case 0: | ||
| 165 | *active = false; | ||
| 166 | break; | ||
| 167 | case 1: | ||
| 168 | *active = true; | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | return -EINVAL; | ||
| 172 | } | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 163 | /* get_cpustate | 177 | /* get_cpustate |
| 164 | * | 178 | * |
| 165 | * Gather the information of all online CPUs into bitmask struct | 179 | * Gather the information of all online CPUs into bitmask struct |
| @@ -259,3 +273,21 @@ void print_speed(unsigned long speed, int no_rounding) · 93 unmodified lines | |||
| 259 | } | 273 | } |
| 260 | } | 274 | } |
| 261 | } | 275 | } |
| 276 | |||
| 277 | int cpupower_set_turbo_boost(int turbo_boost) | ||
| 278 | { | ||
| 279 | char path[SYSFS_PATH_MAX]; | ||
| 280 | char linebuf[2] = {}; | ||
| 281 | |||
| 282 | snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); | ||
| 283 | |||
| 284 | if (!is_valid_path(path)) | ||
| 285 | return -1; | ||
| 286 | |||
| 287 | snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost); | ||
| 288 | |||
| 289 | if (cpupower_write_sysfs(path, linebuf, 2) <= 0) | ||
| 290 | return -1; | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| @@ -408,3 +408,5 @@ · 407 unmodified lines | |||
| 408 | 465 common listxattrat sys_listxattrat | 408 | 465 common listxattrat sys_listxattrat |
| 409 | 466 common removexattrat sys_removexattrat | 409 | 466 common removexattrat sys_removexattrat |
| 410 | 467 common open_tree_attr sys_open_tree_attr | 410 | 467 common open_tree_attr sys_open_tree_attr |
| 411 | 468 common file_getattr sys_file_getattr | ||
| 412 | 469 common file_setattr sys_file_setattr | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | TEST_GEN_FILES += access_memory access_memory_even | 4 | TEST_GEN_FILES += access_memory access_memory_even |
| 5 | 5 | ||
| 6 | TEST_FILES = _damon_sysfs.py | 6 | TEST_FILES = _damon_sysfs.py |
| 7 | TEST_FILES += drgn_dump_damon_status.py | ||
| 7 | 8 | ||
| 8 | # functionality tests | 9 | # functionality tests |
| 9 | TEST_PROGS += sysfs.sh | 10 | TEST_PROGS += sysfs.sh |
| @@ -5,10 +5,14 @@ · 4 unmodified lines | |||
| 5 | #define _GNU_SOURCE | 5 | #define _GNU_SOURCE |
| 6 | 6 | ||
| 7 | #include <errno.h> | 7 | #include <errno.h> |
| 8 | #include <fcntl.h> | ||
| 9 | #include <linux/userfaultfd.h> | ||
| 8 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 9 | #include <stdio.h> | 11 | #include <stdio.h> |
| 10 | #include <string.h> | 12 | #include <string.h> |
| 13 | #include <sys/ioctl.h> | ||
| 11 | #include <sys/mman.h> | 14 | #include <sys/mman.h> |
| 15 | #include <syscall.h> | ||
| 12 | #include <time.h> | 16 | #include <time.h> |
| 13 | #include <stdbool.h> | 17 | #include <stdbool.h> |
| 14 | 18 | ||
| @@ -168,6 +172,7 @@ static bool is_range_mapped(FILE *maps_fp, unsigned long start, · 153 unmodified lines | |||
| 168 | 172 | ||
| 169 | if (first_val <= start && second_val >= end) { | 173 | if (first_val <= start && second_val >= end) { |
| 170 | success = true; | 174 | success = true; |
| 175 | fflush(maps_fp); | ||
| 171 | break; | 176 | break; |
| 172 | } | 177 | } |
| 173 | } | 178 | } |
| @@ -175,6 +180,15 @@ static bool is_range_mapped(FILE *maps_fp, unsigned long start, · 1 unmodified line | |||
| 175 | return success; | 180 | return success; |
| 176 | } | 181 | } |
| 177 | 182 | ||
| 183 | /* Check if [ptr, ptr + size) mapped in /proc/self/maps. */ | ||
| 184 | static bool is_ptr_mapped(FILE *maps_fp, void *ptr, unsigned long size) | ||
| 185 | { | ||
| 186 | unsigned long start = (unsigned long)ptr; | ||
| 187 | unsigned long end = start + size; | ||
| 188 | |||
| 189 | return is_range_mapped(maps_fp, start, end); | ||
| 190 | } | ||
| 191 | |||
| 178 | /* | 192 | /* |
| 179 | * Returns the start address of the mapping on success, else returns | 193 | * Returns the start address of the mapping on success, else returns |
| 180 | * NULL on failure. | 194 | * NULL on failure. |
| @@ -733,6 +747,249 @@ out: · 552 unmodified lines | |||
| 733 | dont_unmap ? " [dontunnmap]" : ""); | 747 | dont_unmap ? " [dontunnmap]" : ""); |
| 734 | } | 748 | } |
| 735 | 749 | ||
| 750 | #ifdef __NR_userfaultfd | ||
| 751 | static void mremap_move_multi_invalid_vmas(FILE *maps_fp, | ||
| 752 | unsigned long page_size) | ||
| 753 | { | ||
| 754 | char *test_name = "mremap move multiple invalid vmas"; | ||
| 755 | const size_t size = 10 * page_size; | ||
| 756 | bool success = true; | ||
| 757 | char *ptr, *tgt_ptr; | ||
| 758 | int uffd, err, i; | ||
| 759 | void *res; | ||
| 760 | struct uffdio_api api = { | ||
| 761 | .api = UFFD_API, | ||
| 762 | .features = UFFD_EVENT_PAGEFAULT, | ||
| 763 | }; | ||
| 764 | |||
| 765 | uffd = syscall(__NR_userfaultfd, O_NONBLOCK); | ||
| 766 | if (uffd == -1) { | ||
| 767 | err = errno; | ||
| 768 | perror("userfaultfd"); | ||
| 769 | if (err == EPERM) { | ||
| 770 | ksft_test_result_skip("%s - missing uffd", test_name); | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | success = false; | ||
| 774 | goto out; | ||
| 775 | } | ||
| 776 | if (ioctl(uffd, UFFDIO_API, &api)) { | ||
| 777 | perror("ioctl UFFDIO_API"); | ||
| 778 | success = false; | ||
| 779 | goto out_close_uffd; | ||
| 780 | } | ||
| 781 | |||
| 782 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, | ||
| 783 | MAP_PRIVATE | MAP_ANON, -1, 0); | ||
| 784 | if (ptr == MAP_FAILED) { | ||
| 785 | perror("mmap"); | ||
| 786 | success = false; | ||
| 787 | goto out_close_uffd; | ||
| 788 | } | ||
| 789 | |||
| 790 | tgt_ptr = mmap(NULL, size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); | ||
| 791 | if (tgt_ptr == MAP_FAILED) { | ||
| 792 | perror("mmap"); | ||
| 793 | success = false; | ||
| 794 | goto out_close_uffd; | ||
| 795 | } | ||
| 796 | if (munmap(tgt_ptr, size)) { | ||
| 797 | perror("munmap"); | ||
| 798 | success = false; | ||
| 799 | goto out_unmap; | ||
| 800 | } | ||
| 801 | |||
| 802 | /* | ||
| 803 | * Unmap so we end up with: | ||
| 804 | * | ||
| 805 | * 0 2 4 6 8 10 offset in buffer | ||
| 806 | * |*| |*| |*| |*| |*| | ||
| 807 | * |*| |*| |*| |*| |*| | ||
| 808 | * | ||
| 809 | * Additionally, register each with UFFD. | ||
| 810 | */ | ||
| 811 | for (i = 0; i < 10; i += 2) { | ||
| 812 | void *unmap_ptr = &ptr[(i + 1) * page_size]; | ||
| 813 | unsigned long start = (unsigned long)&ptr[i * page_size]; | ||
| 814 | struct uffdio_register reg = { | ||
| 815 | .range = { | ||
| 816 | .start = start, | ||
| 817 | .len = page_size, | ||
| 818 | }, | ||
| 819 | .mode = UFFDIO_REGISTER_MODE_MISSING, | ||
| 820 | }; | ||
| 821 | |||
| 822 | if (ioctl(uffd, UFFDIO_REGISTER, ®) == -1) { | ||
| 823 | perror("ioctl UFFDIO_REGISTER"); | ||
| 824 | success = false; | ||
| 825 | goto out_unmap; | ||
| 826 | } | ||
| 827 | if (munmap(unmap_ptr, page_size)) { | ||
| 828 | perror("munmap"); | ||
| 829 | success = false; | ||
| 830 | goto out_unmap; | ||
| 831 | } | ||
| 832 | } | ||
| 833 | |||
| 834 | /* | ||
| 835 | * Now try to move the entire range which is invalid for multi VMA move. | ||
| 836 | * | ||
| 837 | * This will fail, and no VMA should be moved, as we check this ahead of | ||
| 838 | * time. | ||
| 839 | */ | ||
| 840 | res = mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr); | ||
| 841 | err = errno; | ||
| 842 | if (res != MAP_FAILED) { | ||
| 843 | fprintf(stderr, "mremap() succeeded for multi VMA uffd armed\n"); | ||
| 844 | success = false; | ||
| 845 | goto out_unmap; | ||
| 846 | } | ||
| 847 | if (err != EFAULT) { | ||
| 848 | errno = err; | ||
| 849 | perror("mrmeap() unexpected error"); | ||
| 850 | success = false; | ||
| 851 | goto out_unmap; | ||
| 852 | } | ||
| 853 | if (is_ptr_mapped(maps_fp, tgt_ptr, page_size)) { | ||
| 854 | fprintf(stderr, | ||
| 855 | "Invalid uffd-armed VMA at start of multi range moved\n"); | ||
| 856 | success = false; | ||
| 857 | goto out_unmap; | ||
| 858 | } | ||
| 859 | |||
| 860 | /* | ||
| 861 | * Now try to move a single VMA, this should succeed as not multi VMA | ||
| 862 | * move. | ||
| 863 | */ | ||
| 864 | res = mremap(ptr, page_size, page_size, | ||
| 865 | MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr); | ||
| 866 | if (res == MAP_FAILED) { | ||
| 867 | perror("mremap single invalid-multi VMA"); | ||
| 868 | success = false; | ||
| 869 | goto out_unmap; | ||
| 870 | } | ||
| 871 | |||
| 872 | /* | ||
| 873 | * Unmap the VMA, and remap a non-uffd registered (therefore, multi VMA | ||
| 874 | * move valid) VMA at the start of ptr range. | ||
| 875 | */ | ||
| 876 | if (munmap(tgt_ptr, page_size)) { | ||
| 877 | perror("munmap"); | ||
| 878 | success = false; | ||
| 879 | goto out_unmap; | ||
| 880 | } | ||
| 881 | res = mmap(ptr, page_size, PROT_READ | PROT_WRITE, | ||
| 882 | MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); | ||
| 883 | if (res == MAP_FAILED) { | ||
| 884 | perror("mmap"); | ||
| 885 | success = false; | ||
| 886 | goto out_unmap; | ||
| 887 | } | ||
| 888 | |||
| 889 | /* | ||
| 890 | * Now try to move the entire range, we should succeed in moving the | ||
| 891 | * first VMA, but no others, and report a failure. | ||
| 892 | */ | ||
| 893 | res = mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr); | ||
| 894 | err = errno; | ||
| 895 | if (res != MAP_FAILED) { | ||
| 896 | fprintf(stderr, "mremap() succeeded for multi VMA uffd armed\n"); | ||
| 897 | success = false; | ||
| 898 | goto out_unmap; | ||
| 899 | } | ||
| 900 | if (err != EFAULT) { | ||
| 901 | errno = err; | ||
| 902 | perror("mrmeap() unexpected error"); | ||
| 903 | success = false; | ||
| 904 | goto out_unmap; | ||
| 905 | } | ||
| 906 | if (!is_ptr_mapped(maps_fp, tgt_ptr, page_size)) { | ||
| 907 | fprintf(stderr, "Valid VMA not moved\n"); | ||
| 908 | success = false; | ||
| 909 | goto out_unmap; | ||
| 910 | } | ||
| 911 | |||
| 912 | /* | ||
| 913 | * Unmap the VMA, and map valid VMA at start of ptr range, and replace | ||
| 914 | * all existing multi-move invalid VMAs, except the last, with valid | ||
| 915 | * multi-move VMAs. | ||
| 916 | */ | ||
| 917 | if (munmap(tgt_ptr, page_size)) { | ||
| 918 | perror("munmap"); | ||
| 919 | success = false; | ||
| 920 | goto out_unmap; | ||
| 921 | } | ||
| 922 | if (munmap(ptr, size - 2 * page_size)) { | ||
| 923 | perror("munmap"); | ||
| 924 | success = false; | ||
| 925 | goto out_unmap; | ||
| 926 | } | ||
| 927 | for (i = 0; i < 8; i += 2) { | ||
| 928 | res = mmap(&ptr[i * page_size], page_size, | ||
| 929 | PROT_READ | PROT_WRITE, | ||
| 930 | MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); | ||
| 931 | if (res == MAP_FAILED) { | ||
| 932 | perror("mmap"); | ||
| 933 | success = false; | ||
| 934 | goto out_unmap; | ||
| 935 | } | ||
| 936 | } | ||
| 937 | |||
| 938 | /* | ||
| 939 | * Now try to move the entire range, we should succeed in moving all but | ||
| 940 | * the last VMA, and report a failure. | ||
| 941 | */ | ||
| 942 | res = mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr); | ||
| 943 | err = errno; | ||
| 944 | if (res != MAP_FAILED) { | ||
| 945 | fprintf(stderr, "mremap() succeeded for multi VMA uffd armed\n"); | ||
| 946 | success = false; | ||
| 947 | goto out_unmap; | ||
| 948 | } | ||
| 949 | if (err != EFAULT) { | ||
| 950 | errno = err; | ||
| 951 | perror("mrmeap() unexpected error"); | ||
| 952 | success = false; | ||
| 953 | goto out_unmap; | ||
| 954 | } | ||
| 955 | |||
| 956 | for (i = 0; i < 10; i += 2) { | ||
| 957 | bool is_mapped = is_ptr_mapped(maps_fp, | ||
| 958 | &tgt_ptr[i * page_size], page_size); | ||
| 959 | |||
| 960 | if (i < 8 && !is_mapped) { | ||
| 961 | fprintf(stderr, "Valid VMA not moved at %d\n", i); | ||
| 962 | success = false; | ||
| 963 | goto out_unmap; | ||
| 964 | } else if (i == 8 && is_mapped) { | ||
| 965 | fprintf(stderr, "Invalid VMA moved at %d\n", i); | ||
| 966 | success = false; | ||
| 967 | goto out_unmap; | ||
| 968 | } | ||
| 969 | } | ||
| 970 | |||
| 971 | out_unmap: | ||
| 972 | if (munmap(tgt_ptr, size)) | ||
| 973 | perror("munmap tgt"); | ||
| 974 | if (munmap(ptr, size)) | ||
| 975 | perror("munmap src"); | ||
| 976 | out_close_uffd: | ||
| 977 | close(uffd); | ||
| 978 | out: | ||
| 979 | if (success) | ||
| 980 | ksft_test_result_pass("%s\n", test_name); | ||
| 981 | else | ||
| 982 | ksft_test_result_fail("%s\n", test_name); | ||
| 983 | } | ||
| 984 | #else | ||
| 985 | static void mremap_move_multi_invalid_vmas(FILE *maps_fp, unsigned long page_size) | ||
| 986 | { | ||
| 987 | char *test_name = "mremap move multiple invalid vmas"; | ||
| 988 | |||
| 989 | ksft_test_result_skip("%s - missing uffd", test_name); | ||
| 990 | } | ||
| 991 | #endif /* __NR_userfaultfd */ | ||
| 992 | |||
| 736 | /* Returns the time taken for the remap on success else returns -1. */ | 993 | /* Returns the time taken for the remap on success else returns -1. */ |
| 737 | static long long remap_region(struct config c, unsigned int threshold_mb, | 994 | static long long remap_region(struct config c, unsigned int threshold_mb, |
| 738 | char *rand_addr) | 995 | char *rand_addr) |
| @@ -1074,7 +1331,7 @@ int main(int argc, char **argv) · 335 unmodified lines | |||
| 1074 | char *rand_addr; | 1331 | char *rand_addr; |
| 1075 | size_t rand_size; | 1332 | size_t rand_size; |
| 1076 | int num_expand_tests = 2; | 1333 | int num_expand_tests = 2; |
| 1077 | int num_misc_tests = 8; | 1334 | int num_misc_tests = 9; |
| 1078 | struct test test_cases[MAX_TEST] = {}; | 1335 | struct test test_cases[MAX_TEST] = {}; |
| 1079 | struct test perf_test_cases[MAX_PERF_TEST]; | 1336 | struct test perf_test_cases[MAX_PERF_TEST]; |
| 1080 | int page_size; | 1337 | int page_size; |
| @@ -1197,8 +1454,6 @@ int main(int argc, char **argv) · 116 unmodified lines | |||
| 1197 | mremap_expand_merge(maps_fp, page_size); | 1454 | mremap_expand_merge(maps_fp, page_size); |
| 1198 | mremap_expand_merge_offset(maps_fp, page_size); | 1455 | mremap_expand_merge_offset(maps_fp, page_size); |
| 1199 | 1456 | ||
| 1200 | fclose(maps_fp); | ||
| 1201 | |||
| 1202 | mremap_move_within_range(pattern_seed, rand_addr); | 1457 | mremap_move_within_range(pattern_seed, rand_addr); |
| 1203 | mremap_move_1mb_from_start(pattern_seed, rand_addr); | 1458 | mremap_move_1mb_from_start(pattern_seed, rand_addr); |
| 1204 | mremap_shrink_multiple_vmas(page_size, /* inplace= */true); | 1459 | mremap_shrink_multiple_vmas(page_size, /* inplace= */true); |
| @@ -1207,6 +1462,9 @@ int main(int argc, char **argv) · 2 unmodified lines | |||
| 1207 | mremap_move_multiple_vmas(pattern_seed, page_size, /* dontunmap= */ true); | 1462 | mremap_move_multiple_vmas(pattern_seed, page_size, /* dontunmap= */ true); |
| 1208 | mremap_move_multiple_vmas_split(pattern_seed, page_size, /* dontunmap= */ false); | 1463 | mremap_move_multiple_vmas_split(pattern_seed, page_size, /* dontunmap= */ false); |
| 1209 | mremap_move_multiple_vmas_split(pattern_seed, page_size, /* dontunmap= */ true); | 1464 | mremap_move_multiple_vmas_split(pattern_seed, page_size, /* dontunmap= */ true); |
| 1465 | mremap_move_multi_invalid_vmas(maps_fp, page_size); | ||
| 1466 | |||
| 1467 | fclose(maps_fp); | ||
| 1210 | 1468 | ||
| 1211 | if (run_perf_tests) { | 1469 | if (run_perf_tests) { |
| 1212 | ksft_print_msg("\n%s\n", | 1470 | ksft_print_msg("\n%s\n", |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | |||
| 6 | #include <bpf/bpf.h> | 6 | #include <bpf/bpf.h> |
| 7 | #include <sched.h> | 7 | #include <sched.h> |
| 8 | #include <scx/common.h> | 8 | #include <scx/common.h> |
| 9 | #include <sched.h> | ||
| 10 | #include <sys/wait.h> | 9 | #include <sys/wait.h> |
| 11 | #include <unistd.h> | 10 | #include <unistd.h> |
| 12 | 11 | ||
| @@ -1400,7 +1400,7 @@ static int cmd_dev_get_features(void) · 1399 unmodified lines | |||
| 1400 | 1400 | ||
| 1401 | if (!((1ULL << i) & features)) | 1401 | if (!((1ULL << i) & features)) |
| 1402 | continue; | 1402 | continue; |
| 1403 | if (i < sizeof(feat_map) / sizeof(feat_map[0])) | 1403 | if (i < ARRAY_SIZE(feat_map)) |
| 1404 | feat = feat_map[i]; | 1404 | feat = feat_map[i]; |
| 1405 | else | 1405 | else |
| 1406 | feat = "unknown"; | 1406 | feat = "unknown"; |
| @@ -1477,7 +1477,7 @@ static void __cmd_create_help(char *exe, bool recovery) · 70 unmodified lines | |||
| 1477 | printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), dev_id=-1(auto allocation)\n"); | 1477 | printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), dev_id=-1(auto allocation)\n"); |
| 1478 | printf("\tdefault: nthreads=nr_queues"); | 1478 | printf("\tdefault: nthreads=nr_queues"); |
| 1479 | 1479 | ||
| 1480 | for (i = 0; i < sizeof(tgt_ops_list) / sizeof(tgt_ops_list[0]); i++) { | 1480 | for (i = 0; i < ARRAY_SIZE(tgt_ops_list); i++) { |
| 1481 | const struct ublk_tgt_ops *ops = tgt_ops_list[i]; | 1481 | const struct ublk_tgt_ops *ops = tgt_ops_list[i]; |
| 1482 | 1482 | ||
| 1483 | if (ops->usage) | 1483 | if (ops->usage) |
| @@ -1 +1,5 @@ | |||
| 1 | /* Avoid duplicate definitions due to system headers. */ | ||
| 2 | #ifdef __CONCAT | ||
| 3 | #undef __CONCAT | ||
| 4 | #endif | ||
| 1 | #include "../../../../include/linux/idr.h" | 5 | #include "../../../../include/linux/idr.h" |
| @@ -1,7 +1,15 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | ||
| 3 | include $(srctree)/tools/scripts/utilities.mak | ||
| 4 | |||
| 3 | STOP_ERROR := | 5 | STOP_ERROR := |
| 4 | 6 | ||
| 7 | ifndef ($(NO_LIBTRACEEVENT),1) | ||
| 8 | ifeq ($(call get-executable,$(PKG_CONFIG)),) | ||
| 9 | $(error Error: $(PKG_CONFIG) needed by libtraceevent/libtracefs is missing on this system, please install it) | ||
| 10 | endif | ||
| 11 | endif | ||
| 12 | |||
| 5 | define lib_setup | 13 | define lib_setup |
| 6 | $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)")) | 14 | $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)")) |
| 7 | $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)")) | 15 | $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)")) |
| @@ -1,10 +1,18 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | ||
| 3 | include $(srctree)/tools/scripts/utilities.mak | ||
| 4 | |||
| 3 | STOP_ERROR := | 5 | STOP_ERROR := |
| 4 | 6 | ||
| 5 | LIBTRACEEVENT_MIN_VERSION = 1.5 | 7 | LIBTRACEEVENT_MIN_VERSION = 1.5 |
| 6 | LIBTRACEFS_MIN_VERSION = 1.6 | 8 | LIBTRACEFS_MIN_VERSION = 1.6 |
| 7 | 9 | ||
| 10 | ifndef ($(NO_LIBTRACEEVENT),1) | ||
| 11 | ifeq ($(call get-executable,$(PKG_CONFIG)),) | ||
| 12 | $(error Error: $(PKG_CONFIG) needed by libtraceevent/libtracefs is missing on this system, please install it) | ||
| 13 | endif | ||
| 14 | endif | ||
| 15 | |||
| 8 | define lib_setup | 16 | define lib_setup |
| 9 | $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)")) | 17 | $(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)")) |
| 10 | $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)")) | 18 | $(eval LDFLAGS += $(shell sh -c "$(PKG_CONFIG) --libs-only-L lib$(1)")) |